Repository navigation
Description
Version
1.65.0
Steps to reproduce
Repo: https://github.com/AdzerKI/playwright-artifacts-folder-growth
npm ci
npx playwright install chromium
npm run repro
100 passing tests in one worker with trace: 'retain-on-failure' and screenshot: 'only-on-failure'. A worker fixture prints what is left in .playwright-artifacts-0 before the worker exits.
Expected behavior
Nothing from a passed test stays in the artifacts folder: its trace is discarded and its screenshot is not kept, so the folder does not grow with the number of passed tests.
Actual behavior
Artifacts folder before worker exit: test-results/.playwright-artifacts-0
.png: 100 files, 0.7 MB
.network: 200 files, 0.0 MB
.trace: 200 files, 0.6 MB
screencast frames: 136 files, 0.4 MB
100 passed (18.3s)
Every passed test leaves its .trace, .network, screencast frames and a temporary .png behind. The folder is only removed when the worker exits, so it grows for the whole run.
In our e2e suite (a few thousand tests, 12 workers, output dir on tmpfs) the artifacts folders reached 11 GB a third into the run: .trace 4.8 GB, screencast frames 2.4 GB, .network 1.2 GB, .png 0.2 GB. With tmpfs that is RAM, and full runs went into swap.
Additional context
Two places keep the files:
Tracing._stopChunk()inpackages/playwright-core/src/server/trace/recorder/tracing.tsreturns early formode: 'discard'and leaves the chunk's trace file and its screencast frames, screenshots and aria snapshots intracesDir.SnapshotRecorder.persistTemporary()inpackages/playwright/src/index.tsrenames the temporary screenshots when the test failed, but does nothing with them otherwise.
This fixes both, and the folder is empty except .network in the repro:
--- a/packages/playwright-core/src/server/trace/recorder/tracing.ts
+++ b/packages/playwright-core/src/server/trace/recorder/tracing.ts
+ const chunkFiles = this._state.chunkFiles;
this._state.chunkFiles = new Set();
- if (params.mode === 'discard')
+ if (params.mode === 'discard') {
+ this._fs.unlink(this._state.traceFile);
+ for (const file of chunkFiles) {
+ if (file.startsWith('resources/'))
+ continue;
+ this._allResources.delete(file);
+ this._fs.unlink(path.join(this._state.tracesDir, file));
+ }
return undefined;
+ }
--- a/packages/playwright/src/index.ts
+++ b/packages/playwright/src/index.ts
}));
+ } else {
+ await Promise.all(this._temporary.map(file => fs.promises.unlink(file).catch(() => {})));
}plus an unlink operation in SerializedFS, so the delete is ordered after the pending writes. Resources are skipped because they are content-addressed and other chunks and contexts share them.
The .network file of each context still stays. It lives across chunks, so it could only go when tracing stops. I left it out because TR-013 should respect tracesDir and name expects it to exist after tracing.stop().
I'd be glad to send a PR with tests (a library test for the discarded chunk, a test-runner test for the artifacts folder) if this looks right to you.
Environment
System:
OS: Linux 7.0 Ubuntu 26.04.1 LTS 26.04.1 LTS (Resolute Raccoon)
CPU: (32) x64 AMD EPYC 7543 32-Core Processor
Memory: 28.25 GB / 122.03 GB
Container: Yes
Binaries:
Node: 26.13.1 - /usr/bin/node
npm: 12.2.2 - /usr/bin/npm
npmPackages:
@playwright/test: 1.65.0 => 1.65.0
Activity
microsoft-playwright-automation commentedon Nov 12, 2026
microsoft-playwright-automation commentedon Nov 13, 2026
Hi, I'm the Playwright bot. I reproduced this and prepared a fix.
Reproduced on
1.66.0-next, commitc59cf2040091ece8b59f56dd59a6d0e9080a7dfd, on Chromium, Firefox and WebKit. Discarding a chunk did not delete its trace or chunk-only files, and passing tests did not delete temporary screenshots. The proposed patch deletes these files after pending writes finish.Network files and content-addressed resources keep their existing lifetime: they can be shared across chunks and contexts. This patch does not make the entire artifacts folder empty.
Condensed repro
Run with
trace: 'retain-on-failure',screenshot: 'only-on-failure', and one worker per browser:Before the fix, each worker retained six
.tracefiles, three temporary.pngfiles and screencast frames. With the fix, none of those files remained. Six.networkfiles remained in both cases.What I ran
All runs were headless on Linux, using the checkout's
1.66.0-nextbuild.TR-013, Chromium / Firefox / WebKitThe full library tracing file passed: 131 tests, with one existing skip, across all three browsers. The artifact and trace runner files passed all 71 tests in aggregate. Three initial server-fixture timeouts occurred when the library and runner suites competed for the same ports; those three tests passed when rerun separately.
npm run build,npm run flintandgit diff --checkpassed. The final regression assertions were checked again without the fixes and then with them. The reported1.65.0release, headed mode, Windows and macOS were not tested.Draft PR: #44089
Triaged on Linux by the Playwright bot - agent run
Johanl001 commentedon Nov 13, 2026
Hi, I'd like to work on this issue. Could you please assign it to me? I'm interested in contributing and will work on implementing a solution. Thanks!