Skip to content
DevOps AI ToolKit
Newsletter
All prompts
AI for GitLab CI/CD Difficulty: Intermediate ClaudeChatGPTCursor

GitLab CI/CD Playwright Sharded E2E Test Pipeline Prompt

Run Playwright end-to-end tests sharded across GitLab CI jobs — browser caching, blob-report merge, flaky retries, traces on failure, and a single merged HTML report.

Target user
QA and DevOps engineers running Playwright E2E suites in GitLab CI
Difficulty
Intermediate
Tools
Claude, ChatGPT, Cursor

The prompt

You are a senior test-infra engineer who runs Playwright E2E suites in GitLab CI at scale. You shard tests across parallel jobs, merge their blob reports into one HTML report, cache browsers, attach traces only on failure, and keep flakiness visible rather than papered over.

I will provide:
- The Playwright setup (`playwright.config.ts`, projects/browsers, test count, avg duration)
- The app under test and how it's started in CI (service container / built artifact / external URL)
- Current CI (YAML) or none
- Pain points (too slow / flaky / no traces / report scattered across jobs)
- Runner type and available parallelism

Your job:

1. **Shard across jobs** using `--shard=$CI_NODE_INDEX/$CI_NODE_TOTAL` with GitLab `parallel: N`. Each job runs its slice and writes a **blob** report (`--reporter=blob`).
2. **Merge into one report**: a final job downloads all blob reports as artifacts and runs `npx playwright merge-reports --reporter=html` to produce a single HTML report + JUnit for the MR test tab.
3. **Cache browsers correctly**: pin the `mcr.microsoft.com/playwright:v<exact>` image (browsers preinstalled) OR cache `~/.cache/ms-playwright` keyed on the Playwright version; never let version drift install the wrong browser.
4. **Control flakiness visibly**: `retries: process.env.CI ? 1 : 0`, capture the flaky list, and fail if `test.only` is present.
5. **Traces/videos on failure only**: `trace: 'on-first-retry'`, `video: 'retain-on-failure'`, `screenshot: 'only-on-failure'`; upload as artifacts scoped short.
6. **Start the app deterministically**: use `webServer` in config or a GitLab `service`; wait for readiness before tests; pass the base URL via env.
7. **Wire GitLab reports**: `artifacts:reports:junit` for the MR test widget; publish the HTML report as a browsable artifact.

Deliverables:
- A `playwright.config.ts` tuned for CI (retries, trace, reporters, webServer)
- A `.gitlab-ci.yml` with a `parallel` sharded test job + a merge-reports job via `needs`
- Browser caching/image pinning
- The flaky-visibility and `test.only` guard

Mark DESTRUCTIVE or RISKY: unbounded retries, `trace: 'on'` (secret/PII capture), exposing E2E artifacts publicly, and unpinned Playwright images.

---

Playwright setup: [config, browsers, test count, duration]
App-under-test start: [service / artifact / external URL]
Current CI (YAML): [PASTE or none]
Pain points: [slow / flaky / traces / report]
Runner + parallelism: [DESCRIBE]

Run this prompt with AI

Test it, get an AI-improved version, or compare models — live in the Prompt Workspace. No copy-paste.

Why this prompt works

The two things that make Playwright-in-CI good are sharding (wall-clock speed) and a single merged report (so results aren’t scattered across N job logs). Blob reports + merge-reports solve the report problem cleanly, and pinning the Playwright image kills the most common “works locally, wrong browser in CI” failure. The prompt keeps flakiness visible instead of retrying it away.

How to use it

  1. Shard with parallel: N + --shard=$CI_NODE_INDEX/$CI_NODE_TOTAL.
  2. Emit blob reports and merge them in one final job.
  3. Pin the Playwright image to the exact version.
  4. Traces/videos on failure only; cap retries and surface flakes.

Useful commands

# One shard locally (matches a CI job)
npx playwright test --shard=1/4 --reporter=blob

# Merge blob reports from all shards into one HTML report
npx playwright merge-reports --reporter=html ./all-blob-reports

# Ensure the pinned browser build matches package.json
npx playwright --version
npx playwright install --with-deps chromium

# Guard against a committed test.only
grep -rn "test.only\|describe.only" tests/ && exit 1 || true

GitLab CI patterns

Sharded E2E job + merge

stages: [test, report]

.playwright:
  image: mcr.microsoft.com/playwright:v1.48.0-jammy   # pin to package.json version
  variables:
    BASE_URL: "http://localhost:3000"

e2e:
  extends: .playwright
  stage: test
  parallel: 4
  script:
    - npm ci
    - npx playwright test --shard=$CI_NODE_INDEX/$CI_NODE_TOTAL --reporter=blob
  artifacts:
    when: always
    paths: [blob-report/]
    reports:
      junit: results.xml
    expire_in: 3 days

e2e-report:
  extends: .playwright
  stage: report
  needs: ["e2e"]
  when: always
  script:
    - npm ci
    - npx playwright merge-reports --reporter=html ./blob-report
  artifacts:
    paths: [playwright-report/]     # browsable merged HTML report
    expire_in: 7 days

CI-tuned playwright.config.ts

import { defineConfig } from '@playwright/test';

export default defineConfig({
  forbidOnly: !!process.env.CI,          // fail if test.only committed
  retries: process.env.CI ? 1 : 0,       // capped — not unbounded
  reporter: process.env.CI
    ? [['blob'], ['junit', { outputFile: 'results.xml' }]]
    : [['html']],
  use: {
    baseURL: process.env.BASE_URL,
    trace: 'on-first-retry',             // NOT 'on' — avoids secret/PII capture
    video: 'retain-on-failure',
    screenshot: 'only-on-failure',
  },
  webServer: {
    command: 'npm run start',
    url: 'http://localhost:3000',
    reuseExistingServer: !process.env.CI,
    timeout: 120_000,
  },
});

App-under-test as a service

e2e-against-service:
  extends: .playwright
  services:
    - name: $CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA
      alias: app
  variables:
    BASE_URL: "http://app:3000"
  script:
    - npm ci
    - npx wait-on http://app:3000 -t 60000
    - npx playwright test --shard=$CI_NODE_INDEX/$CI_NODE_TOTAL --reporter=blob

Common findings this catches

  • Test results scattered across shard logs with no merged report.
  • Unpinned Playwright image installing a browser build that mismatches the library version.
  • trace: 'on' capturing secrets/PII into long-lived artifacts.
  • Unbounded retries turning a broken feature green on retry.
  • A committed test.only silently shrinking the run on one shard.

When to escalate

  • Persistent flakiness after capped retries — investigate test/app race conditions, don’t raise the retry cap.
  • E2E artifacts containing regulated data — coordinate retention/redaction with security.
  • Suite too slow even sharded — consider trace-guided test splitting or a dedicated E2E runner pool.

Related prompts

More GitLab CI/CD prompts & error guides

Browse every GitLab CI/CD prompt and troubleshooting guide in one place.

Free download · 368-page PDF

Reading prompts? Get all 500 in one free PDF

500 battle-tested, copy-paste AI prompts engineered by a senior systems engineer — every one with fill-in placeholders and safety/back-out notes. Drop your email and it's yours.

  • 500 prompts: Linux · Kubernetes · Terraform · OpenStack · GitLab · Docker · Monitoring · Incident Response
  • Instant PDF download — yours free, forever
  • Plus one practical AI-workflow email a week (no spam)

Single opt-in · unsubscribe anytime · no spam.