How to run Playwright Tests in Parallel on GitLab

Hermann KaoHermann Kao
2 min read

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:

# The slow, sequential way 😴
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:

# The speed-demon parallel way 🚀
test:
  stage: test
  image: mcr.microsoft.com/playwright:v1.51.1-noble
  parallel: 5  # Run 5 parallel jobs
  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
0
Subscribe to my newsletter

Read articles from Hermann Kao directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Hermann Kao
Hermann Kao

Software developer documenting my journey through web and mobile development. I share what I learn, build, and struggle with—from React to SwiftUI, architecture decisions to deployment challenges. Not an expert, just passionate about coding and learning in public. Join me as I navigate the tech landscape one commit at a time.