> ## Documentation Index
> Fetch the complete documentation index at: https://docs.testdino.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Playwright GitLab CI Setup

> Stream Playwright test results from GitLab CI/CD to TestDino live, with sharded jobs grouped into one run.

Stream Playwright test results from GitLab CI/CD to TestDino during the run. Sharded jobs group into one run when they share the same `--ci-run-id`.

## Prerequisites

* A <a href="https://app.testdino.com" target="_blank" rel="noopener noreferrer">TestDino account <Icon icon="arrow-up-right-from-square" size={12} /></a> with a project created
* A TestDino API key ([Generate API Keys](/guides/generate-api-keys))
* A GitLab account with CI/CD pipelines enabled on your repository
* A Playwright test project (or clone the <a href="https://github.com/testdino-hq/TestDino-Example" target="_blank" rel="noopener noreferrer">TestDino Example Repository <Icon icon="arrow-up-right-from-square" size={12} /></a> to get started)
* `@testdino/playwright` installed and configured in `playwright.config.ts|js|mjs`:

```bash theme={null}
npm install @testdino/playwright
```

```typescript playwright.config.ts theme={null}
import { defineConfig } from '@playwright/test';

export default defineConfig({
  reporter: [
    ['@testdino/playwright', {
      token: process.env.TESTDINO_TOKEN,
      serverUrl: "https://reporter.testdino.com",
    }],
  ],
});
```

## Set Up Your API Key

1. Go to your GitLab project
2. Open **Settings → CI/CD**
3. Expand the **Variables** section
4. Click **Add variable**
5. Set the key to `TESTDINO_TOKEN`
6. Paste your TestDino API key as the value
7. Check **Mask variable** to hide it from job logs
8. Save the variable

<Warning>
  **Warning**

  Never commit your API key directly in pipeline files. Always use CI/CD variables. Masked variables are hidden from job output.
</Warning>

## Basic Pipeline Config

For a simple setup without sharding, run your tests with `TESTDINO_TOKEN` set. Results stream to TestDino during the run, so no separate upload step is needed.

<Accordion title=".gitlab-ci.yml: Basic pipeline">
  ```yaml .gitlab-ci.yml theme={null}
  image: mcr.microsoft.com/playwright:v1.59.1-noble

  variables:
    CI: "true"
    TESTDINO_TOKEN: $TESTDINO_TOKEN
    TESTDINO_SERVER_URL: https://reporter.testdino.com

  stages:
    - test

  playwright:
    stage: test
    script:
      - npm ci
      - npx playwright test
    rules:
      - if: $CI_PIPELINE_SOURCE == "merge_request_event"
      - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
      - if: $CI_PIPELINE_SOURCE == "web"
  ```
</Accordion>

<Tip>
  **Tip**

  Results stream live even when tests fail, so failures land on the dashboard without a `when: always` artifact step.
</Tip>

## Sharded Test Runs

For larger test suites, the GitLab CI/CD `parallel` keyword splits tests across multiple jobs. Each shard streams its own results, and TestDino groups them into one run when they share a `ci-run-id`.

### How it works

1. GitLab CI/CD runs Playwright across 4 parallel shards
2. Each shard streams its results to TestDino during the run
3. Every shard passes the same `--ci-run-id` so TestDino merges them into a single run
4. No merge or upload step runs after the shards finish

### Full sharded config

<Accordion title=".gitlab-ci.yml: Sharded pipeline">
  ```yaml .gitlab-ci.yml theme={null}
  image: mcr.microsoft.com/playwright:v1.59.1-noble

  stages:
    - test

  variables:
    CI: "true"
    TESTDINO_TOKEN: $TESTDINO_TOKEN
    TESTDINO_SERVER_URL: https://reporter.testdino.com

  playwright:
    stage: test
    parallel: 4
    script:
      - npm ci
      - npx tdpw test --ci-run-id "$CI_PIPELINE_ID" -- --shard=$CI_NODE_INDEX/$CI_NODE_TOTAL
    rules:
      - if: $CI_PIPELINE_SOURCE == "merge_request_event"
      - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
      - if: $CI_PIPELINE_SOURCE == "web"
  ```
</Accordion>

### Key details

| Config Block                            | What It Does                                                                          |
| :-------------------------------------- | :------------------------------------------------------------------------------------ |
| `parallel: 4`                           | Runs 4 shard jobs in parallel                                                         |
| `--shard=$CI_NODE_INDEX/$CI_NODE_TOTAL` | GitLab provides 1-based index and total count automatically                           |
| `--ci-run-id "$CI_PIPELINE_ID"`         | Groups all shards into one run on the dashboard                                       |
| `TESTDINO_TOKEN`                        | Read from the masked CI/CD variable, used by `@testdino/playwright` to stream results |

Set the `ciRunId` reporter option in `playwright.config` to `$CI_PIPELINE_ID` if you prefer running `npx playwright test` directly instead of `npx tdpw test`.

### Pipeline execution

After the pipeline runs, GitLab shows all shard jobs in the pipeline view. Each shard streams its results, and TestDino merges them into one run.

<img src="https://tdstorageus.blob.core.windows.net/public/docs/installation-and-setup/ci-setup/playwright-gitlab-ci-setup/gitlab-testrun-pipeline-execution.webp" alt="GitLab pipeline view showing 4 parallel playwright shard jobs, each streaming Playwright results to TestDino" />

### Results in TestDino

The test run appears in your TestDino dashboard with full failure details, flaky detection, and trend data as tests complete.

<img src="https://tdstorageus.blob.core.windows.net/public/docs/installation-and-setup/ci-setup/playwright-gitlab-ci-setup/gitlab-uploaded-testdino-testrunscreen.webp" alt="TestDino Test Runs dashboard showing streamed results from GitLab CI pipeline with pass/fail counts and AI Insights" />

## Troubleshooting

<AccordionGroup>
  <Accordion title="Results not appearing on the dashboard">
    Confirm `@testdino/playwright` is in your `playwright.config` `reporter` array and `TESTDINO_TOKEN` is available to the job. Results stream during the run, so no separate upload step is required.
  </Accordion>

  <Accordion title="Sharded runs show up as separate runs">
    Pass the same `--ci-run-id "$CI_PIPELINE_ID"` (or `ciRunId` reporter option) to every shard. Different values create one run per shard.
  </Accordion>

  <Accordion title="TESTDINO_TOKEN not available in job">
    Confirm the variable is set in **Settings → CI/CD → Variables**. If the variable is marked **Protected**, it is only available on protected branches.
  </Accordion>
</AccordionGroup>

## Related

<CardGroup cols={2}>
  <Card title="CI Optimization" icon="gauge-high" href="/guides/playwright-ci-optimization">
    Reduce CI time with smart reruns
  </Card>

  <Card title="Environment Mapping" icon="code-branch" href="/guides/environment-mapping">
    Route test results to Dev, Staging, or Production by branch
  </Card>

  <Card title="Integrations" icon="puzzle-piece" href="/integrations/overview">
    Connect Slack, Jira, Linear, Asana, and more
  </Card>

  <Card title="GitLab Integration" icon="gitlab" href="/integrations/playwright-gitlab-ci">
    MR comments and merge request sync
  </Card>
</CardGroup>
