View as Markdown

Playwright Integration with Mergify

Report your test results from Playwright to Mergify


This guide explains how to integrate Playwright with Test Engine using the @mergifyio/playwright reporter. Once installed, test results are automatically uploaded to Test Engine without any extra workflow changes.

Install the @mergifyio/playwright package alongside @playwright/test to automatically upload your test results to Test Engine.

Terminal window
npm install --save-dev @mergifyio/playwright
Terminal window
yarn add --dev @mergifyio/playwright
Terminal window
pnpm add --save-dev @mergifyio/playwright

Setting up the reporter takes two steps.

Wrap your playwright.config.ts with withMergify:

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

Section titled Import test and expect from Mergify

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

import { test, expect } from '@mergifyio/playwright';
test('logs in', async ({ page }) => {
// ...
});

This import enables test quarantine: when a quarantined test fails, its outcome is reported as passing so it doesn’t block your pipeline.

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

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

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

For example:

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

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

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

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

The test you import from @mergifyio/playwright applies test 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 Engine.

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

Section titled Multi-Project (Cross-Browser) Runs

If your playwright.config.ts defines multiple projects, such as one per browser (chromium, firefox, webkit), the same test runs once per project. A test is identified by its name within the job that ran it, and by default the reporter leaves the project out of that name, so every project’s copy of a test shares one 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 Engine tracks flakiness and quarantine per project:

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.

The reporter uploads each run’s results under your CI job’s name. On GitHub Actions, that name is the job’s identifier (GITHUB_JOB), which every leg of a matrix shares. The job name is part of a test’s identity in Test Engine, so when the legs run the same tests in different environments, their results merge into one test.

Set MERGIFY_TEST_JOB_NAME on each leg and include the matrix value, so each leg reports under its own name:

jobs:
e2e:
strategy:
matrix:
os: [ubuntu-latest, windows-latest]
runs-on: ${{ matrix.os }}
steps:
# ...
- name: Run Tests 🧪
env:
MERGIFY_TOKEN: ${{ secrets.MERGIFY_TOKEN }}
MERGIFY_TEST_JOB_NAME: e2e (${{ matrix.os }})
run: npx playwright test

Legs that each run one --shard of the suite run different tests, so they can share a name. Leave the shard index out of MERGIFY_TEST_JOB_NAME: adding or removing tests can move a test to another shard, and a name per shard would split that test’s history. When you shard within an environment matrix, name each leg after its environment only, as above.

Setting MERGIFY_TEST_JOB_NAME on a job that already reports changes its name, so its tests start a new history in Test Engine.

Verify and Review in Test Engine

Section titled Verify and Review in Test Engine

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

You can then review your test results, including any failures or flaky tests, directly in the Test Engine dashboard.

VariablePurposeDefault
MERGIFY_TOKENAPI authentication tokenRequired
MERGIFY_API_URLAPI endpoint locationhttps://api.mergify.com
PLAYWRIGHT_MERGIFY_ENABLEForce-enable outside CIfalse
PLAYWRIGHT_MERGIFY_INCLUDE_PROJECT_IN_TEST_NAMEPrefix the project name to tests in multi-project runsfalse
MERGIFY_CI_DEBUGPrint spans to console instead of uploadingfalse
MERGIFY_TRACEPARENTW3C distributed trace contextOptional
MERGIFY_TEST_JOB_NAMEName this job reports under; set one per environment, never per shardCI job name

Was this page helpful?