chore: update tracing tests helper (#19848)
To be reused in future tests. Signed-off-by: Dmitry Gozman <dgozman@gmail.com> Co-authored-by: Yury Semikhatsky <yurys@chromium.org>
This commit is contained in:
parent
f58015281a
commit
711a1aadbf
|
|
@ -14,7 +14,6 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { expect } from '@playwright/test';
|
|
||||||
import type { Frame, Page } from 'playwright-core';
|
import type { Frame, Page } from 'playwright-core';
|
||||||
import { ZipFile } from '../../packages/playwright-core/lib/utils/zipFile';
|
import { ZipFile } from '../../packages/playwright-core/lib/utils/zipFile';
|
||||||
|
|
||||||
|
|
@ -37,6 +36,8 @@ export async function detachFrame(page: Page, frameId: string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function verifyViewport(page: Page, width: number, height: number) {
|
export async function verifyViewport(page: Page, width: number, height: number) {
|
||||||
|
// `expect` may clash in test runner tests if imported eagerly.
|
||||||
|
const { expect } = require('@playwright/test');
|
||||||
expect(page.viewportSize().width).toBe(width);
|
expect(page.viewportSize().width).toBe(width);
|
||||||
expect(page.viewportSize().height).toBe(height);
|
expect(page.viewportSize().height).toBe(height);
|
||||||
expect(await page.evaluate('window.innerWidth')).toBe(width);
|
expect(await page.evaluate('window.innerWidth')).toBe(width);
|
||||||
|
|
@ -90,7 +91,7 @@ export function suppressCertificateWarning() {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function parseTrace(file: string): Promise<{ events: any[], resources: Map<string, Buffer> }> {
|
export async function parseTrace(file: string): Promise<{ events: any[], resources: Map<string, Buffer>, actions: string[] }> {
|
||||||
const zipFS = new ZipFile(file);
|
const zipFS = new ZipFile(file);
|
||||||
const resources = new Map<string, Buffer>();
|
const resources = new Map<string, Buffer>();
|
||||||
for (const entry of await zipFS.entries())
|
for (const entry of await zipFS.entries())
|
||||||
|
|
@ -109,9 +110,17 @@ export async function parseTrace(file: string): Promise<{ events: any[], resourc
|
||||||
return {
|
return {
|
||||||
events,
|
events,
|
||||||
resources,
|
resources,
|
||||||
|
actions: eventsToActions(events)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function eventsToActions(events: any[]): string[] {
|
||||||
|
// Trace viewer only shows non-internal non-tracing actions.
|
||||||
|
return events.filter(e => e.type === 'action' && !e.metadata.internal && !e.metadata.method.startsWith('tracing'))
|
||||||
|
.sort((a, b) => a.metadata.startTime - b.metadata.startTime)
|
||||||
|
.map(e => e.metadata.apiName);
|
||||||
|
}
|
||||||
|
|
||||||
export async function parseHar(file: string): Promise<Map<string, Buffer>> {
|
export async function parseHar(file: string): Promise<Map<string, Buffer>> {
|
||||||
const zipFS = new ZipFile(file);
|
const zipFS = new ZipFile(file);
|
||||||
const resources = new Map<string, Buffer>();
|
const resources = new Map<string, Buffer>();
|
||||||
|
|
|
||||||
|
|
@ -37,9 +37,9 @@ test('should collect trace with resources, but no js', async ({ context, page, s
|
||||||
await page.close();
|
await page.close();
|
||||||
await context.tracing.stop({ path: testInfo.outputPath('trace.zip') });
|
await context.tracing.stop({ path: testInfo.outputPath('trace.zip') });
|
||||||
|
|
||||||
const { events } = await parseTrace(testInfo.outputPath('trace.zip'));
|
const { events, actions } = await parseTrace(testInfo.outputPath('trace.zip'));
|
||||||
expect(events[0].type).toBe('context-options');
|
expect(events[0].type).toBe('context-options');
|
||||||
expect(eventsToActions(events)).toEqual([
|
expect(actions).toEqual([
|
||||||
'page.goto',
|
'page.goto',
|
||||||
'page.setContent',
|
'page.setContent',
|
||||||
'page.click',
|
'page.click',
|
||||||
|
|
@ -48,7 +48,6 @@ test('should collect trace with resources, but no js', async ({ context, page, s
|
||||||
'keyboard.insertText',
|
'keyboard.insertText',
|
||||||
'page.waitForTimeout',
|
'page.waitForTimeout',
|
||||||
'page.close',
|
'page.close',
|
||||||
'tracing.stop',
|
|
||||||
]);
|
]);
|
||||||
|
|
||||||
expect(events.some(e => e.type === 'frame-snapshot')).toBeTruthy();
|
expect(events.some(e => e.type === 'frame-snapshot')).toBeTruthy();
|
||||||
|
|
@ -79,9 +78,9 @@ test('should use the correct apiName for event driven callbacks', async ({ conte
|
||||||
await page.evaluate(() => alert('yo'));
|
await page.evaluate(() => alert('yo'));
|
||||||
|
|
||||||
await context.tracing.stop({ path: testInfo.outputPath('trace.zip') });
|
await context.tracing.stop({ path: testInfo.outputPath('trace.zip') });
|
||||||
const { events } = await parseTrace(testInfo.outputPath('trace.zip'));
|
const { events, actions } = await parseTrace(testInfo.outputPath('trace.zip'));
|
||||||
expect(events[0].type).toBe('context-options');
|
expect(events[0].type).toBe('context-options');
|
||||||
expect(eventsToActions(events)).toEqual([
|
expect(actions).toEqual([
|
||||||
'page.route',
|
'page.route',
|
||||||
'page.goto',
|
'page.goto',
|
||||||
'route.continue',
|
'route.continue',
|
||||||
|
|
@ -90,7 +89,6 @@ test('should use the correct apiName for event driven callbacks', async ({ conte
|
||||||
'page.reload',
|
'page.reload',
|
||||||
'page.evaluate',
|
'page.evaluate',
|
||||||
'dialog.accept',
|
'dialog.accept',
|
||||||
'tracing.stop',
|
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -165,23 +163,21 @@ test('should collect two traces', async ({ context, page, server }, testInfo) =>
|
||||||
await context.tracing.stop({ path: testInfo.outputPath('trace2.zip') });
|
await context.tracing.stop({ path: testInfo.outputPath('trace2.zip') });
|
||||||
|
|
||||||
{
|
{
|
||||||
const { events } = await parseTrace(testInfo.outputPath('trace1.zip'));
|
const { events, actions } = await parseTrace(testInfo.outputPath('trace1.zip'));
|
||||||
expect(events[0].type).toBe('context-options');
|
expect(events[0].type).toBe('context-options');
|
||||||
expect(eventsToActions(events)).toEqual([
|
expect(actions).toEqual([
|
||||||
'page.goto',
|
'page.goto',
|
||||||
'page.setContent',
|
'page.setContent',
|
||||||
'page.click',
|
'page.click',
|
||||||
'tracing.stop',
|
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
const { events } = await parseTrace(testInfo.outputPath('trace2.zip'));
|
const { events, actions } = await parseTrace(testInfo.outputPath('trace2.zip'));
|
||||||
expect(events[0].type).toBe('context-options');
|
expect(events[0].type).toBe('context-options');
|
||||||
expect(eventsToActions(events)).toEqual([
|
expect(actions).toEqual([
|
||||||
'page.dblclick',
|
'page.dblclick',
|
||||||
'page.close',
|
'page.close',
|
||||||
'tracing.stop',
|
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
@ -396,11 +392,10 @@ test('should work with multiple chunks', async ({ context, page, server }, testI
|
||||||
|
|
||||||
const trace1 = await parseTrace(testInfo.outputPath('trace.zip'));
|
const trace1 = await parseTrace(testInfo.outputPath('trace.zip'));
|
||||||
expect(trace1.events[0].type).toBe('context-options');
|
expect(trace1.events[0].type).toBe('context-options');
|
||||||
expect(eventsToActions(trace1.events)).toEqual([
|
expect(trace1.actions).toEqual([
|
||||||
'page.setContent',
|
'page.setContent',
|
||||||
'page.click',
|
'page.click',
|
||||||
'page.click',
|
'page.click',
|
||||||
'tracing.stopChunk',
|
|
||||||
]);
|
]);
|
||||||
expect(trace1.events.find(e => e.metadata?.apiName === 'page.click' && !!e.metadata.error)).toBeTruthy();
|
expect(trace1.events.find(e => e.metadata?.apiName === 'page.click' && !!e.metadata.error)).toBeTruthy();
|
||||||
expect(trace1.events.find(e => e.metadata?.apiName === 'page.click' && e.metadata?.error?.error?.message === 'Action was interrupted')).toBeTruthy();
|
expect(trace1.events.find(e => e.metadata?.apiName === 'page.click' && e.metadata?.error?.error?.message === 'Action was interrupted')).toBeTruthy();
|
||||||
|
|
@ -409,9 +404,8 @@ test('should work with multiple chunks', async ({ context, page, server }, testI
|
||||||
|
|
||||||
const trace2 = await parseTrace(testInfo.outputPath('trace2.zip'));
|
const trace2 = await parseTrace(testInfo.outputPath('trace2.zip'));
|
||||||
expect(trace2.events[0].type).toBe('context-options');
|
expect(trace2.events[0].type).toBe('context-options');
|
||||||
expect(eventsToActions(trace2.events)).toEqual([
|
expect(trace2.actions).toEqual([
|
||||||
'page.hover',
|
'page.hover',
|
||||||
'tracing.stopChunk',
|
|
||||||
]);
|
]);
|
||||||
expect(trace2.events.some(e => e.type === 'frame-snapshot')).toBeTruthy();
|
expect(trace2.events.some(e => e.type === 'frame-snapshot')).toBeTruthy();
|
||||||
expect(trace2.events.some(e => e.type === 'resource-snapshot' && e.snapshot.request.url.endsWith('style.css'))).toBeTruthy();
|
expect(trace2.events.some(e => e.type === 'resource-snapshot' && e.snapshot.request.url.endsWith('style.css'))).toBeTruthy();
|
||||||
|
|
@ -459,9 +453,8 @@ test('should ignore iframes in head', async ({ context, page, server }, testInfo
|
||||||
await context.tracing.stopChunk({ path: testInfo.outputPath('trace.zip') });
|
await context.tracing.stopChunk({ path: testInfo.outputPath('trace.zip') });
|
||||||
|
|
||||||
const trace = await parseTrace(testInfo.outputPath('trace.zip'));
|
const trace = await parseTrace(testInfo.outputPath('trace.zip'));
|
||||||
expect(eventsToActions(trace.events)).toEqual([
|
expect(trace.actions).toEqual([
|
||||||
'page.click',
|
'page.click',
|
||||||
'tracing.stopChunk',
|
|
||||||
]);
|
]);
|
||||||
expect(trace.events.find(e => e.type === 'frame-snapshot')).toBeTruthy();
|
expect(trace.events.find(e => e.type === 'frame-snapshot')).toBeTruthy();
|
||||||
expect(trace.events.find(e => e.type === 'frame-snapshot' && JSON.stringify(e.snapshot.html).includes('IFRAME'))).toBeFalsy();
|
expect(trace.events.find(e => e.type === 'frame-snapshot' && JSON.stringify(e.snapshot.html).includes('IFRAME'))).toBeFalsy();
|
||||||
|
|
@ -618,9 +611,3 @@ function expectBlue(pixels: Buffer, offset: number) {
|
||||||
function relativeStack(action: any): string[] {
|
function relativeStack(action: any): string[] {
|
||||||
return action.metadata.stack.map(f => f.file.replace(__dirname + path.sep, ''));
|
return action.metadata.stack.map(f => f.file.replace(__dirname + path.sep, ''));
|
||||||
}
|
}
|
||||||
|
|
||||||
function eventsToActions(events: any[]): string[] {
|
|
||||||
return events.filter(e => e.type === 'action' && !e.metadata.internal)
|
|
||||||
.sort((a, b) => a.metadata.startTime - b.metadata.startTime)
|
|
||||||
.map(e => e.metadata.apiName);
|
|
||||||
}
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue