Skip to content

Bugfix/e2e stress test fixes #1

Bugfix/e2e stress test fixes

Bugfix/e2e stress test fixes #1

Workflow file for this run

# Runs lint, unit tests, and E2E suites to gate deployments
name: Test
on:
push:
branches:
- main
pull_request:
branches:
- main
jobs:
test:
name: Test Suite
runs-on: ubuntu-latest
env:
CONVERTKIT_API_KEY: ${{ secrets.CONVERTKIT_API_KEY }}
CONVERTKIT_FORM_ID: ${{ secrets.CONVERTKIT_FORM_ID }}
CRON_SECRET: ${{ secrets.CRON_SECRET }}
RESEND_API_KEY: ${{ secrets.RESEND_API_KEY }}
SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }}
SENTRY_DSN: ${{ secrets.SENTRY_DSN }}
SUPABASE_URL: ${{ secrets.SUPABASE_URL }}
SUPABASE_KEY: ${{ secrets.SUPABASE_KEY }}
SUPABASE_SERVICE_ROLE_KEY: ${{ secrets.SUPABASE_SERVICE_ROLE_KEY }}
SUPABASE_ACCESS_TOKEN: ${{ secrets.SUPABASE_ACCESS_TOKEN }}
SUPABASE_PROJECT_REF: ${{ secrets.SUPABASE_PROJECT_REF }}
SUPABASE_DB_PASSWORD: ${{ secrets.SUPABASE_DB_PASSWORD }}
KV_URL: ${{ secrets.KV_URL }}
KV_REST_API_URL: ${{ secrets.KV_REST_API_URL }}
KV_REST_API_TOKEN: ${{ secrets.KV_REST_API_TOKEN }}
KV_REST_API_READ_ONLY_TOKEN: ${{ secrets.KV_REST_API_READ_ONLY_TOKEN }}
REDIS_URL: ${{ secrets.REDIS_URL }}
WEBMENTION_IO_TOKEN: ${{ secrets.WEBMENTION_IO_TOKEN }}
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Determine hotfix skip
id: branch-filter
shell: bash
run: |
ref="${GITHUB_HEAD_REF:-${GITHUB_REF#refs/heads/}}"
if [[ "$ref" == hotfix/* ]]; then
echo "skip_tests=true" >> "$GITHUB_OUTPUT"
else
echo "skip_tests=false" >> "$GITHUB_OUTPUT"
fi
- name: Skip notice for hotfix branch
if: steps.branch-filter.outputs.skip_tests == 'true'
run: |
echo "hotfix/* branch detected; skipping lint and test steps."
- name: Setup Node.js
if: steps.branch-filter.outputs.skip_tests != 'true'
uses: actions/setup-node@v4
with:
node-version: '22.x'
cache: 'npm'
- name: Install dependencies
if: steps.branch-filter.outputs.skip_tests != 'true'
run: npm ci --legacy-peer-deps
- name: Sync Astro types
if: steps.branch-filter.outputs.skip_tests != 'true'
run: npm run sync
- name: Run Astro check
if: steps.branch-filter.outputs.skip_tests != 'true'
run: npm run check
- name: Run lint
if: steps.branch-filter.outputs.skip_tests != 'true'
run: npm run lint
- name: Run unit tests (Vitest — coverage with GitHub Actions reporter)
if: steps.branch-filter.outputs.skip_tests != 'true'
id: vitest
run: |
npm run test:coverage
- name: Report Coverage
if: steps.branch-filter.outputs.skip_tests != 'true' && steps.vitest.outcome == 'success' && hashFiles('coverage/coverage-summary.json') != ''
uses: davelosert/vitest-coverage-report-action@v2.9.0
with:
json-summary-path: './coverage/coverage-summary.json'
json-final-path: './coverage/coverage-final.json'
- name: Install Playwright browsers
if: steps.branch-filter.outputs.skip_tests != 'true'
run: npx playwright install --with-deps
- name: Set up Docker Buildx
if: steps.branch-filter.outputs.skip_tests != 'true'
uses: docker/setup-buildx-action@v3.11.1
- name: Build Upstash mock image
if: steps.branch-filter.outputs.skip_tests != 'true'
run: docker buildx build --load -t wb/upstash-redis-local:test test/containers/upstash/local-proxy
- name: Generate container env file
if: steps.branch-filter.outputs.skip_tests != 'true'
shell: bash
run: |
set -euo pipefail
mkdir -p test/containers
: "${SUPABASE_SERVICE_ROLE_KEY:?SUPABASE_SERVICE_ROLE_KEY secret is required}"
cat <<EOF > test/containers/.env
COMPOSE_PROJECT_NAME=wb-e2e
CONVERTKIT_HTTP_PORT=9010
RESEND_HTTP_PORT=9011
UPSTASH_HTTP_PORT=${UPSTASH_HTTP_PORT:-8079}
UPSTASH_REDIS_PORT=${UPSTASH_REDIS_PORT:-6380}
UPSTASH_TOKEN=${UPSTASH_TOKEN:-local-dev-token}
SUPABASE_HEALTH_TIMEOUT=${SUPABASE_HEALTH_TIMEOUT:-240}
SUPABASE_URL=${SUPABASE_URL:-http://127.0.0.1:54321}
SUPABASE_SERVICE_ROLE_KEY=${SUPABASE_SERVICE_ROLE_KEY}
EOF
- name: Start mock containers
if: steps.branch-filter.outputs.skip_tests != 'true'
run: npm run containers:up
- name: Wait for mock services
if: steps.branch-filter.outputs.skip_tests != 'true'
run: npm run containers:wait
- name: Start Supabase stack
if: steps.branch-filter.outputs.skip_tests != 'true'
run: npm run containers:supabase:start
- name: Apply Supabase migrations (local container)
if: steps.branch-filter.outputs.skip_tests != 'true'
run: npm run containers:supabase:db-push
- name: Start Astro dev server
if: steps.branch-filter.outputs.skip_tests != 'true'
run: |
npm run dev -- --host 0.0.0.0 > /tmp/astro-dev.log 2>&1 &
echo $! > /tmp/astro-dev.pid
- name: Wait for dev server
if: steps.branch-filter.outputs.skip_tests != 'true'
run: |
for attempt in $(seq 1 60); do
if curl -fsS http://127.0.0.1:4321 >/dev/null; then
echo "✅ Dev server is responding"
exit 0
fi
sleep 2
done
echo "❌ Dev server failed to start" >&2
if [ -f /tmp/astro-dev.log ]; then
echo '--- Astro dev server log ---'
cat /tmp/astro-dev.log
fi
exit 1
- name: Run Playwright E2E tests
if: steps.branch-filter.outputs.skip_tests != 'true'
run: npx playwright test
env:
CI: '1'
FORCE_COLOR: '1'
E2E_MOCKS: '1'
- name: Stop Astro dev server
if: always() && steps.branch-filter.outputs.skip_tests != 'true'
run: |
if [ -f /tmp/astro-dev.pid ]; then
kill $(cat /tmp/astro-dev.pid) || true
rm /tmp/astro-dev.pid
fi
- name: Upload Playwright report
if: always() && steps.branch-filter.outputs.skip_tests != 'true'
uses: actions/upload-artifact@v4
with:
name: playwright-report
path: playwright-report/
retention-days: 30
- name: Upload test coverage
if: always() && steps.branch-filter.outputs.skip_tests != 'true'
uses: actions/upload-artifact@v5
with:
name: test-coverage
path: coverage/
retention-days: 30
- name: Stop Supabase stack
if: always() && steps.branch-filter.outputs.skip_tests != 'true'
run: npm run containers:supabase:stop || true
- name: Stop mock containers
if: always() && steps.branch-filter.outputs.skip_tests != 'true'
run: npm run containers:down || true