How to Fix “No Playwright Tests Found”
Find why Playwright collected zero tests, fix config and filters, and verify discovery with --list before running the suite.
“No tests found” means Playwright collected zero tests for the command you ran. The cause is usually one of these: you are in the wrong directory or using the wrong config, your files are outside testDir, their names do not match testMatch, ignore rules exclude them, or a CLI filter selects nothing.
Start by separating test discovery from browser execution:
npx playwright test --list
If the intended files do not appear, follow the checks below in order. If the project is new and has no test file yet, create one with a recognized name such as login.spec.ts or login.test.js.
1. Confirm the command and config
Playwright looks for playwright.config.ts or playwright.config.js in the current directory. A different config can be selected with -c. First check where you are and which files exist:
pwd
ls
find . -maxdepth 3 -type f \( -name 'playwright.config.ts' -o -name 'playwright.config.js' \)
npx playwright test -c path/to/playwright.config.ts --list
Run the command from the project that owns the tests, or pass the intended config explicitly. In a monorepo, this is one of the most common reasons a valid test directory appears empty.
2. Inspect testDir
testDir is scanned recursively. If it is not set, Playwright uses the directory containing the config file. A project can also override the global value with its own testDir.
import { defineConfig } from '@playwright/test';
export default defineConfig({
testDir: './tests',
projects: [
{
name: 'chromium',
testDir: './tests/e2e'
}
]
});
Make sure every intended spec is below the active directory:
find tests -type f
find . -type f \( -name '*.spec.ts' -o -name '*.test.ts' -o -name '*.spec.js' -o -name '*.test.js' \)
If you run a project with --project, inspect that project’s testDir, not only the top-level setting.
3. Check the filename against testMatch
The default pattern accepts JavaScript and TypeScript files using .spec or .test, including supported CommonJS, module, JSX and TSX variants. Typical names are:
login.spec.tscheckout.test.jssettings.spec.tsxsearch.test.mjs
Names such as login.ts, login.spec.md or helpers.test-data.ts may not match the configured pattern. Rename the file or deliberately configure a pattern for your convention:
import { defineConfig } from '@playwright/test';
export default defineConfig({
testMatch: '**/*.e2e.ts'
});
Do not change testMatch just to hide the symptom. Verify that the pattern includes the files you actually intend to run.
4. Look for ignore rules
testIgnore excludes matching paths. Playwright can also ignore files matching .gitignore entries by default when neither a global nor project-specific testDir was explicitly set.
import { defineConfig } from '@playwright/test';
export default defineConfig({
testDir: './tests',
testIgnore: [
'**/fixtures/**',
'**/*.generated.ts'
]
});
Check both configuration and repository ignore files:
cat .gitignore
rg -n "testIgnore|testDir|testMatch|ignore" playwright.config.* package.json
A broad rule such as tests/**, **/e2e/** or an ignored parent directory can remove every candidate from collection.
5. Remove filters that select zero tests
Even when files exist, command-line filters can reduce the selected set to zero.
Positional file and directory arguments
Arguments after playwright test are regular expressions matched against full test file paths. A shell expansion or an overly specific expression can match nothing:
# Temporarily remove the path argument
npx playwright test --list
# Then try a deliberately broad path
npx playwright test tests --list
Grep filters
npx playwright test --grep "checkout" --list
npx playwright test --grep-invert "flaky" --list
Remove --grep and --grep-invert while diagnosing. A title, annotation or tag that changed can make a previously valid expression match nothing.
Project selection
npx playwright test --project=chromium --list
Run without --project once to see whether the selected project is the problem. Check each project’s testDir, testMatch and dependencies.
6. Use --list as the collection test
--list collects tests without launching them. It is the fastest way to distinguish discovery problems from browser, fixture or application failures.
# Broad collection check
npx playwright test --list
# With an explicit config
npx playwright test -c playwright.config.ts --list
# With one project
npx playwright test --project=chromium --list
Interpret the result:
| Result | Meaning | Next action |
|---|---|---|
| No files or tests listed | Discovery or selection is still wrong | Check directory, filename, ignore rules and filters |
| Files listed, then runtime failures | Discovery works | Debug browser launch, fixtures, navigation or assertions |
| Some tests listed | A filter or project excludes the missing tests | Compare the listed paths and titles with the intended suite |
7. Add a recognized test if the project is empty
An empty new project can legitimately show Error: No tests found. Make sure that arguments are regular expressions matching test files. The WordPress Developer tutorial uses this message before its first test is created.
Create a minimal test under the configured directory:
// tests/home.spec.ts
import { test, expect } from '@playwright/test';
test('home page has the expected title', async ({ page }) => {
await page.goto('https://example.com');
await expect(page).toHaveTitle(/Example Domain/);
});
Then verify collection and run it:
npx playwright test tests/home.spec.ts --list
npx playwright test tests/home.spec.ts
8. A repeatable diagnosis checklist
- Run from the directory containing the intended config, or pass
-c. - Read the active global and project-level
testDir. - Confirm each file is below that directory.
- Compare filenames with
testMatch. - Inspect
testIgnoreand relevant.gitignoreentries. - Remove positional paths,
--grep,--grep-invertand--project. - Run
npx playwright test --list. - Only after the intended tests are listed, run the normal test command.
9. Common errors and fixes
| Symptom | Likely cause | Fix |
|---|---|---|
No tests found in a new repository |
No test file exists | Add a spec under testDir with a recognized suffix |
| Tests work from one folder but not another | Different config is being discovered | Change directory or pass -c |
| Only files with a custom suffix are missing | testMatch excludes them |
Rename them or configure the custom pattern |
| All files are under an ignored directory | testIgnore or .gitignore excludes them |
Remove or narrow the rule |
| One command returns zero, another finds tests | Path, grep or project filter differs | Compare commands and remove filters temporarily |
Files appear with --list but execution fails |
Discovery is fixed; runtime setup is failing | Debug browser installation, fixtures, web server and assertions separately |
10. Performance, reliability and CI notes
Use --list in a fast diagnostic step before expensive browser runs. It avoids spending time on browsers when collection is empty.
Keep discovery settings explicit in CI. Set the working directory, pass the config path when a repository has multiple Playwright projects, and avoid relying on a developer’s current directory. Print the command and config path in CI logs so a zero-test run can be reproduced.
When changing testDir, testMatch or ignore rules, run --list before and after the change. This gives a simple collection-level check without depending on network availability or browser stability.
Or skip the browser setup
If your goal is a clean image or PDF of a page rather than an end-to-end assertion, ScreenshotNeo can capture it with one request. See the API documentation for all options.
cURL
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
Python
import requests
r = requests.get(
"https://api.screenshotneo.com/v1/shot",
params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"},
timeout=90,
)
r.raise_for_status()
open("shot.webp", "wb").write(r.content)
Node.js
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
if (!res.ok) throw new Error(`Screenshot failed: ${res.status}`);
const fs = await import('node:fs/promises');
await fs.writeFile('shot.webp', Buffer.from(await res.arrayBuffer()));
ScreenshotNeo removes cookie and consent banners, newsletter popups and chat widgets before capture. Bot checks, blank pages, timeouts, failed loads and cache hits are not billed, and the response reports the page verdict and billing status in X-Page-Verdict and X-Billed headers. Its MCP server provides take_screenshot, get_page_info and capture_pdf tools for Claude, Cursor and other MCP clients. You get 1,000 screenshots each month free with no card; paid plans start at $5 for 3,000. Create a free ScreenshotNeo account.
FAQ
Does “No tests found” mean Playwright is broken?
No. It means the current command collected zero tests. Discovery can be empty even when Playwright is installed correctly.
Do test titles affect file discovery?
Titles matter when grep filters are used. File discovery first depends on the active config, directory, filename pattern and ignore rules.
Should I reinstall Playwright?
Usually no. Run --list and inspect configuration before reinstalling browsers or packages.
Why does a test file exist but still not run?
It may be outside testDir, fail testMatch, match an ignore rule, belong to another project, or be excluded by a path or grep filter.
What should I keep in a bug report?
Include the working directory, exact command, config path, relevant testDir/testMatch/testIgnore settings, file path, and output from npx playwright test --list.


