chore: make console stream live in ui mode (#26562)
This commit is contained in:
parent
32a309ccb8
commit
f83d81956d
|
|
@ -33,10 +33,15 @@ export class Tracing extends ChannelOwner<channels.TracingChannel> implements ap
|
|||
super(parent, type, guid, initializer);
|
||||
}
|
||||
|
||||
async start(options: { name?: string, title?: string, snapshots?: boolean, screenshots?: boolean, sources?: boolean } = {}) {
|
||||
async start(options: { name?: string, title?: string, snapshots?: boolean, screenshots?: boolean, sources?: boolean, _live?: boolean } = {}) {
|
||||
this._includeSources = !!options.sources;
|
||||
const traceName = await this._wrapApiCall(async () => {
|
||||
await this._channel.tracingStart(options);
|
||||
await this._channel.tracingStart({
|
||||
name: options.name,
|
||||
snapshots: options.snapshots,
|
||||
screenshots: options.screenshots,
|
||||
live: options._live,
|
||||
});
|
||||
const response = await this._channel.tracingStartChunk({ name: options.name, title: options.title });
|
||||
return response.traceName;
|
||||
});
|
||||
|
|
|
|||
|
|
@ -2130,7 +2130,7 @@ scheme.TracingTracingStartParams = tObject({
|
|||
name: tOptional(tString),
|
||||
snapshots: tOptional(tBoolean),
|
||||
screenshots: tOptional(tBoolean),
|
||||
sources: tOptional(tBoolean),
|
||||
live: tOptional(tBoolean),
|
||||
});
|
||||
scheme.TracingTracingStartResult = tOptional(tObject({}));
|
||||
scheme.TracingTracingStartChunkParams = tObject({
|
||||
|
|
|
|||
|
|
@ -49,6 +49,7 @@ export type TracerOptions = {
|
|||
name?: string;
|
||||
snapshots?: boolean;
|
||||
screenshots?: boolean;
|
||||
live?: boolean;
|
||||
};
|
||||
|
||||
type RecordingState = {
|
||||
|
|
@ -455,8 +456,8 @@ export class Tracing extends SdkObject implements InstrumentationListener, Snaps
|
|||
|
||||
private _appendTraceEvent(event: trace.TraceEvent) {
|
||||
const visited = visitTraceEvent(event, this._state!.traceSha1s);
|
||||
// Do not flush events, they are too noisy.
|
||||
const flush = event.type !== 'event' && event.type !== 'object';
|
||||
// Do not flush (console) events, they are too noisy, unless we are in ui mode (live).
|
||||
const flush = this._state!.options.live || (event.type !== 'event' && event.type !== 'object');
|
||||
this._fs.appendFile(this._state!.traceFile, JSON.stringify(visited) + '\n', flush);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -526,7 +526,7 @@ class ArtifactsRecorder {
|
|||
private _traceMode: TraceMode;
|
||||
private _captureTrace = false;
|
||||
private _screenshotOptions: { mode: ScreenshotMode } & Pick<playwrightLibrary.PageScreenshotOptions, 'fullPage' | 'omitBackground'> | undefined;
|
||||
private _traceOptions: { screenshots: boolean, snapshots: boolean, sources: boolean, attachments: boolean, mode?: TraceMode };
|
||||
private _traceOptions: { screenshots: boolean, snapshots: boolean, sources: boolean, attachments: boolean, _live: boolean, mode?: TraceMode };
|
||||
private _temporaryTraceFiles: string[] = [];
|
||||
private _temporaryScreenshots: string[] = [];
|
||||
private _reusedContexts = new Set<BrowserContext>();
|
||||
|
|
@ -541,7 +541,7 @@ class ArtifactsRecorder {
|
|||
this._screenshotMode = normalizeScreenshotMode(screenshot);
|
||||
this._screenshotOptions = typeof screenshot === 'string' ? undefined : screenshot;
|
||||
this._traceMode = normalizeTraceMode(trace);
|
||||
const defaultTraceOptions = { screenshots: true, snapshots: true, sources: true, attachments: true };
|
||||
const defaultTraceOptions = { screenshots: true, snapshots: true, sources: true, attachments: true, _live: false };
|
||||
this._traceOptions = typeof trace === 'string' ? defaultTraceOptions : { ...defaultTraceOptions, ...trace, mode: undefined };
|
||||
this._screenshottedSymbol = Symbol('screenshotted');
|
||||
this._startedCollectingArtifacts = Symbol('startedCollectingArtifacts');
|
||||
|
|
|
|||
|
|
@ -52,7 +52,7 @@ class UIMode {
|
|||
p.project.repeatEach = 1;
|
||||
}
|
||||
config.configCLIOverrides.use = config.configCLIOverrides.use || {};
|
||||
config.configCLIOverrides.use.trace = { mode: 'on', sources: false };
|
||||
config.configCLIOverrides.use.trace = { mode: 'on', sources: false, _live: true };
|
||||
|
||||
this._originalStdoutWrite = process.stdout.write;
|
||||
this._originalStderrWrite = process.stderr.write;
|
||||
|
|
|
|||
|
|
@ -3803,13 +3803,13 @@ export type TracingTracingStartParams = {
|
|||
name?: string,
|
||||
snapshots?: boolean,
|
||||
screenshots?: boolean,
|
||||
sources?: boolean,
|
||||
live?: boolean,
|
||||
};
|
||||
export type TracingTracingStartOptions = {
|
||||
name?: string,
|
||||
snapshots?: boolean,
|
||||
screenshots?: boolean,
|
||||
sources?: boolean,
|
||||
live?: boolean,
|
||||
};
|
||||
export type TracingTracingStartResult = void;
|
||||
export type TracingTracingStartChunkParams = {
|
||||
|
|
|
|||
|
|
@ -3014,7 +3014,7 @@ Tracing:
|
|||
name: string?
|
||||
snapshots: boolean?
|
||||
screenshots: boolean?
|
||||
sources: boolean?
|
||||
live: boolean?
|
||||
|
||||
tracingStartChunk:
|
||||
parameters:
|
||||
|
|
|
|||
|
|
@ -200,10 +200,14 @@ function format(args: { preview: string, value: any }[]): JSX.Element[] {
|
|||
function parseCSSStyle(cssFormat: string): Record<string, string | number> {
|
||||
try {
|
||||
const styleObject: Record<string, string | number> = {};
|
||||
const cssText = cssFormat.replace(/;$/, '').replace(/: /g, ':').replace(/; /g, ';');
|
||||
const cssProperties = cssText.split(';');
|
||||
for (const property of cssProperties) {
|
||||
const [key, value] = property.split(':');
|
||||
const cssProperties = cssFormat.split(';');
|
||||
for (const token of cssProperties) {
|
||||
const property = token.trim();
|
||||
if (!property)
|
||||
continue;
|
||||
let [key, value] = property.split(':');
|
||||
key = key.trim();
|
||||
value = value.trim();
|
||||
if (!supportProperty(key))
|
||||
continue;
|
||||
// cssProperties are background-color, JSDom ones are backgroundColor
|
||||
|
|
|
|||
|
|
@ -151,3 +151,28 @@ test('should format console messages in page', async ({ runUITest }, testInfo) =
|
|||
await expect(link).toHaveCSS('color', 'rgb(0, 0, 255)');
|
||||
await expect(link).toHaveCSS('text-decoration', 'none solid rgb(0, 0, 255)');
|
||||
});
|
||||
|
||||
test('should stream console messages live', async ({ runUITest }, testInfo) => {
|
||||
const { page } = await runUITest({
|
||||
'a.spec.ts': `
|
||||
import { test, expect } from '@playwright/test';
|
||||
test('print', async ({ page }) => {
|
||||
await page.setContent('<button>Click me</button>');
|
||||
const button = page.getByRole('button', { name: 'Click me' });
|
||||
await button.evaluate(node => node.addEventListener('click', () => {
|
||||
setTimeout(() => { console.log('I was clicked'); }, 1000);
|
||||
}));
|
||||
await button.click();
|
||||
await page.locator('#not-there').waitFor();
|
||||
});
|
||||
`,
|
||||
});
|
||||
await page.getByTitle('Run all').click();
|
||||
await page.getByText('Console').click();
|
||||
await page.getByText('print').click();
|
||||
|
||||
await expect(page.locator('.console-tab .console-line-message')).toHaveText([
|
||||
'I was clicked',
|
||||
]);
|
||||
await page.getByTitle('Stop').click();
|
||||
});
|
||||
|
|
|
|||
Loading…
Reference in a new issue