Merge branch 'microsoft:main' into cnm_dev
This commit is contained in:
commit
798f05eedd
|
|
@ -334,6 +334,8 @@ Whether to populate `'git.commit.info'` field of the [`property: TestConfig.meta
|
||||||
|
|
||||||
This information will appear in the HTML and JSON reports and is available in the Reporter API.
|
This information will appear in the HTML and JSON reports and is available in the Reporter API.
|
||||||
|
|
||||||
|
On Github Actions, this feature is enabled by default.
|
||||||
|
|
||||||
**Usage**
|
**Usage**
|
||||||
|
|
||||||
```js title="playwright.config.ts"
|
```js title="playwright.config.ts"
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@
|
||||||
-->
|
-->
|
||||||
|
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html>
|
<html style='scrollbar-gutter: stable both-edges;'>
|
||||||
<head>
|
<head>
|
||||||
<meta charset='UTF-8'>
|
<meta charset='UTF-8'>
|
||||||
<meta name='color-scheme' content='dark light'>
|
<meta name='color-scheme' content='dark light'>
|
||||||
|
|
|
||||||
|
|
@ -14,4 +14,6 @@ utils/
|
||||||
client/
|
client/
|
||||||
protocol/
|
protocol/
|
||||||
utils/
|
utils/
|
||||||
common/
|
utils/isomorphic
|
||||||
|
server/utils
|
||||||
|
common/
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@
|
||||||
|
|
||||||
import { PlaywrightServer } from './remote/playwrightServer';
|
import { PlaywrightServer } from './remote/playwrightServer';
|
||||||
import { createPlaywright } from './server/playwright';
|
import { createPlaywright } from './server/playwright';
|
||||||
import { createGuid } from './utils';
|
import { createGuid } from './server/utils/crypto';
|
||||||
import { ws } from './utilsBundle';
|
import { ws } from './utilsBundle';
|
||||||
|
|
||||||
import type { BrowserServer } from './client/browserType';
|
import type { BrowserServer } from './client/browserType';
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,7 @@ import { PlaywrightServer } from './remote/playwrightServer';
|
||||||
import { helper } from './server/helper';
|
import { helper } from './server/helper';
|
||||||
import { serverSideCallMetadata } from './server/instrumentation';
|
import { serverSideCallMetadata } from './server/instrumentation';
|
||||||
import { createPlaywright } from './server/playwright';
|
import { createPlaywright } from './server/playwright';
|
||||||
import { createGuid } from './utils';
|
import { createGuid } from './server/utils/crypto';
|
||||||
import { rewriteErrorMessage } from './utils/stackTrace';
|
import { rewriteErrorMessage } from './utils/stackTrace';
|
||||||
import { ws } from './utilsBundle';
|
import { ws } from './utilsBundle';
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@
|
||||||
import * as fs from 'fs';
|
import * as fs from 'fs';
|
||||||
|
|
||||||
import * as playwright from '../..';
|
import * as playwright from '../..';
|
||||||
import { PipeTransport } from '../protocol/transport';
|
import { PipeTransport } from '../utils/pipeTransport';
|
||||||
import { PlaywrightServer } from '../remote/playwrightServer';
|
import { PlaywrightServer } from '../remote/playwrightServer';
|
||||||
import { DispatcherConnection, PlaywrightDispatcher, RootDispatcher, createPlaywright } from '../server';
|
import { DispatcherConnection, PlaywrightDispatcher, RootDispatcher, createPlaywright } from '../server';
|
||||||
import { gracefullyProcessExitDoNotHang } from '../server/utils/processLauncher';
|
import { gracefullyProcessExitDoNotHang } from '../server/utils/processLauncher';
|
||||||
|
|
|
||||||
|
|
@ -22,9 +22,9 @@ import { TargetClosedError, isTargetClosedError } from './errors';
|
||||||
import { Events } from './events';
|
import { Events } from './events';
|
||||||
import { Waiter } from './waiter';
|
import { Waiter } from './waiter';
|
||||||
import { TimeoutSettings } from '../common/timeoutSettings';
|
import { TimeoutSettings } from '../common/timeoutSettings';
|
||||||
import { isRegExp, isString } from '../utils/rtti';
|
import { isRegExp, isString } from '../utils/isomorphic/rtti';
|
||||||
import { monotonicTime } from '../utils/time';
|
import { monotonicTime } from '../utils/isomorphic/time';
|
||||||
import { raceAgainstDeadline } from '../utils/timeoutRunner';
|
import { raceAgainstDeadline } from '../utils/isomorphic/timeoutRunner';
|
||||||
|
|
||||||
import type { Page } from './page';
|
import type { Page } from './page';
|
||||||
import type * as types from './types';
|
import type * as types from './types';
|
||||||
|
|
|
||||||
|
|
@ -36,9 +36,9 @@ import { WebError } from './webError';
|
||||||
import { Worker } from './worker';
|
import { Worker } from './worker';
|
||||||
import { TimeoutSettings } from '../common/timeoutSettings';
|
import { TimeoutSettings } from '../common/timeoutSettings';
|
||||||
import { mkdirIfNeeded } from '../utils/fileUtils';
|
import { mkdirIfNeeded } from '../utils/fileUtils';
|
||||||
import { headersObjectToArray } from '../utils/headers';
|
import { headersObjectToArray } from '../utils/isomorphic/headers';
|
||||||
import { urlMatchesEqual } from '../utils/isomorphic/urlMatch';
|
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 { rewriteErrorMessage } from '../utils/stackTrace';
|
||||||
|
|
||||||
import type { BrowserType } from './browserType';
|
import type { BrowserType } from './browserType';
|
||||||
|
|
|
||||||
|
|
@ -22,9 +22,9 @@ import { ChannelOwner } from './channelOwner';
|
||||||
import { envObjectToArray } from './clientHelper';
|
import { envObjectToArray } from './clientHelper';
|
||||||
import { Events } from './events';
|
import { Events } from './events';
|
||||||
import { assert } from '../utils/debug';
|
import { assert } from '../utils/debug';
|
||||||
import { headersObjectToArray } from '../utils/headers';
|
import { headersObjectToArray } from '../utils/isomorphic/headers';
|
||||||
import { monotonicTime } from '../utils/time';
|
import { monotonicTime } from '../utils/isomorphic/time';
|
||||||
import { raceAgainstDeadline } from '../utils/timeoutRunner';
|
import { raceAgainstDeadline } from '../utils/isomorphic/timeoutRunner';
|
||||||
|
|
||||||
import type { Playwright } from './playwright';
|
import type { Playwright } from './playwright';
|
||||||
import type { ConnectOptions, LaunchOptions, LaunchPersistentContextOptions, LaunchServerOptions, Logger } from './types';
|
import type { ConnectOptions, LaunchOptions, LaunchPersistentContextOptions, LaunchServerOptions, Logger } from './types';
|
||||||
|
|
@ -100,7 +100,7 @@ export class BrowserType extends ChannelOwner<channels.BrowserTypeChannel> imple
|
||||||
ignoreAllDefaultArgs: !!options.ignoreDefaultArgs && !Array.isArray(options.ignoreDefaultArgs),
|
ignoreAllDefaultArgs: !!options.ignoreDefaultArgs && !Array.isArray(options.ignoreDefaultArgs),
|
||||||
env: options.env ? envObjectToArray(options.env) : undefined,
|
env: options.env ? envObjectToArray(options.env) : undefined,
|
||||||
channel: options.channel,
|
channel: options.channel,
|
||||||
userDataDir: path.isAbsolute(userDataDir) ? userDataDir : path.resolve(userDataDir),
|
userDataDir: (path.isAbsolute(userDataDir) || !userDataDir) ? userDataDir : path.resolve(userDataDir),
|
||||||
};
|
};
|
||||||
return await this._wrapApiCall(async () => {
|
return await this._wrapApiCall(async () => {
|
||||||
const result = await this._channel.launchPersistentContext(persistentParams);
|
const result = await this._channel.launchPersistentContext(persistentParams);
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { isString } from '../utils/rtti';
|
import { isString } from '../utils/isomorphic/rtti';
|
||||||
|
|
||||||
import type * as types from './types';
|
import type * as types from './types';
|
||||||
import type { Platform } from '../utils/platform';
|
import type { Platform } from '../utils/platform';
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,7 @@ import { Frame } from './frame';
|
||||||
import { JSHandle, parseResult, serializeArgument } from './jsHandle';
|
import { JSHandle, parseResult, serializeArgument } from './jsHandle';
|
||||||
import { assert } from '../utils/debug';
|
import { assert } from '../utils/debug';
|
||||||
import { fileUploadSizeLimit, mkdirIfNeeded } from '../utils/fileUtils';
|
import { fileUploadSizeLimit, mkdirIfNeeded } from '../utils/fileUtils';
|
||||||
import { isString } from '../utils/rtti';
|
import { isString } from '../utils/isomorphic/rtti';
|
||||||
import { mime } from '../utilsBundle';
|
import { mime } from '../utilsBundle';
|
||||||
import { WritableStream } from './writableStream';
|
import { WritableStream } from './writableStream';
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { parseSerializedValue, serializeValue } from '../protocol/serializers';
|
import { parseSerializedValue, serializeValue } from '../protocol/serializers';
|
||||||
import { isError } from '../utils/rtti';
|
import { isError } from '../utils/isomorphic/rtti';
|
||||||
|
|
||||||
import type { SerializedError } from '@protocol/channels';
|
import type { SerializedError } from '@protocol/channels';
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -21,8 +21,8 @@ import { RawHeaders } from './network';
|
||||||
import { Tracing } from './tracing';
|
import { Tracing } from './tracing';
|
||||||
import { assert } from '../utils/debug';
|
import { assert } from '../utils/debug';
|
||||||
import { mkdirIfNeeded } from '../utils/fileUtils';
|
import { mkdirIfNeeded } from '../utils/fileUtils';
|
||||||
import { headersObjectToArray } from '../utils/headers';
|
import { headersObjectToArray } from '../utils/isomorphic/headers';
|
||||||
import { isString } from '../utils/rtti';
|
import { isString } from '../utils/isomorphic/rtti';
|
||||||
|
|
||||||
import type { Playwright } from './playwright';
|
import type { Playwright } from './playwright';
|
||||||
import type { ClientCertificate, FilePayload, Headers, SetStorageState, StorageState } from './types';
|
import type { ClientCertificate, FilePayload, Headers, SetStorageState, StorageState } from './types';
|
||||||
|
|
|
||||||
|
|
@ -51,7 +51,7 @@ export class LocalUtils extends ChannelOwner<channels.LocalUtilsChannel> {
|
||||||
}
|
}
|
||||||
|
|
||||||
async harOpen(params: channels.LocalUtilsHarOpenParams): Promise<channels.LocalUtilsHarOpenResult> {
|
async harOpen(params: channels.LocalUtilsHarOpenParams): Promise<channels.LocalUtilsHarOpenResult> {
|
||||||
return await localUtils.harOpen(this._harBackends, params);
|
return await localUtils.harOpen(this._platform, this._harBackends, params);
|
||||||
}
|
}
|
||||||
|
|
||||||
async harLookup(params: channels.LocalUtilsHarLookupParams): Promise<channels.LocalUtilsHarLookupResult> {
|
async harLookup(params: channels.LocalUtilsHarLookupParams): Promise<channels.LocalUtilsHarLookupResult> {
|
||||||
|
|
|
||||||
|
|
@ -19,8 +19,8 @@ import { parseResult, serializeArgument } from './jsHandle';
|
||||||
import { asLocator } from '../utils/isomorphic/locatorGenerators';
|
import { asLocator } from '../utils/isomorphic/locatorGenerators';
|
||||||
import { getByAltTextSelector, getByLabelSelector, getByPlaceholderSelector, getByRoleSelector, getByTestIdSelector, getByTextSelector, getByTitleSelector } from '../utils/isomorphic/locatorUtils';
|
import { getByAltTextSelector, getByLabelSelector, getByPlaceholderSelector, getByRoleSelector, getByTestIdSelector, getByTextSelector, getByTitleSelector } from '../utils/isomorphic/locatorUtils';
|
||||||
import { escapeForTextSelector } from '../utils/isomorphic/stringUtils';
|
import { escapeForTextSelector } from '../utils/isomorphic/stringUtils';
|
||||||
import { isString } from '../utils/rtti';
|
import { isString } from '../utils/isomorphic/rtti';
|
||||||
import { monotonicTime } from '../utils/time';
|
import { monotonicTime } from '../utils/isomorphic/time';
|
||||||
|
|
||||||
import type { Frame } from './frame';
|
import type { Frame } from './frame';
|
||||||
import type { FilePayload, FrameExpectParams, Rect, SelectOption, SelectOptionOptions, TimeoutOptions } from './types';
|
import type { FilePayload, FrameExpectParams, Rect, SelectOption, SelectOptionOptions, TimeoutOptions } from './types';
|
||||||
|
|
|
||||||
|
|
@ -24,11 +24,11 @@ import { Frame } from './frame';
|
||||||
import { Waiter } from './waiter';
|
import { Waiter } from './waiter';
|
||||||
import { Worker } from './worker';
|
import { Worker } from './worker';
|
||||||
import { assert } from '../utils/debug';
|
import { assert } from '../utils/debug';
|
||||||
import { headersObjectToArray } from '../utils/headers';
|
import { headersObjectToArray } from '../utils/isomorphic/headers';
|
||||||
import { urlMatches } from '../utils/isomorphic/urlMatch';
|
import { urlMatches } from '../utils/isomorphic/urlMatch';
|
||||||
import { LongStandingScope, ManualPromise } from '../utils/manualPromise';
|
import { LongStandingScope, ManualPromise } from '../utils/isomorphic/manualPromise';
|
||||||
import { MultiMap } from '../utils/multimap';
|
import { MultiMap } from '../utils/isomorphic/multimap';
|
||||||
import { isRegExp, isString } from '../utils/rtti';
|
import { isRegExp, isString } from '../utils/isomorphic/rtti';
|
||||||
import { rewriteErrorMessage } from '../utils/stackTrace';
|
import { rewriteErrorMessage } from '../utils/stackTrace';
|
||||||
import { zones } from '../utils/zones';
|
import { zones } from '../utils/zones';
|
||||||
import { mime } from '../utilsBundle';
|
import { mime } from '../utilsBundle';
|
||||||
|
|
|
||||||
|
|
@ -36,11 +36,11 @@ import { Worker } from './worker';
|
||||||
import { TimeoutSettings } from '../common/timeoutSettings';
|
import { TimeoutSettings } from '../common/timeoutSettings';
|
||||||
import { assert } from '../utils/debug';
|
import { assert } from '../utils/debug';
|
||||||
import { mkdirIfNeeded } from '../utils/fileUtils';
|
import { mkdirIfNeeded } from '../utils/fileUtils';
|
||||||
import { headersObjectToArray } from '../utils/headers';
|
import { headersObjectToArray } from '../utils/isomorphic/headers';
|
||||||
import { trimStringWithEllipsis } from '../utils/isomorphic/stringUtils';
|
import { trimStringWithEllipsis } from '../utils/isomorphic/stringUtils';
|
||||||
import { urlMatches, urlMatchesEqual } from '../utils/isomorphic/urlMatch';
|
import { urlMatches, urlMatchesEqual } from '../utils/isomorphic/urlMatch';
|
||||||
import { LongStandingScope } from '../utils/manualPromise';
|
import { LongStandingScope } from '../utils/isomorphic/manualPromise';
|
||||||
import { isObject, isRegExp, isString } from '../utils/rtti';
|
import { isObject, isRegExp, isString } from '../utils/isomorphic/rtti';
|
||||||
|
|
||||||
import type { BrowserContext } from './browserContext';
|
import type { BrowserContext } from './browserContext';
|
||||||
import type { Clock } from './clock';
|
import type { Clock } from './clock';
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { ManualPromise } from '../utils/manualPromise';
|
import { ManualPromise } from '../utils/isomorphic/manualPromise';
|
||||||
|
|
||||||
import type { Artifact } from './artifact';
|
import type { Artifact } from './artifact';
|
||||||
import type { Connection } from './connection';
|
import type { Connection } from './connection';
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,6 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { TimeoutError } from './errors';
|
import { TimeoutError } from './errors';
|
||||||
import { createGuid } from '../utils/crypto';
|
|
||||||
import { rewriteErrorMessage } from '../utils/stackTrace';
|
import { rewriteErrorMessage } from '../utils/stackTrace';
|
||||||
import { zones } from '../utils/zones';
|
import { zones } from '../utils/zones';
|
||||||
|
|
||||||
|
|
@ -35,7 +34,7 @@ export class Waiter {
|
||||||
private _savedZone: Zone;
|
private _savedZone: Zone;
|
||||||
|
|
||||||
constructor(channelOwner: ChannelOwner<channels.EventTargetChannel>, event: string) {
|
constructor(channelOwner: ChannelOwner<channels.EventTargetChannel>, event: string) {
|
||||||
this._waitId = createGuid();
|
this._waitId = channelOwner._platform.createGuid();
|
||||||
this._channelOwner = channelOwner;
|
this._channelOwner = channelOwner;
|
||||||
this._savedZone = zones.current().without('apiZone');
|
this._savedZone = zones.current().without('apiZone');
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@ import { ChannelOwner } from './channelOwner';
|
||||||
import { TargetClosedError } from './errors';
|
import { TargetClosedError } from './errors';
|
||||||
import { Events } from './events';
|
import { Events } from './events';
|
||||||
import { JSHandle, assertMaxArguments, parseResult, serializeArgument } from './jsHandle';
|
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 { BrowserContext } from './browserContext';
|
||||||
import type { Page } from './page';
|
import type { Page } from './page';
|
||||||
|
|
|
||||||
|
|
@ -18,8 +18,8 @@ import * as childProcess from 'child_process';
|
||||||
import * as path from 'path';
|
import * as path from 'path';
|
||||||
|
|
||||||
import { Connection } from './client/connection';
|
import { Connection } from './client/connection';
|
||||||
import { PipeTransport } from './protocol/transport';
|
import { PipeTransport } from './utils/pipeTransport';
|
||||||
import { ManualPromise } from './utils/manualPromise';
|
import { ManualPromise } from './utils/isomorphic/manualPromise';
|
||||||
import { nodePlatform } from './utils/platform';
|
import { nodePlatform } from './utils/platform';
|
||||||
|
|
||||||
import type { Playwright } from './client/playwright';
|
import type { Playwright } from './client/playwright';
|
||||||
|
|
|
||||||
|
|
@ -6,4 +6,5 @@
|
||||||
../server/dispatchers/
|
../server/dispatchers/
|
||||||
../server/utils/
|
../server/utils/
|
||||||
../utils/
|
../utils/
|
||||||
|
../utils/isomorphic
|
||||||
../utilsBundle.ts
|
../utilsBundle.ts
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@
|
||||||
import { PlaywrightConnection } from './playwrightConnection';
|
import { PlaywrightConnection } from './playwrightConnection';
|
||||||
import { createPlaywright } from '../server/playwright';
|
import { createPlaywright } from '../server/playwright';
|
||||||
import { debugLogger } from '../utils/debugLogger';
|
import { debugLogger } from '../utils/debugLogger';
|
||||||
import { Semaphore } from '../utils/semaphore';
|
import { Semaphore } from '../utils/isomorphic/semaphore';
|
||||||
import { WSServer } from '../server/utils/wsServer';
|
import { WSServer } from '../server/utils/wsServer';
|
||||||
import { wrapInASCIIBox } from '../server/utils/ascii';
|
import { wrapInASCIIBox } from '../server/utils/ascii';
|
||||||
import { getPlaywrightVersion } from '../utils/userAgent';
|
import { getPlaywrightVersion } from '../utils/userAgent';
|
||||||
|
|
|
||||||
|
|
@ -20,8 +20,11 @@ import * as os from 'os';
|
||||||
import * as path from 'path';
|
import * as path from 'path';
|
||||||
|
|
||||||
import { TimeoutSettings } from '../../common/timeoutSettings';
|
import { TimeoutSettings } from '../../common/timeoutSettings';
|
||||||
import { PipeTransport } from '../../protocol/transport';
|
import { PipeTransport } from '../../utils/pipeTransport';
|
||||||
import { createGuid, getPackageManagerExecCommand, isUnderTest, makeWaitForNextTask } from '../../utils';
|
import { createGuid } from '../utils/crypto';
|
||||||
|
import { isUnderTest } from '../../utils/debug';
|
||||||
|
import { getPackageManagerExecCommand } from '../../utils/env';
|
||||||
|
import { makeWaitForNextTask } from '../../utils/task';
|
||||||
import { RecentLogsCollector } from '../../utils/debugLogger';
|
import { RecentLogsCollector } from '../../utils/debugLogger';
|
||||||
import { debug } from '../../utilsBundle';
|
import { debug } from '../../utilsBundle';
|
||||||
import { wsReceiver, wsSender } from '../../utilsBundle';
|
import { wsReceiver, wsSender } from '../../utilsBundle';
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,8 @@
|
||||||
import { EventEmitter } from 'events';
|
import { EventEmitter } from 'events';
|
||||||
import * as net from 'net';
|
import * as net from 'net';
|
||||||
|
|
||||||
import { assert, createGuid } from '../../utils';
|
import { assert } from '../../utils/debug';
|
||||||
|
import { createGuid } from '../utils/crypto';
|
||||||
import { debug } from '../../utilsBundle';
|
import { debug } from '../../utilsBundle';
|
||||||
|
|
||||||
import type { Backend, DeviceBackend, SocketBackend } from './android';
|
import type { Backend, DeviceBackend, SocketBackend } from './android';
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@ import * as fs from 'fs';
|
||||||
import { assert } from '../utils';
|
import { assert } from '../utils';
|
||||||
import { TargetClosedError } from './errors';
|
import { TargetClosedError } from './errors';
|
||||||
import { SdkObject } from './instrumentation';
|
import { SdkObject } from './instrumentation';
|
||||||
import { ManualPromise } from '../utils/manualPromise';
|
import { ManualPromise } from '../utils/isomorphic/manualPromise';
|
||||||
|
|
||||||
type SaveCallback = (localPath: string, error?: Error) => Promise<void>;
|
type SaveCallback = (localPath: string, error?: Error) => Promise<void>;
|
||||||
type CancelCallback = () => Promise<void>;
|
type CancelCallback = () => Promise<void>;
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { eventsHelper } from '../../utils/eventsHelper';
|
import { eventsHelper } from '../utils/eventsHelper';
|
||||||
import { Browser } from '../browser';
|
import { Browser } from '../browser';
|
||||||
import { BrowserContext, assertBrowserContextIsNotOwned } from '../browserContext';
|
import { BrowserContext, assertBrowserContextIsNotOwned } from '../browserContext';
|
||||||
import * as network from '../network';
|
import * as network from '../network';
|
||||||
|
|
@ -23,7 +23,7 @@ import { bidiBytesValueToString } from './bidiNetworkManager';
|
||||||
import { BidiPage } from './bidiPage';
|
import { BidiPage } from './bidiPage';
|
||||||
import * as bidi from './third_party/bidiProtocol';
|
import * as bidi from './third_party/bidiProtocol';
|
||||||
|
|
||||||
import type { RegisteredListener } from '../../utils/eventsHelper';
|
import type { RegisteredListener } from '../utils/eventsHelper';
|
||||||
import type { BrowserOptions } from '../browser';
|
import type { BrowserOptions } from '../browser';
|
||||||
import type { SdkObject } from '../instrumentation';
|
import type { SdkObject } from '../instrumentation';
|
||||||
import type { InitScript, Page } from '../page';
|
import type { InitScript, Page } from '../page';
|
||||||
|
|
|
||||||
|
|
@ -79,6 +79,9 @@ export class RawMouseImpl implements input.RawMouse {
|
||||||
}
|
}
|
||||||
|
|
||||||
async move(x: number, y: number, button: types.MouseButton | 'none', buttons: Set<types.MouseButton>, modifiers: Set<types.KeyboardModifier>, forClick: boolean): Promise<void> {
|
async move(x: number, y: number, button: types.MouseButton | 'none', buttons: Set<types.MouseButton>, modifiers: Set<types.KeyboardModifier>, forClick: boolean): Promise<void> {
|
||||||
|
// Bidi throws when x/y are not integers.
|
||||||
|
x = Math.floor(x);
|
||||||
|
y = Math.floor(y);
|
||||||
await this._performActions([{ type: 'pointerMove', x, y }]);
|
await this._performActions([{ type: 'pointerMove', x, y }]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -91,6 +94,9 @@ export class RawMouseImpl implements input.RawMouse {
|
||||||
}
|
}
|
||||||
|
|
||||||
async wheel(x: number, y: number, buttons: Set<types.MouseButton>, modifiers: Set<types.KeyboardModifier>, deltaX: number, deltaY: number): Promise<void> {
|
async wheel(x: number, y: number, buttons: Set<types.MouseButton>, modifiers: Set<types.KeyboardModifier>, deltaX: number, deltaY: number): Promise<void> {
|
||||||
|
// Bidi throws when x/y are not integers.
|
||||||
|
x = Math.floor(x);
|
||||||
|
y = Math.floor(y);
|
||||||
await this._session.send('input.performActions', {
|
await this._session.send('input.performActions', {
|
||||||
context: this._session.sessionId,
|
context: this._session.sessionId,
|
||||||
actions: [
|
actions: [
|
||||||
|
|
|
||||||
|
|
@ -14,12 +14,12 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { eventsHelper } from '../../utils/eventsHelper';
|
import { eventsHelper } from '../utils/eventsHelper';
|
||||||
import { parseRawCookie } from '../cookieStore';
|
import { parseRawCookie } from '../cookieStore';
|
||||||
import * as network from '../network';
|
import * as network from '../network';
|
||||||
import * as bidi from './third_party/bidiProtocol';
|
import * as bidi from './third_party/bidiProtocol';
|
||||||
|
|
||||||
import type { RegisteredListener } from '../../utils/eventsHelper';
|
import type { RegisteredListener } from '../utils/eventsHelper';
|
||||||
import type * as frames from '../frames';
|
import type * as frames from '../frames';
|
||||||
import type { Page } from '../page';
|
import type { Page } from '../page';
|
||||||
import type * as types from '../types';
|
import type * as types from '../types';
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { assert } from '../../utils';
|
import { assert } from '../../utils';
|
||||||
import { eventsHelper } from '../../utils/eventsHelper';
|
import { eventsHelper } from '../utils/eventsHelper';
|
||||||
import { BrowserContext } from '../browserContext';
|
import { BrowserContext } from '../browserContext';
|
||||||
import * as dialog from '../dialog';
|
import * as dialog from '../dialog';
|
||||||
import * as dom from '../dom';
|
import * as dom from '../dom';
|
||||||
|
|
@ -26,7 +26,7 @@ import { BidiNetworkManager } from './bidiNetworkManager';
|
||||||
import { BidiPDF } from './bidiPdf';
|
import { BidiPDF } from './bidiPdf';
|
||||||
import * as bidi from './third_party/bidiProtocol';
|
import * as bidi from './third_party/bidiProtocol';
|
||||||
|
|
||||||
import type { RegisteredListener } from '../../utils/eventsHelper';
|
import type { RegisteredListener } from '../utils/eventsHelper';
|
||||||
import type * as accessibility from '../accessibility';
|
import type * as accessibility from '../accessibility';
|
||||||
import type * as frames from '../frames';
|
import type * as frames from '../frames';
|
||||||
import type { InitScript, PageDelegate } from '../page';
|
import type { InitScript, PageDelegate } from '../page';
|
||||||
|
|
@ -423,7 +423,22 @@ export class BidiPage implements PageDelegate {
|
||||||
}
|
}
|
||||||
|
|
||||||
async getOwnerFrame(handle: dom.ElementHandle): Promise<string | null> {
|
async getOwnerFrame(handle: dom.ElementHandle): Promise<string | null> {
|
||||||
throw new Error('Method not implemented.');
|
// TODO: switch to utility world?
|
||||||
|
const windowHandle = await handle.evaluateHandle(node => {
|
||||||
|
const doc = node.ownerDocument ?? node as Document;
|
||||||
|
return doc.defaultView;
|
||||||
|
});
|
||||||
|
if (!windowHandle)
|
||||||
|
return null;
|
||||||
|
if (!windowHandle._objectId)
|
||||||
|
return null;
|
||||||
|
const executionContext = toBidiExecutionContext(windowHandle._context as dom.FrameExecutionContext);
|
||||||
|
const contentWindow = await executionContext.rawCallFunction('e => e', { handle: windowHandle._objectId });
|
||||||
|
if (contentWindow.type === 'window') {
|
||||||
|
const frameId = contentWindow.value.context;
|
||||||
|
return frameId;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
isElementHandle(remoteObject: bidi.Script.RemoteValue): boolean {
|
isElementHandle(remoteObject: bidi.Script.RemoteValue): boolean {
|
||||||
|
|
@ -515,11 +530,21 @@ export class BidiPage implements PageDelegate {
|
||||||
}
|
}
|
||||||
|
|
||||||
async setInputFiles(handle: dom.ElementHandle<HTMLInputElement>, files: types.FilePayload[]): Promise<void> {
|
async setInputFiles(handle: dom.ElementHandle<HTMLInputElement>, files: types.FilePayload[]): Promise<void> {
|
||||||
throw new Error('Method not implemented.');
|
throw new Error('Setting FilePayloads is not supported in Bidi.');
|
||||||
}
|
}
|
||||||
|
|
||||||
async setInputFilePaths(handle: dom.ElementHandle<HTMLInputElement>, paths: string[]): Promise<void> {
|
async setInputFilePaths(handle: dom.ElementHandle<HTMLInputElement>, paths: string[]): Promise<void> {
|
||||||
throw new Error('Method not implemented.');
|
const fromContext = toBidiExecutionContext(handle._context);
|
||||||
|
const shared = await fromContext.rawCallFunction('x => x', { handle: handle._objectId });
|
||||||
|
// TODO: store sharedId in the handle.
|
||||||
|
if (!('sharedId' in shared))
|
||||||
|
throw new Error('Element is not a node');
|
||||||
|
const sharedId = shared.sharedId!;
|
||||||
|
await this._session.send('input.setFiles', {
|
||||||
|
context: this._session.sessionId,
|
||||||
|
element: { sharedId },
|
||||||
|
files: paths,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async adoptElementHandle<T extends Node>(handle: dom.ElementHandle<T>, to: dom.FrameExecutionContext): Promise<dom.ElementHandle<T>> {
|
async adoptElementHandle<T extends Node>(handle: dom.ElementHandle<T>, to: dom.FrameExecutionContext): Promise<dom.ElementHandle<T>> {
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,8 @@ import * as fs from 'fs';
|
||||||
import * as path from 'path';
|
import * as path from 'path';
|
||||||
|
|
||||||
import { TimeoutSettings } from '../common/timeoutSettings';
|
import { TimeoutSettings } from '../common/timeoutSettings';
|
||||||
import { createGuid, debugMode } from '../utils';
|
import { createGuid } from './utils/crypto';
|
||||||
|
import { debugMode } from '../utils/debug';
|
||||||
import { Clock } from './clock';
|
import { Clock } from './clock';
|
||||||
import { Debugger } from './debugger';
|
import { Debugger } from './debugger';
|
||||||
import { BrowserContextAPIRequestContext } from './fetch';
|
import { BrowserContextAPIRequestContext } from './fetch';
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,7 @@ import { TimeoutSettings } from '../../common/timeoutSettings';
|
||||||
import { debugMode, headersArrayToObject, headersObjectToArray, } from '../../utils';
|
import { debugMode, headersArrayToObject, headersObjectToArray, } from '../../utils';
|
||||||
import { wrapInASCIIBox } from '../utils/ascii';
|
import { wrapInASCIIBox } from '../utils/ascii';
|
||||||
import { RecentLogsCollector } from '../../utils/debugLogger';
|
import { RecentLogsCollector } from '../../utils/debugLogger';
|
||||||
import { ManualPromise } from '../../utils/manualPromise';
|
import { ManualPromise } from '../../utils/isomorphic/manualPromise';
|
||||||
import { fetchData } from '../utils/network';
|
import { fetchData } from '../utils/network';
|
||||||
import { getUserAgent } from '../../utils/userAgent';
|
import { getUserAgent } from '../../utils/userAgent';
|
||||||
import { validateBrowserContextOptions } from '../browserContext';
|
import { validateBrowserContextOptions } from '../browserContext';
|
||||||
|
|
|
||||||
|
|
@ -37,11 +37,10 @@ export const chromiumSwitches = [
|
||||||
// PaintHolding - https://github.com/microsoft/playwright/issues/28023
|
// PaintHolding - https://github.com/microsoft/playwright/issues/28023
|
||||||
// ThirdPartyStoragePartitioning - https://github.com/microsoft/playwright/issues/32230
|
// ThirdPartyStoragePartitioning - https://github.com/microsoft/playwright/issues/32230
|
||||||
// LensOverlay - Hides the Lens feature in the URL address bar. Its not working in unofficial builds.
|
// LensOverlay - Hides the Lens feature in the URL address bar. Its not working in unofficial builds.
|
||||||
// PlzDedicatedWorker - https://github.com/microsoft/playwright/issues/31747
|
|
||||||
// DeferRendererTasksAfterInput - this makes Page.frameScheduledNavigation arrive much later after a click,
|
// DeferRendererTasksAfterInput - this makes Page.frameScheduledNavigation arrive much later after a click,
|
||||||
// making our navigation auto-wait after click not working. Can be removed once we deperecate noWaitAfter.
|
// making our navigation auto-wait after click not working. Can be removed once we deperecate noWaitAfter.
|
||||||
// See https://github.com/microsoft/playwright/pull/34372.
|
// See https://github.com/microsoft/playwright/pull/34372.
|
||||||
'--disable-features=ImprovedCookieControls,LazyFrameLoading,GlobalMediaControls,DestroyProfileOnBrowserClose,MediaRouter,DialMediaRouteProvider,AcceptCHFrame,AutoExpandDetailsElement,CertificateTransparencyComponentUpdater,AvoidUnnecessaryBeforeUnloadCheckSync,Translate,HttpsUpgrades,PaintHolding,ThirdPartyStoragePartitioning,LensOverlay,PlzDedicatedWorker,DeferRendererTasksAfterInput',
|
'--disable-features=ImprovedCookieControls,LazyFrameLoading,GlobalMediaControls,DestroyProfileOnBrowserClose,MediaRouter,DialMediaRouteProvider,AcceptCHFrame,AutoExpandDetailsElement,CertificateTransparencyComponentUpdater,AvoidUnnecessaryBeforeUnloadCheckSync,Translate,HttpsUpgrades,PaintHolding,ThirdPartyStoragePartitioning,LensOverlay,DeferRendererTasksAfterInput',
|
||||||
'--allow-pre-commit-input',
|
'--allow-pre-commit-input',
|
||||||
'--disable-hang-monitor',
|
'--disable-hang-monitor',
|
||||||
'--disable-ipc-flooding-protection',
|
'--disable-ipc-flooding-protection',
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,8 @@
|
||||||
|
|
||||||
import * as path from 'path';
|
import * as path from 'path';
|
||||||
|
|
||||||
import { assert, createGuid } from '../../utils';
|
import { assert } from '../../utils/debug';
|
||||||
|
import { createGuid } from '../utils/crypto';
|
||||||
import { Artifact } from '../artifact';
|
import { Artifact } from '../artifact';
|
||||||
import { Browser } from '../browser';
|
import { Browser } from '../browser';
|
||||||
import { BrowserContext, assertBrowserContextIsNotOwned, verifyGeolocation } from '../browserContext';
|
import { BrowserContext, assertBrowserContextIsNotOwned, verifyGeolocation } from '../browserContext';
|
||||||
|
|
|
||||||
|
|
@ -16,11 +16,11 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { assert } from '../../utils';
|
import { assert } from '../../utils';
|
||||||
import { eventsHelper } from '../../utils/eventsHelper';
|
import { eventsHelper } from '../utils/eventsHelper';
|
||||||
|
|
||||||
import type { CRSession } from './crConnection';
|
import type { CRSession } from './crConnection';
|
||||||
import type { Protocol } from './protocol';
|
import type { Protocol } from './protocol';
|
||||||
import type { RegisteredListener } from '../../utils/eventsHelper';
|
import type { RegisteredListener } from '../utils/eventsHelper';
|
||||||
import type * as channels from '@protocol/channels';
|
import type * as channels from '@protocol/channels';
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -16,14 +16,14 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { assert, headersArrayToObject, headersObjectToArray } from '../../utils';
|
import { assert, headersArrayToObject, headersObjectToArray } from '../../utils';
|
||||||
import { eventsHelper } from '../../utils/eventsHelper';
|
import { eventsHelper } from '../utils/eventsHelper';
|
||||||
import { helper } from '../helper';
|
import { helper } from '../helper';
|
||||||
import * as network from '../network';
|
import * as network from '../network';
|
||||||
import { isProtocolError, isSessionClosedError } from '../protocolError';
|
import { isProtocolError, isSessionClosedError } from '../protocolError';
|
||||||
|
|
||||||
import type { CRSession } from './crConnection';
|
import type { CRSession } from './crConnection';
|
||||||
import type { Protocol } from './protocol';
|
import type { Protocol } from './protocol';
|
||||||
import type { RegisteredListener } from '../../utils/eventsHelper';
|
import type { RegisteredListener } from '../utils/eventsHelper';
|
||||||
import type * as contexts from '../browserContext';
|
import type * as contexts from '../browserContext';
|
||||||
import type * as frames from '../frames';
|
import type * as frames from '../frames';
|
||||||
import type { Page } from '../page';
|
import type { Page } from '../page';
|
||||||
|
|
|
||||||
|
|
@ -17,8 +17,9 @@
|
||||||
|
|
||||||
import * as path from 'path';
|
import * as path from 'path';
|
||||||
|
|
||||||
import { assert, createGuid } from '../../utils';
|
import { assert } from '../../utils/debug';
|
||||||
import { eventsHelper } from '../../utils/eventsHelper';
|
import { createGuid } from '../utils/crypto';
|
||||||
|
import { eventsHelper } from '../utils/eventsHelper';
|
||||||
import { rewriteErrorMessage } from '../../utils/stackTrace';
|
import { rewriteErrorMessage } from '../../utils/stackTrace';
|
||||||
import * as dialog from '../dialog';
|
import * as dialog from '../dialog';
|
||||||
import * as dom from '../dom';
|
import * as dom from '../dom';
|
||||||
|
|
@ -45,7 +46,7 @@ import { isSessionClosedError } from '../protocolError';
|
||||||
|
|
||||||
import type { CRSession } from './crConnection';
|
import type { CRSession } from './crConnection';
|
||||||
import type { Protocol } from './protocol';
|
import type { Protocol } from './protocol';
|
||||||
import type { RegisteredListener } from '../../utils/eventsHelper';
|
import type { RegisteredListener } from '../utils/eventsHelper';
|
||||||
import type { InitScript, PageDelegate } from '../page';
|
import type { InitScript, PageDelegate } from '../page';
|
||||||
import type { Progress } from '../progress';
|
import type { Progress } from '../progress';
|
||||||
import type * as types from '../types';
|
import type * as types from '../types';
|
||||||
|
|
|
||||||
|
|
@ -31,7 +31,8 @@ import { Recorder } from '../recorder';
|
||||||
import { TracingDispatcher } from './tracingDispatcher';
|
import { TracingDispatcher } from './tracingDispatcher';
|
||||||
import { WebSocketRouteDispatcher } from './webSocketRouteDispatcher';
|
import { WebSocketRouteDispatcher } from './webSocketRouteDispatcher';
|
||||||
import { WritableStreamDispatcher } from './writableStreamDispatcher';
|
import { WritableStreamDispatcher } from './writableStreamDispatcher';
|
||||||
import { createGuid, urlMatches } from '../../utils';
|
import { createGuid } from '../utils/crypto';
|
||||||
|
import { urlMatches } from '../../utils/isomorphic/urlMatch';
|
||||||
import { RecorderApp } from '../recorder/recorderApp';
|
import { RecorderApp } from '../recorder/recorderApp';
|
||||||
|
|
||||||
import type { Artifact } from '../artifact';
|
import type { Artifact } from '../artifact';
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@ import { DebugController } from '../debugController';
|
||||||
import { Dispatcher } from './dispatcher';
|
import { Dispatcher } from './dispatcher';
|
||||||
|
|
||||||
import type { DispatcherConnection, RootDispatcher } from './dispatcher';
|
import type { DispatcherConnection, RootDispatcher } from './dispatcher';
|
||||||
import type { RegisteredListener } from '../../utils/eventsHelper';
|
import type { RegisteredListener } from '../utils/eventsHelper';
|
||||||
import type * as channels from '@protocol/channels';
|
import type * as channels from '@protocol/channels';
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@
|
||||||
|
|
||||||
import { EventEmitter } from 'events';
|
import { EventEmitter } from 'events';
|
||||||
|
|
||||||
import { eventsHelper } from '../..//utils/eventsHelper';
|
import { eventsHelper } from '../utils/eventsHelper';
|
||||||
import { ValidationError, createMetadataValidator, findValidator } from '../../protocol/validator';
|
import { ValidationError, createMetadataValidator, findValidator } from '../../protocol/validator';
|
||||||
import { LongStandingScope, assert, compressCallLog, isUnderTest, monotonicTime, rewriteErrorMessage } from '../../utils';
|
import { LongStandingScope, assert, compressCallLog, isUnderTest, monotonicTime, rewriteErrorMessage } from '../../utils';
|
||||||
import { TargetClosedError, isTargetClosedError, serializeError } from '../errors';
|
import { TargetClosedError, isTargetClosedError, serializeError } from '../errors';
|
||||||
|
|
@ -25,7 +25,7 @@ import { isProtocolError } from '../protocolError';
|
||||||
|
|
||||||
import type { CallMetadata } from '../instrumentation';
|
import type { CallMetadata } from '../instrumentation';
|
||||||
import type { PlaywrightDispatcher } from './playwrightDispatcher';
|
import type { PlaywrightDispatcher } from './playwrightDispatcher';
|
||||||
import type { RegisteredListener } from '../..//utils/eventsHelper';
|
import type { RegisteredListener } from '../utils/eventsHelper';
|
||||||
import type { ValidatorContext } from '../../protocol/validator';
|
import type { ValidatorContext } from '../../protocol/validator';
|
||||||
import type * as channels from '@protocol/channels';
|
import type * as channels from '@protocol/channels';
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { Dispatcher } from './dispatcher';
|
import { Dispatcher } from './dispatcher';
|
||||||
import { createGuid } from '../../utils';
|
import { createGuid } from '../utils/crypto';
|
||||||
|
|
||||||
import type { LocalUtilsDispatcher } from './localUtilsDispatcher';
|
import type { LocalUtilsDispatcher } from './localUtilsDispatcher';
|
||||||
import type * as channels from '@protocol/channels';
|
import type * as channels from '@protocol/channels';
|
||||||
|
|
|
||||||
|
|
@ -54,7 +54,7 @@ export class LocalUtilsDispatcher extends Dispatcher<{ guid: string }, channels.
|
||||||
}
|
}
|
||||||
|
|
||||||
async harOpen(params: channels.LocalUtilsHarOpenParams, metadata: CallMetadata): Promise<channels.LocalUtilsHarOpenResult> {
|
async harOpen(params: channels.LocalUtilsHarOpenParams, metadata: CallMetadata): Promise<channels.LocalUtilsHarOpenResult> {
|
||||||
return await localUtils.harOpen(this._harBackends, params);
|
return await localUtils.harOpen(nodePlatform, this._harBackends, params);
|
||||||
}
|
}
|
||||||
|
|
||||||
async harLookup(params: channels.LocalUtilsHarLookupParams, metadata: CallMetadata): Promise<channels.LocalUtilsHarLookupResult> {
|
async harLookup(params: channels.LocalUtilsHarLookupParams, metadata: CallMetadata): Promise<channels.LocalUtilsHarLookupResult> {
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,8 @@ import { RequestDispatcher } from './networkDispatchers';
|
||||||
import { ResponseDispatcher } from './networkDispatchers';
|
import { ResponseDispatcher } from './networkDispatchers';
|
||||||
import { RouteDispatcher, WebSocketDispatcher } from './networkDispatchers';
|
import { RouteDispatcher, WebSocketDispatcher } from './networkDispatchers';
|
||||||
import { WebSocketRouteDispatcher } from './webSocketRouteDispatcher';
|
import { WebSocketRouteDispatcher } from './webSocketRouteDispatcher';
|
||||||
import { createGuid, urlMatches } from '../../utils';
|
import { createGuid } from '../utils/crypto';
|
||||||
|
import { urlMatches } from '../../utils/isomorphic/urlMatch';
|
||||||
|
|
||||||
import type { Artifact } from '../artifact';
|
import type { Artifact } from '../artifact';
|
||||||
import type { BrowserContext } from '../browserContext';
|
import type { BrowserContext } from '../browserContext';
|
||||||
|
|
|
||||||
|
|
@ -25,12 +25,12 @@ import { ElectronDispatcher } from './electronDispatcher';
|
||||||
import { LocalUtilsDispatcher } from './localUtilsDispatcher';
|
import { LocalUtilsDispatcher } from './localUtilsDispatcher';
|
||||||
import { APIRequestContextDispatcher } from './networkDispatchers';
|
import { APIRequestContextDispatcher } from './networkDispatchers';
|
||||||
import { SelectorsDispatcher } from './selectorsDispatcher';
|
import { SelectorsDispatcher } from './selectorsDispatcher';
|
||||||
import { createGuid } from '../../utils';
|
import { createGuid } from '../utils/crypto';
|
||||||
import { eventsHelper } from '../../utils/eventsHelper';
|
import { eventsHelper } from '../utils/eventsHelper';
|
||||||
|
|
||||||
import type { RootDispatcher } from './dispatcher';
|
import type { RootDispatcher } from './dispatcher';
|
||||||
import type { SocksSocketClosedPayload, SocksSocketDataPayload, SocksSocketRequestedPayload } from '../utils/socksProxy';
|
import type { SocksSocketClosedPayload, SocksSocketDataPayload, SocksSocketRequestedPayload } from '../utils/socksProxy';
|
||||||
import type { RegisteredListener } from '../../utils/eventsHelper';
|
import type { RegisteredListener } from '../utils/eventsHelper';
|
||||||
import type { AndroidDevice } from '../android/android';
|
import type { AndroidDevice } from '../android/android';
|
||||||
import type { Browser } from '../browser';
|
import type { Browser } from '../browser';
|
||||||
import type { Playwright } from '../playwright';
|
import type { Playwright } from '../playwright';
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,8 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { Dispatcher } from './dispatcher';
|
import { Dispatcher } from './dispatcher';
|
||||||
import { ManualPromise, createGuid } from '../../utils';
|
import { ManualPromise } from '../../utils/isomorphic/manualPromise';
|
||||||
|
import { createGuid } from '../utils/crypto';
|
||||||
|
|
||||||
import type { ArtifactDispatcher } from './artifactDispatcher';
|
import type { ArtifactDispatcher } from './artifactDispatcher';
|
||||||
import type * as channels from '@protocol/channels';
|
import type * as channels from '@protocol/channels';
|
||||||
|
|
|
||||||
|
|
@ -18,8 +18,9 @@ import { Page } from '../page';
|
||||||
import { Dispatcher, existingDispatcher } from './dispatcher';
|
import { Dispatcher, existingDispatcher } from './dispatcher';
|
||||||
import { PageDispatcher } from './pageDispatcher';
|
import { PageDispatcher } from './pageDispatcher';
|
||||||
import * as webSocketMockSource from '../../generated/webSocketMockSource';
|
import * as webSocketMockSource from '../../generated/webSocketMockSource';
|
||||||
import { createGuid, urlMatches } from '../../utils';
|
import { createGuid } from '../utils/crypto';
|
||||||
import { eventsHelper } from '../../utils/eventsHelper';
|
import { urlMatches } from '../../utils/isomorphic/urlMatch';
|
||||||
|
import { eventsHelper } from '../utils/eventsHelper';
|
||||||
|
|
||||||
import type { BrowserContextDispatcher } from './browserContextDispatcher';
|
import type { BrowserContextDispatcher } from './browserContextDispatcher';
|
||||||
import type { BrowserContext } from '../browserContext';
|
import type { BrowserContext } from '../browserContext';
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@
|
||||||
import * as fs from 'fs';
|
import * as fs from 'fs';
|
||||||
|
|
||||||
import { Dispatcher } from './dispatcher';
|
import { Dispatcher } from './dispatcher';
|
||||||
import { createGuid } from '../../utils';
|
import { createGuid } from '../utils/crypto';
|
||||||
|
|
||||||
import type { BrowserContextDispatcher } from './browserContextDispatcher';
|
import type { BrowserContextDispatcher } from './browserContextDispatcher';
|
||||||
import type * as channels from '@protocol/channels';
|
import type * as channels from '@protocol/channels';
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,7 @@ import { TimeoutSettings } from '../../common/timeoutSettings';
|
||||||
import { ManualPromise } from '../../utils';
|
import { ManualPromise } from '../../utils';
|
||||||
import { wrapInASCIIBox } from '../utils/ascii';
|
import { wrapInASCIIBox } from '../utils/ascii';
|
||||||
import { RecentLogsCollector } from '../../utils/debugLogger';
|
import { RecentLogsCollector } from '../../utils/debugLogger';
|
||||||
import { eventsHelper } from '../../utils/eventsHelper';
|
import { eventsHelper } from '../utils/eventsHelper';
|
||||||
import { validateBrowserContextOptions } from '../browserContext';
|
import { validateBrowserContextOptions } from '../browserContext';
|
||||||
import { CRBrowser } from '../chromium/crBrowser';
|
import { CRBrowser } from '../chromium/crBrowser';
|
||||||
import { CRConnection } from '../chromium/crConnection';
|
import { CRConnection } from '../chromium/crConnection';
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,8 @@ import * as url from 'url';
|
||||||
import * as zlib from 'zlib';
|
import * as zlib from 'zlib';
|
||||||
|
|
||||||
import { TimeoutSettings } from '../common/timeoutSettings';
|
import { TimeoutSettings } from '../common/timeoutSettings';
|
||||||
import { assert, constructURLBasedOnBaseURL, createGuid, eventsHelper, monotonicTime } from '../utils';
|
import { assert, constructURLBasedOnBaseURL, eventsHelper, monotonicTime } from '../utils';
|
||||||
|
import { createGuid } from './utils/crypto';
|
||||||
import { getUserAgent } from '../utils/userAgent';
|
import { getUserAgent } from '../utils/userAgent';
|
||||||
import { HttpsProxyAgent, SocksProxyAgent } from '../utilsBundle';
|
import { HttpsProxyAgent, SocksProxyAgent } from '../utilsBundle';
|
||||||
import { BrowserContext, verifyClientCertificates } from './browserContext';
|
import { BrowserContext, verifyClientCertificates } from './browserContext';
|
||||||
|
|
|
||||||
|
|
@ -15,12 +15,12 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { eventsHelper } from '../../utils/eventsHelper';
|
import { eventsHelper } from '../utils/eventsHelper';
|
||||||
import * as network from '../network';
|
import * as network from '../network';
|
||||||
|
|
||||||
import type { FFSession } from './ffConnection';
|
import type { FFSession } from './ffConnection';
|
||||||
import type { HeadersArray } from '../../server/types';
|
import type { HeadersArray } from '../../server/types';
|
||||||
import type { RegisteredListener } from '../../utils/eventsHelper';
|
import type { RegisteredListener } from '../utils/eventsHelper';
|
||||||
import type * as frames from '../frames';
|
import type * as frames from '../frames';
|
||||||
import type { Page } from '../page';
|
import type { Page } from '../page';
|
||||||
import type * as types from '../types';
|
import type * as types from '../types';
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { eventsHelper } from '../../utils/eventsHelper';
|
import { eventsHelper } from '../utils/eventsHelper';
|
||||||
import * as dialog from '../dialog';
|
import * as dialog from '../dialog';
|
||||||
import * as dom from '../dom';
|
import * as dom from '../dom';
|
||||||
import { InitScript } from '../page';
|
import { InitScript } from '../page';
|
||||||
|
|
@ -33,7 +33,7 @@ import { TargetClosedError } from '../errors';
|
||||||
import type { Progress } from '../progress';
|
import type { Progress } from '../progress';
|
||||||
import type { FFBrowserContext } from './ffBrowser';
|
import type { FFBrowserContext } from './ffBrowser';
|
||||||
import type { Protocol } from './protocol';
|
import type { Protocol } from './protocol';
|
||||||
import type { RegisteredListener } from '../../utils/eventsHelper';
|
import type { RegisteredListener } from '../utils/eventsHelper';
|
||||||
import type * as frames from '../frames';
|
import type * as frames from '../frames';
|
||||||
import type { PageDelegate } from '../page';
|
import type { PageDelegate } from '../page';
|
||||||
import type * as types from '../types';
|
import type * as types from '../types';
|
||||||
|
|
|
||||||
|
|
@ -30,9 +30,9 @@ import * as types from './types';
|
||||||
import { LongStandingScope, asLocator, assert, compressCallLog, constructURLBasedOnBaseURL, makeWaitForNextTask, monotonicTime } from '../utils';
|
import { LongStandingScope, asLocator, assert, compressCallLog, constructURLBasedOnBaseURL, makeWaitForNextTask, monotonicTime } from '../utils';
|
||||||
import { isSessionClosedError } from './protocolError';
|
import { isSessionClosedError } from './protocolError';
|
||||||
import { debugLogger } from '../utils/debugLogger';
|
import { debugLogger } from '../utils/debugLogger';
|
||||||
import { eventsHelper } from '../utils/eventsHelper';
|
import { eventsHelper } from './utils/eventsHelper';
|
||||||
import { isInvalidSelectorError } from '../utils/isomorphic/selectorParser';
|
import { isInvalidSelectorError } from '../utils/isomorphic/selectorParser';
|
||||||
import { ManualPromise } from '../utils/manualPromise';
|
import { ManualPromise } from '../utils/isomorphic/manualPromise';
|
||||||
|
|
||||||
import type { ConsoleMessage } from './console';
|
import type { ConsoleMessage } from './console';
|
||||||
import type { Dialog } from './dialog';
|
import type { Dialog } from './dialog';
|
||||||
|
|
@ -40,7 +40,7 @@ import type { ElementStateWithoutStable, FrameExpectParams, InjectedScript } fro
|
||||||
import type { CallMetadata } from './instrumentation';
|
import type { CallMetadata } from './instrumentation';
|
||||||
import type { Progress } from './progress';
|
import type { Progress } from './progress';
|
||||||
import type { ScreenshotOptions } from './screenshotter';
|
import type { ScreenshotOptions } from './screenshotter';
|
||||||
import type { RegisteredListener } from '../utils/eventsHelper';
|
import type { RegisteredListener } from './utils/eventsHelper';
|
||||||
import type { ParsedSelector } from '../utils/isomorphic/selectorParser';
|
import type { ParsedSelector } from '../utils/isomorphic/selectorParser';
|
||||||
import type * as channels from '@protocol/channels';
|
import type * as channels from '@protocol/channels';
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -19,8 +19,8 @@ import * as path from 'path';
|
||||||
|
|
||||||
import { Artifact } from '../artifact';
|
import { Artifact } from '../artifact';
|
||||||
import { HarTracer } from './harTracer';
|
import { HarTracer } from './harTracer';
|
||||||
import { createGuid } from '../../utils';
|
import { createGuid } from '../utils/crypto';
|
||||||
import { ManualPromise } from '../../utils/manualPromise';
|
import { ManualPromise } from '../../utils/isomorphic/manualPromise';
|
||||||
import { yazl } from '../../zipBundle';
|
import { yazl } from '../../zipBundle';
|
||||||
|
|
||||||
import type { BrowserContext } from '../browserContext';
|
import type { BrowserContext } from '../browserContext';
|
||||||
|
|
|
||||||
|
|
@ -16,8 +16,8 @@
|
||||||
|
|
||||||
import { assert, calculateSha1, monotonicTime } from '../../utils';
|
import { assert, calculateSha1, monotonicTime } from '../../utils';
|
||||||
import { getPlaywrightVersion, isTextualMimeType, urlMatches } from '../../utils';
|
import { getPlaywrightVersion, isTextualMimeType, urlMatches } from '../../utils';
|
||||||
import { eventsHelper } from '../../utils/eventsHelper';
|
import { eventsHelper } from '../utils/eventsHelper';
|
||||||
import { ManualPromise } from '../../utils/manualPromise';
|
import { ManualPromise } from '../../utils/isomorphic/manualPromise';
|
||||||
import { mime } from '../../utilsBundle';
|
import { mime } from '../../utilsBundle';
|
||||||
import { BrowserContext } from '../browserContext';
|
import { BrowserContext } from '../browserContext';
|
||||||
import { APIRequestContext } from '../fetch';
|
import { APIRequestContext } from '../fetch';
|
||||||
|
|
@ -25,7 +25,7 @@ import { Frame } from '../frames';
|
||||||
import { helper } from '../helper';
|
import { helper } from '../helper';
|
||||||
import * as network from '../network';
|
import * as network from '../network';
|
||||||
|
|
||||||
import type { RegisteredListener } from '../../utils/eventsHelper';
|
import type { RegisteredListener } from '../utils/eventsHelper';
|
||||||
import type { APIRequestEvent, APIRequestFinishedEvent } from '../fetch';
|
import type { APIRequestEvent, APIRequestFinishedEvent } from '../fetch';
|
||||||
import type { Page } from '../page';
|
import type { Page } from '../page';
|
||||||
import type { Worker } from '../page';
|
import type { Worker } from '../page';
|
||||||
|
|
|
||||||
|
|
@ -16,11 +16,11 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { debugLogger } from '../utils/debugLogger';
|
import { debugLogger } from '../utils/debugLogger';
|
||||||
import { eventsHelper } from '../utils/eventsHelper';
|
import { eventsHelper } from './utils/eventsHelper';
|
||||||
|
|
||||||
import type { Progress } from './progress';
|
import type { Progress } from './progress';
|
||||||
import type * as types from './types';
|
import type * as types from './types';
|
||||||
import type { RegisteredListener } from '../utils/eventsHelper';
|
import type { RegisteredListener } from './utils/eventsHelper';
|
||||||
import type { EventEmitter } from 'events';
|
import type { EventEmitter } from 'events';
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@
|
||||||
|
|
||||||
import { EventEmitter } from 'events';
|
import { EventEmitter } from 'events';
|
||||||
|
|
||||||
import { createGuid } from '../utils';
|
import { createGuid } from './utils/crypto';
|
||||||
|
|
||||||
import type { Browser } from './browser';
|
import type { Browser } from './browser';
|
||||||
import type { BrowserContext } from './browserContext';
|
import type { BrowserContext } from './browserContext';
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@ import { SdkObject } from './instrumentation';
|
||||||
import * as utilityScriptSource from '../generated/utilityScriptSource';
|
import * as utilityScriptSource from '../generated/utilityScriptSource';
|
||||||
import { isUnderTest } from '../utils';
|
import { isUnderTest } from '../utils';
|
||||||
import { serializeAsCallArgument } from './isomorphic/utilityScriptSerializers';
|
import { serializeAsCallArgument } from './isomorphic/utilityScriptSerializers';
|
||||||
import { LongStandingScope } from '../utils/manualPromise';
|
import { LongStandingScope } from '../utils/isomorphic/manualPromise';
|
||||||
|
|
||||||
import type * as dom from './dom';
|
import type * as dom from './dom';
|
||||||
import type { UtilityScript } from './injected/utilityScript';
|
import type { UtilityScript } from './injected/utilityScript';
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@ import { assert } from '../utils';
|
||||||
import { BrowserContext } from './browserContext';
|
import { BrowserContext } from './browserContext';
|
||||||
import { APIRequestContext } from './fetch';
|
import { APIRequestContext } from './fetch';
|
||||||
import { SdkObject } from './instrumentation';
|
import { SdkObject } from './instrumentation';
|
||||||
import { ManualPromise } from '../utils/manualPromise';
|
import { ManualPromise } from '../utils/isomorphic/manualPromise';
|
||||||
|
|
||||||
import type * as contexts from './browserContext';
|
import type * as contexts from './browserContext';
|
||||||
import type * as frames from './frames';
|
import type * as frames from './frames';
|
||||||
|
|
|
||||||
|
|
@ -29,12 +29,13 @@ import * as js from './javascript';
|
||||||
import { ProgressController } from './progress';
|
import { ProgressController } from './progress';
|
||||||
import { Screenshotter, validateScreenshotOptions } from './screenshotter';
|
import { Screenshotter, validateScreenshotOptions } from './screenshotter';
|
||||||
import { TimeoutSettings } from '../common/timeoutSettings';
|
import { TimeoutSettings } from '../common/timeoutSettings';
|
||||||
import { LongStandingScope, assert, compressCallLog, createGuid, trimStringWithEllipsis } from '../utils';
|
import { LongStandingScope, assert, compressCallLog, trimStringWithEllipsis } from '../utils';
|
||||||
|
import { createGuid } from './utils/crypto';
|
||||||
import { asLocator } from '../utils';
|
import { asLocator } from '../utils';
|
||||||
import { getComparator } from './utils/comparators';
|
import { getComparator } from './utils/comparators';
|
||||||
import { debugLogger } from '../utils/debugLogger';
|
import { debugLogger } from '../utils/debugLogger';
|
||||||
import { isInvalidSelectorError } from '../utils/isomorphic/selectorParser';
|
import { isInvalidSelectorError } from '../utils/isomorphic/selectorParser';
|
||||||
import { ManualPromise } from '../utils/manualPromise';
|
import { ManualPromise } from '../utils/isomorphic/manualPromise';
|
||||||
|
|
||||||
import type { Artifact } from './artifact';
|
import type { Artifact } from './artifact';
|
||||||
import type * as dom from './dom';
|
import type * as dom from './dom';
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@
|
||||||
|
|
||||||
import { TimeoutError } from './errors';
|
import { TimeoutError } from './errors';
|
||||||
import { assert, monotonicTime } from '../utils';
|
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 { CallMetadata, Instrumentation, SdkObject } from './instrumentation';
|
||||||
import type { Progress as CommonProgress } from '../common/progress';
|
import type { Progress as CommonProgress } from '../common/progress';
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@ import { EventEmitter } from 'events';
|
||||||
import { RecorderCollection } from './recorderCollection';
|
import { RecorderCollection } from './recorderCollection';
|
||||||
import * as recorderSource from '../../generated/pollingRecorderSource';
|
import * as recorderSource from '../../generated/pollingRecorderSource';
|
||||||
import { eventsHelper, monotonicTime, quoteCSSAttributeValue } from '../../utils';
|
import { eventsHelper, monotonicTime, quoteCSSAttributeValue } from '../../utils';
|
||||||
import { raceAgainstDeadline } from '../../utils/timeoutRunner';
|
import { raceAgainstDeadline } from '../../utils/isomorphic/timeoutRunner';
|
||||||
import { BrowserContext } from '../browserContext';
|
import { BrowserContext } from '../browserContext';
|
||||||
import { languageSet } from '../codegen/languages';
|
import { languageSet } from '../codegen/languages';
|
||||||
import { Frame } from '../frames';
|
import { Frame } from '../frames';
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@ import { EventEmitter } from 'events';
|
||||||
import { performAction } from './recorderRunner';
|
import { performAction } from './recorderRunner';
|
||||||
import { collapseActions } from './recorderUtils';
|
import { collapseActions } from './recorderUtils';
|
||||||
import { isUnderTest } from '../../utils/debug';
|
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 { Signal } from '../../../../recorder/src/actions';
|
||||||
import type { Frame } from '../frames';
|
import type { Frame } from '../frames';
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,7 @@ import * as os from 'os';
|
||||||
import * as path from 'path';
|
import * as path from 'path';
|
||||||
|
|
||||||
import { debugLogger } from '../../utils/debugLogger';
|
import { debugLogger } from '../../utils/debugLogger';
|
||||||
import { ManualPromise } from '../../utils/manualPromise';
|
import { ManualPromise } from '../../utils/isomorphic/manualPromise';
|
||||||
import { getUserAgent } from '../../utils/userAgent';
|
import { getUserAgent } from '../../utils/userAgent';
|
||||||
import { colors, progress as ProgressBar } from '../../utilsBundle';
|
import { colors, progress as ProgressBar } from '../../utilsBundle';
|
||||||
import { existsAsync } from '../utils/fileUtils';
|
import { existsAsync } from '../utils/fileUtils';
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@
|
||||||
import * as fs from 'fs';
|
import * as fs from 'fs';
|
||||||
import * as path from 'path';
|
import * as path from 'path';
|
||||||
|
|
||||||
import { ManualPromise } from '../../utils/manualPromise';
|
import { ManualPromise } from '../../utils/isomorphic/manualPromise';
|
||||||
import { httpRequest } from '../utils/network';
|
import { httpRequest } from '../utils/network';
|
||||||
import { extract } from '../../zipBundle';
|
import { extract } from '../../zipBundle';
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@
|
||||||
|
|
||||||
import { helper } from './helper';
|
import { helper } from './helper';
|
||||||
import { assert } from '../utils';
|
import { assert } from '../utils';
|
||||||
import { MultiMap } from '../utils/multimap';
|
import { MultiMap } from '../utils/isomorphic/multimap';
|
||||||
|
|
||||||
import type * as dom from './dom';
|
import type * as dom from './dom';
|
||||||
import type { Frame } from './frames';
|
import type { Frame } from './frames';
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { createGuid } from '../utils';
|
import { createGuid } from './utils/crypto';
|
||||||
import { InvalidSelectorError, parseSelector, stringifySelector, visitAllSelectorParts } from '../utils/isomorphic/selectorParser';
|
import { InvalidSelectorError, parseSelector, stringifySelector, visitAllSelectorParts } from '../utils/isomorphic/selectorParser';
|
||||||
|
|
||||||
import type { ParsedSelector } from '../utils/isomorphic/selectorParser';
|
import type { ParsedSelector } from '../utils/isomorphic/selectorParser';
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@
|
||||||
../../../protocol/
|
../../../protocol/
|
||||||
../../../utils/
|
../../../utils/
|
||||||
../../../utilsBundle.ts
|
../../../utilsBundle.ts
|
||||||
|
../../../utils/isomorphic/
|
||||||
../../../zipBundle.ts
|
../../../zipBundle.ts
|
||||||
../../dispatchers/dispatcher.ts
|
../../dispatchers/dispatcher.ts
|
||||||
../../utils
|
../../utils
|
||||||
|
|
|
||||||
|
|
@ -15,15 +15,16 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { frameSnapshotStreamer } from './snapshotterInjected';
|
import { frameSnapshotStreamer } from './snapshotterInjected';
|
||||||
import { calculateSha1, createGuid, monotonicTime } from '../../../utils';
|
import { monotonicTime } from '../../../utils/isomorphic/time';
|
||||||
|
import { calculateSha1, createGuid } from '../../utils/crypto';
|
||||||
import { debugLogger } from '../../../utils/debugLogger';
|
import { debugLogger } from '../../../utils/debugLogger';
|
||||||
import { eventsHelper } from '../../../utils/eventsHelper';
|
import { eventsHelper } from '../../utils/eventsHelper';
|
||||||
import { mime } from '../../../utilsBundle';
|
import { mime } from '../../../utilsBundle';
|
||||||
import { BrowserContext } from '../../browserContext';
|
import { BrowserContext } from '../../browserContext';
|
||||||
import { Page } from '../../page';
|
import { Page } from '../../page';
|
||||||
|
|
||||||
import type { SnapshotData } from './snapshotterInjected';
|
import type { SnapshotData } from './snapshotterInjected';
|
||||||
import type { RegisteredListener } from '../../../utils/eventsHelper';
|
import type { RegisteredListener } from '../../utils/eventsHelper';
|
||||||
import type { Frame } from '../../frames';
|
import type { Frame } from '../../frames';
|
||||||
import type { FrameSnapshot } from '@trace/snapshot';
|
import type { FrameSnapshot } from '@trace/snapshot';
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,10 @@ import * as path from 'path';
|
||||||
|
|
||||||
import { Snapshotter } from './snapshotter';
|
import { Snapshotter } from './snapshotter';
|
||||||
import { commandsWithTracingSnapshots } from '../../../protocol/debug';
|
import { commandsWithTracingSnapshots } from '../../../protocol/debug';
|
||||||
import { assert, createGuid, eventsHelper, monotonicTime } from '../../../utils';
|
import { assert } from '../../../utils/debug';
|
||||||
|
import { monotonicTime } from '../../../utils/isomorphic/time';
|
||||||
|
import { eventsHelper } from '../../utils/eventsHelper';
|
||||||
|
import { createGuid } from '../../utils/crypto';
|
||||||
import { Artifact } from '../../artifact';
|
import { Artifact } from '../../artifact';
|
||||||
import { BrowserContext } from '../../browserContext';
|
import { BrowserContext } from '../../browserContext';
|
||||||
import { Dispatcher } from '../../dispatchers/dispatcher';
|
import { Dispatcher } from '../../dispatchers/dispatcher';
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,9 @@
|
||||||
[*]
|
[*]
|
||||||
../../utils
|
../../utils
|
||||||
|
../../utils/isomorphic
|
||||||
../../utilsBundle.ts
|
../../utilsBundle.ts
|
||||||
../../zipBundle.ts
|
../../zipBundle.ts
|
||||||
|
|
||||||
[comparators.ts]
|
[comparators.ts]
|
||||||
./image_tools
|
./image_tools
|
||||||
../../third_party/pixelmatch
|
../../third_party/pixelmatch
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@
|
||||||
|
|
||||||
import * as crypto from 'crypto';
|
import * as crypto from 'crypto';
|
||||||
|
|
||||||
import { assert } from './debug';
|
import { assert } from '../../utils/debug';
|
||||||
|
|
||||||
export function createGuid(): string {
|
export function createGuid(): string {
|
||||||
return crypto.randomBytes(16).toString('hex');
|
return crypto.randomBytes(16).toString('hex');
|
||||||
|
|
@ -14,7 +14,7 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { isRegExp, isString } from './rtti';
|
import { isRegExp, isString } from '../../utils/isomorphic/rtti';
|
||||||
|
|
||||||
import type { ExpectedTextValue } from '@protocol/channels';
|
import type { ExpectedTextValue } from '@protocol/channels';
|
||||||
|
|
||||||
|
|
@ -17,7 +17,7 @@
|
||||||
import * as fs from 'fs';
|
import * as fs from 'fs';
|
||||||
import * as path from 'path';
|
import * as path from 'path';
|
||||||
|
|
||||||
import { ManualPromise } from '../../utils/manualPromise';
|
import { ManualPromise } from '../../utils/isomorphic/manualPromise';
|
||||||
import { yazl } from '../../zipBundle';
|
import { yazl } from '../../zipBundle';
|
||||||
|
|
||||||
import type { EventEmitter } from 'events';
|
import type { EventEmitter } from 'events';
|
||||||
|
|
|
||||||
|
|
@ -21,8 +21,8 @@ import * as net from 'net';
|
||||||
import * as tls from 'tls';
|
import * as tls from 'tls';
|
||||||
|
|
||||||
import { assert } from '../../utils/debug';
|
import { assert } from '../../utils/debug';
|
||||||
import { ManualPromise } from '../../utils/manualPromise';
|
import { ManualPromise } from '../../utils/isomorphic/manualPromise';
|
||||||
import { monotonicTime } from '../../utils/time';
|
import { monotonicTime } from '../../utils/isomorphic/time';
|
||||||
|
|
||||||
// Implementation(partial) of Happy Eyeballs 2 algorithm described in
|
// Implementation(partial) of Happy Eyeballs 2 algorithm described in
|
||||||
// https://www.rfc-editor.org/rfc/rfc8305
|
// https://www.rfc-editor.org/rfc/rfc8305
|
||||||
|
|
|
||||||
|
|
@ -18,9 +18,9 @@ import * as fs from 'fs';
|
||||||
import * as path from 'path';
|
import * as path from 'path';
|
||||||
|
|
||||||
import { mime, wsServer } from '../../utilsBundle';
|
import { mime, wsServer } from '../../utilsBundle';
|
||||||
import { createGuid } from '../../utils/crypto';
|
import { createGuid } from './crypto';
|
||||||
import { assert } from '../../utils/debug';
|
import { assert } from '../../utils/debug';
|
||||||
import { ManualPromise } from '../../utils/manualPromise';
|
import { ManualPromise } from '../../utils/isomorphic/manualPromise';
|
||||||
import { createHttpServer } from './network';
|
import { createHttpServer } from './network';
|
||||||
|
|
||||||
import type http from 'http';
|
import type http from 'http';
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,8 @@
|
||||||
import EventEmitter from 'events';
|
import EventEmitter from 'events';
|
||||||
import * as net from 'net';
|
import * as net from 'net';
|
||||||
|
|
||||||
import { assert, createGuid, } from '../../utils';
|
import { assert } from '../../utils/debug';
|
||||||
|
import { createGuid } from './crypto';
|
||||||
import { debugLogger } from '../../utils/debugLogger';
|
import { debugLogger } from '../../utils/debugLogger';
|
||||||
import { createSocket } from './happyEyeballs';
|
import { createSocket } from './happyEyeballs';
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -17,8 +17,10 @@
|
||||||
|
|
||||||
import * as path from 'path';
|
import * as path from 'path';
|
||||||
|
|
||||||
import { assert, createGuid, debugAssert, headersArrayToObject } from '../../utils';
|
import { assert, debugAssert } from '../../utils';
|
||||||
import { eventsHelper } from '../../utils/eventsHelper';
|
import { headersArrayToObject } from '../../utils/isomorphic/headers';
|
||||||
|
import { createGuid } from '../utils/crypto';
|
||||||
|
import { eventsHelper } from '../utils/eventsHelper';
|
||||||
import { hostPlatform } from '../../utils/hostPlatform';
|
import { hostPlatform } from '../../utils/hostPlatform';
|
||||||
import { splitErrorMessage } from '../../utils/stackTrace';
|
import { splitErrorMessage } from '../../utils/stackTrace';
|
||||||
import { PNG, jpegjs } from '../../utilsBundle';
|
import { PNG, jpegjs } from '../../utilsBundle';
|
||||||
|
|
@ -41,7 +43,7 @@ import { debugLogger } from '../../utils/debugLogger';
|
||||||
|
|
||||||
import type { Protocol } from './protocol';
|
import type { Protocol } from './protocol';
|
||||||
import type { WKBrowserContext } from './wkBrowser';
|
import type { WKBrowserContext } from './wkBrowser';
|
||||||
import type { RegisteredListener } from '../../utils/eventsHelper';
|
import type { RegisteredListener } from '../utils/eventsHelper';
|
||||||
import type * as accessibility from '../accessibility';
|
import type * as accessibility from '../accessibility';
|
||||||
import type * as frames from '../frames';
|
import type * as frames from '../frames';
|
||||||
import type { JSHandle } from '../javascript';
|
import type { JSHandle } from '../javascript';
|
||||||
|
|
|
||||||
|
|
@ -15,12 +15,12 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { assert } from '../../utils';
|
import { assert } from '../../utils';
|
||||||
import { eventsHelper } from '../../utils/eventsHelper';
|
import { eventsHelper } from '../utils/eventsHelper';
|
||||||
|
|
||||||
import type { Protocol } from './protocol';
|
import type { Protocol } from './protocol';
|
||||||
import type { WKSession } from './wkConnection';
|
import type { WKSession } from './wkConnection';
|
||||||
import type { WKPage } from './wkPage';
|
import type { WKPage } from './wkPage';
|
||||||
import type { RegisteredListener } from '../../utils/eventsHelper';
|
import type { RegisteredListener } from '../utils/eventsHelper';
|
||||||
import type * as network from '../network';
|
import type * as network from '../network';
|
||||||
|
|
||||||
export class WKProvisionalPage {
|
export class WKProvisionalPage {
|
||||||
|
|
|
||||||
|
|
@ -14,13 +14,13 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { eventsHelper } from '../../utils/eventsHelper';
|
import { eventsHelper } from '../utils/eventsHelper';
|
||||||
import { Worker } from '../page';
|
import { Worker } from '../page';
|
||||||
import { WKSession } from './wkConnection';
|
import { WKSession } from './wkConnection';
|
||||||
import { WKExecutionContext } from './wkExecutionContext';
|
import { WKExecutionContext } from './wkExecutionContext';
|
||||||
|
|
||||||
import type { Protocol } from './protocol';
|
import type { Protocol } from './protocol';
|
||||||
import type { RegisteredListener } from '../../utils/eventsHelper';
|
import type { RegisteredListener } from '../utils/eventsHelper';
|
||||||
import type { Page } from '../page';
|
import type { Page } from '../page';
|
||||||
import type * as types from '../types';
|
import type * as types from '../types';
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -14,38 +14,39 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
export * from './utils/crypto';
|
export * from './utils/isomorphic/locatorGenerators';
|
||||||
|
export * from './utils/isomorphic/manualPromise';
|
||||||
|
export * from './utils/isomorphic/mimeType';
|
||||||
|
export * from './utils/isomorphic/multimap';
|
||||||
|
export * from './utils/isomorphic/rtti';
|
||||||
|
export * from './utils/isomorphic/stringUtils';
|
||||||
|
export * from './utils/isomorphic/time';
|
||||||
|
export * from './utils/isomorphic/timeoutRunner';
|
||||||
|
export * from './utils/isomorphic/urlMatch';
|
||||||
|
|
||||||
export * from './utils/debug';
|
export * from './utils/debug';
|
||||||
export * from './utils/debugLogger';
|
export * from './utils/debugLogger';
|
||||||
export * from './utils/env';
|
export * from './utils/env';
|
||||||
export * from './utils/eventsHelper';
|
|
||||||
export * from './utils/expectUtils';
|
|
||||||
export * from './utils/headers';
|
|
||||||
export * from './utils/hostPlatform';
|
export * from './utils/hostPlatform';
|
||||||
export * from './utils/manualPromise';
|
export * from './utils/isomorphic/headers';
|
||||||
export * from './utils/isomorphic/locatorGenerators';
|
export * from './utils/isomorphic/semaphore';
|
||||||
export * from './utils/isomorphic/mimeType';
|
export * from './utils/platform';
|
||||||
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/stackTrace';
|
export * from './utils/stackTrace';
|
||||||
export * from './utils/task';
|
export * from './utils/task';
|
||||||
export * from './utils/time';
|
|
||||||
export * from './utils/timeoutRunner';
|
|
||||||
export * from './utils/traceUtils';
|
|
||||||
export * from './utils/userAgent';
|
export * from './utils/userAgent';
|
||||||
export * from './utils/zipFile';
|
export * from './utils/zipFile';
|
||||||
export * from './utils/zones';
|
export * from './utils/zones';
|
||||||
|
|
||||||
export * from './server/utils/socksProxy';
|
|
||||||
export * from './server/utils/processLauncher';
|
|
||||||
export * from './server/utils/ascii';
|
export * from './server/utils/ascii';
|
||||||
export * from './server/utils/comparators';
|
export * from './server/utils/comparators';
|
||||||
|
export * from './server/utils/crypto';
|
||||||
|
export * from './server/utils/eventsHelper';
|
||||||
|
export * from './server/utils/expectUtils';
|
||||||
export * from './server/utils/fileUtils';
|
export * from './server/utils/fileUtils';
|
||||||
export * from './server/utils/httpServer';
|
export * from './server/utils/httpServer';
|
||||||
export * from './server/utils/network';
|
export * from './server/utils/network';
|
||||||
|
export * from './server/utils/processLauncher';
|
||||||
export * from './server/utils/profiler';
|
export * from './server/utils/profiler';
|
||||||
export * from './server/utils/wsServer';
|
export * from './server/utils/socksProxy';
|
||||||
export * from './server/utils/spawnAsync';
|
export * from './server/utils/spawnAsync';
|
||||||
|
export * from './server/utils/wsServer';
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,6 @@
|
||||||
[*]
|
[*]
|
||||||
./
|
./
|
||||||
|
./isomorphic
|
||||||
../utilsBundle.ts
|
../utilsBundle.ts
|
||||||
../zipBundle.ts
|
../zipBundle.ts
|
||||||
|
../utils/isomorphic
|
||||||
|
|
@ -14,24 +14,24 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import * as fs from 'fs';
|
|
||||||
import * as path from 'path';
|
|
||||||
|
|
||||||
import { createGuid } from './crypto';
|
|
||||||
import { ZipFile } from './zipFile';
|
import { ZipFile } from './zipFile';
|
||||||
|
|
||||||
import type { HeadersArray } from '../common/types';
|
import type { HeadersArray } from '../common/types';
|
||||||
import type * as har from '@trace/har';
|
import type * as har from '@trace/har';
|
||||||
|
import type { Platform } from './platform';
|
||||||
|
|
||||||
const redirectStatus = [301, 302, 303, 307, 308];
|
const redirectStatus = [301, 302, 303, 307, 308];
|
||||||
|
|
||||||
export class HarBackend {
|
export class HarBackend {
|
||||||
readonly id = createGuid();
|
readonly id: string;
|
||||||
private _harFile: har.HARFile;
|
private _harFile: har.HARFile;
|
||||||
private _zipFile: ZipFile | null;
|
private _zipFile: ZipFile | null;
|
||||||
private _baseDir: string | null;
|
private _baseDir: string | null;
|
||||||
|
private _platform: Platform;
|
||||||
|
|
||||||
constructor(harFile: har.HARFile, baseDir: string | null, zipFile: ZipFile | null) {
|
constructor(platform: Platform, harFile: har.HARFile, baseDir: string | null, zipFile: ZipFile | null) {
|
||||||
|
this._platform = platform;
|
||||||
|
this.id = platform.createGuid();
|
||||||
this._harFile = harFile;
|
this._harFile = harFile;
|
||||||
this._baseDir = baseDir;
|
this._baseDir = baseDir;
|
||||||
this._zipFile = zipFile;
|
this._zipFile = zipFile;
|
||||||
|
|
@ -79,7 +79,7 @@ export class HarBackend {
|
||||||
if (this._zipFile)
|
if (this._zipFile)
|
||||||
buffer = await this._zipFile.read(file);
|
buffer = await this._zipFile.read(file);
|
||||||
else
|
else
|
||||||
buffer = await fs.promises.readFile(path.resolve(this._baseDir!, file));
|
buffer = await this._platform.fs().promises.readFile(this._platform.path().resolve(this._baseDir!, file));
|
||||||
} else {
|
} else {
|
||||||
buffer = Buffer.from(content.text || '', content.encoding === 'base64' ? 'base64' : 'utf-8');
|
buffer = Buffer.from(content.text || '', content.encoding === 'base64' ? 'base64' : 'utf-8');
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -14,8 +14,6 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { captureRawStack } from './stackTrace';
|
|
||||||
|
|
||||||
export class ManualPromise<T = void> extends Promise<T> {
|
export class ManualPromise<T = void> extends Promise<T> {
|
||||||
private _resolve!: (t: T) => void;
|
private _resolve!: (t: T) => void;
|
||||||
private _reject!: (e: Error) => 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');
|
clone.stack = [error.name + ':' + error.message, ...frames].join('\n');
|
||||||
return clone;
|
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');
|
||||||
|
}
|
||||||
|
|
@ -14,7 +14,7 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
export { isString } from './isomorphic/stringUtils';
|
export { isString } from './stringUtils';
|
||||||
|
|
||||||
export function isRegExp(obj: any): obj is RegExp {
|
export function isRegExp(obj: any): obj is RegExp {
|
||||||
return obj instanceof RegExp || Object.prototype.toString.call(obj) === '[object RegExp]';
|
return obj instanceof RegExp || Object.prototype.toString.call(obj) === '[object RegExp]';
|
||||||
19
packages/playwright-core/src/utils/isomorphic/time.ts
Normal file
19
packages/playwright-core/src/utils/isomorphic/time.ts
Normal 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;
|
||||||
|
}
|
||||||
|
|
@ -14,7 +14,7 @@
|
||||||
* limitations under the License.
|
* 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 }> {
|
export async function raceAgainstDeadline<T>(cb: () => Promise<T>, deadline: number): Promise<{ result: T, timedOut: false } | { timedOut: true }> {
|
||||||
let timer: NodeJS.Timeout | undefined;
|
let timer: NodeJS.Timeout | undefined;
|
||||||
|
|
@ -14,7 +14,7 @@
|
||||||
* limitations under the License.
|
* 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 SerializedStackFrame = [number, number, number, string];
|
||||||
export type SerializedStack = [number, SerializedStackFrame[]];
|
export type SerializedStack = [number, SerializedStackFrame[]];
|
||||||
|
|
@ -33,3 +33,24 @@ export function parseClientSideCallMetadata(data: SerializedClientSideCallMetada
|
||||||
}
|
}
|
||||||
return result;
|
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 };
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -20,11 +20,11 @@ import * as path from 'path';
|
||||||
|
|
||||||
import { removeFolders } from './fileUtils';
|
import { removeFolders } from './fileUtils';
|
||||||
import { HarBackend } from './harBackend';
|
import { HarBackend } from './harBackend';
|
||||||
import { ManualPromise } from './manualPromise';
|
import { ManualPromise } from './isomorphic/manualPromise';
|
||||||
import { ZipFile } from './zipFile';
|
import { ZipFile } from './zipFile';
|
||||||
import { yauzl, yazl } from '../zipBundle';
|
import { yauzl, yazl } from '../zipBundle';
|
||||||
import { serializeClientSideCallMetadata } from '../utils';
|
import { serializeClientSideCallMetadata } from '../utils/isomorphic/traceUtils';
|
||||||
import { assert, calculateSha1 } from '../utils';
|
import { assert } from '../utils/debug';
|
||||||
|
|
||||||
import type { Platform } from './platform';
|
import type { Platform } from './platform';
|
||||||
import type * as channels from '@protocol/channels';
|
import type * as channels from '@protocol/channels';
|
||||||
|
|
@ -77,7 +77,7 @@ export async function zip(platform: Platform, stackSessions: Map<string, StackSe
|
||||||
sourceFiles.add(file);
|
sourceFiles.add(file);
|
||||||
}
|
}
|
||||||
for (const sourceFile of sourceFiles)
|
for (const sourceFile of sourceFiles)
|
||||||
addFile(sourceFile, 'resources/src@' + calculateSha1(sourceFile) + '.txt');
|
addFile(sourceFile, 'resources/src@' + await platform.calculateSha1(sourceFile) + '.txt');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (params.mode === 'write') {
|
if (params.mode === 'write') {
|
||||||
|
|
@ -137,7 +137,7 @@ async function deleteStackSession(platform: Platform, stackSessions: Map<string,
|
||||||
stackSessions.delete(stacksId!);
|
stackSessions.delete(stacksId!);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function harOpen(harBackends: Map<string, HarBackend>, params: channels.LocalUtilsHarOpenParams): Promise<channels.LocalUtilsHarOpenResult> {
|
export async function harOpen(platform: Platform, harBackends: Map<string, HarBackend>, params: channels.LocalUtilsHarOpenParams): Promise<channels.LocalUtilsHarOpenResult> {
|
||||||
let harBackend: HarBackend;
|
let harBackend: HarBackend;
|
||||||
if (params.file.endsWith('.zip')) {
|
if (params.file.endsWith('.zip')) {
|
||||||
const zipFile = new ZipFile(params.file);
|
const zipFile = new ZipFile(params.file);
|
||||||
|
|
@ -147,10 +147,10 @@ export async function harOpen(harBackends: Map<string, HarBackend>, params: chan
|
||||||
return { error: 'Specified archive does not have a .har file' };
|
return { error: 'Specified archive does not have a .har file' };
|
||||||
const har = await zipFile.read(harEntryName);
|
const har = await zipFile.read(harEntryName);
|
||||||
const harFile = JSON.parse(har.toString()) as har.HARFile;
|
const harFile = JSON.parse(har.toString()) as har.HARFile;
|
||||||
harBackend = new HarBackend(harFile, null, zipFile);
|
harBackend = new HarBackend(platform, harFile, null, zipFile);
|
||||||
} else {
|
} else {
|
||||||
const harFile = JSON.parse(await fs.promises.readFile(params.file, 'utf-8')) as har.HARFile;
|
const harFile = JSON.parse(await fs.promises.readFile(params.file, 'utf-8')) as har.HARFile;
|
||||||
harBackend = new HarBackend(harFile, path.dirname(params.file), null);
|
harBackend = new HarBackend(platform, harFile, path.dirname(params.file), null);
|
||||||
}
|
}
|
||||||
harBackends.set(harBackend.id, harBackend);
|
harBackends.set(harBackend.id, harBackend);
|
||||||
return { harId: harBackend.id };
|
return { harId: harBackend.id };
|
||||||
|
|
|
||||||
|
|
@ -14,18 +14,18 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { makeWaitForNextTask } from '../utils';
|
import { makeWaitForNextTask } from './task';
|
||||||
|
|
||||||
export interface WritableStream {
|
interface WritableStream {
|
||||||
write(data: Buffer): void;
|
write(data: Buffer): void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ReadableStream {
|
interface ReadableStream {
|
||||||
on(event: 'data', callback: (b: Buffer) => void): void;
|
on(event: 'data', callback: (b: Buffer) => void): void;
|
||||||
on(event: 'close', callback: () => void): void;
|
on(event: 'close', callback: () => void): void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ClosableStream {
|
interface ClosableStream {
|
||||||
close(): void;
|
close(): void;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -14,36 +14,56 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import * as crypto from 'crypto';
|
||||||
import * as fs from 'fs';
|
import * as fs from 'fs';
|
||||||
import * as path from 'path';
|
import * as path from 'path';
|
||||||
import * as util from 'util';
|
import * as util from 'util';
|
||||||
|
|
||||||
export type Platform = {
|
export type Platform = {
|
||||||
|
calculateSha1(text: string): Promise<string>;
|
||||||
|
createGuid: () => string;
|
||||||
fs: () => typeof fs;
|
fs: () => typeof fs;
|
||||||
path: () => typeof path;
|
|
||||||
inspectCustom: symbol | undefined;
|
inspectCustom: symbol | undefined;
|
||||||
|
path: () => typeof path;
|
||||||
ws?: (url: string) => WebSocket;
|
ws?: (url: string) => WebSocket;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const emptyPlatform: Platform = {
|
export const nodePlatform: Platform = {
|
||||||
|
calculateSha1: (text: string) => {
|
||||||
|
const sha1 = crypto.createHash('sha1');
|
||||||
|
sha1.update(text);
|
||||||
|
return Promise.resolve(sha1.digest('hex'));
|
||||||
|
},
|
||||||
|
|
||||||
|
createGuid: () => crypto.randomBytes(16).toString('hex'),
|
||||||
|
|
||||||
|
fs: () => fs,
|
||||||
|
|
||||||
|
inspectCustom: util.inspect.custom,
|
||||||
|
|
||||||
|
path: () => path,
|
||||||
|
};
|
||||||
|
|
||||||
|
export const webPlatform: Platform = {
|
||||||
|
calculateSha1: async (text: string) => {
|
||||||
|
const bytes = new TextEncoder().encode(text);
|
||||||
|
const hashBuffer = await crypto.subtle.digest('SHA-1', bytes);
|
||||||
|
return Array.from(new Uint8Array(hashBuffer), b => b.toString(16).padStart(2, '0')).join('');
|
||||||
|
},
|
||||||
|
|
||||||
|
createGuid: () => {
|
||||||
|
return Array.from(crypto.getRandomValues(new Uint8Array(16)), b => b.toString(16).padStart(2, '0')).join('');
|
||||||
|
},
|
||||||
|
|
||||||
fs: () => {
|
fs: () => {
|
||||||
throw new Error('File system is not available');
|
throw new Error('File system is not available');
|
||||||
},
|
},
|
||||||
|
|
||||||
|
inspectCustom: undefined,
|
||||||
|
|
||||||
path: () => {
|
path: () => {
|
||||||
throw new Error('Path module is not available');
|
throw new Error('Path module is not available');
|
||||||
},
|
},
|
||||||
|
|
||||||
inspectCustom: undefined,
|
|
||||||
};
|
|
||||||
|
|
||||||
export const nodePlatform: Platform = {
|
|
||||||
fs: () => fs,
|
|
||||||
path: () => path,
|
|
||||||
inspectCustom: util.inspect.custom,
|
|
||||||
};
|
|
||||||
|
|
||||||
export const webPlatform: Platform = {
|
|
||||||
...emptyPlatform,
|
|
||||||
ws: (url: string) => new WebSocket(url),
|
ws: (url: string) => new WebSocket(url),
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -17,15 +17,13 @@
|
||||||
import * as path from 'path';
|
import * as path from 'path';
|
||||||
|
|
||||||
import { colors } from '../utilsBundle';
|
import { colors } from '../utilsBundle';
|
||||||
import { findRepeatedSubsequences } from './sequence';
|
import { findRepeatedSubsequences } from './isomorphic/sequence';
|
||||||
import { StackUtils } from './stackUtils';
|
import { parseStackFrame } from './stackUtils';
|
||||||
|
|
||||||
import type { StackFrame } from '@protocol/channels';
|
import type { StackFrame } from '@protocol/channels';
|
||||||
|
|
||||||
const stackUtils = new StackUtils();
|
|
||||||
|
|
||||||
export function parseStackTraceLine(line: string): StackFrame | null {
|
export function parseStackTraceLine(line: string): StackFrame | null {
|
||||||
const frame = stackUtils.parseLine(line);
|
const frame = parseStackFrame(line);
|
||||||
if (!frame)
|
if (!frame)
|
||||||
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:')))
|
||||||
|
|
|
||||||
|
|
@ -35,84 +35,82 @@ type StackData = {
|
||||||
evalFile?: string | undefined;
|
evalFile?: string | undefined;
|
||||||
};
|
};
|
||||||
|
|
||||||
export class StackUtils {
|
export function parseStackFrame(line: string): StackData | null {
|
||||||
parseLine(line: string) {
|
const match = line && line.match(re);
|
||||||
const match = line && line.match(re);
|
if (!match)
|
||||||
if (!match)
|
return null;
|
||||||
return null;
|
|
||||||
|
|
||||||
const ctor = match[1] === 'new';
|
const ctor = match[1] === 'new';
|
||||||
let fname = match[2];
|
let fname = match[2];
|
||||||
const evalOrigin = match[3];
|
const evalOrigin = match[3];
|
||||||
const evalFile = match[4];
|
const evalFile = match[4];
|
||||||
const evalLine = Number(match[5]);
|
const evalLine = Number(match[5]);
|
||||||
const evalCol = Number(match[6]);
|
const evalCol = Number(match[6]);
|
||||||
let file = match[7];
|
let file = match[7];
|
||||||
const lnum = match[8];
|
const lnum = match[8];
|
||||||
const col = match[9];
|
const col = match[9];
|
||||||
const native = match[10] === 'native';
|
const native = match[10] === 'native';
|
||||||
const closeParen = match[11] === ')';
|
const closeParen = match[11] === ')';
|
||||||
let method;
|
let method;
|
||||||
|
|
||||||
const res: StackData = {};
|
const res: StackData = {};
|
||||||
|
|
||||||
if (lnum)
|
if (lnum)
|
||||||
res.line = Number(lnum);
|
res.line = Number(lnum);
|
||||||
|
|
||||||
if (col)
|
if (col)
|
||||||
res.column = Number(col);
|
res.column = Number(col);
|
||||||
|
|
||||||
if (closeParen && file) {
|
if (closeParen && file) {
|
||||||
// make sure parens are balanced
|
// make sure parens are balanced
|
||||||
// if we have a file like "asdf) [as foo] (xyz.js", then odds are
|
// 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
|
// that the fname should be += " (asdf) [as foo]" and the file
|
||||||
// should be just "xyz.js"
|
// should be just "xyz.js"
|
||||||
// walk backwards from the end to find the last unbalanced (
|
// walk backwards from the end to find the last unbalanced (
|
||||||
let closes = 0;
|
let closes = 0;
|
||||||
for (let i = file.length - 1; i > 0; i--) {
|
for (let i = file.length - 1; i > 0; i--) {
|
||||||
if (file.charAt(i) === ')') {
|
if (file.charAt(i) === ')') {
|
||||||
closes++;
|
closes++;
|
||||||
} else if (file.charAt(i) === '(' && file.charAt(i - 1) === ' ') {
|
} else if (file.charAt(i) === '(' && file.charAt(i - 1) === ' ') {
|
||||||
closes--;
|
closes--;
|
||||||
if (closes === -1 && file.charAt(i - 1) === ' ') {
|
if (closes === -1 && file.charAt(i - 1) === ' ') {
|
||||||
const before = file.slice(0, i - 1);
|
const before = file.slice(0, i - 1);
|
||||||
const after = file.slice(i + 1);
|
const after = file.slice(i + 1);
|
||||||
file = after;
|
file = after;
|
||||||
fname += ` (${before}`;
|
fname += ` (${before}`;
|
||||||
break;
|
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) {
|
function setFile(result: StackData, filename: string) {
|
||||||
|
|
|
||||||
|
|
@ -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;
|
|
||||||
}
|
|
||||||
|
|
@ -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 };
|
|
||||||
}
|
|
||||||
|
|
@ -78,7 +78,7 @@ export class FullConfigInternal {
|
||||||
const privateConfiguration = (userConfig as any)['@playwright/test'];
|
const privateConfiguration = (userConfig as any)['@playwright/test'];
|
||||||
this.plugins = (privateConfiguration?.plugins || []).map((p: any) => ({ factory: p }));
|
this.plugins = (privateConfiguration?.plugins || []).map((p: any) => ({ factory: p }));
|
||||||
this.singleTSConfigPath = pathResolve(configDir, userConfig.tsconfig);
|
this.singleTSConfigPath = pathResolve(configDir, userConfig.tsconfig);
|
||||||
this.populateGitInfo = takeFirst(userConfig.populateGitInfo, false);
|
this.populateGitInfo = takeFirst(userConfig.populateGitInfo, defaultPopulateGitInfo);
|
||||||
|
|
||||||
this.globalSetups = (Array.isArray(userConfig.globalSetup) ? userConfig.globalSetup : [userConfig.globalSetup]).map(s => resolveScript(s, configDir)).filter(script => script !== undefined);
|
this.globalSetups = (Array.isArray(userConfig.globalSetup) ? userConfig.globalSetup : [userConfig.globalSetup]).map(s => resolveScript(s, configDir)).filter(script => script !== undefined);
|
||||||
this.globalTeardowns = (Array.isArray(userConfig.globalTeardown) ? userConfig.globalTeardown : [userConfig.globalTeardown]).map(s => resolveScript(s, configDir)).filter(script => script !== undefined);
|
this.globalTeardowns = (Array.isArray(userConfig.globalTeardown) ? userConfig.globalTeardown : [userConfig.globalTeardown]).map(s => resolveScript(s, configDir)).filter(script => script !== undefined);
|
||||||
|
|
@ -301,6 +301,7 @@ function resolveScript(id: string | undefined, rootDir: string): string | undefi
|
||||||
|
|
||||||
export const defaultGrep = /.*/;
|
export const defaultGrep = /.*/;
|
||||||
export const defaultReporter = process.env.CI ? 'dot' : 'list';
|
export const defaultReporter = process.env.CI ? 'dot' : 'list';
|
||||||
|
const defaultPopulateGitInfo = process.env.GITHUB_ACTIONS === 'true';
|
||||||
|
|
||||||
const configInternalSymbol = Symbol('configInternalSymbol');
|
const configInternalSymbol = Symbol('configInternalSymbol');
|
||||||
|
|
||||||
|
|
|
||||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue