chore: move utils that are user in server to server/utils (3) (#34739)

This commit is contained in:
Pavel Feldman 2025-02-12 09:34:01 -08:00 committed by GitHub
parent 703ca9f851
commit f54478a23e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
60 changed files with 204 additions and 227 deletions

View file

@ -14,4 +14,6 @@ utils/
client/
protocol/
utils/
common/
utils/isomorphic
server/utils
common/

View file

@ -19,7 +19,7 @@
import * as fs from 'fs';
import * as playwright from '../..';
import { PipeTransport } from '../protocol/transport';
import { PipeTransport } from '../utils/pipeTransport';
import { PlaywrightServer } from '../remote/playwrightServer';
import { DispatcherConnection, PlaywrightDispatcher, RootDispatcher, createPlaywright } from '../server';
import { gracefullyProcessExitDoNotHang } from '../server/utils/processLauncher';

View file

@ -22,9 +22,9 @@ import { TargetClosedError, isTargetClosedError } from './errors';
import { Events } from './events';
import { Waiter } from './waiter';
import { TimeoutSettings } from '../common/timeoutSettings';
import { isRegExp, isString } from '../utils/rtti';
import { monotonicTime } from '../utils/time';
import { raceAgainstDeadline } from '../utils/timeoutRunner';
import { isRegExp, isString } from '../utils/isomorphic/rtti';
import { monotonicTime } from '../utils/isomorphic/time';
import { raceAgainstDeadline } from '../utils/isomorphic/timeoutRunner';
import type { Page } from './page';
import type * as types from './types';

View file

@ -36,9 +36,9 @@ import { WebError } from './webError';
import { Worker } from './worker';
import { TimeoutSettings } from '../common/timeoutSettings';
import { mkdirIfNeeded } from '../utils/fileUtils';
import { headersObjectToArray } from '../utils/headers';
import { headersObjectToArray } from '../utils/isomorphic/headers';
import { urlMatchesEqual } from '../utils/isomorphic/urlMatch';
import { isRegExp, isString } from '../utils/rtti';
import { isRegExp, isString } from '../utils/isomorphic/rtti';
import { rewriteErrorMessage } from '../utils/stackTrace';
import type { BrowserType } from './browserType';

View file

@ -22,9 +22,9 @@ import { ChannelOwner } from './channelOwner';
import { envObjectToArray } from './clientHelper';
import { Events } from './events';
import { assert } from '../utils/debug';
import { headersObjectToArray } from '../utils/headers';
import { monotonicTime } from '../utils/time';
import { raceAgainstDeadline } from '../utils/timeoutRunner';
import { headersObjectToArray } from '../utils/isomorphic/headers';
import { monotonicTime } from '../utils/isomorphic/time';
import { raceAgainstDeadline } from '../utils/isomorphic/timeoutRunner';
import type { Playwright } from './playwright';
import type { ConnectOptions, LaunchOptions, LaunchPersistentContextOptions, LaunchServerOptions, Logger } from './types';

View file

@ -15,7 +15,7 @@
* limitations under the License.
*/
import { isString } from '../utils/rtti';
import { isString } from '../utils/isomorphic/rtti';
import type * as types from './types';
import type { Platform } from '../utils/platform';

View file

@ -21,7 +21,7 @@ import { Frame } from './frame';
import { JSHandle, parseResult, serializeArgument } from './jsHandle';
import { assert } from '../utils/debug';
import { fileUploadSizeLimit, mkdirIfNeeded } from '../utils/fileUtils';
import { isString } from '../utils/rtti';
import { isString } from '../utils/isomorphic/rtti';
import { mime } from '../utilsBundle';
import { WritableStream } from './writableStream';

View file

@ -15,7 +15,7 @@
*/
import { parseSerializedValue, serializeValue } from '../protocol/serializers';
import { isError } from '../utils/rtti';
import { isError } from '../utils/isomorphic/rtti';
import type { SerializedError } from '@protocol/channels';

View file

@ -21,8 +21,8 @@ import { RawHeaders } from './network';
import { Tracing } from './tracing';
import { assert } from '../utils/debug';
import { mkdirIfNeeded } from '../utils/fileUtils';
import { headersObjectToArray } from '../utils/headers';
import { isString } from '../utils/rtti';
import { headersObjectToArray } from '../utils/isomorphic/headers';
import { isString } from '../utils/isomorphic/rtti';
import type { Playwright } from './playwright';
import type { ClientCertificate, FilePayload, Headers, SetStorageState, StorageState } from './types';

View file

@ -19,8 +19,8 @@ import { parseResult, serializeArgument } from './jsHandle';
import { asLocator } from '../utils/isomorphic/locatorGenerators';
import { getByAltTextSelector, getByLabelSelector, getByPlaceholderSelector, getByRoleSelector, getByTestIdSelector, getByTextSelector, getByTitleSelector } from '../utils/isomorphic/locatorUtils';
import { escapeForTextSelector } from '../utils/isomorphic/stringUtils';
import { isString } from '../utils/rtti';
import { monotonicTime } from '../utils/time';
import { isString } from '../utils/isomorphic/rtti';
import { monotonicTime } from '../utils/isomorphic/time';
import type { Frame } from './frame';
import type { FilePayload, FrameExpectParams, Rect, SelectOption, SelectOptionOptions, TimeoutOptions } from './types';

View file

@ -24,11 +24,11 @@ import { Frame } from './frame';
import { Waiter } from './waiter';
import { Worker } from './worker';
import { assert } from '../utils/debug';
import { headersObjectToArray } from '../utils/headers';
import { headersObjectToArray } from '../utils/isomorphic/headers';
import { urlMatches } from '../utils/isomorphic/urlMatch';
import { LongStandingScope, ManualPromise } from '../utils/manualPromise';
import { MultiMap } from '../utils/multimap';
import { isRegExp, isString } from '../utils/rtti';
import { LongStandingScope, ManualPromise } from '../utils/isomorphic/manualPromise';
import { MultiMap } from '../utils/isomorphic/multimap';
import { isRegExp, isString } from '../utils/isomorphic/rtti';
import { rewriteErrorMessage } from '../utils/stackTrace';
import { zones } from '../utils/zones';
import { mime } from '../utilsBundle';

View file

@ -36,11 +36,11 @@ import { Worker } from './worker';
import { TimeoutSettings } from '../common/timeoutSettings';
import { assert } from '../utils/debug';
import { mkdirIfNeeded } from '../utils/fileUtils';
import { headersObjectToArray } from '../utils/headers';
import { headersObjectToArray } from '../utils/isomorphic/headers';
import { trimStringWithEllipsis } from '../utils/isomorphic/stringUtils';
import { urlMatches, urlMatchesEqual } from '../utils/isomorphic/urlMatch';
import { LongStandingScope } from '../utils/manualPromise';
import { isObject, isRegExp, isString } from '../utils/rtti';
import { LongStandingScope } from '../utils/isomorphic/manualPromise';
import { isObject, isRegExp, isString } from '../utils/isomorphic/rtti';
import type { BrowserContext } from './browserContext';
import type { Clock } from './clock';

View file

@ -14,7 +14,7 @@
* limitations under the License.
*/
import { ManualPromise } from '../utils/manualPromise';
import { ManualPromise } from '../utils/isomorphic/manualPromise';
import type { Artifact } from './artifact';
import type { Connection } from './connection';

View file

@ -18,7 +18,7 @@ import { ChannelOwner } from './channelOwner';
import { TargetClosedError } from './errors';
import { Events } from './events';
import { JSHandle, assertMaxArguments, parseResult, serializeArgument } from './jsHandle';
import { LongStandingScope } from '../utils/manualPromise';
import { LongStandingScope } from '../utils/isomorphic/manualPromise';
import type { BrowserContext } from './browserContext';
import type { Page } from './page';

View file

@ -18,8 +18,8 @@ import * as childProcess from 'child_process';
import * as path from 'path';
import { Connection } from './client/connection';
import { PipeTransport } from './protocol/transport';
import { ManualPromise } from './utils/manualPromise';
import { PipeTransport } from './utils/pipeTransport';
import { ManualPromise } from './utils/isomorphic/manualPromise';
import { nodePlatform } from './utils/platform';
import type { Playwright } from './client/playwright';

View file

@ -6,4 +6,5 @@
../server/dispatchers/
../server/utils/
../utils/
../utils/isomorphic
../utilsBundle.ts

View file

@ -17,7 +17,7 @@
import { PlaywrightConnection } from './playwrightConnection';
import { createPlaywright } from '../server/playwright';
import { debugLogger } from '../utils/debugLogger';
import { Semaphore } from '../utils/semaphore';
import { Semaphore } from '../utils/isomorphic/semaphore';
import { WSServer } from '../server/utils/wsServer';
import { wrapInASCIIBox } from '../server/utils/ascii';
import { getPlaywrightVersion } from '../utils/userAgent';

View file

@ -20,7 +20,7 @@ import * as os from 'os';
import * as path from 'path';
import { TimeoutSettings } from '../../common/timeoutSettings';
import { PipeTransport } from '../../protocol/transport';
import { PipeTransport } from '../../utils/pipeTransport';
import { createGuid, getPackageManagerExecCommand, isUnderTest, makeWaitForNextTask } from '../../utils';
import { RecentLogsCollector } from '../../utils/debugLogger';
import { debug } from '../../utilsBundle';

View file

@ -19,7 +19,7 @@ import * as fs from 'fs';
import { assert } from '../utils';
import { TargetClosedError } from './errors';
import { SdkObject } from './instrumentation';
import { ManualPromise } from '../utils/manualPromise';
import { ManualPromise } from '../utils/isomorphic/manualPromise';
type SaveCallback = (localPath: string, error?: Error) => Promise<void>;
type CancelCallback = () => Promise<void>;

View file

@ -26,7 +26,7 @@ import { TimeoutSettings } from '../../common/timeoutSettings';
import { debugMode, headersArrayToObject, headersObjectToArray, } from '../../utils';
import { wrapInASCIIBox } from '../utils/ascii';
import { RecentLogsCollector } from '../../utils/debugLogger';
import { ManualPromise } from '../../utils/manualPromise';
import { ManualPromise } from '../../utils/isomorphic/manualPromise';
import { fetchData } from '../utils/network';
import { getUserAgent } from '../../utils/userAgent';
import { validateBrowserContextOptions } from '../browserContext';

View file

@ -32,7 +32,7 @@ import { isSessionClosedError } from './protocolError';
import { debugLogger } from '../utils/debugLogger';
import { eventsHelper } from '../utils/eventsHelper';
import { isInvalidSelectorError } from '../utils/isomorphic/selectorParser';
import { ManualPromise } from '../utils/manualPromise';
import { ManualPromise } from '../utils/isomorphic/manualPromise';
import type { ConsoleMessage } from './console';
import type { Dialog } from './dialog';

View file

@ -20,7 +20,7 @@ import * as path from 'path';
import { Artifact } from '../artifact';
import { HarTracer } from './harTracer';
import { createGuid } from '../../utils';
import { ManualPromise } from '../../utils/manualPromise';
import { ManualPromise } from '../../utils/isomorphic/manualPromise';
import { yazl } from '../../zipBundle';
import type { BrowserContext } from '../browserContext';

View file

@ -17,7 +17,7 @@
import { assert, calculateSha1, monotonicTime } from '../../utils';
import { getPlaywrightVersion, isTextualMimeType, urlMatches } from '../../utils';
import { eventsHelper } from '../../utils/eventsHelper';
import { ManualPromise } from '../../utils/manualPromise';
import { ManualPromise } from '../../utils/isomorphic/manualPromise';
import { mime } from '../../utilsBundle';
import { BrowserContext } from '../browserContext';
import { APIRequestContext } from '../fetch';

View file

@ -18,7 +18,7 @@ import { SdkObject } from './instrumentation';
import * as utilityScriptSource from '../generated/utilityScriptSource';
import { isUnderTest } from '../utils';
import { serializeAsCallArgument } from './isomorphic/utilityScriptSerializers';
import { LongStandingScope } from '../utils/manualPromise';
import { LongStandingScope } from '../utils/isomorphic/manualPromise';
import type * as dom from './dom';
import type { UtilityScript } from './injected/utilityScript';

View file

@ -18,7 +18,7 @@ import { assert } from '../utils';
import { BrowserContext } from './browserContext';
import { APIRequestContext } from './fetch';
import { SdkObject } from './instrumentation';
import { ManualPromise } from '../utils/manualPromise';
import { ManualPromise } from '../utils/isomorphic/manualPromise';
import type * as contexts from './browserContext';
import type * as frames from './frames';

View file

@ -34,7 +34,7 @@ import { asLocator } from '../utils';
import { getComparator } from './utils/comparators';
import { debugLogger } from '../utils/debugLogger';
import { isInvalidSelectorError } from '../utils/isomorphic/selectorParser';
import { ManualPromise } from '../utils/manualPromise';
import { ManualPromise } from '../utils/isomorphic/manualPromise';
import type { Artifact } from './artifact';
import type * as dom from './dom';

View file

@ -16,7 +16,7 @@
import { TimeoutError } from './errors';
import { assert, monotonicTime } from '../utils';
import { ManualPromise } from '../utils/manualPromise';
import { ManualPromise } from '../utils/isomorphic/manualPromise';
import type { CallMetadata, Instrumentation, SdkObject } from './instrumentation';
import type { Progress as CommonProgress } from '../common/progress';

View file

@ -19,7 +19,7 @@ import { EventEmitter } from 'events';
import { RecorderCollection } from './recorderCollection';
import * as recorderSource from '../../generated/pollingRecorderSource';
import { eventsHelper, monotonicTime, quoteCSSAttributeValue } from '../../utils';
import { raceAgainstDeadline } from '../../utils/timeoutRunner';
import { raceAgainstDeadline } from '../../utils/isomorphic/timeoutRunner';
import { BrowserContext } from '../browserContext';
import { languageSet } from '../codegen/languages';
import { Frame } from '../frames';

View file

@ -19,7 +19,7 @@ import { EventEmitter } from 'events';
import { performAction } from './recorderRunner';
import { collapseActions } from './recorderUtils';
import { isUnderTest } from '../../utils/debug';
import { monotonicTime } from '../../utils/time';
import { monotonicTime } from '../../utils/isomorphic/time';
import type { Signal } from '../../../../recorder/src/actions';
import type { Frame } from '../frames';

View file

@ -21,7 +21,7 @@ import * as os from 'os';
import * as path from 'path';
import { debugLogger } from '../../utils/debugLogger';
import { ManualPromise } from '../../utils/manualPromise';
import { ManualPromise } from '../../utils/isomorphic/manualPromise';
import { getUserAgent } from '../../utils/userAgent';
import { colors, progress as ProgressBar } from '../../utilsBundle';
import { existsAsync } from '../utils/fileUtils';

View file

@ -17,7 +17,7 @@
import * as fs from 'fs';
import * as path from 'path';
import { ManualPromise } from '../../utils/manualPromise';
import { ManualPromise } from '../../utils/isomorphic/manualPromise';
import { httpRequest } from '../utils/network';
import { extract } from '../../zipBundle';

View file

@ -17,7 +17,7 @@
import { helper } from './helper';
import { assert } from '../utils';
import { MultiMap } from '../utils/multimap';
import { MultiMap } from '../utils/isomorphic/multimap';
import type * as dom from './dom';
import type { Frame } from './frames';

View file

@ -1,9 +1,9 @@
[*]
../../utils
../../utils/isomorphic
../../utilsBundle.ts
../../zipBundle.ts
[comparators.ts]
./image_tools
../../third_party/pixelmatch

View file

@ -17,7 +17,7 @@
import * as fs from 'fs';
import * as path from 'path';
import { ManualPromise } from '../../utils/manualPromise';
import { ManualPromise } from '../../utils/isomorphic/manualPromise';
import { yazl } from '../../zipBundle';
import type { EventEmitter } from 'events';

View file

@ -21,8 +21,8 @@ import * as net from 'net';
import * as tls from 'tls';
import { assert } from '../../utils/debug';
import { ManualPromise } from '../../utils/manualPromise';
import { monotonicTime } from '../../utils/time';
import { ManualPromise } from '../../utils/isomorphic/manualPromise';
import { monotonicTime } from '../../utils/isomorphic/time';
// Implementation(partial) of Happy Eyeballs 2 algorithm described in
// https://www.rfc-editor.org/rfc/rfc8305

View file

@ -20,7 +20,7 @@ import * as path from 'path';
import { mime, wsServer } from '../../utilsBundle';
import { createGuid } from '../../utils/crypto';
import { assert } from '../../utils/debug';
import { ManualPromise } from '../../utils/manualPromise';
import { ManualPromise } from '../../utils/isomorphic/manualPromise';
import { createHttpServer } from './network';
import type http from 'http';

View file

@ -14,27 +14,28 @@
* limitations under the License.
*/
export * from './utils/isomorphic/manualPromise';
export * from './utils/isomorphic/locatorGenerators';
export * from './utils/isomorphic/mimeType';
export * from './utils/isomorphic/stringUtils';
export * from './utils/isomorphic/urlMatch';
export * from './utils/isomorphic/multimap';
export * from './utils/isomorphic/rtti';
export * from './utils/isomorphic/time';
export * from './utils/isomorphic/timeoutRunner';
export * from './utils/crypto';
export * from './utils/debug';
export * from './utils/debugLogger';
export * from './utils/env';
export * from './utils/eventsHelper';
export * from './utils/expectUtils';
export * from './utils/headers';
export * from './utils/isomorphic/headers';
export * from './utils/hostPlatform';
export * from './utils/manualPromise';
export * from './utils/isomorphic/locatorGenerators';
export * from './utils/isomorphic/mimeType';
export * from './utils/isomorphic/stringUtils';
export * from './utils/isomorphic/urlMatch';
export * from './utils/multimap';
export * from './utils/rtti';
export * from './utils/semaphore';
export * from './utils/platform';
export * from './utils/isomorphic/semaphore';
export * from './utils/stackTrace';
export * from './utils/task';
export * from './utils/time';
export * from './utils/timeoutRunner';
export * from './utils/traceUtils';
export * from './utils/userAgent';
export * from './utils/zipFile';
export * from './utils/zones';

View file

@ -1,4 +1,6 @@
[*]
./
./isomorphic
../utilsBundle.ts
../zipBundle.ts
../utils/isomorphic

View file

@ -14,7 +14,7 @@
* limitations under the License.
*/
import { isRegExp, isString } from './rtti';
import { isRegExp, isString } from './isomorphic/rtti';
import type { ExpectedTextValue } from '@protocol/channels';

View file

@ -14,8 +14,6 @@
* limitations under the License.
*/
import { captureRawStack } from './stackTrace';
export class ManualPromise<T = void> extends Promise<T> {
private _resolve!: (t: T) => void;
private _reject!: (e: Error) => void;
@ -118,3 +116,12 @@ function cloneError(error: Error, frames: string[]) {
clone.stack = [error.name + ':' + error.message, ...frames].join('\n');
return clone;
}
function captureRawStack(): string[] {
const stackTraceLimit = Error.stackTraceLimit;
Error.stackTraceLimit = 50;
const error = new Error();
const stack = error.stack || '';
Error.stackTraceLimit = stackTraceLimit;
return stack.split('\n');
}

View file

@ -14,7 +14,7 @@
* limitations under the License.
*/
export { isString } from './isomorphic/stringUtils';
export { isString } from './stringUtils';
export function isRegExp(obj: any): obj is RegExp {
return obj instanceof RegExp || Object.prototype.toString.call(obj) === '[object RegExp]';

View file

@ -0,0 +1,19 @@
/**
* Copyright (c) Microsoft Corporation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
export function monotonicTime(): number {
return (performance.now() * 1000 | 0) / 1000;
}

View file

@ -14,7 +14,7 @@
* limitations under the License.
*/
import { monotonicTime } from '../utils';
import { monotonicTime } from './time';
export async function raceAgainstDeadline<T>(cb: () => Promise<T>, deadline: number): Promise<{ result: T, timedOut: false } | { timedOut: true }> {
let timer: NodeJS.Timeout | undefined;

View file

@ -14,7 +14,7 @@
* limitations under the License.
*/
import type { StackFrame } from '@protocol/channels';
import type { ClientSideCallMetadata, StackFrame } from '@protocol/channels';
export type SerializedStackFrame = [number, number, number, string];
export type SerializedStack = [number, SerializedStackFrame[]];
@ -33,3 +33,24 @@ export function parseClientSideCallMetadata(data: SerializedClientSideCallMetada
}
return result;
}
export function serializeClientSideCallMetadata(metadatas: ClientSideCallMetadata[]): SerializedClientSideCallMetadata {
const fileNames = new Map<string, number>();
const stacks: SerializedStack[] = [];
for (const m of metadatas) {
if (!m.stack || !m.stack.length)
continue;
const stack: SerializedStackFrame[] = [];
for (const frame of m.stack) {
let ordinal = fileNames.get(frame.file);
if (typeof ordinal !== 'number') {
ordinal = fileNames.size;
fileNames.set(frame.file, ordinal);
}
const stackFrame: SerializedStackFrame = [ordinal, frame.line || 0, frame.column || 0, frame.function || ''];
stack.push(stackFrame);
}
stacks.push([m.id, stack]);
}
return { files: [...fileNames.keys()], stacks };
}

View file

@ -20,11 +20,12 @@ import * as path from 'path';
import { removeFolders } from './fileUtils';
import { HarBackend } from './harBackend';
import { ManualPromise } from './manualPromise';
import { ManualPromise } from './isomorphic/manualPromise';
import { ZipFile } from './zipFile';
import { yauzl, yazl } from '../zipBundle';
import { serializeClientSideCallMetadata } from '../utils';
import { assert, calculateSha1 } from '../utils';
import { serializeClientSideCallMetadata } from '../utils/isomorphic/traceUtils';
import { assert } from '../utils/debug';
import { calculateSha1 } from '../utils/crypto';
import type { Platform } from './platform';
import type * as channels from '@protocol/channels';

View file

@ -14,18 +14,18 @@
* limitations under the License.
*/
import { makeWaitForNextTask } from '../utils';
import { makeWaitForNextTask } from './task';
export interface WritableStream {
interface WritableStream {
write(data: Buffer): void;
}
export interface ReadableStream {
interface ReadableStream {
on(event: 'data', callback: (b: Buffer) => void): void;
on(event: 'close', callback: () => void): void;
}
export interface ClosableStream {
interface ClosableStream {
close(): void;
}

View file

@ -17,15 +17,13 @@
import * as path from 'path';
import { colors } from '../utilsBundle';
import { findRepeatedSubsequences } from './sequence';
import { StackUtils } from './stackUtils';
import { findRepeatedSubsequences } from './isomorphic/sequence';
import { parseStackFrame } from './stackUtils';
import type { StackFrame } from '@protocol/channels';
const stackUtils = new StackUtils();
export function parseStackTraceLine(line: string): StackFrame | null {
const frame = stackUtils.parseLine(line);
const frame = parseStackFrame(line);
if (!frame)
return null;
if (!process.env.PWDEBUGIMPL && (frame.file?.startsWith('internal') || frame.file?.startsWith('node:')))

View file

@ -35,84 +35,82 @@ type StackData = {
evalFile?: string | undefined;
};
export class StackUtils {
parseLine(line: string) {
const match = line && line.match(re);
if (!match)
return null;
export function parseStackFrame(line: string): StackData | null {
const match = line && line.match(re);
if (!match)
return null;
const ctor = match[1] === 'new';
let fname = match[2];
const evalOrigin = match[3];
const evalFile = match[4];
const evalLine = Number(match[5]);
const evalCol = Number(match[6]);
let file = match[7];
const lnum = match[8];
const col = match[9];
const native = match[10] === 'native';
const closeParen = match[11] === ')';
let method;
const ctor = match[1] === 'new';
let fname = match[2];
const evalOrigin = match[3];
const evalFile = match[4];
const evalLine = Number(match[5]);
const evalCol = Number(match[6]);
let file = match[7];
const lnum = match[8];
const col = match[9];
const native = match[10] === 'native';
const closeParen = match[11] === ')';
let method;
const res: StackData = {};
const res: StackData = {};
if (lnum)
res.line = Number(lnum);
if (lnum)
res.line = Number(lnum);
if (col)
res.column = Number(col);
if (col)
res.column = Number(col);
if (closeParen && file) {
// make sure parens are balanced
// if we have a file like "asdf) [as foo] (xyz.js", then odds are
// that the fname should be += " (asdf) [as foo]" and the file
// should be just "xyz.js"
// walk backwards from the end to find the last unbalanced (
let closes = 0;
for (let i = file.length - 1; i > 0; i--) {
if (file.charAt(i) === ')') {
closes++;
} else if (file.charAt(i) === '(' && file.charAt(i - 1) === ' ') {
closes--;
if (closes === -1 && file.charAt(i - 1) === ' ') {
const before = file.slice(0, i - 1);
const after = file.slice(i + 1);
file = after;
fname += ` (${before}`;
break;
}
if (closeParen && file) {
// make sure parens are balanced
// if we have a file like "asdf) [as foo] (xyz.js", then odds are
// that the fname should be += " (asdf) [as foo]" and the file
// should be just "xyz.js"
// walk backwards from the end to find the last unbalanced (
let closes = 0;
for (let i = file.length - 1; i > 0; i--) {
if (file.charAt(i) === ')') {
closes++;
} else if (file.charAt(i) === '(' && file.charAt(i - 1) === ' ') {
closes--;
if (closes === -1 && file.charAt(i - 1) === ' ') {
const before = file.slice(0, i - 1);
const after = file.slice(i + 1);
file = after;
fname += ` (${before}`;
break;
}
}
}
if (fname) {
const methodMatch = fname.match(methodRe);
if (methodMatch) {
fname = methodMatch[1];
method = methodMatch[2];
}
}
setFile(res, file);
if (ctor)
res.isConstructor = true;
if (evalOrigin) {
res.evalOrigin = evalOrigin;
res.evalLine = evalLine;
res.evalColumn = evalCol;
res.evalFile = evalFile && evalFile.replace(/\\/g, '/');
}
if (native)
res.native = true;
if (fname)
res.function = fname;
if (method && fname !== method)
res.method = method;
return res;
}
if (fname) {
const methodMatch = fname.match(methodRe);
if (methodMatch) {
fname = methodMatch[1];
method = methodMatch[2];
}
}
setFile(res, file);
if (ctor)
res.isConstructor = true;
if (evalOrigin) {
res.evalOrigin = evalOrigin;
res.evalLine = evalLine;
res.evalColumn = evalCol;
res.evalFile = evalFile && evalFile.replace(/\\/g, '/');
}
if (native)
res.native = true;
if (fname)
res.function = fname;
if (method && fname !== method)
res.method = method;
return res;
}
function setFile(result: StackData, filename: string) {

View file

@ -1,32 +0,0 @@
/**
* Copyright (c) Microsoft Corporation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// The `process.hrtime()` returns a time from some arbitrary
// date in the past; on certain systems, this is the time from the system boot.
// The `monotonicTime()` converts this to milliseconds.
//
// For a Linux server with uptime of 36 days, the `monotonicTime()` value
// will be 36 * 86400 * 1000 = 3_110_400_000, which is larger than
// the maximum value that `setTimeout` accepts as an argument: 2_147_483_647.
//
// To make the `monotonicTime()` a reasonable value, we anchor
// it to the time of the first import of this utility.
const initialTime = process.hrtime();
export function monotonicTime(): number {
const [seconds, nanoseconds] = process.hrtime(initialTime);
return seconds * 1000 + (nanoseconds / 1000 | 0) / 1000;
}

View file

@ -1,39 +0,0 @@
/**
* Copyright (c) Microsoft Corporation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import type { SerializedClientSideCallMetadata, SerializedStack, SerializedStackFrame } from './isomorphic/traceUtils';
import type { ClientSideCallMetadata } from '@protocol/channels';
export function serializeClientSideCallMetadata(metadatas: ClientSideCallMetadata[]): SerializedClientSideCallMetadata {
const fileNames = new Map<string, number>();
const stacks: SerializedStack[] = [];
for (const m of metadatas) {
if (!m.stack || !m.stack.length)
continue;
const stack: SerializedStackFrame[] = [];
for (const frame of m.stack) {
let ordinal = fileNames.get(frame.file);
if (typeof ordinal !== 'number') {
ordinal = fileNames.size;
fileNames.set(frame.file, ordinal);
}
const stackFrame: SerializedStackFrame = [ordinal, frame.line || 0, frame.column || 0, frame.function || ''];
stack.push(stackFrame);
}
stacks.push([m.id, stack]);
}
return { files: [...fileNames.keys()], stacks };
}

View file

@ -19,9 +19,7 @@ import * as path from 'path';
import * as url from 'url';
import util from 'util';
import { sanitizeForFilePath } from 'playwright-core/lib/utils';
import { calculateSha1, formatCallLog, isRegExp, isString, stringifyStackFrames } from 'playwright-core/lib/utils';
import { parseStackTraceLine } from 'playwright-core/lib/utils';
import { parseStackTraceLine, sanitizeForFilePath, calculateSha1, formatCallLog, isRegExp, isString, stringifyStackFrames } from 'playwright-core/lib/utils';
import { debug, mime, minimatch } from 'playwright-core/lib/utilsBundle';
import type { Location } from './../types/testReporter';

View file

@ -15,7 +15,7 @@
* limitations under the License.
*/
import { ManualPromise } from '../../../packages/playwright-core/lib/utils/manualPromise';
import { ManualPromise } from '../../../packages/playwright-core/lib/utils/isomorphic/manualPromise';
import { EventEmitter } from '../../../packages/playwright-core/lib/client/eventEmitter';
import { test, expect } from '@playwright/test';

View file

@ -16,7 +16,7 @@
import { test as it, expect } from '@playwright/test';
import { findRepeatedSubsequences } from '../../../packages/playwright-core/lib/utils/sequence';
import { findRepeatedSubsequences } from '../../../packages/playwright-core/lib/utils/isomorphic/sequence';
it('should return an empty array when the input is empty', () => {
const input = [];

View file

@ -14,7 +14,7 @@
* limitations under the License.
*/
import { MultiMap } from '../../packages/playwright-core/lib/utils/multimap';
import { MultiMap } from '../../packages/playwright-core/lib/utils/isomorphic/multimap';
import { test, expect } from './pageTest';
function leakedJSHandles(): string {

View file

@ -15,7 +15,7 @@
* limitations under the License.
*/
import { ManualPromise } from '../../packages/playwright-core/lib/utils/manualPromise';
import { ManualPromise } from '../../packages/playwright-core/lib/utils/isomorphic/manualPromise';
import { test as it, expect } from './pageTest';
// This test is mostly for type checking, the actual tests are in the library/events.

View file

@ -14,7 +14,7 @@
* limitations under the License.
*/
import { ManualPromise } from '../../packages/playwright-core/lib/utils/manualPromise';
import { ManualPromise } from '../../packages/playwright-core/lib/utils/isomorphic/manualPromise';
import { test, expect, retries, dumpTestTree } from './ui-mode-fixtures';
test.describe.configure({ mode: 'parallel', retries });