chore: render expect in trace viewer (#9141)

This commit is contained in:
Pavel Feldman 2021-09-27 09:19:59 -07:00 committed by GitHub
parent 1a2aa0e2e5
commit 241411ad42
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
11 changed files with 25 additions and 17 deletions

View file

@ -110,7 +110,7 @@ export class Connection extends EventEmitter {
if (!callback)
throw new Error(`Cannot find command to respond: ${id}`);
this._callbacks.delete(id);
if (error)
if (error && !result)
callback.reject(parseError(error));
else
callback.resolve(this._replaceGuidsWithChannels(result));

View file

@ -281,11 +281,12 @@ export class DispatcherConnection {
await sdkObject?.instrumentation.onAfterCall(sdkObject, callMetadata);
}
const log = validMetadata.collectLogs ? callMetadata.log : undefined;
if (callMetadata.error)
this.onmessage({ id, error: error, log });
else
this.onmessage({ id, result: callMetadata.result, log });
const response: any = { id };
if (callMetadata.result)
response.result = callMetadata.result;
if (error)
response.error = error;
this.onmessage(response);
}
private _replaceDispatchersWithGuids(payload: any): any {

View file

@ -232,6 +232,8 @@ export class FrameDispatcher extends Dispatcher<Frame, channels.FrameInitializer
const result = await this._frame.expect(metadata, params.selector, { ...params, expectedValue });
if (result.received !== undefined)
result.received = serializeResult(result.received);
if (result.pass === !!params.isNot)
metadata.error = { error: { name: 'Expect', message: 'Expect failed' } };
return result;
}
}

View file

@ -33,7 +33,6 @@ export type StackFrame = {
export type Metadata = {
stack?: StackFrame[],
apiName?: string,
collectLogs?: boolean,
};
export type Point = {

View file

@ -29,7 +29,6 @@ Metadata:
type: array?
items: StackFrame
apiName: string?
collectLogs: boolean?
Point:

View file

@ -42,7 +42,6 @@ export function createScheme(tChannel: (name: string) => Validator): Scheme {
scheme.Metadata = tObject({
stack: tOptional(tArray(tType('StackFrame'))),
apiName: tOptional(tString),
collectLogs: tOptional(tBoolean),
});
scheme.Point = tObject({
x: tNumber,

View file

@ -107,7 +107,6 @@ function wrap(matcherName: string, matcher: any) {
reportStepError(e);
}
};
result.displayName = 'expect.' + matcherName;
return result;
}

View file

@ -212,6 +212,8 @@ export const test = _baseTest.extend<TestFixtures, WorkerAndFileFixtures>({
}
(context as any)._csi = {
onApiCallBegin: (apiCall: string) => {
if (apiCall.startsWith('expect.'))
return { userObject: null };
const step = (testInfo as any)._addStep({
category: 'pw:api',
title: apiCall,

View file

@ -62,15 +62,14 @@ export function captureStackTrace(): ParsedStackTrace {
return null;
if (frame.file.startsWith('internal'))
return null;
if (frame.file.includes(path.join('node_modules', 'expect')))
return null;
const fileName = path.resolve(process.cwd(), frame.file);
if (isTesting && fileName.includes(path.join('playwright', 'tests', 'config', 'coverage.js')))
return null;
const inClient =
// Allow fixtures in the reported stacks.
(!fileName.includes('test/index') && !fileName.includes('test\\index')) && (
fileName.startsWith(CLIENT_LIB)
frame.file.includes(path.join('node_modules', 'expect'))
|| fileName.startsWith(CLIENT_LIB)
|| fileName.startsWith(CLIENT_SRC)
|| fileName.startsWith(TEST_LIB)
|| fileName.startsWith(TEST_SRC));
@ -94,7 +93,15 @@ export function captureStackTrace(): ParsedStackTrace {
for (let i = 0; i < parsedFrames.length - 1; i++) {
if (parsedFrames[i].inClient && !parsedFrames[i + 1].inClient) {
const frame = parsedFrames[i].frame;
apiName = frame.function ? frame.function[0].toLowerCase() + frame.function.slice(1) : '';
const text = parsedFrames[i].frameText;
// expect matchers have the following stack structure:
// at __EXTERNAL_MATCHER_TRAP__ (.../index.js:342:30)
// at Object.throwingMatcher [as toBeChecked] (.../index.js:343:15)
const aliasIndex = text.indexOf('[as ');
if (aliasIndex !== -1)
apiName = 'expect.' + text.substring(aliasIndex + 4, text.indexOf(']'));
else
apiName = frame.function ? frame.function[0].toLowerCase() + frame.function.slice(1) : '';
parsedFrames = parsedFrames.slice(i + 1);
break;
}

View file

@ -143,6 +143,8 @@ export const playwrightFixtures: Fixtures<PlaywrightTestOptions & PlaywrightTest
await context.tracing.start({ screenshots: true, snapshots: true });
(context as any)._csi = {
onApiCallBegin: (apiCall: string) => {
if (apiCall.startsWith('expect.'))
return { userObject: null };
const testInfoImpl = testInfo as any;
const step = testInfoImpl._addStep({
category: 'pw:api',

View file

@ -229,9 +229,7 @@ test('should report expect steps', async ({ runInlineTest }) => {
`%% end {\"title\":\"browserContext.newPage\",\"category\":\"pw:api\"}`,
`%% end {\"title\":\"Before Hooks\",\"category\":\"hook\",\"steps\":[{\"title\":\"browserContext.newPage\",\"category\":\"pw:api\"}]}`,
`%% begin {\"title\":\"expect.not.toHaveTitle\",\"category\":\"expect\"}`,
`%% begin {\"title\":\"object.expect.toHaveTitle(:root)\",\"category\":\"pw:api\"}`,
`%% end {\"title\":\"object.expect.toHaveTitle(:root)\",\"category\":\"pw:api\"}`,
`%% end {\"title\":\"expect.not.toHaveTitle\",\"category\":\"expect\",\"steps\":[{\"title\":\"object.expect.toHaveTitle(:root)\",\"category\":\"pw:api\"}]}`,
`%% end {\"title\":\"expect.not.toHaveTitle\",\"category\":\"expect\"}`,
`%% begin {\"title\":\"After Hooks\",\"category\":\"hook\"}`,
`%% begin {\"title\":\"browserContext.close\",\"category\":\"pw:api\"}`,
`%% end {\"title\":\"browserContext.close\",\"category\":\"pw:api\"}`,