playwright-best-practices
Audited by Runlayer on Mar 14, 2026
Risky tool definition detected
```yaml image: mcr.microsoft.com/playwright:v1.48.0-noble stages: - install - test - report variables: CI: "true" npm_config_cache: "$CI_PROJECT_DIR/.npm" cache: key: files: - package-lock.json paths: - .npm/ - node_modules/ setup: stage: install script: - npm ci artifacts: paths: - node_modules/ expire_in: 1 hour e2e: stage: test needs: [setup] parallel: 4 script: - npx playwright test --shard=$CI_NODE_INDEX/$CI_NODE_TOTAL artifacts: when: always paths: - blob-report/ expire_in: 1 hour rules: -
**Fix**: Match the Docker image tag to your Playwright version: ```yaml # Check your version: npm ls @playwright/test image: mcr.microsoft.com/playwright:v1.48.0-noble ``` ### Tests hang in GitLab runner: "Navigation timeout exceeded" **Cause**: GitLab shared runners may have limited resources.
Tool passed security scan
Risky tool definition detected
Description: } return violations; } ``` ## Advanced Patterns ### Merging Coverage Across Shards ```typescript // scripts/merge-coverage.ts import fs from "fs"; import { glob } from "glob"; async function mergeCoverage() { const files = await glob("shard-*/coverage/*.json"); const merged = new Map<string, any>(); for (const file of files) { const data = JSON.parse(fs.readFileSync(file, "utf-8")); for (const entry of data) { if (merged.has(entry.url)) { const existing = merged.get(entry.url); exis
Tool passed security scan
Data Exfiltration
Supply Chain Compromise
Risky tool definition detected
Risky tool definition detected
Use `latest` tag or match versions: ```yaml docker: - image: mcr.microsoft.com/playwright:v1.48.0-noble ``` ### Azure DevOps: Test results not showing Missing JUnit reporter or `PublishTestResults@2` task: ```typescript reporter: [['junit', { outputFile: 'results/junit.xml' }]], ``` ```yaml - task: PublishTestResults@2 condition: always() inputs: testResultsFormat: "JUnit" testResultsFiles: "results/junit.xml" ``` ### Shard index off by one CircleCI's `CIRCLE_NODE_INDEX` is 0-based, Playwright's
Data Exfiltration
Risky tool definition detected
**Fix**: - Wait for the post-login page to load: `await page.waitForURL('/home')` - Verify cookies exist before saving: ```typescript const cookies = await context.cookies(); if (cookies.length === 0) { throw new Error("No cookies found after login"); } await context.storageState({ path: ".auth/session.json" }); ``` ### Different browsers get different cookies **Cause**: Some auth flows set cookies with `SameSite=Strict` or use browser-specific cookie behavior.
Risky tool definition detected
[["github"], ["blob"], ["html"]] : [["list"], ["html"]], use: { baseURL: process.env.BASE_URL || "http://localhost:3000", trace: "on-first-retry", screenshot: "only-on-failure", video: "on-first-retry", }, }); ``` ## Related References - **Test tags**: See [test-tags.md](../core/test-tags.md) for tagging and filtering patterns - **Performance optimization**: See [performance.md](performance.md) for sharding and parallelization - **Debugging CI failures**: See [debugging.md](../debugging/debuggin
Tool passed security scan
Risky tool definition detected
```ts webServer: { command: 'npm run dev', url: 'http://localhost:4000/api/health', // use real endpoint reuseExistingServer: !process.env.CI, timeout: 120_000, }, ``` ### Tests Pass Locally But Timeout in CI **Cause**: CI machines are slower.
Risky tool definition detected
**Fix**: Kill stale processes before starting: ```yaml - name: Kill stale processes run: lsof -ti:3000 | xargs kill -9 2>/dev/null || true ``` ### No PR annotations **Cause**: `github` reporter not configured.
Tool passed security scan
Context Poisoning
Supply Chain Compromise
Risky tool definition detected
Tool passed security scan
Risky tool definition detected
2 : 0, use: { trace: 'on-first-retry', }, }); ``` ### JUnit XML Not Recognized Ensure path matches CI configuration: ```typescript reporter: [['junit', { outputFile: 'results/junit.xml' }]], ``` ```yaml # GitHub Actions - uses: dorny/test-reporter@latest with: path: results/junit.xml reporter: java-junit # Azure DevOps - task: PublishTestResults@latest inputs: testResultsFiles: 'results/junit.xml' # Jenkins junit 'results/junit.xml' ``` ### Empty Merged Report Use `blob` reporter for sharded run
Tool passed security scan
Risky tool definition detected
Description: // ✅ GOOD: Proper fixture with cleanup export const test = base.extend<{ tempFile: string }>({ tempFile: async ({}, use) => { const file = `/tmp/test-${Date.now()}.json`; fs.writeFileSync(file, "{}"); await use(file); // Cleanup always runs, even on failure if (fs.existsSync(file)) { fs.unlinkSync(file); } }, }); ``` ## CI-Specific Flakiness ### Why Tests Fail Only in CI | CI Condition | Impact | Solution | | ------------------ | ------------------------------------- | -------------
Risky tool definition detected
Tool passed security scan
Risky tool definition detected
}); }); ``` ### Running Tagged Tests ```bash # Run smoke tests npx playwright test --grep @smoke # Run all except slow tests npx playwright test --grep-invert @slow # Combine tags npx playwright test --grep "@smoke|@critical" ``` For project-based filtering and advanced project configuration, see **[projects-dependencies.md](projects-dependencies.md)**.
Risky tool definition detected
Supply Chain Compromise
Tool passed security scan
Tool passed security scan
Tool passed security scan
Tool passed security scan
Tool passed security scan
Tool passed security scan
Tool passed security scan
Tool passed security scan
Tool passed security scan
Passed Files (37)Click to expand
Tool passed security scan
Tool passed security scan
Tool passed security scan
Tool passed security scan
Tool passed security scan
Tool passed security scan
Tool passed security scan
Tool passed security scan
Tool passed security scan
Tool passed security scan
Tool passed security scan
Tool passed security scan
Tool passed security scan
Tool passed security scan
Tool passed security scan
Tool passed security scan
Tool passed security scan
Tool passed security scan
Tool passed security scan
Tool passed security scan
Tool passed security scan
Tool passed security scan
Tool passed security scan
Tool passed security scan
Tool passed security scan
Tool passed security scan
Tool passed security scan
Tool passed security scan
Tool passed security scan
Tool passed security scan
Tool passed security scan
Tool passed security scan
Tool passed security scan
Tool passed security scan
Tool passed security scan
Tool passed security scan
Tool passed security scan