> For the complete documentation index, see [llms.txt](https://learning.contextqa.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://learning.contextqa.com/testing-with-ai-coding-agents/playwright-testing.md).

# Playwright Testing with AI Agents

Use Claude Code, Cursor, or Codex to write and review Playwright tests, verify assertions, and evaluate ContextQA MCP creation and Playwright export.

## Quick answer

An AI coding agent can inspect an application, propose Playwright scenarios, write specs, run them, and investigate failures. Start with an explicit behavior contract and review the generated assertions. Use ContextQA MCP when you want the same assistant to create and run managed tests and retrieve their evidence. If you export those tests to Playwright, inspect the generated project for manual steps and missing assertions before treating it as automated regression coverage.

This tutorial starts with ordinary Playwright. It works with [Claude Code](/testing-with-ai-coding-agents/claude-code-testing.md), [Cursor](/testing-with-ai-coding-agents/cursor-testing.md), [Codex](/testing-with-ai-coding-agents/codex-testing.md), or another coding agent that can edit your repository and run its test command.

## Prerequisites

* A repository with an approved Node.js version and package manager.
* An installed `@playwright/test` dependency and its browser binaries, or permission to add them on a feature branch.
* A disposable local or staging application for real application testing.
* A written expected result, relevant source files, and reproducible test data.
* For the ContextQA path, an account, a reachable test environment, and [MCP setup](/mcp-server/installation-and-setup.md).

If Playwright already exists in the repository, retain its configuration and fixtures. Do not ask the agent to replace working test infrastructure simply to follow a tutorial. For a new project, follow the official [Playwright installation guide](https://playwright.dev/docs/intro) and commit the resulting lockfile.

## 1. Define the behavior before generating code

For a report filter, a useful contract is:

| Condition                      | Expected behavior                                | Evidence                                     |
| ------------------------------ | ------------------------------------------------ | -------------------------------------------- |
| A user selects September       | The requested reporting period is September      | Submitted value or request payload           |
| The report finishes            | The page identifies the selected period          | Exact visible result                         |
| The service fails              | The page reports failure without showing success | Error assertion and response evidence        |
| The user cannot access reports | The operation is denied                          | Authorization and absence of restricted data |

Avoid a test that clicks “Generate” and merely checks that the page still exists. That would miss an incorrect period, a failed request, or an unauthorized result. Decide which checks belong in [unit tests](/testing-with-ai-coding-agents/unit-testing.md), [integration tests](/testing-with-ai-coding-agents/integration-testing.md), and a real [end-to-end journey](/testing-with-ai-coding-agents/end-to-end-testing.md).

Give the agent a bounded task:

```
Read our Playwright configuration, report-page component, existing fixtures,
and report API contract. Propose tests for period selection and service failure.
Use the existing test runner and data setup. Show the expected result for each
scenario before writing specs. Identify any missing fixture or requirement.
Do not invent an API endpoint or weaken an assertion to make a run pass.
```

## 2. Learn the assertion pattern with a small fixture

The following spec is self-contained: it creates a tiny report form in the browser. It teaches locator and assertion behavior; it does **not** test your application's backend, authentication, or reporting implementation.

Save it as `tests/report-form.spec.ts` in a Playwright project:

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

test('the report result identifies the selected month', async ({ page }) => {
  await page.setContent(`
    <form aria-label="Report filters">
      <label for="period">Reporting month</label>
      <select id="period" name="period">
        <option value="2026-08">August 2026</option>
        <option value="2026-09">September 2026</option>
      </select>
      <button type="submit">Generate report</button>
    </form>
    <p role="status"></p>
    <script>
      document.querySelector('form').addEventListener('submit', (event) => {
        event.preventDefault();
        const month = document.querySelector('select').value;
        document.querySelector('[role="status"]').textContent =
          'Report ready for ' + month;
      });
    </script>
  `);

  await page.getByLabel('Reporting month').selectOption('2026-09');
  await page.getByRole('button', { name: 'Generate report', exact: true }).click();
  await expect(page.getByRole('status')).toHaveText('Report ready for 2026-09');
});
```

Run only this spec initially:

```bash
npx playwright test tests/report-form.spec.ts
```

The `page` fixture gives the test its own browser page and context. It does not create isolated database records for an application. Real test-data setup and cleanup remain your responsibility. See [Playwright fixtures](https://playwright.dev/docs/test-fixtures).

The final `await expect(...).toHaveText(...)` retries the condition until it matches or times out. An immediate boolean check can inspect the page too early. Playwright's [assertion reference](https://playwright.dev/docs/test-assertions) explains which matchers retry.

## 3. Turn the pattern into an application test

Replace `page.setContent()` with navigation to your actual report page. Reuse your repository's authenticated fixture and create a unique test account or report record through its approved setup routine. Do not paste the example markup into the application to make the test pass.

Ask the agent to inspect the rendered page before choosing locators. Prefer accessible labels and roles where they identify the control; use an agreed test ID for otherwise ambiguous elements. Scope repeated buttons to the correct form or section. These choices follow [Playwright's locator guidance](https://playwright.dev/docs/best-practices).

For a real report workflow, add the missing boundary checks:

1. Confirm the chosen period reaches the report service.
2. Confirm the final result contains the expected seeded data.
3. Verify failure behavior with an approved service stub or disposable fault scenario.
4. Verify permissions with a separate restricted account.
5. Clean up created data even if an assertion fails.

A stubbed response is useful for deterministic UI behavior. Label that test as a UI test with a stubbed service; keep a separate application-backed test if service integration matters to the release decision.

## 4. Review and diagnose the result

Reject fixed sleeps added to hide timing problems. Ask which condition the test needs to await. Preserve the first failure when investigating retries, and inspect whether the failure concerns the product, test data, locator, or environment.

For a focused debugging run:

```bash
npx playwright test tests/report-form.spec.ts --trace on --reporter=html
npx playwright show-report
```

Traces can reveal actions, DOM snapshots, and network activity. Treat them as potentially sensitive application evidence and restrict sharing accordingly. See [Trace Viewer](https://playwright.dev/docs/trace-viewer).

Prove the test can fail: in a disposable branch, change the fixture's result to the wrong month and run the unchanged spec. It must fail on the month assertion. Restore the behavior and rerun. This checks the oracle rather than rewarding a green result.

## 5. Create the equivalent managed test with ContextQA MCP

After [connecting your assistant](/mcp-server/installation-and-setup.md), first confirm the active workspace and available tools. The hosted MCP server does not automatically see your local filesystem or `localhost`; use a reachable test deployment or your organization's approved private-network setup.

```
In the confirmed ContextQA workspace, create one test for the report page at
<approved staging URL>. Use the prepared test account and reporting data.
Select September 2026, generate the report, and assert both the selected period
and the expected seeded total. Do not execute yet. Return the new test ID and
all steps so I can review the assertions and data references.
```

Review the returned steps, then request execution for the approved test ID. Wait for the terminal result and inspect step evidence; a monitoring URL alone is not proof of a pass. Ask for relevant logs or screenshots when available, and distinguish a likely root cause from a confirmed diagnosis. The [execution reference](/mcp-server/tool-reference/execution-and-results.md) describes this loop.

## 6. Evaluate export before moving coverage

Use the [Playwright export and portability guide](/testing-with-ai-coding-agents/export-and-portability.md) for the generated file manifest, local saving, credential review, and acceptance procedure. AI verification placeholders and manual checkpoints need remediation before unattended CI. Existing suites should follow the separate [Playwright migration guide](/migrate-to-contextqa/playwright-to-contextqa.md).

## Troubleshooting and FAQ

**The locator matches multiple buttons.** Scope it to the observed form, dialog, or row. Do not select an arbitrary first match unless position is itself the contract.

**The sample passes, but the application fails.** The sample proves only the local fixture. Investigate authentication, seed data, service responses, and application locators separately.

**Can the agent maintain tests automatically?** It can propose changes. Review any changed assertion, new skip, removed scenario, or altered expected result as a coverage decision.

**Is an exported green run equivalent to ContextQA passing?** Only after meaningful assertions and execution dependencies are reconciled. An assumed-success placeholder does not verify the business outcome.

*Sources and implementation reviewed September 25, 2026. Verify the tool schema in your connected client before using version-dependent capabilities.*

## Next step

[Connect ContextQA MCP and create one reviewed test](/mcp-server/first-test-tutorial.md). To evaluate managed execution alongside your repository, [book a testing workflow demo](https://contextqa.com/book-a-demo/?utm_source=learning.contextqa.com\&utm_medium=referral\&utm_campaign=docs_demand_gen\&utm_content=playwright-testing) and bring one Playwright spec, its fixtures, and a failure you need to diagnose.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://learning.contextqa.com/testing-with-ai-coding-agents/playwright-testing.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
