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 --list
Observed 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 the TestCase.location line/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 --list and current --test-list test matching.
test._requireFile: internal root loaded file copied from the file suite's suite._requireFile during TestTypeImpl._createTest().
- Reporter-visible root loaded file:
TestCase.titlePath()[2] relative to the root test dir, or the parent file-suite's Suite.location.file in 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
Version
1.62.1
Steps to reproduce
Self-contained minimal reproduction; no external repository is needed.
Run this in an empty directory:
Observed locally on Windows with Playwright 1.62.1:
Expected behavior
A test-list entry derived from
--listoutput should select the same test.One possible fix is to extend the
--list/--test-listtext format so one logical test-list entry, on one line, carries both paths when they differ:tests/root-loaded.spec.ts, which Playwright must load to register the test;tests/declared-tests.ts, which owns theTestCase.locationline/column and title identity.This should not require two test-list lines.
--test-listneeds the root loaded file for loading/file filtering and the declaration file/title/line for matching the concreteTestCase. When both paths are the same, the format can remain unchanged.If Playwright intentionally does not support this, the docs should explicitly say that
--listoutput is not always usable as--test-listinput 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
--listand--test-listnon-round-trippable for this pattern.loadTestList()parses onefilefield per line and uses it both to filter loaded files and to matchtest.location.file. Here those are different files: the root loaded file causes registration, while the declaration file is stored intest.location.fileand 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().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 fromTestCase.location.file. The incompatibility is that plain--test-listhas 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-listidentity.HTML report data preserves the distinction, but not as one explicit per-test
_requireFilefield: per-test source location comes fromtest.location, while groupingtestFile.fileNamecomes fromfileSuite.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--listprints 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