Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
93 changes: 93 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -235,3 +235,96 @@ jobs:
name: playwright-live-report
path: playwright-report/
retention-days: 7

# Cross-browser live smoke tests against real cross-origin deployment (merge queue only)
live-preview-cross-browser-tests:
name: Live Preview Cross-Browser (${{ matrix.browser }})
runs-on: ubuntu-latest
needs: [deploy-preview]
if: github.event_name == 'merge_group'
strategy:
fail-fast: false
matrix:
browser: [chromium, firefox, webkit]
env:
LIVE_TARGET: preview
PLAYWRIGHT_BASE_URL: https://bugdrop-widget-test-git-preview-jermwatts-projects.vercel.app
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0

- uses: actions/setup-node@v4
with:
node-version: '22'
cache: 'npm'

- name: Install dependencies
run: make install

- name: Get Playwright version
id: pw-version
run: echo "version=$(npx playwright --version | awk '{print $2}')" >> "$GITHUB_OUTPUT"

- name: Cache Playwright browser
id: pw-cache
uses: actions/cache@v4
with:
path: ~/.cache/ms-playwright
key: pw-${{ runner.os }}-${{ matrix.browser }}-${{ steps.pw-version.outputs.version }}

- name: Install Playwright browser
if: steps.pw-cache.outputs.cache-hit != 'true'
run: npx playwright install --with-deps ${{ matrix.browser }}

- name: Install Playwright system deps
if: steps.pw-cache.outputs.cache-hit == 'true'
run: npx playwright install-deps ${{ matrix.browser }}

- name: Verify test venue is reachable
run: |
VENUE_URL="${PLAYWRIGHT_BASE_URL}"
echo "Checking test venue at $VENUE_URL..."
BYPASS_ARGS=""
if [ -n "$VERCEL_AUTOMATION_BYPASS_SECRET" ]; then
BYPASS_ARGS="-H x-vercel-protection-bypass:${VERCEL_AUTOMATION_BYPASS_SECRET}"
fi
curl -sfo /dev/null $BYPASS_ARGS "$VENUE_URL" || (echo "Test venue unreachable at $VENUE_URL" && exit 1)
echo "Test venue reachable"
env:
VERCEL_AUTOMATION_BYPASS_SECRET: ${{ secrets.VERCEL_AUTOMATION_BYPASS_SECRET }}

- name: Record expected preview widget asset
run: |
VERSION=$(git describe --tags --abbrev=0) npm run build:widget
echo "EXPECTED_WIDGET_ORIGIN=https://bugdrop-preview.neonwatty.workers.dev" >> "$GITHUB_ENV"
echo "EXPECTED_WIDGET_SHA256=$(shasum -a 256 public/widget.js | awk '{print $1}')" >> "$GITHUB_ENV"

- name: Wait for expected preview widget asset
run: |
WIDGET_URL="https://bugdrop-preview.neonwatty.workers.dev/widget.js"
echo "Waiting for $WIDGET_URL to serve $EXPECTED_WIDGET_SHA256..."
for i in $(seq 1 30); do
ACTUAL_SHA="$(curl -sSf "$WIDGET_URL" | shasum -a 256 | awk '{print $1}')"
if [ "$ACTUAL_SHA" = "$EXPECTED_WIDGET_SHA256" ]; then
echo "Preview widget asset matched after $((i * 5))s"
exit 0
fi
echo "Attempt $i/30 served $ACTUAL_SHA; waiting 5s..."
sleep 5
done
echo "Preview widget did not serve expected asset $EXPECTED_WIDGET_SHA256"
exit 1

- name: Run cross-browser live smoke tests
run: npx playwright test e2e/widget.cross-browser-live.spec.ts --project=${{ matrix.browser }}-cross-browser-live --workers=1
env:
VERCEL_AUTOMATION_BYPASS_SECRET: ${{ secrets.VERCEL_AUTOMATION_BYPASS_SECRET }}

- name: Upload cross-browser test report
uses: actions/upload-artifact@v4
if: failure()
with:
name: playwright-cross-browser-report-${{ matrix.browser }}
path: playwright-report/
retention-days: 7
19 changes: 16 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
.PHONY: dev build build-widget build-all deploy test test-watch test-e2e test-e2e-ui test-e2e-shard lint lint-fix format format-check typecheck knip audit check ci clean install install-playwright help
.PHONY: dev build build-widget build-all deploy test test-watch test-e2e test-e2e-ui test-e2e-shard test-live-cross-browser lint lint-fix format format-check typecheck knip audit check ci clean install install-playwright help

# Development
dev:
Expand All @@ -24,7 +24,7 @@ test-watch:
npm run test:watch

test-e2e:
npm run test:e2e
npx playwright test --project=chromium

test-e2e-ui:
npm run test:e2e:ui
Expand All @@ -36,6 +36,15 @@ test-e2e-shard:
fi
npx playwright test --project=chromium --shard=$(SHARD)

test-live-cross-browser:
@if [ -z "$(BROWSER)" ] || [ -z "$(LIVE_TARGET)" ] || [ -z "$(PLAYWRIGHT_BASE_URL)" ]; then \
echo "Usage: LIVE_TARGET=preview PLAYWRIGHT_BASE_URL=https://example.com make test-live-cross-browser BROWSER=chromium|firefox|webkit"; \
echo "Required: BROWSER, LIVE_TARGET, PLAYWRIGHT_BASE_URL"; \
echo "Set VERCEL_AUTOMATION_BYPASS_SECRET when the Vercel venue is protected."; \
exit 1; \
fi
npx playwright test e2e/widget.cross-browser-live.spec.ts --project=$(BROWSER)-cross-browser-live --workers=1

# Code Quality
lint:
npx eslint .
Expand Down Expand Up @@ -92,6 +101,9 @@ help:
@echo " make test-e2e - Run E2E tests"
@echo " make test-e2e-ui - Run E2E tests with UI"
@echo " make test-e2e-shard SHARD=1/2 - Run E2E test shard"
@echo " LIVE_TARGET=preview PLAYWRIGHT_BASE_URL=<url> make test-live-cross-browser BROWSER=chromium|firefox|webkit"
@echo " - Run live cross-browser E2E tests"
@echo " - Set VERCEL_AUTOMATION_BYPASS_SECRET for protected Vercel venues"
@echo ""
@echo " Code Quality:"
@echo " make lint - Run ESLint"
Expand All @@ -109,4 +121,5 @@ help:
@echo " Utilities:"
@echo " make clean - Clean build artifacts"
@echo " make install - Install dependencies"
@echo " make install-playwright - Install Playwright browsers"
@echo " make install-playwright - Install Chromium Playwright browser"
@echo " npx playwright install --with-deps firefox webkit - Install Firefox/WebKit Playwright browsers"
Loading
Loading