Ci test win #104
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Test Scripts - Mac, Linux and Windows | |
| permissions: | |
| contents: read | |
| on: | |
| schedule: | |
| # Run daily at 2 AM UTC | |
| - cron: '0 2 * * *' | |
| pull_request: | |
| branches: | |
| - main | |
| workflow_dispatch: | |
| jobs: | |
| test-mac: | |
| name: Test mac/run.sh on macOS | |
| if: false | |
| runs-on: macos-latest | |
| timeout-minutes: 15 | |
| environment: BrowserStack | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Set up Python 3.12 | |
| uses: actions/setup-python@v5 | |
| with: | |
| python-version: '3.12' | |
| - name: Set up Bash | |
| run: | | |
| echo "Bash version:" | |
| bash --version | |
| - name: Validate shell script syntax | |
| run: | | |
| echo "Validating mac/run.sh syntax..." | |
| bash -n mac/run.sh | |
| echo "✅ mac/run.sh syntax is valid" | |
| - name: Validate supporting scripts syntax | |
| run: | | |
| echo "Validating supporting scripts..." | |
| bash -n mac/common-utils.sh | |
| bash -n mac/logging-utils.sh | |
| bash -n mac/env-setup-run.sh | |
| bash -n mac/user-interaction.sh | |
| bash -n mac/env-prequisite-checks.sh | |
| echo "✅ All supporting scripts are valid" | |
| - name: Check if scripts are executable | |
| run: | | |
| chmod +x mac/run.sh | |
| chmod +x mac/common-utils.sh | |
| chmod +x mac/logging-utils.sh | |
| chmod +x mac/env-setup-run.sh | |
| chmod +x mac/user-interaction.sh | |
| chmod +x mac/env-prequisite-checks.sh | |
| echo "✅ All scripts are executable" | |
| - name: Run ShellCheck on mac scripts | |
| run: | | |
| brew install shellcheck | |
| echo "Running ShellCheck on mac scripts..." | |
| shellcheck -x mac/run.sh || true | |
| shellcheck -x mac/common-utils.sh || true | |
| shellcheck -x mac/logging-utils.sh || true | |
| shellcheck -x mac/env-setup-run.sh || true | |
| shellcheck -x mac/user-interaction.sh || true | |
| shellcheck -x mac/env-prequisite-checks.sh || true | |
| echo "✅ ShellCheck analysis complete" | |
| - name: Verify required dependencies | |
| run: | | |
| echo "Checking required dependencies..." | |
| command -v bash && echo "✅ bash found" | |
| command -v curl && echo "✅ curl found" | |
| command -v git && echo "✅ git found" | |
| command -v bc && echo "✅ bc found" | |
| echo "All required dependencies are available" | |
| - name: Test script sourcing (dry run) | |
| run: | | |
| set -e | |
| echo "Testing script sourcing..." | |
| bash -c "source mac/common-utils.sh && echo '✅ common-utils.sh sourced successfully'" | |
| echo "✅ Script sourcing successful" | |
| - name: Integration Test - Silent Mode Execution | |
| if: success() | |
| env: | |
| BROWSERSTACK_USERNAME: ${{ secrets.BROWSERSTACK_USERNAME }} | |
| BROWSERSTACK_ACCESS_KEY: ${{ secrets.BROWSERSTACK_ACCESS_KEY }} | |
| TURL: https://bstackdemo.com | |
| run: | | |
| echo "Running integration tests in silent mode..." | |
| # Set default values if secrets are not provided | |
| BROWSERSTACK_USERNAME="${BROWSERSTACK_USERNAME:-test_user}" | |
| BROWSERSTACK_ACCESS_KEY="${BROWSERSTACK_ACCESS_KEY:-test_key}" | |
| export BROWSERSTACK_USERNAME | |
| export BROWSERSTACK_ACCESS_KEY | |
| export TURL | |
| # Test configurations | |
| test_configs=( | |
| "web java" | |
| "app java" | |
| "web python" | |
| "app python" | |
| "web nodejs" | |
| "app nodejs" | |
| ) | |
| for config in "${test_configs[@]}"; do | |
| read -r test_type tech_stack <<< "$config" | |
| echo "================================" | |
| echo "Testing: mac/run.sh --silent $test_type $tech_stack" | |
| echo "================================" | |
| # Run with timeout and capture exit code (macOS compatible) | |
| bash mac/run.sh --silent "$test_type" "$tech_stack" >> "/tmp/run_test_${test_type}_${tech_stack}.log" 2>&1 & | |
| job_pid=$! | |
| # Wait with 600 second timeout using sleep loop (macOS compatible) | |
| count=0 | |
| max_wait=600 | |
| while kill -0 "$job_pid" 2>/dev/null && [ $count -lt $max_wait ]; do | |
| sleep 1 | |
| count=$((count + 1)) | |
| done | |
| # Check if process is still running after timeout | |
| if kill -0 "$job_pid" 2>/dev/null; then | |
| echo "⚠️ mac/run.sh --silent $test_type $tech_stack timed out after 600 seconds" | |
| kill -9 "$job_pid" 2>/dev/null || true | |
| exit_code=124 | |
| else | |
| wait "$job_pid" || exit_code=$? | |
| fi | |
| if [ -z "$exit_code" ] || [ "$exit_code" -eq 0 ] || [ "$exit_code" -eq 124 ]; then | |
| echo "✅ mac/run.sh --silent $test_type $tech_stack completed (exit code: ${exit_code:-0})" | |
| else | |
| echo "⚠️ mac/run.sh --silent $test_type $tech_stack exited with code: $exit_code" | |
| if [ -f "/tmp/run_test_${test_type}_${tech_stack}.log" ]; then | |
| echo "Log output (last 20 lines):" | |
| tail -n 20 "/tmp/run_test_${test_type}_${tech_stack}.log" | |
| fi | |
| fi | |
| unset exit_code | |
| done | |
| echo "✅ All integration tests completed" | |
| - name: Sync BrowserStack logs to workspace | |
| if: always() | |
| run: | | |
| mkdir -p ${{ github.workspace }}/bs-logs | |
| if [ -d ~/.browserstack/NOW/logs ]; then | |
| cp -R ~/.browserstack/NOW/logs/* ${{ github.workspace }}/bs-logs/ || true | |
| else | |
| echo "No logs found in ~/.browserstack/NOW/logs" | |
| fi | |
| - name: Upload BrowserStack Logs as Artifacts | |
| if: always() | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: browserstack-logs-macos | |
| path: | | |
| ${{ github.workspace }}/bs-logs | |
| /tmp/run_test_*.log | |
| retention-days: 30 | |
| if-no-files-found: ignore | |
| test-windows: | |
| name: Test win/run.ps1 on Windows | |
| runs-on: windows-latest | |
| timeout-minutes: 25 | |
| environment: BrowserStack | |
| defaults: | |
| run: | |
| shell: powershell | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Set up Python 3.12 | |
| uses: actions/setup-python@v5 | |
| with: | |
| python-version: '3.12' | |
| - name: Check PowerShell version | |
| run: | | |
| $PSVersionTable.PSVersion | |
| Write-Host "✅ PowerShell version check complete" | |
| - name: Validate PowerShell script syntax | |
| run: | | |
| Write-Host "Validating win/run.ps1 syntax..." | |
| $ScriptPath = "win/run.ps1" | |
| $null = [System.Management.Automation.PSParser]::Tokenize((Get-Content -Raw $ScriptPath), [ref]$null) | |
| Write-Host "✅ win/run.ps1 syntax is valid" | |
| - name: Validate supporting PowerShell scripts syntax | |
| run: | | |
| Write-Host "Validating supporting PowerShell scripts..." | |
| $Scripts = @( | |
| "win/common-utils.ps1", | |
| "win/logging-utils.ps1", | |
| "win/env-prequisite-checks.ps1", | |
| "win/user-interaction.ps1", | |
| "win/env-setup-run.ps1", | |
| "win/device-machine-allocation.ps1" | |
| ) | |
| foreach ($Script in $Scripts) { | |
| $null = [System.Management.Automation.PSParser]::Tokenize((Get-Content -Raw $Script), [ref]$null) | |
| Write-Host "✅ $Script syntax is valid" | |
| } | |
| - name: Run PSScriptAnalyzer | |
| run: | | |
| Write-Host "Installing PSScriptAnalyzer if needed..." | |
| if (-not (Get-Module -ListAvailable -Name PSScriptAnalyzer)) { | |
| Install-Module -Name PSScriptAnalyzer -Force -SkipPublisherCheck -Scope CurrentUser | |
| } | |
| Write-Host "Running PSScriptAnalyzer..." | |
| Invoke-ScriptAnalyzer -Path "win" -Recurse -ReportSummary -ErrorAction Continue | |
| Write-Host "✅ PSScriptAnalyzer analysis complete (continuing even if issues are found)" | |
| - name: Check script file encoding | |
| run: | | |
| Write-Host "Checking PowerShell script encoding..." | |
| $ScriptPath = "win/run.ps1" | |
| $bytes = [System.IO.File]::ReadAllBytes($ScriptPath) | |
| $encoding = "Unknown / ASCII / UTF-8 without BOM" | |
| if ($bytes.Length -ge 3 -and $bytes[0] -eq 0xEF -and $bytes[1] -eq 0xBB -and $bytes[2] -eq 0xBF) { | |
| $encoding = "UTF-8 with BOM" | |
| } elseif ($bytes.Length -ge 2 -and $bytes[0] -eq 0xFF -and $bytes[1] -eq 0xFE) { | |
| $encoding = "UTF-16 LE" | |
| } elseif ($bytes.Length -ge 2 -and $bytes[0] -eq 0xFE -and $bytes[1] -eq 0xFF) { | |
| $encoding = "UTF-16 BE" | |
| } | |
| Write-Host "Detected encoding (heuristic): $encoding" | |
| Write-Host "✅ Encoding check complete" | |
| - name: Verify required dependencies | |
| run: | | |
| Write-Host "Checking required dependencies..." | |
| if (Get-Command curl.exe -ErrorAction SilentlyContinue) { Write-Host "✅ curl found" } else { Write-Host "⚠️ curl not found" } | |
| if (Get-Command git.exe -ErrorAction SilentlyContinue) { Write-Host "✅ git found" } else { Write-Host "⚠️ git not found" } | |
| Write-Host "✅ PowerShell dependencies verified" | |
| - name: Integration Test - Silent Mode Execution | |
| if: success() | |
| env: | |
| BROWSERSTACK_USERNAME: ${{ secrets.BROWSERSTACK_USERNAME }} | |
| BROWSERSTACK_ACCESS_KEY: ${{ secrets.BROWSERSTACK_ACCESS_KEY }} | |
| TURL: https://bstackdemo.com | |
| run: | | |
| Write-Host "Running integration tests in silent mode..." | |
| # Use defaults if secrets are missing (for local / dry runs) | |
| $BrowserStackUsername = if ($env:BROWSERSTACK_USERNAME) { $env:BROWSERSTACK_USERNAME } else { "test_user" } | |
| $BrowserStackAccessKey = if ($env:BROWSERSTACK_ACCESS_KEY) { $env:BROWSERSTACK_ACCESS_KEY } else { "test_key" } | |
| $TestUrl = $env:TURL | |
| $env:BROWSERSTACK_USERNAME = $BrowserStackUsername | |
| $env:BROWSERSTACK_ACCESS_KEY = $BrowserStackAccessKey | |
| $env:TURL = $TestUrl | |
| # Absolute path is safer in CI | |
| $scriptPath = Join-Path $env:GITHUB_WORKSPACE "win\run.ps1" | |
| $testConfigs = @( | |
| @("web", "java"), | |
| @("app", "java"), | |
| @("web", "python"), | |
| @("app", "python"), | |
| @("web", "nodejs"), | |
| @("app", "nodejs") | |
| ) | |
| $overallFailed = $false | |
| $logRoot = Join-Path $env:TEMP "now-tests" | |
| New-Item -ItemType Directory -Force -Path $logRoot | Out-Null | |
| foreach ($config in $testConfigs) { | |
| $testType = $config[0] | |
| $techStack = $config[1] | |
| Write-Host "================================" | |
| Write-Host "Testing: $scriptPath --silent $testType $techStack" | |
| Write-Host "================================" | |
| $logPath = Join-Path $logRoot "run_test_${testType}_${techStack}.log" | |
| & $scriptPath --silent $testType $techStack 2>&1 | Tee-Object -FilePath $logPath -Append | |
| $exitCode = $LASTEXITCODE | |
| if ($exitCode -eq 0) { | |
| Write-Host "✅ $testType / $techStack completed (exit code: $exitCode)" | |
| } else { | |
| Write-Host "⚠️ $testType / $techStack exited with code: $exitCode" | |
| $overallFailed = $true | |
| if (Test-Path $logPath) { | |
| Write-Host "Log output (last 20 lines):" | |
| Get-Content -Path $logPath -Tail 20 | |
| } | |
| } | |
| } | |
| if ($overallFailed) { | |
| Write-Error "One or more configurations failed." | |
| exit 1 | |
| } | |
| Write-Host "✅ All integration tests completed successfully" | |
| - name: Sync BrowserStack logs to workspace (Windows) | |
| if: always() | |
| run: | | |
| $dest = Join-Path $env:GITHUB_WORKSPACE "bs-logs" | |
| New-Item -ItemType Directory -Force -Path $dest | Out-Null | |
| $bsLogPath = Join-Path $env:USERPROFILE ".browserstack\NOW\logs" | |
| $tempLogDir = Join-Path $env:TEMP "now-tests" | |
| if (Test-Path $bsLogPath) { | |
| Write-Host "Copying logs from $bsLogPath" | |
| Copy-Item -Path (Join-Path $bsLogPath "*") -Destination $dest -Recurse -Force -ErrorAction SilentlyContinue | |
| } else { | |
| Write-Host "No logs found at $bsLogPath" | |
| } | |
| if (Test-Path $tempLogDir) { | |
| Write-Host "Copying integration logs from $tempLogDir" | |
| Copy-Item -Path (Join-Path $tempLogDir "*") -Destination $dest -Recurse -Force -ErrorAction SilentlyContinue | |
| } | |
| - name: Upload BrowserStack Logs as Artifacts | |
| if: always() | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: browserstack-logs-windows | |
| path: ${{ github.workspace }}/bs-logs | |
| retention-days: 30 | |
| if-no-files-found: ignore | |
| test-linux: | |
| name: Test mac/run.sh on Linux | |
| if: false | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 15 | |
| environment: BrowserStack | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Set up Python 3.12 | |
| uses: actions/setup-python@v5 | |
| with: | |
| python-version: '3.12' | |
| - name: Set up Bash | |
| run: | | |
| echo "Bash version:" | |
| bash --version | |
| - name: Validate shell script syntax | |
| run: | | |
| echo "Validating mac/run.sh syntax..." | |
| bash -n mac/run.sh | |
| echo "✅ mac/run.sh syntax is valid" | |
| - name: Validate supporting scripts syntax | |
| run: | | |
| echo "Validating supporting scripts..." | |
| bash -n mac/common-utils.sh | |
| bash -n mac/logging-utils.sh | |
| bash -n mac/env-setup-run.sh | |
| bash -n mac/user-interaction.sh | |
| bash -n mac/env-prequisite-checks.sh | |
| echo "✅ All supporting scripts are valid" | |
| - name: Check if scripts are executable | |
| run: | | |
| chmod +x mac/run.sh | |
| chmod +x mac/common-utils.sh | |
| chmod +x mac/logging-utils.sh | |
| chmod +x mac/env-setup-run.sh | |
| chmod +x mac/user-interaction.sh | |
| chmod +x mac/env-prequisite-checks.sh | |
| echo "✅ All scripts are executable" | |
| - name: Install ShellCheck | |
| run: | | |
| echo "Installing ShellCheck..." | |
| sudo apt-get update | |
| sudo apt-get install -y shellcheck | |
| shellcheck --version | |
| - name: Run ShellCheck on mac scripts | |
| run: | | |
| echo "Running ShellCheck on mac scripts..." | |
| shellcheck -x mac/run.sh || true | |
| shellcheck -x mac/common-utils.sh || true | |
| shellcheck -x mac/logging-utils.sh || true | |
| shellcheck -x mac/env-setup-run.sh || true | |
| shellcheck -x mac/user-interaction.sh || true | |
| shellcheck -x mac/env-prequisite-checks.sh || true | |
| echo "✅ ShellCheck analysis complete" | |
| - name: Verify required dependencies | |
| run: | | |
| echo "Checking required dependencies..." | |
| command -v bash && echo "✅ bash found" | |
| command -v curl && echo "✅ curl found" | |
| command -v git && echo "✅ git found" | |
| command -v bc && echo "✅ bc found" | |
| echo "All required dependencies are available" | |
| - name: Test script sourcing (dry run) | |
| run: | | |
| set -e | |
| echo "Testing script sourcing..." | |
| bash -c "source mac/common-utils.sh && echo '✅ common-utils.sh sourced successfully'" | |
| echo "✅ Script sourcing successful" | |
| - name: Integration Test - Silent Mode Execution | |
| if: success() | |
| env: | |
| BROWSERSTACK_USERNAME: ${{ secrets.BROWSERSTACK_USERNAME }} | |
| BROWSERSTACK_ACCESS_KEY: ${{ secrets.BROWSERSTACK_ACCESS_KEY }} | |
| TURL: https://bstackdemo.com | |
| run: | | |
| echo "Running integration tests in silent mode..." | |
| # Set default values if secrets are not provided | |
| BROWSERSTACK_USERNAME="${BROWSERSTACK_USERNAME:-test_user}" | |
| BROWSERSTACK_ACCESS_KEY="${BROWSERSTACK_ACCESS_KEY:-test_key}" | |
| export BROWSERSTACK_USERNAME | |
| export BROWSERSTACK_ACCESS_KEY | |
| export TURL | |
| # Test configurations | |
| test_configs=( | |
| "web java" | |
| "app java" | |
| "web python" | |
| "app python" | |
| "web nodejs" | |
| "app nodejs" | |
| ) | |
| for config in "${test_configs[@]}"; do | |
| read -r test_type tech_stack <<< "$config" | |
| echo "================================" | |
| echo "Testing: mac/run.sh --silent $test_type $tech_stack" | |
| echo "================================" | |
| # Run with timeout and capture exit code (using timeout command on Linux) | |
| timeout 600 bash mac/run.sh --silent "$test_type" "$tech_stack" >> "/tmp/run_test_${test_type}_${tech_stack}.log" 2>&1 & | |
| job_pid=$! | |
| wait "$job_pid" || exit_code=$? | |
| if [ -z "$exit_code" ] || [ "$exit_code" -eq 0 ] || [ "$exit_code" -eq 124 ]; then | |
| echo "✅ mac/run.sh --silent $test_type $tech_stack completed (exit code: ${exit_code:-0})" | |
| else | |
| echo "⚠️ mac/run.sh --silent $test_type $tech_stack exited with code: $exit_code" | |
| if [ -f "/tmp/run_test_${test_type}_${tech_stack}.log" ]; then | |
| echo "Log output (last 20 lines):" | |
| tail -n 20 "/tmp/run_test_${test_type}_${tech_stack}.log" | |
| fi | |
| fi | |
| unset exit_code | |
| done | |
| echo "✅ All integration tests completed" | |
| - name: Sync BrowserStack logs to workspace | |
| if: always() | |
| run: | | |
| mkdir -p ${{ github.workspace }}/bs-logs | |
| if [ -d ~/.browserstack/NOW/logs ]; then | |
| cp -R ~/.browserstack/NOW/logs/* ${{ github.workspace }}/bs-logs/ || true | |
| else | |
| echo "No logs found in ~/.browserstack/NOW/logs" | |
| fi | |
| - name: Upload BrowserStack Logs as Artifacts | |
| if: always() | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: browserstack-logs-linux | |
| path: | | |
| ${{ github.workspace }}/bs-logs | |
| /tmp/run_test_*.log | |
| retention-days: 30 | |
| if-no-files-found: ignore | |
| test-summary: | |
| name: Test Summary | |
| runs-on: ubuntu-latest | |
| needs: [test-windows] | |
| if: always() | |
| steps: | |
| - name: Check test results | |
| run: | | |
| echo "=== Test Results Summary ===" | |
| echo "Windows Tests: ${{ needs.test-windows.result }}" | |
| if [ "${{ needs.test-windows.result }}" = "failure" ]; then | |
| echo "❌ Some tests failed" | |
| exit 1 | |
| fi | |
| echo "✅ All tests passed!" | |
| - name: Notify success | |
| if: success() | |
| run: | | |
| echo "✅ All script validations passed successfully!" | |
| echo "- mac/run.sh and supporting scripts validated on macOS and Linux" | |
| echo "- win/run.ps1 and supporting scripts validated on Windows" | |
| echo "- win/run.ps1 and supporting scripts validated on Windows" |