mirror of
https://github.com/microsoft/playwright.git
synced 2024-12-11 12:33:45 +03:00
feat: support name
option in tracing.startChunk()
(#21692)
This commit is contained in:
parent
bde2e90973
commit
40a6eff8f2
@ -267,6 +267,13 @@ await context.Tracing.StopChunkAsync(new()
|
||||
|
||||
Trace name to be shown in the Trace Viewer.
|
||||
|
||||
### option: Tracing.startChunk.name
|
||||
* since: v1.32
|
||||
- `name` <[string]>
|
||||
|
||||
If specified, the trace is going to be saved into the file with the
|
||||
given name inside the [`option: tracesDir`] folder specified in [`method: BrowserType.launch`].
|
||||
|
||||
## async method: Tracing.stop
|
||||
* since: v1.12
|
||||
|
||||
|
@ -34,13 +34,13 @@ export class Tracing extends ChannelOwner<channels.TracingChannel> implements ap
|
||||
this._includeSources = !!options.sources;
|
||||
await this._wrapApiCall(async () => {
|
||||
await this._channel.tracingStart(options);
|
||||
await this._channel.tracingStartChunk({ title: options.title });
|
||||
await this._channel.tracingStartChunk({ name: options.name, title: options.title });
|
||||
});
|
||||
this._metadataCollector = [];
|
||||
this._connection.startCollectingCallMetadata(this._metadataCollector);
|
||||
}
|
||||
|
||||
async startChunk(options: { title?: string } = {}) {
|
||||
async startChunk(options: { name?: string, title?: string } = {}) {
|
||||
await this._channel.tracingStartChunk(options);
|
||||
this._metadataCollector = [];
|
||||
this._connection.startCollectingCallMetadata(this._metadataCollector);
|
||||
|
@ -2092,6 +2092,7 @@ scheme.TracingTracingStartParams = tObject({
|
||||
});
|
||||
scheme.TracingTracingStartResult = tOptional(tObject({}));
|
||||
scheme.TracingTracingStartChunkParams = tObject({
|
||||
name: tOptional(tString),
|
||||
title: tOptional(tString),
|
||||
});
|
||||
scheme.TracingTracingStartChunkResult = tOptional(tObject({}));
|
||||
|
@ -125,6 +125,8 @@ export class Tracing extends SdkObject implements InstrumentationListener, Snaps
|
||||
const o = this._state.options;
|
||||
if (!o.screenshots !== !options.screenshots || !o.snapshots !== !options.snapshots)
|
||||
throw new Error('Tracing has been already started with different options');
|
||||
if (options.name && options.name !== this._state.traceName)
|
||||
await this._changeTraceName(this._state, options.name);
|
||||
return;
|
||||
}
|
||||
// TODO: passing the same name for two contexts makes them write into a single file
|
||||
@ -143,7 +145,7 @@ export class Tracing extends SdkObject implements InstrumentationListener, Snaps
|
||||
this._harTracer.start();
|
||||
}
|
||||
|
||||
async startChunk(options: { title?: string } = {}) {
|
||||
async startChunk(options: { name?: string, title?: string } = {}) {
|
||||
if (this._state && this._state.recording)
|
||||
await this.stopChunk({ mode: 'discard' });
|
||||
|
||||
@ -158,6 +160,8 @@ export class Tracing extends SdkObject implements InstrumentationListener, Snaps
|
||||
state.traceFile = path.join(state.tracesDir, `${state.traceName}${suffix}.trace`);
|
||||
state.recording = true;
|
||||
|
||||
if (options.name && options.name !== this._state.traceName)
|
||||
this._changeTraceName(this._state, options.name);
|
||||
this._appendTraceOperation(async () => {
|
||||
await mkdirIfNeeded(state.traceFile);
|
||||
await fs.promises.appendFile(state.traceFile, JSON.stringify({ ...this._contextCreatedEvent, title: options.title, wallTime: Date.now() }) + '\n');
|
||||
@ -188,6 +192,16 @@ export class Tracing extends SdkObject implements InstrumentationListener, Snaps
|
||||
page.setScreencastOptions(null);
|
||||
}
|
||||
|
||||
private async _changeTraceName(state: RecordingState, name: string) {
|
||||
await this._appendTraceOperation(async () => {
|
||||
const oldNetworkFile = state.networkFile;
|
||||
state.traceFile = path.join(state.tracesDir, name + '.trace');
|
||||
state.networkFile = path.join(state.tracesDir, name + '.network');
|
||||
// Network file survives across chunks, so make a copy with the new name.
|
||||
await fs.promises.copyFile(oldNetworkFile, state.networkFile);
|
||||
});
|
||||
}
|
||||
|
||||
async stop() {
|
||||
if (!this._state)
|
||||
return;
|
||||
@ -257,7 +271,7 @@ export class Tracing extends SdkObject implements InstrumentationListener, Snaps
|
||||
if (params.mode === 'discard')
|
||||
return {};
|
||||
|
||||
// Har files are live, make a snapshot before returning the resulting entries.
|
||||
// Network file survives across chunks, make a snapshot before returning the resulting entries.
|
||||
const networkFile = path.join(state.networkFile, '..', createGuid());
|
||||
await fs.promises.copyFile(state.networkFile, networkFile);
|
||||
|
||||
|
7
packages/playwright-core/types/types.d.ts
vendored
7
packages/playwright-core/types/types.d.ts
vendored
@ -18262,6 +18262,13 @@ export interface Tracing {
|
||||
* @param options
|
||||
*/
|
||||
startChunk(options?: {
|
||||
/**
|
||||
* If specified, the trace is going to be saved into the file with the given name inside the `tracesDir` folder
|
||||
* specified in
|
||||
* [browserType.launch([options])](https://playwright.dev/docs/api/class-browsertype#browser-type-launch).
|
||||
*/
|
||||
name?: string;
|
||||
|
||||
/**
|
||||
* Trace name to be shown in the Trace Viewer.
|
||||
*/
|
||||
|
@ -3749,9 +3749,11 @@ export type TracingTracingStartOptions = {
|
||||
};
|
||||
export type TracingTracingStartResult = void;
|
||||
export type TracingTracingStartChunkParams = {
|
||||
name?: string,
|
||||
title?: string,
|
||||
};
|
||||
export type TracingTracingStartChunkOptions = {
|
||||
name?: string,
|
||||
title?: string,
|
||||
};
|
||||
export type TracingTracingStartChunkResult = void;
|
||||
|
@ -2925,6 +2925,7 @@ Tracing:
|
||||
|
||||
tracingStartChunk:
|
||||
parameters:
|
||||
name: string?
|
||||
title: string?
|
||||
|
||||
tracingStopChunk:
|
||||
|
@ -180,6 +180,58 @@ test('should collect two traces', async ({ context, page, server }, testInfo) =>
|
||||
}
|
||||
});
|
||||
|
||||
test('should respect tracesDir and name', async ({ browserType, server }, testInfo) => {
|
||||
const tracesDir = testInfo.outputPath('traces');
|
||||
const browser = await browserType.launch({ tracesDir });
|
||||
const context = await browser.newContext();
|
||||
const page = await context.newPage();
|
||||
|
||||
await context.tracing.start({ name: 'name1', snapshots: true });
|
||||
await page.goto(server.PREFIX + '/one-style.html');
|
||||
await context.tracing.stopChunk({ path: testInfo.outputPath('trace1.zip') });
|
||||
expect(fs.existsSync(path.join(tracesDir, 'name1.trace'))).toBe(true);
|
||||
expect(fs.existsSync(path.join(tracesDir, 'name1.network'))).toBe(true);
|
||||
|
||||
await context.tracing.startChunk({ name: 'name2' });
|
||||
await page.goto(server.PREFIX + '/har.html');
|
||||
await context.tracing.stop({ path: testInfo.outputPath('trace2.zip') });
|
||||
expect(fs.existsSync(path.join(tracesDir, 'name2.trace'))).toBe(true);
|
||||
expect(fs.existsSync(path.join(tracesDir, 'name2.network'))).toBe(true);
|
||||
|
||||
await browser.close();
|
||||
|
||||
function resourceNames(resources: Map<string, Buffer>) {
|
||||
return [...resources.keys()].map(file => {
|
||||
return file.replace(/^resources\/.*\.(html|css)$/, 'resources/XXX.$1');
|
||||
}).sort();
|
||||
}
|
||||
|
||||
{
|
||||
const { resources, actions } = await parseTrace(testInfo.outputPath('trace1.zip'));
|
||||
expect(actions).toEqual(['page.goto']);
|
||||
expect(resourceNames(resources)).toEqual([
|
||||
'resources/XXX.css',
|
||||
'resources/XXX.html',
|
||||
'trace.network',
|
||||
'trace.stacks',
|
||||
'trace.trace',
|
||||
]);
|
||||
}
|
||||
|
||||
{
|
||||
const { resources, actions } = await parseTrace(testInfo.outputPath('trace2.zip'));
|
||||
expect(actions).toEqual(['page.goto']);
|
||||
expect(resourceNames(resources)).toEqual([
|
||||
'resources/XXX.css',
|
||||
'resources/XXX.html',
|
||||
'resources/XXX.html',
|
||||
'trace.network',
|
||||
'trace.stacks',
|
||||
'trace.trace',
|
||||
]);
|
||||
}
|
||||
});
|
||||
|
||||
test('should not include trace resources from the provious chunks', async ({ context, page, server, browserName }, testInfo) => {
|
||||
test.skip(browserName !== 'chromium', 'The number of screenshots is flaky in non-Chromium');
|
||||
await context.tracing.start({ screenshots: true, snapshots: true, sources: true });
|
||||
|
Loading…
Reference in New Issue
Block a user