Visitar URL original
[Bug]: Trace files of discarded chunks and temporary screenshots stay in the worker artifacts folder until the worker exits · Issue #44086 · microsoft/playwright · GitHub
Skip to content

[Bug]: Trace files of discarded chunks and temporary screenshots stay in the worker artifacts folder until the worker exits #44086

Open

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:

  1. Tracing._stopChunk() in packages/playwright-core/src/server/trace/recorder/tracing.ts returns early for mode: 'discard' and leaves the chunk's trace file and its screencast frames, screenshots and aria snapshots in tracesDir.
  2. SnapshotRecorder.persistTemporary() in packages/playwright/src/index.ts renames 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

  1. microsoft-playwright-automation commented on Nov 12, 2026

    @microsoft-playwright-automation
  2. microsoft-playwright-automation commented on Nov 13, 2026

    @microsoft-playwright-automation
    Contributor

    Hi, I'm the Playwright bot. I reproduced this and prepared a fix.

    Reproduced on 1.66.0-next, commit c59cf2040091ece8b59f56dd59a6d0e9080a7dfd, 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:

    import fs from 'fs';
    import path from 'path';
    import { test as base, expect } from '@playwright/test';
    
    const test = base.extend({
      inspectArtifacts: [async ({}, use, workerInfo) => {
        await use();
        const dir = path.join(workerInfo.project.outputDir,
            '.playwright-artifacts-' + workerInfo.workerIndex);
        const files = fs.readdirSync(dir, { recursive: true }).map(String);
        expect(files.filter(file => /\.(trace|png|jpeg)$/.test(file))).toEqual([]);
      }, { scope: 'worker', auto: true }],
    });
    
    for (let i = 0; i < 3; ++i) {
      test('passing ' + i, async ({ page }) => {
        await page.setContent('<button>Click</button>');
        await page.getByRole('button').click();
      });
    }

    Before the fix, each worker retained six .trace files, three temporary .png files and screencast frames. With the fix, none of those files remained. Six .network files remained in both cases.

    What I ran

    All runs were headless on Linux, using the checkout's 1.66.0-next build.

    Check Without the fix With the fix
    Three passing tests per browser, Chromium / Firefox / WebKit Left discarded traces, screenshots and frames on all three No discarded traces, screenshots or frames on all three
    Extended TR-013, Chromium / Firefox / WebKit Discarded trace remained on all three Trace, screencast, screen snapshots and aria snapshots removed; saved traces preserved
    Extended screenshot-only-on-failure artifact test, Chromium Temporary screenshots remained Temporary screenshots removed; failure attachments preserved

    The 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 flint and git diff --check passed. The final regression assertions were checked again without the fixes and then with them. The reported 1.65.0 release, headed mode, Windows and macOS were not tested.

    Draft PR: #44089

    Triaged on Linux by the Playwright bot - agent run

  3. Johanl001 commented on Nov 13, 2026

    @Johanl001

    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!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions