TL;DR
Add parallel: N to your GitLab CI job and pass --shard=${CI_NODE_INDEX}/${CI_NODE_TOTAL} to Playwright to slash your test execution time and keep your team shipping fast.
The Backstory
Last week, our test suite execution time crossed the dreaded 30-minute mark. Team members were context-switching during test runs, and our deploy frequency started to suffer. That's when I discovered we weren't using GitLab CI's parallelization capabilities with our Playwright tests.
The Problem
Running Playwright tests sequentially in GitLab CI can take forever, especially as your test suite grows. Without parallelization, even simple PR validations become coffee-break-length waits:
test:
stage: test
image: mcr.microsoft.com/playwright:v1.51.1-noble
script:
- npm install
- npx playwright test
artifacts:
when: always
paths:
- playwright-report/
- junit.xml
reports:
junit: junit.xml
The Insight
GitLab CI supports running jobs in parallel using the parallel keyword, and Playwright can shard tests with the --shard flag. Combining these powers is like discovering you can breathe underwater:
test:
stage: test
image: mcr.microsoft.com/playwright:v1.51.1-noble
parallel: 5
script:
- npm ci
- npx playwright test --shard=${CI_NODE_INDEX}/${CI_NODE_TOTAL}
artifacts:
when: always
paths:
- playwright-report/
- junit.xml
reports:
junit: junit.xml
Playwright's --shard flag takes two parameters: current shard index and total shards. The magic here is that GitLab CI automatically provides environment variables CI_NODE_INDEX and CI_NODE_TOTAL that perfectly match what Playwright expects!
Why It Matters
After implementing this change:
Our test suite execution time dropped from 30+ minutes to under 10 minutes
Developers stopped context-switching during test runs
We caught integration issues faster and deployed more frequently
For larger projects, you can refine this further by using GitLab's matrix syntax to run different browser tests in parallel:
test:
stage: test
image: mcr.microsoft.com/playwright:v1.51.1-noble
parallel:
matrix:
- BROWSER: [chromium, firefox, webkit]
script:
- npm install
- npx playwright test --project=$BROWSER --shard=${CI_NODE_INDEX}/${CI_NODE_TOTAL}
artifacts:
when: always
paths:
- playwright-report/
- junit.xml
reports:
junit: junit.xml