Repository navigation
[Bug]: --test-list cannot round-trip --list output when test declaration file differs from root loaded file #42299
Description
Version
1.62.1
Steps to reproduce
Self-contained minimal reproduction; no external repository is needed.
Run this in an empty directory:
mkdir pw-test-list-mre
cd pw-test-list-mre
mkdir tests
cat > package.json <<'JSON'
{"private":true,"devDependencies":{"@playwright/test":"1.62.1"},"scripts":{"repro":"playwright test --list tests/root-loaded.spec.ts && printf '[chromium] > tests/declared-tests.ts:4:7 > declared in imported file\n' > test-list.txt && playwright test --test-list test-list.txt --list"}}
JSON
cat > playwright.config.ts <<'TS'
import { defineConfig } from '@playwright/test';
export default defineConfig({ projects: [{ name: 'chromium', testDir: './tests' }] });
TS
cat > tests/declared-tests.ts <<'TS'
import { test, expect } from '@playwright/test';
export function defineTests() {
test('declared in imported file', async () => {
expect(1).toBe(1);
});
}
TS
cat > tests/root-loaded.spec.ts <<'TS'
import { defineTests } from './declared-tests';
defineTests();
TS
npm install
npx playwright test --list tests/root-loaded.spec.ts
printf '[chromium] > tests/declared-tests.ts:4:7 > declared in imported file\n' > test-list.txt
npx playwright test --test-list test-list.txt --listObserved locally on Windows with Playwright 1.62.1:
Listing tests:
[chromium] > tests\declared-tests.ts:4:7 > declared in imported file
Total: 1 test in 1 file
Listing tests:
Total: 0 tests in 0 files
Expected behavior
A test-list entry derived from --list output should select the same test.
One possible fix is to extend the --list / --test-list text format so one logical test-list entry, on one line, carries both paths when they differ:
- root loaded file:
tests/root-loaded.spec.ts, which Playwright must load to register the test; - declaration/location file:
tests/declared-tests.ts, which owns theTestCase.locationline/column and title identity.
This should not require two test-list lines. --test-list needs the root loaded file for loading/file filtering and the declaration file/title/line for matching the concrete TestCase. When both paths are the same, the format can remain unchanged.
If Playwright intentionally does not support this, the docs should explicitly say that --list output is not always usable as --test-list input when the declaration file differs from the root loaded file.
Actual behavior
No tests are selected. The declaration file alone does not register the test unless it is imported/called by the root loaded file.
This makes --list and --test-list non-round-trippable for this pattern. loadTestList() parses one file field per line and uses it both to filter loaded files and to match test.location.file. Here those are different files: the root loaded file causes registration, while the declaration file is stored in test.location.file and printed by --list.
Playwright already has both paths internally and in the reporter-visible suite model:
test.location.file: declaration/location file, used by--listand current--test-listtest matching.test._requireFile: internal root loaded file copied from the file suite'ssuite._requireFileduringTestTypeImpl._createTest().- Reporter-visible root loaded file:
TestCase.titlePath()[2]relative to the root test dir, or the parent file-suite'sSuite.location.filein its suite path form.
Our custom reporter therefore computes the root loaded file from TestCase.titlePath()[2] and the declaration file from TestCase.location.file. The incompatibility is that plain --test-list has only one file field but currently needs two meanings.
Additional context
There is also ambiguity if public identity uses only declaration/location file plus title. The same test(...) callback can be registered through multiple root loaded files, producing distinct Playwright tests that look identical unless root loaded file is part of the identity.
We added a defensive guard in our custom test-listing reporter for this case: same declaration file and effective title, different root loaded files. Such tests cannot be selected independently by the current plain --test-list identity.
HTML report data preserves the distinction, but not as one explicit per-test _requireFile field: per-test source location comes from test.location, while grouping testFile.fileName comes from fileSuite.location.file. So serialized/displayed identity should consistently distinguish root loaded file for loading/grouping from declaration/location file for source location.
If Playwright does not want to support this pattern, it may be worth documenting that declaring tests from a file imported by multiple root loaded files is discouraged because it can create ambiguous public identities.
A related change, #39901, intentionally avoids loading files not matching --test-list. That optimization is reasonable, but exposes this incompatibility because --list prints the declaration file, not necessarily the root executable test file that must be loaded.
Environment
System:
OS: Windows 11 10.0.26200
CPU: (16) x64 11th Gen Intel(R) Core(TM) i7-11850H @ 2.50GHz
Memory: 12.65 GB / 63.73 GB
Binaries:
Node: 24.11.1 - C:\Program Files\nodejs\node.EXE
Yarn: 4.12.0 - C:\Program Files\nodejs\yarn.CMD
npm: 10.9.4 - C:\Program Files\nodejs\npm.CMD
pnpm: 10.33.2 - C:\Program Files\nodejs\pnpm.CMD
IDEs:
VSCode: 1.109.4 - C:\Users\mkotoun\AppData\Local\Programs\Microsoft VS Code\bin\code.CMD
Claude Code: 2.1.68 - C:\Users\mkotoun\.local\bin\claude.EXE
Languages:
Bash: 5.2.37 - C:\msys64\usr\bin\bash.EXE
npmPackages:
@playwright/test: 1.62.1 => 1.62.1
Activity