Do not add retries yet. First make the CI job identical to a documented local command, then capture a trace on the first failure.
name: e2e
on: [pull_request]
jobs:
playwright:
runs-on: ubuntu-latest
timeout-minutes: 20
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 22
cache: npm
- run: npm ci
- run: npx playwright install --with-deps chromium
- name: Run Playwright
env:
TZ: UTC
LANG: en_US.UTF-8
CI: true
BASE_URL: ${{ vars.BASE_URL }}
run: npx playwright test --project=chromium --reporter=github
- uses: actions/upload-artifact@v4
if: failure()
with:
name: playwright-trace
path: test-results/
import { defineConfig } from "@playwright/test";
export default defineConfig({
use: {
baseURL: process.env.BASE_URL ?? "http://127.0.0.1:3000",
locale: "en-US",
timezoneId: "UTC",
trace: "on-first-retry",
screenshot: "only-on-failure",
video: "retain-on-failure",
},
retries: process.env.CI ? 1 : 0,
workers: process.env.CI ? 2 : undefined,
});
- Run the same install command locally: npx playwright install --with-deps chromium.
- Set TZ=UTC and BASE_URL before npm test so your laptop matches the job.
- Open the uploaded trace with npx playwright show-trace and compare the URL bar, not just the screenshot.
- If the trace shows a different host or an empty app shell, fix deploy/preview — not the locator.