Skip to content

Commit 47285ec

Browse files
committed
add powershell test scripts
1 parent aa63f48 commit 47285ec

7 files changed

Lines changed: 785 additions & 0 deletions
Lines changed: 311 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,311 @@
1+
#!/usr/bin/env pwsh
2+
3+
$ErrorActionPreference = 'Stop'
4+
5+
$UNRECOVERABLE_ERROR_EXIT_CODE = 69
6+
7+
$NPM_INSTALL_OUTPUT_FILTER = "up to date in|added [0-9]* packages, removed [0-9]* packages, and changed [0-9]* packages in|removed [0-9]* packages, and changed [0-9]* packages in|added [0-9]* packages in|removed [0-9]* packages in"
8+
9+
# Function to check and kill any Node process running on port 3000 (React development server)
10+
function Check-AndKillNodeServer {
11+
try {
12+
$connections = Get-NetTCPConnection -LocalPort 3000 -ErrorAction SilentlyContinue
13+
if ($connections) {
14+
foreach ($conn in $connections) {
15+
$proc = Get-Process -Id $conn.OwningProcess -ErrorAction SilentlyContinue
16+
if ($proc -and $proc.ProcessName -eq "node") {
17+
Write-Host "Found Node server running on port 3000. Killing it..."
18+
Stop-Process -Id $proc.Id -Force -ErrorAction SilentlyContinue
19+
Start-Sleep -Seconds 1
20+
if ($env:VERBOSE -eq "1") {
21+
Write-Host "Node server terminated."
22+
}
23+
}
24+
}
25+
}
26+
} catch {
27+
# Silently ignore errors (port may not be in use)
28+
}
29+
}
30+
31+
# Function to get all child processes of a given PID recursively
32+
function Get-ChildProcesses {
33+
param([int]$ParentPid)
34+
35+
$children = Get-CimInstance Win32_Process -Filter "ParentProcessId = $ParentPid" -ErrorAction SilentlyContinue
36+
$result = @()
37+
foreach ($child in $children) {
38+
$result += $child.ProcessId
39+
$result += Get-ChildProcesses -ParentPid $child.ProcessId
40+
}
41+
return $result
42+
}
43+
44+
# Cleanup function to ensure all processes are terminated
45+
function Cleanup {
46+
# Kill any running npm processes started by this script
47+
if ($script:NPM_PID) {
48+
Stop-Process -Id $script:NPM_PID -Force -ErrorAction SilentlyContinue
49+
}
50+
51+
# Kill React app and its children if they exist
52+
if ($script:REACT_APP_PID) {
53+
$processesToKill = Get-ChildProcesses -ParentPid $script:REACT_APP_PID
54+
55+
# Kill the main process
56+
Stop-Process -Id $script:REACT_APP_PID -Force -ErrorAction SilentlyContinue
57+
58+
# Kill all the subprocesses
59+
foreach ($pid in $processesToKill) {
60+
Stop-Process -Id $pid -Force -ErrorAction SilentlyContinue
61+
}
62+
63+
if ($env:VERBOSE -eq "1") {
64+
Write-Host "React app is terminated!"
65+
}
66+
}
67+
68+
# Remove temporary files if they exist
69+
if ($script:build_output -and (Test-Path $script:build_output)) {
70+
Remove-Item $script:build_output -Force -ErrorAction SilentlyContinue
71+
}
72+
}
73+
74+
# Check for and kill any existing Node server from previous runs
75+
Check-AndKillNodeServer
76+
77+
# Check if build folder name is provided
78+
if (-not $args[0]) {
79+
Write-Host "Error: No build folder name provided."
80+
Write-Host "Usage: $($MyInvocation.MyCommand.Name) <build_folder_name> <conformance_tests_folder>"
81+
exit $UNRECOVERABLE_ERROR_EXIT_CODE
82+
}
83+
84+
# Check if conformance tests folder name is provided
85+
if (-not $args[1]) {
86+
Write-Host "Error: No conformance tests folder name provided."
87+
Write-Host "Usage: $($MyInvocation.MyCommand.Name) <build_folder_name> <conformance_tests_folder>"
88+
exit $UNRECOVERABLE_ERROR_EXIT_CODE
89+
}
90+
91+
$BuildFolder = $args[0]
92+
$ConformanceTestsFolder = $args[1]
93+
94+
if ($args[2] -eq "-v" -or $args[2] -eq "--verbose") {
95+
$env:VERBOSE = "1"
96+
}
97+
98+
$current_dir = Get-Location
99+
100+
try {
101+
# Define the path to the subfolder
102+
$NODE_SUBFOLDER = ".tmp/$BuildFolder"
103+
104+
# Running React application
105+
Write-Host "### Step 1: Starting the React application in folder $NODE_SUBFOLDER..."
106+
107+
if ($env:VERBOSE -eq "1") {
108+
Write-Host "Preparing Node subfolder: $NODE_SUBFOLDER"
109+
}
110+
111+
# Check if the node subfolder exists
112+
if (Test-Path $NODE_SUBFOLDER) {
113+
# Delete all files and folders except "node_modules", "plain_modules", and "package-lock.json"
114+
Get-ChildItem -Path $NODE_SUBFOLDER -Force |
115+
Where-Object {
116+
$_.Name -ne "node_modules" -and
117+
$_.Name -ne "plain_modules" -and
118+
$_.Name -ne "package-lock.json"
119+
} | Remove-Item -Recurse -Force
120+
121+
if ($env:VERBOSE -eq "1") {
122+
Write-Host "Cleanup completed, keeping 'node_modules' and 'package-lock.json'."
123+
}
124+
} else {
125+
if ($env:VERBOSE -eq "1") {
126+
Write-Host "Subfolder does not exist. Creating it..."
127+
}
128+
129+
New-Item -ItemType Directory -Path $NODE_SUBFOLDER -Force | Out-Null
130+
}
131+
132+
Copy-Item -Path "$BuildFolder/*" -Destination $NODE_SUBFOLDER -Recurse -Force
133+
134+
# Move to the subfolder
135+
if (-not (Test-Path $NODE_SUBFOLDER)) {
136+
Write-Host "Error: Node build folder '$NODE_SUBFOLDER' does not exist."
137+
exit $UNRECOVERABLE_ERROR_EXIT_CODE
138+
}
139+
140+
Push-Location $NODE_SUBFOLDER
141+
142+
$npmInstallOutput = npm install --prefer-offline --no-audit --no-fund --loglevel error 2>&1 | Out-String
143+
# Filter out noisy npm install lines
144+
$npmInstallOutput -split "`n" | Where-Object { $_ -notmatch $NPM_INSTALL_OUTPUT_FILTER } | ForEach-Object {
145+
if ($_.Trim()) { Write-Host $_ }
146+
}
147+
148+
if ($LASTEXITCODE -ne 0) {
149+
Write-Host "Error: Installing Node modules."
150+
exit 2
151+
}
152+
153+
if ($env:VERBOSE -eq "1") {
154+
Write-Host "Building the application..."
155+
}
156+
157+
$script:build_output = [System.IO.Path]::GetTempFileName()
158+
159+
npm run build > $script:build_output 2>&1
160+
161+
if ($LASTEXITCODE -ne 0) {
162+
Write-Host "Error: Building application."
163+
Get-Content $script:build_output
164+
Remove-Item $script:build_output -Force -ErrorAction SilentlyContinue
165+
exit 2
166+
}
167+
168+
Remove-Item $script:build_output -Force -ErrorAction SilentlyContinue
169+
170+
if ($env:VERBOSE -eq "1") {
171+
Write-Host "Starting the application..."
172+
}
173+
174+
# Start the React app in the background and redirect output to a log file
175+
$env:BROWSER = "none"
176+
$reactProcess = Start-Process -FilePath "npm" -ArgumentList "start", "--", "--no-open" `
177+
-NoNewWindow -PassThru -RedirectStandardOutput "app.log" -RedirectStandardError "app_err.log"
178+
179+
if ($env:VERBOSE -eq "1") {
180+
Write-Host "Application is starting..."
181+
}
182+
183+
# Capture the process ID
184+
$script:REACT_APP_PID = $reactProcess.Id
185+
186+
# Try to find the child npm process
187+
Start-Sleep -Milliseconds 500
188+
$npmChild = Get-CimInstance Win32_Process -Filter "ParentProcessId = $($script:REACT_APP_PID)" -ErrorAction SilentlyContinue |
189+
Where-Object { $_.Name -match "npm" } | Select-Object -First 1
190+
if ($npmChild) {
191+
$script:NPM_PID = $npmChild.ProcessId
192+
}
193+
194+
# Wait for the "compiled successfully!" or Vite ready message in the log file
195+
while ($true) {
196+
if (Test-Path "app.log") {
197+
$logContent = Get-Content "app.log" -Raw -ErrorAction SilentlyContinue
198+
if ($logContent) {
199+
if ($logContent -match "(?i)compiled successfully|compiled with warnings") {
200+
break
201+
}
202+
if ($logContent -match "(?i)VITE v[0-9]+\.[0-9]+\.[0-9]+\s+ready in") {
203+
break
204+
}
205+
}
206+
}
207+
208+
# Also check if localhost:3000 responds
209+
try {
210+
$response = Invoke-WebRequest -Uri "http://localhost:3000" -UseBasicParsing -TimeoutSec 1 -ErrorAction SilentlyContinue
211+
if ($response) { break }
212+
} catch {
213+
# Not ready yet
214+
}
215+
216+
# Check if the React app process is still running
217+
$proc = Get-Process -Id $script:REACT_APP_PID -ErrorAction SilentlyContinue
218+
if (-not $proc -or $proc.HasExited) {
219+
Write-Host "Error in :ImplementationCode: (React app process (PID: $($script:REACT_APP_PID)) has terminated unexpectedly)."
220+
if (Test-Path "app.log") { Get-Content "app.log" }
221+
if (Test-Path "app_err.log") { Get-Content "app_err.log" }
222+
exit 2
223+
}
224+
225+
Start-Sleep -Milliseconds 100
226+
}
227+
228+
# At this point, the React app is up and running in the background
229+
if ($env:VERBOSE -eq "1") {
230+
Write-Host "React app is up and running!"
231+
}
232+
233+
Pop-Location
234+
235+
# Execute all Cypress conformance tests in the build folder
236+
Write-Host "### Step 2: Running Cypress conformance tests $ConformanceTestsFolder..."
237+
238+
# Move back to the original directory
239+
Set-Location $current_dir
240+
241+
# Define the path to the conformance tests subfolder
242+
$NODE_CONFORMANCE_TESTS_SUBFOLDER = ".tmp/$ConformanceTestsFolder"
243+
244+
if ($env:VERBOSE -eq "1") {
245+
Write-Host "Preparing conformance tests Node subfolder: $NODE_CONFORMANCE_TESTS_SUBFOLDER"
246+
}
247+
248+
# Check if the conformance tests node subfolder exists
249+
if (Test-Path $NODE_CONFORMANCE_TESTS_SUBFOLDER) {
250+
# Delete all files and folders except "node_modules", "plain_modules", and "package-lock.json"
251+
Get-ChildItem -Path $NODE_CONFORMANCE_TESTS_SUBFOLDER -Force |
252+
Where-Object {
253+
$_.Name -ne "node_modules" -and
254+
$_.Name -ne "plain_modules" -and
255+
$_.Name -ne "package-lock.json"
256+
} | Remove-Item -Recurse -Force
257+
258+
if ($env:VERBOSE -eq "1") {
259+
Write-Host "Cleanup completed, keeping 'node_modules' and 'package-lock.json'."
260+
}
261+
} else {
262+
if ($env:VERBOSE -eq "1") {
263+
Write-Host "Subfolder does not exist. Creating it..."
264+
}
265+
266+
New-Item -ItemType Directory -Path $NODE_CONFORMANCE_TESTS_SUBFOLDER -Force | Out-Null
267+
}
268+
269+
Copy-Item -Path "$ConformanceTestsFolder/*" -Destination $NODE_CONFORMANCE_TESTS_SUBFOLDER -Recurse -Force
270+
271+
# Move to the subfolder with Cypress tests
272+
if (-not (Test-Path $NODE_CONFORMANCE_TESTS_SUBFOLDER)) {
273+
Write-Host "Error: conformance tests Node folder '$NODE_CONFORMANCE_TESTS_SUBFOLDER' does not exist."
274+
exit $UNRECOVERABLE_ERROR_EXIT_CODE
275+
}
276+
277+
Push-Location $NODE_CONFORMANCE_TESTS_SUBFOLDER
278+
279+
$npmInstallOutput = npm install cypress --save-dev --prefer-offline --no-audit --no-fund --loglevel error 2>&1 | Out-String
280+
$npmInstallOutput -split "`n" | Where-Object { $_ -notmatch $NPM_INSTALL_OUTPUT_FILTER } | ForEach-Object {
281+
if ($_.Trim()) { Write-Host $_ }
282+
}
283+
284+
if ($env:VERBOSE -eq "1") {
285+
Write-Host "Running Cypress conformance tests..."
286+
}
287+
288+
$cypress_info_output = npx cypress info 2>&1 | Out-String
289+
$CYPRESS_BROWSER_FLAG = ""
290+
if ($cypress_info_output -match "(?i)chrome") {
291+
$CYPRESS_BROWSER_FLAG = "--browser=chrome"
292+
}
293+
Write-Host "CYPRESS_BROWSER_FLAG: $(if ($CYPRESS_BROWSER_FLAG) { $CYPRESS_BROWSER_FLAG } else { 'none' })"
294+
295+
$env:BROWSERSLIST_IGNORE_OLD_DATA = "1"
296+
if ($CYPRESS_BROWSER_FLAG) {
297+
npx cypress run $CYPRESS_BROWSER_FLAG --config video=false 2>$null
298+
} else {
299+
npx cypress run --config video=false 2>$null
300+
}
301+
$cypress_run_result = $LASTEXITCODE
302+
303+
if ($cypress_run_result -ne 0) {
304+
if ($env:VERBOSE -eq "1") {
305+
Write-Host "Error: Cypress conformance tests have failed."
306+
}
307+
exit 1
308+
}
309+
} finally {
310+
Cleanup
311+
}

0 commit comments

Comments
 (0)