chore: migrate to protocol's StackFrame type (#21198)

This commit is contained in:
Pavel Feldman 2023-02-24 18:36:15 -08:00 committed by GitHub
parent ed41fd0643
commit 09f77c41dd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 33 additions and 55 deletions

View File

@ -22,8 +22,8 @@ export { ValidationError, findValidator, maybeFindValidator, createMetadataValid
scheme.StackFrame = tObject({ scheme.StackFrame = tObject({
file: tString, file: tString,
line: tOptional(tNumber), line: tNumber,
column: tOptional(tNumber), column: tNumber,
function: tOptional(tString), function: tOptional(tString),
}); });
scheme.Metadata = tObject({ scheme.Metadata = tObject({

View File

@ -17,6 +17,7 @@
import path from 'path'; import path from 'path';
import { parseStackTraceLine } from '../utilsBundle'; import { parseStackTraceLine } from '../utilsBundle';
import { isUnderTest } from './'; import { isUnderTest } from './';
import type { StackFrame } from '@protocol/channels';
export function rewriteErrorMessage<E extends Error>(e: E, newMessage: string): E { export function rewriteErrorMessage<E extends Error>(e: E, newMessage: string): E {
const lines: string[] = (e.stack?.split('\n') || []).filter(l => l.startsWith(' at ')); const lines: string[] = (e.stack?.split('\n') || []).filter(l => l.startsWith(' at '));
@ -35,13 +36,6 @@ const internalStackPrefixes = [
]; ];
export const addInternalStackPrefix = (prefix: string) => internalStackPrefixes.push(prefix); export const addInternalStackPrefix = (prefix: string) => internalStackPrefixes.push(prefix);
export type StackFrame = {
file: string,
line?: number,
column?: number,
function?: string,
};
export type ParsedStackTrace = { export type ParsedStackTrace = {
allFrames: StackFrame[]; allFrames: StackFrame[];
frames: StackFrame[]; frames: StackFrame[];
@ -71,18 +65,13 @@ export function captureLibraryStackTrace(rawStack?: RawStack): ParsedStackTrace
}; };
let parsedFrames = stack.map(line => { let parsedFrames = stack.map(line => {
const frame = parseStackTraceLine(line); const frame = parseStackTraceLine(line);
if (!frame || !frame.fileName) if (!frame || !frame.file)
return null; return null;
if (!process.env.PWDEBUGIMPL && isTesting && frame.fileName.includes(COVERAGE_PATH)) if (!process.env.PWDEBUGIMPL && isTesting && frame.file.includes(COVERAGE_PATH))
return null; return null;
const isPlaywrightLibrary = frame.fileName.startsWith(CORE_DIR); const isPlaywrightLibrary = frame.file.startsWith(CORE_DIR);
const parsed: ParsedFrame = { const parsed: ParsedFrame = {
frame: { frame,
file: frame.fileName,
line: frame.line,
column: frame.column,
function: frame.function,
},
frameText: line, frameText: line,
isPlaywrightLibrary isPlaywrightLibrary
}; };

View File

@ -36,21 +36,14 @@ export const wsReceiver = require('./utilsBundleImpl').wsReceiver;
export const wsSender = require('./utilsBundleImpl').wsSender; export const wsSender = require('./utilsBundleImpl').wsSender;
export type { Command } from '../bundles/utils/node_modules/commander'; export type { Command } from '../bundles/utils/node_modules/commander';
export type { WebSocket, WebSocketServer, RawData as WebSocketRawData, EventEmitter as WebSocketEventEmitter } from '../bundles/utils/node_modules/@types/ws'; export type { WebSocket, WebSocketServer, RawData as WebSocketRawData, EventEmitter as WebSocketEventEmitter } from '../bundles/utils/node_modules/@types/ws';
import type { StackFrame } from '@protocol/channels';
const StackUtils: typeof import('../bundles/utils/node_modules/@types/stack-utils') = require('./utilsBundleImpl').StackUtils; const StackUtils: typeof import('../bundles/utils/node_modules/@types/stack-utils') = require('./utilsBundleImpl').StackUtils;
const stackUtils = new StackUtils({ internals: StackUtils.nodeInternals() }); const stackUtils = new StackUtils({ internals: StackUtils.nodeInternals() });
const nodeInternals = StackUtils.nodeInternals(); const nodeInternals = StackUtils.nodeInternals();
const nodeMajorVersion = +process.versions.node.split('.')[0]; const nodeMajorVersion = +process.versions.node.split('.')[0];
export type StackFrameData = { export function parseStackTraceLine(line: string): StackFrame | null {
line?: number | undefined;
column?: number | undefined;
fileName?: string | undefined;
fileOrUrl?: string | undefined;
function?: string | undefined;
};
export function parseStackTraceLine(line: string): StackFrameData | null {
if (!process.env.PWDEBUGIMPL && nodeMajorVersion < 16 && nodeInternals.some(internal => internal.test(line))) if (!process.env.PWDEBUGIMPL && nodeMajorVersion < 16 && nodeInternals.some(internal => internal.test(line)))
return null; return null;
const frame = stackUtils.parseLine(line); const frame = stackUtils.parseLine(line);
@ -58,16 +51,14 @@ export function parseStackTraceLine(line: string): StackFrameData | null {
return null; return null;
if (!process.env.PWDEBUGIMPL && (frame.file?.startsWith('internal') || frame.file?.startsWith('node:'))) if (!process.env.PWDEBUGIMPL && (frame.file?.startsWith('internal') || frame.file?.startsWith('node:')))
return null; return null;
let fileName: string | undefined = undefined; if (!frame.file)
if (frame.file) { return null;
// ESM files return file:// URLs, see here: https://github.com/tapjs/stack-utils/issues/60 // ESM files return file:// URLs, see here: https://github.com/tapjs/stack-utils/issues/60
fileName = frame.file.startsWith('file://') ? url.fileURLToPath(frame.file) : path.resolve(process.cwd(), frame.file); const file = frame.file.startsWith('file://') ? url.fileURLToPath(frame.file) : path.resolve(process.cwd(), frame.file);
}
return { return {
line: frame.line, file,
column: frame.column, line: frame.line || 0,
fileName, column: frame.column || 0,
fileOrUrl: frame.file,
function: frame.function, function: frame.function,
}; };
} }

View File

@ -16,7 +16,6 @@
import { captureRawStack, pollAgainstTimeout } from 'playwright-core/lib/utils'; import { captureRawStack, pollAgainstTimeout } from 'playwright-core/lib/utils';
import type { ExpectZone } from 'playwright-core/lib/utils'; import type { ExpectZone } from 'playwright-core/lib/utils';
import path from 'path';
import { import {
toBeChecked, toBeChecked,
toBeDisabled, toBeDisabled,
@ -200,12 +199,11 @@ class ExpectMetaInfoProxyHandler {
const rawStack = captureRawStack(); const rawStack = captureRawStack();
const stackFrames = filteredStackTrace(rawStack); const stackFrames = filteredStackTrace(rawStack);
const frame = stackFrames[0];
const customMessage = this._info.message || ''; const customMessage = this._info.message || '';
const defaultTitle = `expect${this._info.isPoll ? '.poll' : ''}${this._info.isSoft ? '.soft' : ''}${this._info.isNot ? '.not' : ''}.${matcherName}`; const defaultTitle = `expect${this._info.isPoll ? '.poll' : ''}${this._info.isSoft ? '.soft' : ''}${this._info.isNot ? '.not' : ''}.${matcherName}`;
const wallTime = Date.now(); const wallTime = Date.now();
const step = testInfo._addStep({ const step = testInfo._addStep({
location: frame && frame.fileName ? { file: path.resolve(process.cwd(), frame.fileName), line: frame.line || 0, column: frame.column || 0 } : undefined, location: stackFrames[0],
category: 'expect', category: 'expect',
title: trimLongString(customMessage || defaultTitle, 1024), title: trimLongString(customMessage || defaultTitle, 1024),
canHaveChildren: true, canHaveChildren: true,

View File

@ -442,11 +442,11 @@ export function prepareErrorStack(stack: string): {
let location: Location | undefined; let location: Location | undefined;
for (const line of stackLines) { for (const line of stackLines) {
const frame = parseStackTraceLine(line); const frame = parseStackTraceLine(line);
if (!frame || !frame.fileName) if (!frame || !frame.file)
continue; continue;
if (belongsToNodeModules(frame.fileName)) if (belongsToNodeModules(frame.file))
continue; continue;
location = { file: frame.fileName, column: frame.column || 0, line: frame.line || 0 }; location = { file: frame.file, column: frame.column || 0, line: frame.line || 0 };
break; break;
} }
return { message, stackLines, location }; return { message, stackLines, location };

View File

@ -16,7 +16,7 @@
import fs from 'fs'; import fs from 'fs';
import { mime } from 'playwright-core/lib/utilsBundle'; import { mime } from 'playwright-core/lib/utilsBundle';
import type { StackFrameData } from 'playwright-core/lib/utilsBundle'; import type { StackFrame } from '@protocol/channels';
import util from 'util'; import util from 'util';
import path from 'path'; import path from 'path';
import url from 'url'; import url from 'url';
@ -37,28 +37,28 @@ export function filterStackTrace(e: Error) {
e.message = message; e.message = message;
} }
export function filteredStackTrace(rawStack: RawStack): StackFrameData[] { export function filteredStackTrace(rawStack: RawStack): StackFrame[] {
const frames: StackFrameData[] = []; const frames: StackFrame[] = [];
for (const line of rawStack) { for (const line of rawStack) {
const frame = parseStackTraceLine(line); const frame = parseStackTraceLine(line);
if (!frame || !frame.fileName) if (!frame || !frame.file)
continue; continue;
if (!process.env.PWDEBUGIMPL && frame.fileName.startsWith(PLAYWRIGHT_TEST_PATH)) if (!process.env.PWDEBUGIMPL && frame.file.startsWith(PLAYWRIGHT_TEST_PATH))
continue; continue;
if (!process.env.PWDEBUGIMPL && frame.fileName.startsWith(PLAYWRIGHT_CORE_PATH)) if (!process.env.PWDEBUGIMPL && frame.file.startsWith(PLAYWRIGHT_CORE_PATH))
continue; continue;
frames.push(frame); frames.push(frame);
} }
return frames; return frames;
} }
export function stringifyStackFrames(frames: StackFrameData[]): string[] { export function stringifyStackFrames(frames: StackFrame[]): string[] {
const stackLines: string[] = []; const stackLines: string[] = [];
for (const frame of frames) { for (const frame of frames) {
if (frame.function) if (frame.function)
stackLines.push(` at ${frame.function} (${frame.fileName}:${frame.line}:${frame.column})`); stackLines.push(` at ${frame.function} (${frame.file}:${frame.line}:${frame.column})`);
else else
stackLines.push(` at ${frame.fileName}:${frame.line}:${frame.column}`); stackLines.push(` at ${frame.file}:${frame.line}:${frame.column}`);
} }
return stackLines; return stackLines;
} }

View File

@ -139,8 +139,8 @@ export type EventTargetTraits<T> =
export type StackFrame = { export type StackFrame = {
file: string, file: string,
line?: number, line: number,
column?: number, column: number,
function?: string, function?: string,
}; };

View File

@ -16,8 +16,8 @@ StackFrame:
type: object type: object
properties: properties:
file: string file: string
line: number? line: number
column: number? column: number
function: string? function: string?
# This object can be send with any rpc call in the "metadata" field. # This object can be send with any rpc call in the "metadata" field.