# How to run Playwright Tests in Parallel on GitLab

## 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:

```yaml
# 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:

```yaml
# 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](https://playwright.dev/docs/test-sharding) 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`](https://docs.gitlab.com/ci/variables/predefined_variables/) 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:

```yaml
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
```
