---
title: Playwright Integration with Mergify
description: Report your test results from Playwright to Mergify
---

<IntegrationLogo src={playwrightLogo} alt="Playwright logo" />

This guide explains how to integrate [Playwright](https://playwright.dev/) with
Test Insights using the `@mergifyio/playwright` reporter. Once installed, test
results are automatically uploaded to Test Insights without any extra workflow
changes.

## Installation

Install the
[`@mergifyio/playwright`](https://www.npmjs.com/package/@mergifyio/playwright)
package alongside `@playwright/test` to automatically upload your test results
to **Test Insights**.

### npm

```bash
npm install --save-dev @mergifyio/playwright
```

### yarn

```bash
yarn add --dev @mergifyio/playwright
```

### pnpm

```bash
pnpm add --save-dev @mergifyio/playwright
```

## Configuration

Setting up the reporter takes two steps.

### Wrap your Playwright config

Wrap your `playwright.config.ts` with `withMergify`:

```typescript
import { defineConfig } from '@playwright/test';
import { withMergify } from '@mergifyio/playwright';

export default withMergify(
  defineConfig({
    // ... your existing configuration
  })
);
```

`withMergify` adds the Mergify reporter while preserving any reporters,
`globalSetup`, and `globalTeardown` you already have configured.

### Import `test` and `expect` from Mergify

In your test files, import `test` and `expect` from `@mergifyio/playwright`
instead of `@playwright/test`:

```typescript
import { test, expect } from '@mergifyio/playwright';

test('logs in', async ({ page }) => {
  // ...
});
```

This import enables [test quarantine](/test-insights/quarantine): when a
quarantined test fails, its outcome is reported as passing so it doesn't block
your pipeline.

:::caution
  If you wrap your config with `withMergify` but forget to update the `test`
  import, the quarantine list is fetched but never applied, so quarantined
  tests still fail your pipeline.
:::

## Update Your CI Workflow

<CIInsightsSetupNote />

Your workflow should run your tests as usual while exporting the secret
`MERGIFY_TOKEN` as an environment variable.

### GitHub Actions

Add the following to the GitHub Actions step running your tests:

```yaml
env:
  MERGIFY_TOKEN: ${{ secrets.MERGIFY_TOKEN }}
```

For example:

```yaml
- name: Run Tests 🧪
  env:
    MERGIFY_TOKEN: ${{ secrets.MERGIFY_TOKEN }}
  run: npx playwright test
```

### Buildkite

Set `MERGIFY_TOKEN` in the environment of the agents running your tests.
The step itself then needs no Mergify-specific configuration:

```yaml
steps:
  - label: "Run Tests 🧪"
    command: npx playwright test
```

<BuildkiteTokenNote plugin={false} />

The reporter automatically collects your test results and sends them to Test
Insights.

## Quarantine and Crashed Runs

The [`test` you import from `@mergifyio/playwright`](#import-test-and-expect-from-mergify)
applies [test quarantine](/test-insights/quarantine) inside the Playwright run.
When a quarantined test ends in any failing status, a timeout included, that
`test` sets the expected status to the outcome, so Playwright counts the result
as expected and the result does not change Playwright's exit code. The exit
code of your test step already accounts for quarantine, so the step needs
nothing more:

- Do not add `continue-on-error: true`. The recipes that upload a JUnit report
  with the `mergifyio/gha-mergify-ci` action need it because the action decides
  the job's result after the tests. Here nothing does, so it would let every
  real failure through.

- There is no step `id` to set and no `test_step_outcome` to pass: both belong
  to that action, which this setup does not use.

A crash cannot pass for a green run either. If Playwright dies mid-run, it
exits non-zero and the step fails. The reporter uploads results when the run
ends, so a process killed outright before then, such as by the out-of-memory
killer, sends nothing to Test Insights.

If the global setup that `withMergify` adds cannot fetch the quarantine list,
the run quarantines nothing, and a quarantined test that fails makes the step
fail as usual.

## Multi-Project (Cross-Browser) Runs

If your `playwright.config.ts` defines multiple
[projects](https://playwright.dev/docs/test-projects), such as one per browser
(`chromium`, `firefox`, `webkit`), the same test runs once per project. By
default, Test Insights identifies each test by name only, so every project's
copy of a test shares the same identity and is treated as a single test. A test
that passes on `chromium` but fails on `webkit` then looks flaky instead of
consistently broken on one browser.

To keep each project's tests separate, set
`PLAYWRIGHT_MERGIFY_INCLUDE_PROJECT_IN_TEST_NAME` to `true`. The reporter then
prefixes each test name with its project, for example
`[chromium] > login.spec.ts > logs in`, so Test Insights tracks flakiness and
quarantine per project:

```yaml
env:
  MERGIFY_TOKEN: ${{ secrets.MERGIFY_TOKEN }}
  PLAYWRIGHT_MERGIFY_INCLUDE_PROJECT_IN_TEST_NAME: "true"
```

This option is opt-in (off by default) to preserve the history of tests that
already report without a project prefix.

## Verify and Review in Test Insights

After pushing these changes, your next CI run reports its Playwright results
automatically.

<ReviewInTestInsights />

## Environment Variables

| Variable | Purpose | Default |
|----------|---------|---------|
| `MERGIFY_TOKEN` | API authentication token | **Required** |
| `MERGIFY_API_URL` | API endpoint location | `https://api.mergify.com` |
| `PLAYWRIGHT_MERGIFY_ENABLE` | Force-enable outside CI | `false` |
| `PLAYWRIGHT_MERGIFY_INCLUDE_PROJECT_IN_TEST_NAME` | Prefix the project name to tests in multi-project runs | `false` |
| `MERGIFY_CI_DEBUG` | Print spans to console instead of uploading | `false` |
| `MERGIFY_TRACEPARENT` | W3C distributed trace context | Optional |

:::tip
  The reporter auto-activates in CI environments (detected via the `CI`
  environment variable). To enable it outside CI, set
  `PLAYWRIGHT_MERGIFY_ENABLE=true`.
:::
