playwright
playwright copied to clipboard
[Feature] Prevent certain actions from being recorded in traces
I maintain (internally at Microsoft) a custom testing framework originally built around Puppeteer, but we have recently migrated to Playwright, and it has been an amazing improvement. Thanks for creating and maintaining it!
One thing that is a bit of an annoyance though is the presence of some unnecessary noise in the trace files. Within the custom framework we have some code which looks similar to this:
public categorizeErrorsWhenLoadingDocuments = async (request: Request) => {
if (request.resourceType() !== 'document') {
return;
}
if ((await request.headersArray()).length === 0) {
return;
}
const url: string = request.url();
const response = await request.response();
const statusCode: number = response.status();
if (statusCode >= 400) {
const specialError: string = await response.headerValue('special-header');
const specialErrorRef: string = await response.headerValue('special-error-ref');
this.setHttpResponseError(statusCode, specialError, specialErrorRef, url);
}
};
It functions as intended. However, it has the side effect of adding a lot of noise to the trace files. For example:

Most of the actions in the list are not actually helpful for debugging. In particular: request.headersArray, request.response, and request.headerValue show up repeatedly, but don't provide any more information than was already there under the network tab. This makes it hard to walk through the actual meaningful actions like navigation, clicking buttons, etc.
What I'd like is to exclude those less than helpful actions from the actions list. That could be as simple as a code change to stop recording those as actions.
But if you feel that they do provide value to some users of Playwright, perhaps we could add an option to filter out unwanted actions.
Maybe something like this?
context.tracing.stop({
path: 'my-trace.zip',
filterOutActions: (action) => action.metadata.apiName === "response.headerValue",
});
I'd be willing to take a stab at implementing either of these approaches.
@rwoll I see that you tagged the issue as "collecting feedback." Is the Playwright team open to one of the solutions I suggested above?
This is causing a fair bit of annoyance for my team at Microsoft. Obviously, I could modify the custom test framework to open up the trace files and remove the irrelevant actions, but it would be significantly simpler if that could be handled within Playwright itself.
Thanks @joshuacc! I've added this issue to our triage session for tomorrow. We'll review the use case/root issue, and comment whether the proposed API is the route to take across the userbase.
Depending on what you're debugging having all the public API calls in the trace is ideal. Often times, until you debug, you don't know what is helpful, so an alternative idea could be to have a filter in the traceviewer UI itself, so you can filter out events in the UI, but still be able to show them if that's the code you need to debug.
@rwoll Thanks!
Regarding your suggestion, having a filter in the UI would be helpful, but because in my specific scenario I know that recording these API calls isn't useful for debugging, I'd still prefer to exclude them entirely.
One other option that occurs to me is the possibility of marking the API calls as hidden at the call site. Perhaps something like this?
const headers = await request.headersArray({ recordInTrace: false })
@joshuacc Here's the summary: Playwright welcomes a patch which changes how the Trace Viewer presents the data, but does not alter the data that ends up in the trace itself. e.g. A filtering mechanism in the UI (possibly with some canned/default filters of hiding request.*/response.*)
Pre-filtering the traces, while OK for your specific usecase, creates incomplete traces which makes debugging more difficult and confusing in the general usecase.
For example (if Playwright allows pre-filtering) and my teammate shares a trace with me or a user from the community asks us to help them debug an issue on GitHub and they send us a trace, we'd now be looking at an incomplete story and either (A) wondering if there was some pre-filter enabled, or (B) if we know there was, we'd need to go back and ask for a new, unfiltered trace. This creates more friction in the debugging experience and increases the time it takes us to help users.
A followup/second patch to a UI filter, could be a grouping mechanism similar to test.step(…) where the API calls are preserved, but they are just collapsed in the UI by default under the step.
@rwoll Thanks! I'll start working on a patch to filter in the UI. :)
Any updates for this? I have a lot of noise in my traces as well.

I am also curious about this issue. This would be very helpful for me and my dev team
Hey. I hope to get around to implementing this sometime in the next month or two, but I've had a bunch of other work take priority for the moment. If someone else has time, feel free to take a crack at it. :)
Hi everyone, any update on this feature ?
I'd also really find it useful to prevent "noise" actions from showing up in the trace viewer, or at minimum being filtered out of the main view (but still expandable) by default, here's my use-case:
We have a custom Playwright fixture that customers use, which uses Chrome Devtools Protocol to archive resources used by the test. Each of these cdpSession.send entries (see screenshot below) are just network listeners (we’re just sending the original request/response on its merry way after archiving the response data).
We’ve gotten customer feedback that these entries are burying useful actions in the logs and inhibit debugging, so we’d like a way to not show them in the logs at all. Ideally there'd be an option when instantiating the CDP session, like page.context().newCDPSession(page, { includeInTrace: false }), or some regex-filter option that could be added to playwright.config.js so it just happens everywhere in the test suite.
We're having an SDK help clients to retrieve information about the page. We have tried using test.step with box:true to aggregate our browser interaction, but it doesn't work when you're using macro-task operation such as setTimeout (see #28417).
Having the ability to mark actions as hidden-by-default would be amazing.
Alternatively, I think it can be useful to distinguish actions coming from the user source code, and actions coming from packages.