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
63 changes: 30 additions & 33 deletions .github/workflows/playwright-scheduled.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,28 @@ name: Playwright scheduled
# Runs the Playwright suite weekly and on manual dispatch.
# Does NOT gate pull requests — pull-request-check.yml is unrelated.
# See QA_PLAN.md §5 for the full specification.
#
# Mirrors the cypress-manual.yml pattern: the workflow builds *this branch's
# source* with the chosen environment's `.env.<target>` file, starts a local
# `next start` server, and runs Playwright against `http://localhost:3005`.
# This decouples the test from whatever is currently deployed at staging /
# prod URLs — newly added selectors, fixtures, and components are exercised
# against real Strapi data without waiting for a deploy.

on:
schedule:
# Monday 06:00 UTC = Monday 10:00 Yerevan (UTC+4).
- cron: '0 6 * * 1'
workflow_dispatch:
inputs:
environment:
description: 'Target environment'
target_env:
description: 'Which env file to build with (controls Strapi backend, OAuth IDs, etc.)'
type: choice
required: true
default: staging
options:
- staging
- production
- prod
scope:
description: 'Which tier to run (ignored if spec_path is provided)'
type: choice
Expand Down Expand Up @@ -49,22 +56,16 @@ permissions:

jobs:
playwright:
name: Playwright (${{ github.event.inputs.environment || 'staging' }} / ${{ github.event.inputs.scope || 'all' }} / ${{ github.event.inputs.browser || 'chromium' }})
name: Playwright (${{ github.event.inputs.target_env || 'staging' }} / ${{ github.event.inputs.scope || 'all' }} / ${{ github.event.inputs.browser || 'chromium' }})
runs-on: ubuntu-latest
timeout-minutes: 45
env:
CI: 'true'
# scheduled run. Leave unset → the job will fail fast with a clear
# message instead of silently hitting localhost.
#
# Suggested setup:
# If the environment needs auth headers or cookies to reach the app,
# add those as repo secrets and wire them through `env:` here.
PLAYWRIGHT_STAGING_URL: ${{ secrets.PLAYWRIGHT_STAGING_URL }}
PLAYWRIGHT_PRODUCTION_URL: ${{ secrets.PLAYWRIGHT_PRODUCTION_URL }}
# Disable the webServer block in playwright.config.ts — in CI we run
# against a deployed URL, never against a freshly-spawned `yarn dev`.
PLAYWRIGHT_NO_SERVER: '1'
NODE_ENV: production
APP_ENV: ${{ github.event.inputs.target_env || 'staging' }}
# The webServer block in playwright.config.ts reads APP_ENV and runs
# `next start` against the freshly-built `.next/`. baseURL stays at
# the default localhost:3005.
steps:
- name: Checkout
uses: actions/checkout@v4
Expand All @@ -78,23 +79,19 @@ jobs:
- name: Install dependencies
run: yarn install --frozen-lockfile

- name: Decode prod env file
if: env.APP_ENV == 'prod'
run: echo "${{ secrets.ENV_PRODUCTION }}" | base64 -d > .env.prod

- name: Decode staging env file
if: env.APP_ENV == 'staging'
run: echo "${{ secrets.ENV_STAGING }}" | base64 -d > .env.staging

- name: Install Playwright browsers
run: yarn playwright install --with-deps ${{ github.event.inputs.browser == 'all' && 'chromium firefox webkit' || github.event.inputs.browser || 'chromium' }}

- name: Resolve base URL
id: resolve
run: |
ENV_INPUT="${{ github.event.inputs.environment || 'staging' }}"
if [ "$ENV_INPUT" = "production" ]; then
URL="$PLAYWRIGHT_PRODUCTION_URL"
else
URL="$PLAYWRIGHT_STAGING_URL"
fi
if [ -z "$URL" ]; then
echo "::error ::Base URL for environment '$ENV_INPUT' is not configured. Set the PLAYWRIGHT_${ENV_INPUT^^}_URL repository secret."
exit 1
fi
echo "base_url=$URL" >> "$GITHUB_OUTPUT"
- name: Build app
run: yarn cross-env NODE_ENV=production APP_ENV=${{ env.APP_ENV }} next build

- name: Resolve scope path
id: scope
Expand Down Expand Up @@ -123,10 +120,10 @@ jobs:
fi

- name: Run Playwright
env:
PLAYWRIGHT_BASE_URL: ${{ steps.resolve.outputs.base_url }}
run: |
yarn playwright test ${{ steps.scope.outputs.path }} ${{ steps.projects.outputs.args }}
# webServer block in playwright.config.ts spawns `next start` itself
# (because APP_ENV is set), waits for http://localhost:3005, runs
# the suite, and tears the server down at the end.
run: yarn playwright test ${{ steps.scope.outputs.path }} ${{ steps.projects.outputs.args }}

- name: Upload HTML report
if: failure()
Expand Down
15 changes: 13 additions & 2 deletions playwright.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,13 +39,24 @@ export default defineConfig({
use: { ...devices['Desktop Safari'] },
},
],
// Server selection:
// - PLAYWRIGHT_NO_SERVER=1 → don't manage one (e.g. workflow already
// started it, or running against a deployed URL).
// - APP_ENV=staging|prod → pre-built production server (`next start`).
// The CI workflow runs `next build` first, then this block boots
// `next start` against the chosen env file. See
// .github/workflows/playwright-scheduled.yml.
// - else → local `yarn dev`.
webServer: process.env.PLAYWRIGHT_NO_SERVER
? undefined
: {
command: 'yarn dev',
command:
process.env.APP_ENV === 'staging' || process.env.APP_ENV === 'prod'
? `cross-env NODE_ENV=production APP_ENV=${process.env.APP_ENV} next start -p 3005`
: 'yarn dev',
url: baseURL,
reuseExistingServer: !isCI,
timeout: 120_000,
timeout: 180_000,
stdout: 'ignore',
stderr: 'pipe',
},
Expand Down
Loading