Skip to main content

Command Palette

Search for a command to run...

How to run Playwright Tests in Parallel on GitLab

Updated
2 min read
How to run Playwright Tests in Parallel on GitLab
H

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.

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

today i learned

Part 3 of 6

Daily code discoveries from my developer journey. Each post delivers concise, actionable insights I've uncovered while building with React, Typescript, and more. Brief but impactful lessons for curious developers looking to grow incrementally.

Up next

Why .bind(this) put me through hell

The Backstory I was peacefully implementing authentication for an Angular app, sipping my coffee, feeling productive. I added a simple tap operator to my login method to store the JWT token in localStorage. Easy-peasy, right? Wrong. The injected Stor...

More from this blog

C

Code Craft by Hermann Kao | Fullstack Development Learning Journey & Tutorials

22 posts

Following my journey through web and mobile development—sharing insights, challenges, and lessons learned as I build with React, SwiftUI, and more. Learning in public, one commit at a time.