Skip to content

Commit 9e15501

Browse files
authored
feat: record all actions in the trace and filter them in UI (#36929)
1 parent d2edfcc commit 9e15501

File tree

17 files changed

+317
-175
lines changed

17 files changed

+317
-175
lines changed

packages/playwright-core/src/client/browserContext.ts

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -236,7 +236,7 @@ export class BrowserContext extends ChannelOwner<channels.BrowserContextChannel>
236236
this._routes.splice(index, 1);
237237
const handled = await routeHandler.handle(route);
238238
if (!this._routes.length)
239-
this._updateInterceptionPatterns().catch(() => {});
239+
this._updateInterceptionPatterns({ internal: true }).catch(() => {});
240240
if (handled)
241241
return;
242242
}
@@ -351,12 +351,12 @@ export class BrowserContext extends ChannelOwner<channels.BrowserContextChannel>
351351

352352
async route(url: URLMatch, handler: network.RouteHandlerCallback, options: { times?: number } = {}): Promise<void> {
353353
this._routes.unshift(new network.RouteHandler(this._platform, this._options.baseURL, url, handler, options.times));
354-
await this._updateInterceptionPatterns();
354+
await this._updateInterceptionPatterns({ title: 'Route requests' });
355355
}
356356

357357
async routeWebSocket(url: URLMatch, handler: network.WebSocketRouteHandlerCallback): Promise<void> {
358358
this._webSocketRoutes.unshift(new network.WebSocketRouteHandler(this._options.baseURL, url, handler));
359-
await this._updateWebSocketInterceptionPatterns();
359+
await this._updateWebSocketInterceptionPatterns({ title: 'Route WebSockets' });
360360
}
361361

362362
async _recordIntoHAR(har: string, page: Page | null, options: { url?: string | RegExp, updateContent?: 'attach' | 'embed' | 'omit', updateMode?: 'minimal' | 'full'} = {}): Promise<void> {
@@ -415,17 +415,17 @@ export class BrowserContext extends ChannelOwner<channels.BrowserContextChannel>
415415
const promises = removed.map(routeHandler => routeHandler.stop(behavior));
416416
await Promise.all(promises);
417417
}
418-
await this._updateInterceptionPatterns();
418+
await this._updateInterceptionPatterns({ title: 'Unroute requests' });
419419
}
420420

421-
private async _updateInterceptionPatterns() {
421+
private async _updateInterceptionPatterns(options: { internal: true } | { title: string }) {
422422
const patterns = network.RouteHandler.prepareInterceptionPatterns(this._routes);
423-
await this._channel.setNetworkInterceptionPatterns({ patterns });
423+
await this._wrapApiCall(() => this._channel.setNetworkInterceptionPatterns({ patterns }), options);
424424
}
425425

426-
private async _updateWebSocketInterceptionPatterns() {
426+
private async _updateWebSocketInterceptionPatterns(options: { internal: true } | { title: string }) {
427427
const patterns = network.WebSocketRouteHandler.prepareInterceptionPatterns(this._webSocketRoutes);
428-
await this._channel.setWebSocketInterceptionPatterns({ patterns });
428+
await this._wrapApiCall(() => this._channel.setWebSocketInterceptionPatterns({ patterns }), options);
429429
}
430430

431431
_effectiveCloseReason(): string | undefined {

packages/playwright-core/src/client/page.ts

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -203,7 +203,7 @@ export class Page extends ChannelOwner<channels.PageChannel> implements api.Page
203203
this._routes.splice(index, 1);
204204
const handled = await routeHandler.handle(route);
205205
if (!this._routes.length)
206-
this._updateInterceptionPatterns().catch(() => {});
206+
this._updateInterceptionPatterns({ internal: true }).catch(() => {});
207207
if (handled)
208208
return;
209209
}
@@ -520,7 +520,7 @@ export class Page extends ChannelOwner<channels.PageChannel> implements api.Page
520520

521521
async route(url: URLMatch, handler: RouteHandlerCallback, options: { times?: number } = {}): Promise<void> {
522522
this._routes.unshift(new RouteHandler(this._platform, this._browserContext._options.baseURL, url, handler, options.times));
523-
await this._updateInterceptionPatterns();
523+
await this._updateInterceptionPatterns({ title: 'Route requests' });
524524
}
525525

526526
async routeFromHAR(har: string, options: { url?: string | RegExp, notFound?: 'abort' | 'fallback', update?: boolean, updateContent?: 'attach' | 'embed', updateMode?: 'minimal' | 'full'} = {}): Promise<void> {
@@ -538,7 +538,7 @@ export class Page extends ChannelOwner<channels.PageChannel> implements api.Page
538538

539539
async routeWebSocket(url: URLMatch, handler: WebSocketRouteHandlerCallback): Promise<void> {
540540
this._webSocketRoutes.unshift(new WebSocketRouteHandler(this._browserContext._options.baseURL, url, handler));
541-
await this._updateWebSocketInterceptionPatterns();
541+
await this._updateWebSocketInterceptionPatterns({ title: 'Route WebSockets' });
542542
}
543543

544544
private _disposeHarRouters() {
@@ -569,17 +569,17 @@ export class Page extends ChannelOwner<channels.PageChannel> implements api.Page
569569
const promises = removed.map(routeHandler => routeHandler.stop(behavior));
570570
await Promise.all(promises);
571571
}
572-
await this._updateInterceptionPatterns();
572+
await this._updateInterceptionPatterns({ title: 'Unroute requests' });
573573
}
574574

575-
private async _updateInterceptionPatterns() {
575+
private async _updateInterceptionPatterns(options: { internal: true } | { title: string }) {
576576
const patterns = RouteHandler.prepareInterceptionPatterns(this._routes);
577-
await this._channel.setNetworkInterceptionPatterns({ patterns });
577+
await this._wrapApiCall(() => this._channel.setNetworkInterceptionPatterns({ patterns }), options);
578578
}
579579

580-
private async _updateWebSocketInterceptionPatterns() {
580+
private async _updateWebSocketInterceptionPatterns(options: { internal: true } | { title: string }) {
581581
const patterns = WebSocketRouteHandler.prepareInterceptionPatterns(this._webSocketRoutes);
582-
await this._channel.setWebSocketInterceptionPatterns({ patterns });
582+
await this._wrapApiCall(() => this._channel.setWebSocketInterceptionPatterns({ patterns }), options);
583583
}
584584

585585
async screenshot(options: Omit<channels.PageScreenshotOptions, 'mask'> & TimeoutOptions & { path?: string, mask?: api.Locator[] } = {}): Promise<Buffer> {

packages/playwright-core/src/client/tracing.ts

Lines changed: 21 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -35,20 +35,24 @@ export class Tracing extends ChannelOwner<channels.TracingChannel> implements ap
3535
}
3636

3737
async start(options: { name?: string, title?: string, snapshots?: boolean, screenshots?: boolean, sources?: boolean, _live?: boolean } = {}) {
38-
this._includeSources = !!options.sources;
39-
await this._channel.tracingStart({
40-
name: options.name,
41-
snapshots: options.snapshots,
42-
screenshots: options.screenshots,
43-
live: options._live,
38+
await this._wrapApiCall(async () => {
39+
this._includeSources = !!options.sources;
40+
await this._channel.tracingStart({
41+
name: options.name,
42+
snapshots: options.snapshots,
43+
screenshots: options.screenshots,
44+
live: options._live,
45+
});
46+
const { traceName } = await this._channel.tracingStartChunk({ name: options.name, title: options.title });
47+
await this._startCollectingStacks(traceName);
4448
});
45-
const { traceName } = await this._channel.tracingStartChunk({ name: options.name, title: options.title });
46-
await this._startCollectingStacks(traceName);
4749
}
4850

4951
async startChunk(options: { name?: string, title?: string } = {}) {
50-
const { traceName } = await this._channel.tracingStartChunk(options);
51-
await this._startCollectingStacks(traceName);
52+
await this._wrapApiCall(async () => {
53+
const { traceName } = await this._channel.tracingStartChunk(options);
54+
await this._startCollectingStacks(traceName);
55+
});
5256
}
5357

5458
async group(name: string, options: { location?: { file: string, line?: number, column?: number } } = {}) {
@@ -69,12 +73,16 @@ export class Tracing extends ChannelOwner<channels.TracingChannel> implements ap
6973
}
7074

7175
async stopChunk(options: { path?: string } = {}) {
72-
await this._doStopChunk(options.path);
76+
await this._wrapApiCall(async () => {
77+
await this._doStopChunk(options.path);
78+
});
7379
}
7480

7581
async stop(options: { path?: string } = {}) {
76-
await this._doStopChunk(options.path);
77-
await this._channel.tracingStop();
82+
await this._wrapApiCall(async () => {
83+
await this._doStopChunk(options.path);
84+
await this._channel.tracingStop();
85+
});
7886
}
7987

8088
private async _doStopChunk(filePath: string | undefined) {

packages/playwright-core/src/server/trace/recorder/tracing.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import path from 'path';
2020

2121
import { Snapshotter } from './snapshotter';
2222
import { methodMetainfo } from '../../../utils/isomorphic/protocolMetainfo';
23+
import { getActionGroup } from '../../../utils/isomorphic/protocolFormatter';
2324
import { assert } from '../../../utils/isomorphic/assert';
2425
import { monotonicTime } from '../../../utils/isomorphic/time';
2526
import { eventsHelper } from '../../utils/eventsHelper';
@@ -650,7 +651,7 @@ function visitTraceEvent(object: any, sha1s: Set<string>): any {
650651
return object;
651652
}
652653

653-
export function shouldCaptureSnapshot(metadata: CallMetadata): boolean {
654+
function shouldCaptureSnapshot(metadata: CallMetadata): boolean {
654655
const metainfo = methodMetainfo.get(metadata.type + '.' + metadata.method);
655656
return !!metainfo?.snapshot;
656657
}
@@ -668,6 +669,7 @@ function createBeforeActionTraceEvent(metadata: CallMetadata, parentId?: string)
668669
params: metadata.params,
669670
stepId: metadata.stepId,
670671
pageId: metadata.pageId,
672+
visibility: getActionGroup(metadata) ? 'hidden' : undefined,
671673
};
672674
if (parentId)
673675
event.parentId = parentId;

packages/playwright-core/src/utils/isomorphic/protocolFormatter.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,3 +64,7 @@ export function renderTitleForCall(metadata: { title?: string, type: string, met
6464
return formatProtocolParam(metadata.params, p1) ?? fullMatch;
6565
});
6666
}
67+
68+
export function getActionGroup(metadata: { type: string, method: string }) {
69+
return methodMetainfo.get(metadata.type + '.' + metadata.method)?.group as undefined | 'configuration' | 'route' | 'getter';
70+
}

0 commit comments

Comments
 (0)