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({
file: tString,
line: tOptional(tNumber),
column: tOptional(tNumber),
line: tNumber,
column: tNumber,
function: tOptional(tString),
});
scheme.Metadata = tObject({

View File

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

View File

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

View File

@ -16,7 +16,6 @@
import { captureRawStack, pollAgainstTimeout } from 'playwright-core/lib/utils';
import type { ExpectZone } from 'playwright-core/lib/utils';
import path from 'path';
import {
toBeChecked,
toBeDisabled,
@ -200,12 +199,11 @@ class ExpectMetaInfoProxyHandler {
const rawStack = captureRawStack();
const stackFrames = filteredStackTrace(rawStack);
const frame = stackFrames[0];
const customMessage = this._info.message || '';
const defaultTitle = `expect${this._info.isPoll ? '.poll' : ''}${this._info.isSoft ? '.soft' : ''}${this._info.isNot ? '.not' : ''}.${matcherName}`;
const wallTime = Date.now();
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',
title: trimLongString(customMessage || defaultTitle, 1024),
canHaveChildren: true,

View File

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

View File

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

View File

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

View File

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