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

# Turn your Playwright tests into monitors

> Run the Playwright tests you already have as scheduled production monitors with a Playwright Check Suite, without rewriting them.

By the end of this guide, two of your existing Playwright tests run against production every ten minutes from two regions, and you have seen what a failure looks like before a real one happens.

![The Shop critical flows Playwright Check Suite in Checkly, passing from two locations](https://mintcdn.com/checkly-422f444a/U1NBK7F5MuPmuEmT/images/guides/playwright-to-monitoring/outcome-check-detail.png?fit=max\&auto=format\&n=U1NBK7F5MuPmuEmT\&q=85\&s=8c8c32d886753bab67c367f45568aeb2)

No Playwright project handy? Clone the [sample project](https://github.com/checkly/docs/tree/main/samples/guides/playwright-to-monitoring) this guide is built on. It runs against the [Danube demo shop](https://danube-web.shop).

> [accordion] Let your agent do it
>
> To run this guide from your terminal or your coding agent, run `npx checkly init` in your project first. It installs the Checkly CLI and [Checkly Skills](https://www.checklyhq.com/docs/ai/skills.md) for your agent. Then paste the prompt below into Claude Code, Cursor, Codex, or any agent that supports skills. It builds the same setup as this guide, proves it with `npx checkly test --record`, and stops for your confirmation before `npx checkly deploy`.
>
> ```txt Prompt theme={null}
> Turn the Playwright tests in this repository into Checkly production monitors.
>
> Goal: a Playwright Check Suite that runs only the tests worth alerting on, every 10 minutes, from us-east-1 and eu-west-1.
>
> Success criteria:
> 1. Add a `monitoring` project to my existing `playwright.config.ts` that selects tests tagged `@monitor`. Do not change the other projects.
> 2. Use `process.env.CHECKLY === '1'` to point `baseURL` at production on Checkly and keep local runs on my dev server. Set `maxFailures: 1` and `retries: 2` for Checkly runs only.
> 3. Tag at most two critical user-flow tests with `@monitor`. Ask me which ones if it is not obvious. Never tag tests that create accounts or mutate data.
> 4. Create `checkly.config.ts` with one entry in `playwrightChecks` that selects the `monitoring` project.
> 5. Run `npx checkly test --record` and show me the session link.
> 6. Stop. Show me `npx checkly deploy --preview` and wait for my confirmation before `npx checkly deploy`.
>
> Explain each file you changed and why.
> ```
>
> Every step below is what the agent just did, in the open, so you can read the result or do it by hand.

## Step 1: Pick the tests that become monitors

Not every test belongs in production monitoring. The sample has three: a search, a checkout, and a signup. Signup creates accounts, so it stays in CI. Search and checkout are what you want to know about within minutes, so they get a `@monitor` tag.

![Diagram: three panels of dots, one per Playwright test. Local runs 40 tests, CI on staging runs all 60 after a pull request, and 12 tagged @monitor become production monitors after merge and deploy](https://mintcdn.com/checkly-422f444a/U1NBK7F5MuPmuEmT/images/guides/playwright-to-monitoring/test-to-monitor-journey.png?fit=max\&auto=format\&n=U1NBK7F5MuPmuEmT\&q=85\&s=b222cf6979ca7511e9b2225fa4d47470)

```ts tests/checkout.spec.ts highlight={3} theme={null}
import { test, expect } from '@playwright/test'

test('checkout completes', { tag: '@monitor' }, async ({ page }) => {
  await page.goto('/')

  // Add the first two books to the cart.
  for (const position of [1, 2]) {
    await page.locator(`.preview:nth-child(${position}) > .preview-author`).click()
    await page.getByRole('button', { name: 'Add to cart' }).click()
    await page.locator('#logo').click()
  }

  await page.locator('#cart').click()
  await page.getByRole('button', { name: 'Checkout' }).click()

  await page.getByPlaceholder('Name', { exact: true }).fill('Max')
  await page.getByPlaceholder('Surname', { exact: true }).fill('Mustermann')
  await page.getByPlaceholder('Address').fill('Charlottenstr. 57')
  await page.getByPlaceholder('Zipcode').fill('10117')
  await page.getByPlaceholder('City').fill('Berlin')
  await page.getByPlaceholder('Company (optional)').fill('Firma GmbH')
  await page.getByLabel('as soon as possible').check()
  await page.getByRole('button', { name: 'Buy' }).click()

  await expect(page.locator('#order-confirmation')).toContainText('Thank you')
})
```

Then give the tagged tests their own Playwright project. Checkly sets `CHECKLY=1` on every run, which is the one switch you need to point monitoring at production while local runs keep using your dev server.

```ts playwright.config.ts highlight={5,10,13,25-26} theme={null}
import { defineConfig, devices } from '@playwright/test'

// Checkly sets CHECKLY=1 on every run. Use it to point monitoring at
// production while local runs keep hitting your dev server.
const onCheckly = process.env.CHECKLY === '1'

export default defineConfig({
  testDir: './tests',
  retries: onCheckly ? 2 : 0,
  // Stop after the first failure on Checkly so alerts fire sooner.
  maxFailures: onCheckly ? 1 : 0,
  use: {
    baseURL: onCheckly ? 'https://danube-web.shop' : 'http://localhost:3000',
    trace: 'retain-on-failure',
  },
  projects: [
    // Everything, for local runs and CI.
    {
      name: 'chromium',
      use: { ...devices['Desktop Chrome'] },
    },
    // Only the flows worth waking someone up for.
    {
      name: 'monitoring',
      grep: /@monitor/,
      use: { ...devices['Desktop Chrome'] },
    },
  ],
})
```

Three settings matter for monitoring and not for testing. `baseURL` makes the same `page.goto('/')` hit production on Checkly. `maxFailures: 1` stops the run at the first failure so the alert goes out sooner. `retries` absorbs a transient network blip before it becomes an alert. Checkly records a trace on every run to collect network and console data, then keeps the trace file according to your `trace` setting, so with `retain-on-failure` only failed tests keep a trace.

> [!TIP]
>
> If your config starts a `webServer`, guard it the same way: `webServer: onCheckly ? undefined : { ... }`. On Checkly the deployed site is already running.

## Step 2: Define the monitor

Install the CLI if this repository does not have it yet, then describe the monitor in a `checkly.config.ts` next to your Playwright config.

```bash Terminal theme={null}
npm install --save-dev checkly
```

A Playwright Check Suite reuses your Playwright config and runs a whole project. A Browser check runs a single spec file with Checkly's own Playwright setup. Pick one.

```ts checkly.config.ts (Playwright Check Suite) theme={null}
import { defineConfig } from 'checkly'
import { Frequency } from 'checkly/constructs'

export default defineConfig({
  projectName: 'Docs guide: Playwright tests to monitors',
  logicalId: 'docs-guide-playwright-to-monitoring',
  checks: {
    // Reuse the Playwright config your tests already run with.
    playwrightConfigPath: './playwright.config.ts',
    playwrightChecks: [
      {
        name: 'Shop critical flows',
        logicalId: 'shop-critical-flows',
        // Run only the `monitoring` project: the @monitor-tagged tests.
        pwProjects: ['monitoring'],
        frequency: Frequency.EVERY_10M,
        locations: ['us-east-1', 'eu-west-1'],
      },
    ],
  },
  cli: {
    runLocation: 'eu-west-1',
  },
})
```

```ts checks/checkout.check.ts (Browser Check) theme={null}
import { BrowserCheck, Frequency } from 'checkly/constructs'
import * as path from 'path'

// The single-file alternative: one spec file becomes one Browser Check.
// Browser Checks run the file on its own, without playwright.config.ts,
// so the spec uses full URLs instead of baseURL.
new BrowserCheck('shop-checkout-browser-check', {
  name: 'Shop checkout (Browser Check)',
  frequency: Frequency.EVERY_10M,
  locations: ['us-east-1', 'eu-west-1'],
  code: {
    entrypoint: path.join(__dirname, 'checkout.spec.ts'),
  },
})
```

The Check Suite path needs nothing else: the `pwProjects` entry selects the `monitoring` project, and the suite runs every ten minutes from Virginia and Ireland. The Browser check path needs a copy of the spec with `page.goto('https://danube-web.shop/')`, because there is no `playwright.config.ts` to supply `baseURL`. The sample keeps that copy in `checks/checkout.spec.ts`.

> [!NOTE]
>
> Prefer to have your coding agent write this file? The [Playwright Check Suite quickstart](https://www.checklyhq.com/docs/detect/synthetic-monitoring/playwright-checks/quickstart.md) has a prompt that inspects your Playwright config and generates the `checkly.config.ts`.

## Step 3: Run it on Checkly before you deploy

`npx checkly test` bundles the project, runs it on Checkly's infrastructure, and streams the result back. `--record` keeps the run so you can open it in the app.

```bash Terminal theme={null}
npx checkly test --record
```

```text Terminal theme={null}
Parsing your project... ✅
Validating project resources... ✅
Bundling project resources... ✅
Uploading Playwright tests... ✅

Test session ID: 01a0ce89-ce0c-74e1-8ee7-e95a2430af87
Open session: https://app.checklyhq.com/accounts/<account-id>/test-sessions/01a0ce89-ce0c-74e1-8ee7-e95a2430af87

Running 2 checks in eu-west-1.

checks/checkout.check.ts
  ✔ Shop checkout (Browser Check) (7s)
playwright.config.ts
  ✔ Shop critical flows (12s)

2 passed, 2 total
```

Both variants from step 2 ran because the sample contains both. Open the session link. Each test in the suite shows its steps and timing. With this config, traces and videos are kept for failed or retried tests, the same as a local run. Set `trace: 'on'` if you want a trace for passing tests too.

![A passing Shop critical flows result in Checkly listing the checkout and search test cases with trace and video attachments](https://mintcdn.com/checkly-422f444a/U1NBK7F5MuPmuEmT/images/guides/playwright-to-monitoring/result-passing.png?fit=max\&auto=format\&n=U1NBK7F5MuPmuEmT\&q=85\&s=c266f66346611786bcf72d45ce8c2267)

## Step 4: Deploy

```bash Terminal theme={null}
npx checkly deploy --schedule-on-deploy
```

```text Terminal theme={null}
Parsing your project... ✅
Validating project resources... ✅
Bundling project resources... ✅
Checking what would change... ✅

Deploy preview · Docs guide: Playwright tests to monitors → account Checkly Marketing

  + PlaywrightCheck  shop-critical-flows          checkly.config.ts
  + BrowserCheck     shop-checkout-browser-check  checks/checkout.check.ts

2 to create, 0 unchanged

This will:
  - Deploy project "Docs guide: Playwright tests to monitors" to account "Checkly Marketing"
  - Schedule changed checks after deploy
  - Delete any resources removed from code, losing their run history. Pass --preserve-resources to keep them in your Checkly account instead

? Apply these changes? › (y/N) y

Uploading Playwright tests... ✅
Deploying project... ✅

Successfully deployed project "Docs guide: Playwright tests to monitors" to account "Checkly Marketing".
```

The suite now runs on its schedule. Because of `--schedule-on-deploy`, the first run starts immediately with `CHECKLY_RUN_SOURCE=CLI_DEPLOY`, then every ten minutes from both locations. It appears in your check list as a Playwright check.

![The Checkly check list showing the Shop critical flows Playwright check with its locations and pass rate](https://mintcdn.com/checkly-422f444a/U1NBK7F5MuPmuEmT/images/guides/playwright-to-monitoring/check-list.png?fit=max\&auto=format\&n=U1NBK7F5MuPmuEmT\&q=85\&s=ebf055935b41c95399128a647f5b28b1)

Every later `npx checkly deploy` updates the suite in place, so the monitor changes whenever the tests do. Wire that into CI and the tests and the monitors ship together.

## Verify it works

Break the checkout on purpose before production does. Rename the `Buy` button in the spec to `Purchase` and run the suite again, without deploying.

```bash Terminal theme={null}
npx checkly test --record --grep "Shop critical flows"
```

```text Terminal theme={null}
Running 1 checks in eu-west-1.

playwright.config.ts
  ✖ Shop critical flows (101s)

    09:53:59 ERROR Error: locator.click: Test timeout of 30000ms exceeded.
    Call log:
      - waiting for getByRole('button', { name: 'Purchase' })

        at tests/checkout.spec.ts:23:56
    09:55:04 INFO  1 ✘ [monitoring] checkout.spec.ts > checkout completes
    09:55:04 INFO  2 ✓ [monitoring] search.spec.ts > search finds a book
    09:55:04 ERROR Testing stopped early after 1 maximum allowed failures.

    View result: https://chkly.link/l/_rONl

1 failed, 1 total
```

Playwright retried the test twice, the search test still passed, and `maxFailures` stopped the run. The result page shows the failing step, the error, a screenshot at the moment of failure, and the trace. This is the page an alert links to.

![The failed checkout test case in Checkly showing three failed attempts, the Playwright error with the failing line highlighted, and View Trace and Analyze root cause buttons](https://mintcdn.com/checkly-422f444a/U1NBK7F5MuPmuEmT/images/guides/playwright-to-monitoring/result-failing.png?fit=max\&auto=format\&n=U1NBK7F5MuPmuEmT\&q=85\&s=cff8b98373f8c3523947a0d2b32a9ef3)

Put `Buy` back. The deployed monitor never saw the broken version, because `npx checkly test` runs the code in your working tree and `npx checkly deploy` is what changes the monitor.

> [!NOTE]
>
> `--grep` matches the check's `name`, not its `logicalId`.

## Next

[Cover every endpoint with uptime monitors](https://www.checklyhq.com/docs/guides/uptime-monitoring.md): add URL and SSL monitors around the flows you just covered, from a few lines of code.

## Reference

* [Playwright Check Suites overview](https://www.checklyhq.com/docs/detect/synthetic-monitoring/playwright-checks/overview.md)
* [Playwright Check Suite configuration](https://www.checklyhq.com/docs/detect/synthetic-monitoring/playwright-checks/configuration.md)
* [Organize your tests and monitors](https://www.checklyhq.com/docs/detect/synthetic-monitoring/playwright-checks/test-organization.md)
* [Playwright Check Suite environment variables](https://www.checklyhq.com/docs/detect/synthetic-monitoring/playwright-checks/environment-variables.md)
* [`PlaywrightCheck` construct](https://www.checklyhq.com/docs/constructs/playwright-check)
* [`BrowserCheck` construct](https://www.checklyhq.com/docs/constructs/browser-check)
* [`npx checkly test`](https://www.checklyhq.com/docs/cli/checkly-test) and [`npx checkly deploy`](https://www.checklyhq.com/docs/cli/checkly-deploy)
* [Checkly Skills](https://www.checklyhq.com/docs/ai/skills.md)


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.