# Trigger workflow run name: Playwright E2E Tests on: push: branches: [main, develop, dev] pull_request: branches: [main, develop, dev] env: GRAFANA_LOKI_URL: ${{ secrets.GRAFANA_LOKI_URL }} GRAFANA_LOKI_USERNAME: ${{ secrets.GRAFANA_LOKI_USERNAME }} GRAFANA_LOKI_PASSWORD: ${{ secrets.GRAFANA_LOKI_PASSWORD }} jobs: # Pre-flight validation to ensure environment is ready preflight: name: Validate Environment runs-on: ubuntu-latest environment: production steps: - name: Check Required Secrets run: | echo "๐Ÿ” Validating required secrets..." if [ -z "${{ secrets.SUPABASE_SERVICE_ROLE_KEY }}" ]; then echo "โŒ SUPABASE_SERVICE_ROLE_KEY is not set" exit 1 fi if [ -z "${{ secrets.TEST_USER_EMAIL }}" ]; then echo "โš ๏ธ TEST_USER_EMAIL is not set" fi echo "โœ… Required secrets validated" - name: Test Grafana Cloud Loki Connection continue-on-error: true run: | if [ -z "${{ secrets.GRAFANA_LOKI_URL }}" ]; then echo "โญ๏ธ Skipping Loki connection test (GRAFANA_LOKI_URL not configured)" exit 0 fi echo "๐Ÿ” Testing Grafana Cloud Loki connection..." timestamp=$(date +%s)000000000 response=$(curl -s -w "\n%{http_code}" \ --max-time 10 \ -u "${{ secrets.GRAFANA_LOKI_USERNAME }}:${{ secrets.GRAFANA_LOKI_PASSWORD }}" \ -H "Content-Type: application/json" \ -H "User-Agent: ThrillWiki-Playwright-Tests/1.0" \ -X POST "${{ secrets.GRAFANA_LOKI_URL }}/loki/api/v1/push" \ -d "{ \"streams\": [{ \"stream\": { \"job\": \"playwright_preflight\", \"workflow\": \"${{ github.workflow }}\", \"branch\": \"${{ github.ref_name }}\", \"commit\": \"${{ github.sha }}\", \"run_id\": \"${{ github.run_id }}\" }, \"values\": [[\"$timestamp\", \"Preflight check complete\"]] }] }") http_code=$(echo "$response" | tail -n1) if [ "$http_code" = "204" ] || [ "$http_code" = "200" ]; then echo "โœ… Successfully connected to Grafana Cloud Loki" else echo "โš ๏ธ Loki connection returned HTTP $http_code" echo "Response: $(echo "$response" | head -n -1)" echo "Tests will continue but logs may not be sent to Loki" fi test: needs: preflight timeout-minutes: 60 runs-on: ubuntu-latest environment: production strategy: fail-fast: false matrix: browser: [chromium, firefox, webkit] steps: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: node-version: 20 cache: 'npm' - name: Install dependencies run: npm install - name: Install Playwright Browsers run: npx playwright install --with-deps chromium ${{ matrix.browser }} - name: Send Test Start Event to Loki continue-on-error: true run: | if [ -z "${{ secrets.GRAFANA_LOKI_URL }}" ]; then echo "โญ๏ธ Skipping Loki logging (GRAFANA_LOKI_URL not configured)" exit 0 fi timestamp=$(date +%s)000000000 response=$(curl -s -w "\n%{http_code}" \ --max-time 10 \ --retry 3 \ --retry-delay 2 \ -u "${{ secrets.GRAFANA_LOKI_USERNAME }}:${{ secrets.GRAFANA_LOKI_PASSWORD }}" \ -H "Content-Type: application/json" \ -H "User-Agent: ThrillWiki-Playwright-Tests/1.0" \ -X POST "${{ secrets.GRAFANA_LOKI_URL }}/loki/api/v1/push" \ -d "{ \"streams\": [{ \"stream\": { \"job\": \"playwright_tests\", \"browser\": \"${{ matrix.browser }}\", \"workflow\": \"${{ github.workflow }}\", \"branch\": \"${{ github.ref_name }}\", \"commit\": \"${{ github.sha }}\", \"run_id\": \"${{ github.run_id }}\", \"event\": \"test_start\" }, \"values\": [[\"$timestamp\", \"Starting Playwright tests for ${{ matrix.browser }}\"]] }] }") http_code=$(echo "$response" | tail -n1) if [ "$http_code" != "204" ] && [ "$http_code" != "200" ]; then echo "โš ๏ธ Failed to send to Loki (HTTP $http_code): $(echo "$response" | head -n -1)" fi - name: Run Playwright tests id: playwright-run env: SUPABASE_SERVICE_ROLE_KEY: ${{ secrets.SUPABASE_SERVICE_ROLE_KEY }} TEST_USER_EMAIL: ${{ secrets.TEST_USER_EMAIL }} TEST_USER_PASSWORD: ${{ secrets.TEST_USER_PASSWORD }} TEST_MODERATOR_EMAIL: ${{ secrets.TEST_MODERATOR_EMAIL }} TEST_MODERATOR_PASSWORD: ${{ secrets.TEST_MODERATOR_PASSWORD }} BASE_URL: ${{ secrets.BASE_URL || 'http://localhost:8080' }} # Enable Loki reporter GRAFANA_LOKI_URL: ${{ secrets.GRAFANA_LOKI_URL }} GRAFANA_LOKI_USERNAME: ${{ secrets.GRAFANA_LOKI_USERNAME }} GRAFANA_LOKI_PASSWORD: ${{ secrets.GRAFANA_LOKI_PASSWORD }} run: | echo "๐Ÿงช Running Playwright tests for ${{ matrix.browser }}..." npx playwright test --project=${{ matrix.browser }} 2>&1 | tee test-execution.log TEST_EXIT_CODE=${PIPESTATUS[0]} echo "test_exit_code=$TEST_EXIT_CODE" >> $GITHUB_OUTPUT exit $TEST_EXIT_CODE continue-on-error: true - name: Parse Test Results if: always() id: parse-results run: | if [ -f "test-results.json" ]; then echo "๐Ÿ“Š Parsing test results..." TOTAL=$(jq '[.suites[].specs[]] | length' test-results.json || echo "0") PASSED=$(jq '[.suites[].specs[].tests[] | select(.results[].status == "passed")] | length' test-results.json || echo "0") FAILED=$(jq '[.suites[].specs[].tests[] | select(.results[].status == "failed")] | length' test-results.json || echo "0") SKIPPED=$(jq '[.suites[].specs[].tests[] | select(.results[].status == "skipped")] | length' test-results.json || echo "0") DURATION=$(jq '[.suites[].specs[].tests[].results[].duration] | add' test-results.json || echo "0") echo "total=$TOTAL" >> $GITHUB_OUTPUT echo "passed=$PASSED" >> $GITHUB_OUTPUT echo "failed=$FAILED" >> $GITHUB_OUTPUT echo "skipped=$SKIPPED" >> $GITHUB_OUTPUT echo "duration=$DURATION" >> $GITHUB_OUTPUT echo "โœ… Results: $PASSED passed, $FAILED failed, $SKIPPED skipped (${DURATION}ms total)" else echo "โš ๏ธ test-results.json not found" fi - name: Send Test Results to Loki if: always() continue-on-error: true run: | if [ -z "${{ secrets.GRAFANA_LOKI_URL }}" ]; then echo "โญ๏ธ Skipping Loki logging (GRAFANA_LOKI_URL not configured)" exit 0 fi STATUS="${{ steps.playwright-run.outputs.test_exit_code == '0' && 'success' || 'failure' }}" timestamp=$(date +%s)000000000 response=$(curl -s -w "\n%{http_code}" \ --max-time 10 \ --retry 3 \ --retry-delay 2 \ -u "${{ secrets.GRAFANA_LOKI_USERNAME }}:${{ secrets.GRAFANA_LOKI_PASSWORD }}" \ -H "Content-Type: application/json" \ -H "User-Agent: ThrillWiki-Playwright-Tests/1.0" \ -X POST "${{ secrets.GRAFANA_LOKI_URL }}/loki/api/v1/push" \ -d "{ \"streams\": [{ \"stream\": { \"job\": \"playwright_tests\", \"browser\": \"${{ matrix.browser }}\", \"workflow\": \"${{ github.workflow }}\", \"branch\": \"${{ github.ref_name }}\", \"commit\": \"${{ github.sha }}\", \"run_id\": \"${{ github.run_id }}\", \"status\": \"$STATUS\", \"event\": \"test_complete\" }, \"values\": [[\"$timestamp\", \"{\\\"total\\\": ${{ steps.parse-results.outputs.total || 0 }}, \\\"passed\\\": ${{ steps.parse-results.outputs.passed || 0 }}, \\\"failed\\\": ${{ steps.parse-results.outputs.failed || 0 }}, \\\"skipped\\\": ${{ steps.parse-results.outputs.skipped || 0 }}, \\\"duration_ms\\\": ${{ steps.parse-results.outputs.duration || 0 }}}\"]] }] }") http_code=$(echo "$response" | tail -n1) if [ "$http_code" != "204" ] && [ "$http_code" != "200" ]; then echo "โš ๏ธ Failed to send results to Loki (HTTP $http_code): $(echo "$response" | head -n -1)" fi - name: Upload test results uses: actions/upload-artifact@v4 if: always() with: name: playwright-results-${{ matrix.browser }} path: test-results/ retention-days: 30 - name: Upload Playwright report uses: actions/upload-artifact@v4 if: always() with: name: playwright-report-${{ matrix.browser }} path: playwright-report/ retention-days: 30 - name: Comment PR with results uses: daun/playwright-report-comment@v3 if: always() && github.event_name == 'pull_request' with: report-path: test-results.json test-summary: name: Test Summary runs-on: ubuntu-latest needs: test if: always() steps: - name: Download all artifacts uses: actions/download-artifact@v4 - name: Generate summary run: | echo "## Playwright Test Results" >> $GITHUB_STEP_SUMMARY echo "" >> $GITHUB_STEP_SUMMARY echo "Tests completed across all browsers." >> $GITHUB_STEP_SUMMARY echo "" >> $GITHUB_STEP_SUMMARY echo "See artifacts for detailed reports and screenshots." >> $GITHUB_STEP_SUMMARY