Root causes of web E2E failures: 1. CSP connect-src only included API origin for NODE_ENV=development, blocking test mode (NODE_ENV=test) from fetching API data 2. CORS_ORIGINS missing the test web port (3010), so API rejected cross-origin requests from the web app 3. NEXT_PUBLIC_API_URL not set in .env.test or playwright config, causing web app to default to port 3001 instead of test port 3011 4. Playwright webServer config didn't inherit parent env vars, so API server lacked Redis/Typesense/MinIO connection info Fixes: - next.config.js: CSP connect-src allows API origins for all non-prod envs - next.config.js: image remotePatterns allow localhost in test mode - .env.test: add NEXT_PUBLIC_API_URL and CORS_ORIGINS - playwright.config.ts: spread process.env into webServer env configs - e2e.yml: add NEXT_PUBLIC_API_URL, API_PORT, WEB_PORT to GH Actions env - homepage.spec.ts: update stale assertions to match current UI Result: 147/202 tests passing (111 API + 36 web), up from 37/91. Remaining 55 web failures are stale UI assertions needing frontend update. Co-Authored-By: Paperclip <noreply@paperclip.ing>
168 lines
4.9 KiB
YAML
168 lines
4.9 KiB
YAML
name: E2E Tests
|
|
|
|
on:
|
|
push:
|
|
branches: [master]
|
|
pull_request:
|
|
branches: [master]
|
|
|
|
concurrency:
|
|
group: e2e-${{ github.ref }}
|
|
cancel-in-progress: true
|
|
|
|
jobs:
|
|
e2e:
|
|
name: Playwright E2E
|
|
runs-on: ubuntu-latest
|
|
timeout-minutes: 20
|
|
|
|
services:
|
|
postgres:
|
|
image: postgis/postgis:16-3.4
|
|
env:
|
|
POSTGRES_DB: goodgo_test
|
|
POSTGRES_USER: goodgo
|
|
POSTGRES_PASSWORD: goodgo_test_secret
|
|
ports:
|
|
- 5432:5432
|
|
options: >-
|
|
--health-cmd "pg_isready -U goodgo -d goodgo_test"
|
|
--health-interval 10s
|
|
--health-timeout 5s
|
|
--health-retries 5
|
|
--health-start-period 30s
|
|
|
|
redis:
|
|
image: redis:7-alpine
|
|
ports:
|
|
- 6379:6379
|
|
options: >-
|
|
--health-cmd "redis-cli ping"
|
|
--health-interval 10s
|
|
--health-timeout 5s
|
|
--health-retries 5
|
|
|
|
typesense:
|
|
image: typesense/typesense:27.1
|
|
ports:
|
|
- 8108:8108
|
|
env:
|
|
TYPESENSE_API_KEY: ts_ci_key
|
|
TYPESENSE_DATA_DIR: /data
|
|
options: >-
|
|
--health-cmd "curl -sf http://localhost:8108/health || exit 1"
|
|
--health-interval 10s
|
|
--health-timeout 5s
|
|
--health-retries 5
|
|
|
|
minio:
|
|
image: minio/minio:latest
|
|
ports:
|
|
- 9000:9000
|
|
env:
|
|
MINIO_ROOT_USER: ${{ vars.CI_MINIO_ACCESS_KEY || 'ci_minio_user' }}
|
|
MINIO_ROOT_PASSWORD: ${{ vars.CI_MINIO_SECRET_KEY || 'ci_minio_secret_key_32chars!!' }}
|
|
options: >-
|
|
--health-cmd "curl -sf http://localhost:9000/minio/health/live || exit 1"
|
|
--health-interval 10s
|
|
--health-timeout 5s
|
|
--health-retries 5
|
|
|
|
env:
|
|
DATABASE_URL: postgresql://goodgo:goodgo_test_secret@localhost:5432/goodgo_test
|
|
REDIS_URL: redis://localhost:6379
|
|
REDIS_HOST: localhost
|
|
REDIS_PORT: 6379
|
|
TYPESENSE_URL: http://localhost:8108
|
|
TYPESENSE_HOST: localhost
|
|
TYPESENSE_PORT: 8108
|
|
TYPESENSE_PROTOCOL: http
|
|
TYPESENSE_API_KEY: ts_ci_key
|
|
MINIO_ENDPOINT: localhost
|
|
MINIO_PORT: 9000
|
|
MINIO_ACCESS_KEY: ${{ vars.CI_MINIO_ACCESS_KEY || 'ci_minio_user' }}
|
|
MINIO_SECRET_KEY: ${{ vars.CI_MINIO_SECRET_KEY || 'ci_minio_secret_key_32chars!!' }}
|
|
MINIO_BUCKET: goodgo-uploads
|
|
NODE_ENV: test
|
|
CI: true
|
|
# API and Web ports for Playwright webServer
|
|
API_PORT: 3001
|
|
WEB_PORT: 3000
|
|
API_BASE_URL: http://localhost:3001/api/v1/
|
|
WEB_BASE_URL: http://localhost:3000
|
|
NEXT_PUBLIC_API_URL: http://localhost:3001/api/v1
|
|
JWT_SECRET: e2e-test-jwt-secret-key-minimum-32-chars-long-enough
|
|
JWT_REFRESH_SECRET: e2e-test-refresh-secret-key-minimum-32-chars-ok
|
|
JWT_EXPIRES_IN: 15m
|
|
JWT_REFRESH_EXPIRES_IN: 7d
|
|
BCRYPT_ROUNDS: 4
|
|
VNPAY_TMN_CODE: TESTCODE
|
|
VNPAY_HASH_SECRET: TESTHASHSECRETTESTHASHSECRETTEST
|
|
VNPAY_URL: https://sandbox.vnpayment.vn/paymentv2/vpcpay.html
|
|
VNPAY_RETURN_URL: http://localhost:3000/payment/return
|
|
GOOGLE_CLIENT_ID: test-google-client-id
|
|
GOOGLE_CLIENT_SECRET: test-google-client-secret
|
|
GOOGLE_CALLBACK_URL: http://localhost:3001/api/v1/auth/google/callback
|
|
ZALO_APP_ID: test-zalo-app-id
|
|
ZALO_APP_SECRET: test-zalo-app-secret
|
|
ZALO_CALLBACK_URL: http://localhost:3001/api/v1/auth/zalo/callback
|
|
|
|
steps:
|
|
- name: Checkout
|
|
uses: actions/checkout@v4
|
|
|
|
- name: Install pnpm
|
|
uses: pnpm/action-setup@v4
|
|
|
|
- name: Setup Node.js
|
|
uses: actions/setup-node@v4
|
|
with:
|
|
node-version: 22
|
|
cache: pnpm
|
|
|
|
- name: Install dependencies
|
|
run: pnpm install --frozen-lockfile
|
|
|
|
- name: Cache Playwright browsers
|
|
id: playwright-cache
|
|
uses: actions/cache@v4
|
|
with:
|
|
path: ~/.cache/ms-playwright
|
|
key: playwright-${{ runner.os }}-${{ hashFiles('pnpm-lock.yaml') }}
|
|
|
|
- name: Install Playwright browsers
|
|
if: steps.playwright-cache.outputs.cache-hit != 'true'
|
|
run: npx playwright install --with-deps chromium
|
|
|
|
- name: Install Playwright system deps
|
|
if: steps.playwright-cache.outputs.cache-hit == 'true'
|
|
run: npx playwright install-deps chromium
|
|
|
|
- name: Generate Prisma client
|
|
run: pnpm db:generate
|
|
|
|
- name: Run database migrations
|
|
run: pnpm db:migrate:deploy
|
|
|
|
- name: Seed database
|
|
run: pnpm db:seed
|
|
|
|
- name: Run E2E tests
|
|
run: pnpm test:e2e
|
|
|
|
- name: Upload Playwright report
|
|
if: ${{ !cancelled() }}
|
|
uses: actions/upload-artifact@v4
|
|
with:
|
|
name: playwright-report
|
|
path: playwright-report/
|
|
retention-days: 14
|
|
|
|
- name: Upload Playwright traces
|
|
if: failure()
|
|
uses: actions/upload-artifact@v4
|
|
with:
|
|
name: playwright-traces
|
|
path: test-results/
|
|
retention-days: 7
|