QA How-To
How to Run a single test in Playwright (2026)
Learn playwright how to run a single test with it.only, --spec filters, grep tags, open mode selection, and CI-safe isolation patterns for 2026.
22 min read | 2,659 words
TL;DR
To run one Playwright test, use test.only locally, or run npx playwright test "path/to/file.cy.ts" without editing source. For title-level focus, use a grep plugin or tags. In the GUI, open the spec and select the example. Never commit .only markers.
Key Takeaways
- Use test.only or test.describe.only for short local debugging loops, never for committed main-branch code.
- Prefer npx playwright test for file or folder isolation that stays clean in CI.
- Add title or tag grep when one file still contains too many examples.
- playwright test --ui lets you click a single test for time-travel debugging without permanent source edits.
- Gate exclusive tests with ESLint and CI checks so focus markers cannot merge silently.
- Combine with --browser and --headed when reproduction depends on a real window.
- Always re-expand from one test to the full file before you merge a fix.
The short answer to playwright how to run a single test is to isolate it either by Mocha focus (test.only / test.test.describe.only), by CLI filters (playwright test and optional --grep filters), or by selecting the test in playwright test --ui. For local debugging, test.only is the fastest feedback loop. For CI and shared machines, prefer --spec (and grep when you need title-level targeting) so isolation never depends on edited source that could be committed by mistake.
Running one test is not a luxury. It is how you diagnose flaky failures, refine selectors, and keep a large suite usable. This guide covers every practical isolation method Playwright supports in 2026, when to use each one, how to avoid committing focused tests, and how to make single-test workflows safe in CI.
TL;DR
| Goal | Recommended approach | Where it runs |
|---|---|---|
| Debug one failing example locally | test.only or test.test.describe.only |
Open or run |
| Run one or more files | npx playwright test "tests/login.spec.ts" |
CLI / CI |
| Run a folder of specs | npx playwright test "tests/checkout/**/*" |
CLI / CI |
| Match by test title | --grep filter or env-based title filter |
CLI / CI |
| Click one test interactively | npx playwright test --ui then select spec and test |
GUI |
| Prevent focused tests in main | ESLint rule + CI check | Pre-commit / pipeline |
Start with the method that matches your context. Local debugging favors Mocha focus. Shared runners favor file and title filters that leave source clean.
1. Playwright How to Run a Single Test: Choose the Right Isolation Layer
Playwright organizes execution in layers: project, browser, spec file, describe block, and individual it example. Isolation can happen at any of those layers. Picking the wrong layer creates either too little focus (you still wait for half the suite) or too much risk (you ship test.only and silently skip coverage).
Spec-file isolation is best when the failing scenario lives alone in a file, or when a file is already small and cohesive. Suite isolation with test.test.describe.only is best when several related examples share expensive setup you still need. Example isolation with test.only is best for a single assertion path. Title filtering is best when the suite is large and you cannot edit the file, such as in a temporary CI re-run.
Also separate run mode from open mode. playwright test is headless by default, exits with a code, and is what CI uses. playwright test --ui launches the Test Runner GUI for interactive debugging. You can isolate in both, but the UX differs. For headed single-test runs without the full GUI, see how to run tests in headed mode in Playwright.
Write down the question you are answering: "Does this one assertion pass?" versus "Does this whole payment flow file pass?" The answer dictates whether you need test.only, --spec, or a folder glob.
2. Use test.only and test.test.describe.only for Local Debugging
Mocha focus is the fastest way to answer playwright how to run a single test when you already have the file open. Prefix the target with .only:
// tests/checkout/payment.spec.ts
test.describe('Checkout payment', () => {
test.beforeEach(async ({ page }) => {
page.loginAs('buyer@example.com')
await page.goto('/checkout')
})
test.only('applies a valid promo code', () => {
page.locator('[data-testid=promo-input]').type('SAVE10')
page.locator('[data-testid=apply-promo]').click()
page.locator('[data-testid=discount-line]').should('contain', '10%')
})
test('rejects an expired promo code', () => {
// skipped while test.only is active
})
})
test.test.describe.only focuses an entire block and still runs nested before / beforeEach hooks for that block:
test.describe.only('Checkout payment', () => {
test('applies a valid promo code', () => { /* ... */ })
test('rejects an expired promo code', () => { /* ... */ })
})
Rules that keep .only safe:
- Never commit focused tests to the default branch.
- Prefer one
.onlyat a time. Multiple.onlymarkers still run only the focused set, but the intent becomes harder to read. - Nested
.onlybehaves as you would expect: the focused suite or test is selected, and non-focused siblings are skipped. - Pair with an ESLint rule such as
mocha/no-exclusive-testsor a Playwright lint rule so CI fails if focus lands in a PR.
Focused tests are a scalpel. They cut the feedback loop to seconds. They are not a release strategy. When the bug is fixed, remove .only immediately and re-run the surrounding file.
3. Filter Specs With playwright test
When you need a single file or a small set of files without editing source, pass --spec:
# one file
npx playwright test "tests/login.spec.ts"
# several files (comma-separated)
npx playwright test "tests/login.spec.ts,tests/logout.spec.ts"
# glob a folder
npx playwright test "tests/checkout/**/*.spec.ts"
On Windows shells, quoting rules differ. Prefer double quotes around globs and avoid unquoted * expansion. In npm scripts, escape carefully:
{
"scripts": {
"cy:login": "playwright test \"tests/login.spec.ts\"",
"cy:checkout": "playwright test \"tests/checkout/**/*.spec.ts\""
}
}
--spec works with both absolute and project-relative paths. In CI, relative paths from the repo root are clearer in logs. Combine with browser and headed flags when needed:
npx playwright test --project=chromium --headed "tests/login.spec.ts"
Spec filtering is the correct default for "run this area of the product" workflows. It does not require dirty working trees, and it composes cleanly with sharding strategies that already split by file path.
4. Match a Single Test Title With Grep-Style Filters
File-level isolation is often still too broad. Title-level filtering lets you run one example by its name. The common 2026 approach is a --grep filter such as Playwright built-in grep (or a maintained community equivalent with the same usage pattern). After installing and registering it in support and config, you can target titles from the CLI:
# conceptual usage with a `--grep` filter
npx playwright test --grep "applies a valid promo code"
npx playwright test --grep "promo" "tests/checkout/**/*"
npx playwright test --grep "@smoke"
Typical registration lives in config and support files per the plugin docs. Tagging tests improves grepping:
test('applies a valid promo code', { tag: ['@smoke', '@checkout'] }, () => {
page.locator('[data-testid=promo-input]').type('SAVE10')
page.locator('[data-testid=apply-promo]').click()
page.locator('[data-testid=discount-line]')).toBeVisible()
})
Without a plugin, you can still approximate title focus with temporary test.only, or by moving one example into a scratch spec. Prefer a documented grep approach for shared teams so engineers do not invent incompatible scripts.
Title filters shine when CI re-runs "the one test that failed in the last job" without checking out a patch that adds .only. Combine --spec and grep so the runner does not load unrelated files.
5. Run One Test Interactively in playwright test --ui
Interactive mode is ideal when you need time-travel debugging, DOM snapshots, and command log inspection for a single example.
npx playwright test --ui
# or pin e2e testing type
npx playwright test --ui --project=chromium
Workflow:
- Choose E2E Testing (or Component Testing).
- Pick the browser.
- Open the target spec from the list.
- Click a single test title in the runner to re-run only that example.
- Use the command log, snapshots, and console to inspect failures.
Open mode still honors test.only in the source if present. For pure UI isolation without source edits, select the test from the list after the spec loads. This is the best path for teaching juniors and for visual confirmation of selector behavior.
When scrolling or visibility issues make a single test fail only under certain viewport sizes, open mode plus viewport presets reveals the problem quickly. Pair with how to scroll to an element in Playwright when the failure is actionability related.
6. Compare Isolation Methods Side by Side
| Method | Edits source? | Granularity | CI friendly | Risk |
|---|---|---|---|---|
test.only |
Yes | One test | Poor if committed | Silent coverage loss |
test.test.describe.only |
Yes | Suite | Poor if committed | Skips sibling suites |
--spec file |
No | File | Excellent | May still run many tests |
--spec glob |
No | Folder / pattern | Excellent | Over-broad globs |
| Grep by title/tag | No | Title / tag | Excellent | Requires plugin setup |
| Open mode click | No | One test | Local only | Not for pipelines |
Practical rule: edit source only on your machine for minutes, not for hours on a shared branch. Convert a local .only session into a --spec or grep command before you push, open a PR, or ask a teammate to reproduce.
Also note Mocha's skip API is the opposite of focus. test.skip and test.describe.skip exclude tests intentionally. Focus includes; skip excludes. For a full treatment of skip, pending, and grouping patterns, read how to skip and group tests in Playwright.
7. Wire Package Scripts and Environment-Specific Single Runs
Teams waste time retyping long CLI strings. Encode the common single-run patterns once:
{
"scripts": {
"pw:ui": "playwright test --ui",
"pw:test": "playwright test",
"pw:test:chrome": "playwright test --project=chromium",
"pw:spec": "playwright test",
"pw:smoke": "playwright test --grep @smoke"
}
}
Usage examples:
npm run pw:spec -- "tests/login.spec.ts"
npm run pw:smoke
PLAYWRIGHT_baseUrl=https://staging.example.com npm run pw:spec -- "tests/auth/**/*"
Environment variables matter when the single test depends on a target environment:
export PLAYWRIGHT_baseUrl=https://staging.example.com
npx playwright test "tests/login.spec.ts"
npx playwright test --config baseUrl=https://staging.example.com "tests/login.spec.ts"
Keep secrets out of scripts committed to git. Use CI secret stores for tokens and inject them as PLAYWRIGHT_* variables. Single-test debugging against production data is usually the wrong move; prefer staging with seeded fixtures.
8. Keep Single-Test Workflows Safe in CI
CI should never depend on committed .only. Use layered defenses:
# GitHub Actions example: run one path on demand
jobs:
playwright-one-spec:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '22'
- run: npm ci
- run: npx playwright test --project=chromium "${{ inputs.spec }}"
Additional CI practices:
- Fail the build if a search finds
test.onlyortest.test.describe.onlyunderplaywright/on protected branches. - Quarantine flaky tests with skip plus ticket links rather than permanent
.onlyworkarounds. - Shard by spec path for full suite speed; use single-spec jobs only for reproduction and smoke.
- Artifacts: always upload screenshots and videos for the isolated run so the single failure is inspectable.
A single-test CI job is a surgical tool for "prove this fix" and "repro this flake." It is not a substitute for the full suite gate.
9. Playwright How to Run a Single Test Across Browsers and Modes
Isolation combines with browser selection:
npx playwright test --project=chromium "tests/login.spec.ts"
npx playwright test --project=chromium "tests/login.spec.ts"
npx playwright test --project=firefox "tests/login.spec.ts"
npx playwright test --project=msedge "tests/login.spec.ts"
Headed single runs help when a failure is visual or timing-related under a real window:
npx playwright test --headed --project=chromium "tests/login.spec.ts"
Component tests follow the same isolation ideas with the component testing type:
npx playwright test --ui --component
npx playwright test --component "src/components/Button.spec.tsx"
If your failure only appears after a cold cache or first navigation, do not only re-run the green path in open mode. Use playwright test once to match CI determinism, then open mode to inspect. Recordings and retries can also change timing; when investigating flakes, disable extra retries temporarily so you see the first failure clearly.
For network-heavy single tests, keep intercepts tight and deterministic. Review Playwright page.route examples so a solo run does not depend on unrelated backend noise.
10. Diagnose Why Your Single Test Still Runs Neighbors
Common surprises when you thought you isolated one test:
- Multiple
.onlymarkers in imported helpers or partial files still expand the focused set. - Root hooks in
support/e2e.tsalways run and can mask timing differences. - Glob too wide: patterns without
**may miss nested folders, while over-broad**may pull too much. - Wrong working directory:
--specpaths resolve relative to the Playwright project root. - Grep string too loose:
grep=loginmay match many titles; prefer unique phrases or tags. - Test retries: a single test may execute multiple attempts; that is isolation by title, not by attempt count.
test.onlyinsidetest.describe.skip: mixed markers confuse readers; clean them up.
Read the Playwright runner summary: it lists passing, pending, and failing counts. Pending often means skipped via .skip or filtered out. If the count is higher than one for an test.only session, search the repo for other .only occurrences.
11. Patterns for Large Monorepos and Multiple Playwright Projects
Monorepos often host several Playwright configs (app, admin, marketing). Isolation must name the config:
npx playwright test --config-file apps/web/playwright.config.ts "apps/web/tests/login.spec.ts"
npx playwright test --project apps/admin "tests/users.spec.ts"
Align path conventions so engineers do not mix admin specs into the web project. Document the canonical scripts in the root README. When using Nx, Turbo, or pnpm filters, wrap Playwright so --spec still reaches the correct package:
pnpm --filter @acme/web exec playwright test "tests/login.spec.ts"
Shared libraries that export test helpers should not contain .only. Put demo-only specs behind a path that CI never selects, or name them *.manual.spec.ts and exclude them from default globs in playwright.config.ts.
12. A Practical Playbook You Can Reuse Tomorrow
Use this sequence the next time a CI job fails on one assertion:
- Copy the failing title and file path from the CI log.
- Reproduce with file isolation:
npx playwright test --project=chromium "path/from/log.spec.ts" - If the file is large, add temporary
test.onlylocally or apply a title grep. - Switch to
playwright test --uifor the same file when you need snapshots. - Fix the product or the test.
- Remove
.only, re-run the full file, then the related folder. - Push and let CI run the broader suite.
This playbook keeps isolation intentional. You move from wide (CI) to narrow (local) and back to wide (verification) without leaving traps in the branch.
Single-Test Hygiene Checklist
Before you merge, confirm no exclusive tests remain, the related file still passes without focus, flaky skips have tickets, and the new assertion is not covered only under a special env flag nobody runs. Confirm screenshots or videos from the isolated run are attached to the PR when the bug was hard to see. Confirm docs or scripts were updated if you introduced a new smoke tag. This checklist turns a fast local fix into durable suite health. Re-run at least once on the same browser CI uses so local Electron success is not a false friend. If the bug involved auth, reset sessions with page.session carefully so isolation does not hide cache issues. Finally, note the reproduction command in the PR description so reviewers can re-run the same single path in minutes.
When you teach this workflow to a new hire, demonstrate both a happy path and a failure path. Show them the CI log line that prints the spec path, paste it into --spec, and watch the local runner reproduce the same assertion. Then intentionally introduce an test.only, run the suite, and show how the green bar can lie when siblings are pending. That five-minute demo prevents months of accidental coverage gaps.
Finally, store a short internal cheat sheet next to your Playwright config: one command for file isolation, one for smoke tags, one for headed Chrome, and one for open mode. Teams that write these four lines once stop inventing divergent scripts in every PR description. Consistency is part of isolation quality, not a separate concern.
Interview Questions and Answers
Q: How do you run only one Playwright test from the command line?
I use npx playwright test --spec with the file path when file isolation is enough. For title-level isolation I use a --grep filter or tags. I avoid committing test.only.
Q: What is the difference between test.only and --spec?
test.only edits source and focuses one example inside Mocha. --spec selects files without source changes and is safer for CI and shared branches.
Q: How do you prevent test.only from merging?
I enable an ESLint rule for exclusive tests and optionally a CI grep gate on protected branches. Code review also checks for focus markers.
Q: Can you run a single test in headed mode?
Yes. Combine --headed with --spec and a browser flag, or use open mode and select the test in the GUI.
Q: How do tags help single-test selection?
Tags like @smoke let grep filters select a cross-file subset without listing every path. They work well for on-demand CI jobs.
Q: What happens if multiple tests have .only?
Mocha runs the focused set: all exclusive tests and suites. Non-focused examples are skipped. That can surprise people who expected exactly one test.
Q: How do you re-run only the failed Playwright test in CI?
I re-trigger a job with an input for the spec path and optional grep string, using the same browser and baseUrl as the original failure.
Common Mistakes
- Committing
test.onlyortest.test.describe.onlyto the main branch. - Using a glob that matches far more files than intended.
- Forgetting quotes around
--specglobs in shells that expand*. - Assuming open mode behaves identically to CI headless timing.
- Using a vague grep string that matches half the suite.
- Debugging only in open mode and never confirming with
playwright test. - Leaving exclusive tests in shared support files.
- Treating
test.skipas a focus tool (it excludes, it does not isolate). - Running a single test against production without safeguards.
- Ignoring root
beforeEachhooks that still dominate runtime in a "single" test.
Conclusion
For playwright how to run a single test, match the isolation tool to the job. Use test.only or the open-mode picker for rapid local debugging, --spec for clean file selection, and grep or tags when titles matter across files. Keep CI free of committed focus markers so a debugging habit never becomes silent coverage loss.
Pick one failing example from your last pipeline, reproduce it with --spec, tighten to a single title if needed, fix it, then re-expand to the full file. That narrow-wide loop is the professional habit that keeps large Playwright suites fast to debug and safe to ship.
Interview Questions and Answers
How would you run only one failing Playwright test from a CI log?
I copy the file path and title from the log, reproduce with playwright test on that file, then tighten with test.only or grep if needed. I keep the same browser and baseUrl as CI, fix the issue, remove focus markers, and re-run the full file before merging.
Why is committing test.only dangerous?
Exclusive tests cause Mocha to skip non-focused examples, so CI can go green while most coverage never runs. That creates false confidence and hides regressions until someone removes the marker.
When do you prefer --spec over test.only?
I prefer for anything shared: CI jobs, teammate reproduction, and long-lived scripts. test.only is a private, temporary local tool. Source filters that require edits do not scale across a team.
How do tags improve Playwright test selection?
Tags such as @smoke or @checkout let a grep filter select a cross-cutting subset without listing every file. They support on-demand pipelines and local smoke runs while leaving default full-suite globs unchanged.
How do open mode and run mode differ for single-test debugging?
Open mode provides the interactive command log, snapshots, and easy re-runs of one example. Run mode matches CI more closely with exit codes, videos, and headless defaults. I often confirm a fix in both.
What safeguards would you add to a monorepo Playwright setup?
I document per-package config files, encode scripts per app, exclude manual specs from default globs, lint against .only, and ensure CI selects the correct --config-file or --project so isolation cannot target the wrong app.
How do you explain pending versus failed versus skipped counts after isolation?
Failed means assertions or commands errored. Pending often reflects .skip or tests filtered out by focus or grep. I read the runner summary and search for .only, .skip, and filter env vars when counts look wrong.
Frequently Asked Questions
How do I run a single Playwright test from the CLI?
Use npx playwright test with the file path for file isolation. For one example by name, add a grep plugin or tags. test.only works locally but should not be committed.
What does test.only do in Playwright?
It tells Mocha to run only that focused example (plus any other .only markers) and skip the rest of the non-focused tests in the loaded specs.
How do I run one Playwright file in CI?
Pass with the repo-relative path in your pipeline command. Keep baseUrl, browser, and env vars identical to the full suite job for a fair reproduction.
Can I run a single test in playwright test --ui?
Yes. Open the project, select the spec, then click the individual test in the runner. You can also temporarily add test.only in the source while debugging.
How do I stop myself from committing test.only?
Enable an ESLint rule against exclusive tests and add a CI check that fails when .only appears under the Playwright folders on protected branches.
What is the difference between --spec and grep?
selects which files Playwright loads. Grep filters which tests inside those files run based on title or tags. They combine well: narrow files, then narrow titles.
Does --spec work with globs?
Yes. Patterns such as playwright/e2e/checkout/**/*.cy.ts select a folder tree. Quote the glob so your shell does not expand it unexpectedly.
Related Guides
- How to Debug a failing test in VS Code in Playwright (2026)
- How to Run a single test in Cypress (2026)
- How to Run a single test in Selenium (2026)
- How to Debug a failing test in VS Code in Cypress (2026)
- How to Debug a failing test in VS Code in Selenium (2026)
- How to Run tests in headed mode in Playwright (2026)