From d1c161ce99d79f7eb3b3ea279e47f7e13da4eb79 Mon Sep 17 00:00:00 2001 From: Pavel Feldman Date: Fri, 13 Jan 2023 13:50:38 -0800 Subject: [PATCH] chore: merge the util exports (#20110) --- packages/playwright-core/package.json | 16 +- packages/playwright-core/src/client/fetch.ts | 19 +- packages/playwright-core/src/client/frame.ts | 2 +- .../playwright-core/src/client/network.ts | 2 +- packages/playwright-core/src/client/page.ts | 2 +- .../playwright-core/src/common/socksProxy.ts | 4 +- .../playwright-core/src/containers/docker.ts | 2 +- .../playwright-core/src/grid/gridAgent.ts | 2 +- .../playwright-core/src/grid/gridServer.ts | 2 +- .../src/server/chromium/chromium.ts | 21 +- .../dispatchers/localUtilsDispatcher.ts | 6 +- packages/playwright-core/src/server/fetch.ts | 2 +- .../src/server/har/harTracer.ts | 4 +- .../src/server/registry/browserFetcher.ts | 2 +- .../src/server/registry/dependencies.ts | 2 +- .../src/server/registry/index.ts | 4 +- .../src/server/registry/oopDownloadMain.ts | 2 +- packages/playwright-core/src/utils/ascii.ts | 25 ++ packages/playwright-core/src/utils/crypto.ts | 27 +++ packages/playwright-core/src/utils/debug.ts | 45 ++++ packages/playwright-core/src/utils/env.ts | 27 +++ packages/playwright-core/src/utils/glob.ts | 73 ++++++ packages/playwright-core/src/utils/headers.ts | 44 ++++ packages/playwright-core/src/utils/index.ts | 225 ++---------------- .../{common/netUtils.ts => utils/network.ts} | 67 +----- packages/playwright-core/src/utils/rtti.ts | 33 +++ packages/playwright-core/src/utils/task.ts | 55 +++++ packages/playwright-core/src/utils/time.ts | 20 ++ .../src/{common => utils}/userAgent.ts | 0 packages/playwright-test/src/dispatcher.ts | 2 +- packages/playwright-test/src/expect.ts | 2 +- packages/playwright-test/src/fixtures.ts | 2 +- packages/playwright-test/src/index.ts | 3 +- .../playwright-test/src/matchers/matchers.ts | 6 +- .../playwright-test/src/matchers/toEqual.ts | 4 +- .../src/matchers/toMatchSnapshot.ts | 4 +- .../src/plugins/gitCommitInfoPlugin.ts | 3 +- .../playwright-test/src/plugins/vitePlugin.ts | 2 +- .../src/plugins/webServerPlugin.ts | 3 +- .../playwright-test/src/reporters/html.ts | 4 +- .../playwright-test/src/reporters/json.ts | 2 +- packages/playwright-test/src/reporters/raw.ts | 2 +- packages/playwright-test/src/runner.ts | 2 +- .../playwright-test/src/timeoutManager.ts | 2 +- packages/playwright-test/src/util.ts | 7 +- packages/playwright-test/src/workerRunner.ts | 2 +- tests/config/comparator.ts | 2 +- tests/electron/electronTest.ts | 2 +- tests/installation/globalSetup.ts | 2 +- tests/library/browsertype-connect.spec.ts | 2 +- tests/library/chromium/chromium.spec.ts | 2 +- tests/library/debug-controller.spec.ts | 2 +- tests/library/global-fetch.spec.ts | 2 +- tests/page/interception.spec.ts | 2 +- .../playwright-test/playwright.trace.spec.ts | 2 +- tests/playwright-test/reporter-html.spec.ts | 4 +- utils/doclint/since.js | 2 +- 57 files changed, 466 insertions(+), 345 deletions(-) create mode 100644 packages/playwright-core/src/utils/ascii.ts create mode 100644 packages/playwright-core/src/utils/crypto.ts create mode 100644 packages/playwright-core/src/utils/debug.ts create mode 100644 packages/playwright-core/src/utils/env.ts create mode 100644 packages/playwright-core/src/utils/glob.ts create mode 100644 packages/playwright-core/src/utils/headers.ts rename packages/playwright-core/src/{common/netUtils.ts => utils/network.ts} (75%) create mode 100644 packages/playwright-core/src/utils/rtti.ts create mode 100644 packages/playwright-core/src/utils/task.ts create mode 100644 packages/playwright-core/src/utils/time.ts rename packages/playwright-core/src/{common => utils}/userAgent.ts (100%) diff --git a/packages/playwright-core/package.json b/packages/playwright-core/package.json index 2ad7c0eed5..6c0e33b5a5 100644 --- a/packages/playwright-core/package.json +++ b/packages/playwright-core/package.json @@ -22,28 +22,14 @@ "./package.json": "./package.json", "./lib/grid/gridServer": "./lib/grid/gridServer.js", "./lib/outofprocess": "./lib/outofprocess.js", - "./lib/utils": "./lib/utils/index.js", "./lib/image_tools/stats": "./lib/image_tools/stats.js", "./lib/image_tools/compare": "./lib/image_tools/compare.js", "./lib/image_tools/imageChannel": "./lib/image_tools/imageChannel.js", "./lib/image_tools/colorUtils": "./lib/image_tools/colorUtils.js", - "./lib/common/userAgent": "./lib/common/userAgent.js", "./lib/containers/docker": "./lib/containers/docker.js", - "./lib/utils/comparators": "./lib/utils/comparators.js", - "./lib/utils/eventsHelper": "./lib/utils/eventsHelper.js", - "./lib/utils/fileUtils": "./lib/utils/fileUtils.js", - "./lib/utils/httpServer": "./lib/utils/httpServer.js", - "./lib/utils/hostPlatform": "./lib/utils/hostPlatform.js", - "./lib/utils/manualPromise": "./lib/utils/manualPromise.js", - "./lib/utils/mimeType": "./lib/utils/mimeType.js", - "./lib/utils/multimap": "./lib/utils/multimap.js", - "./lib/utils/processLauncher": "./lib/utils/processLauncher.js", - "./lib/utils/processLauncherCleanupEntrypoint": "./lib/utils/processLauncherCleanupEntrypoint.js", - "./lib/utils/spawnAsync": "./lib/utils/spawnAsync.js", - "./lib/utils/stackTrace": "./lib/utils/stackTrace.js", - "./lib/utils/timeoutRunner": "./lib/utils/timeoutRunner.js", "./lib/remote/playwrightServer": "./lib/remote/playwrightServer.js", "./lib/server": "./lib/server/index.js", + "./lib/utils": "./lib/utils/index.js", "./lib/utilsBundle": "./lib/utilsBundle.js", "./lib/zipBundle": "./lib/zipBundle.js", "./types/protocol": "./types/protocol.d.ts", diff --git a/packages/playwright-core/src/client/fetch.ts b/packages/playwright-core/src/client/fetch.ts index ae42727320..2bb144971d 100644 --- a/packages/playwright-core/src/client/fetch.ts +++ b/packages/playwright-core/src/client/fetch.ts @@ -19,10 +19,10 @@ import path from 'path'; import * as util from 'util'; import type { Serializable } from '../../types/structs'; import type * as api from '../../types/types'; -import type { HeadersArray } from '../common/types'; +import type { HeadersArray, NameValue } from '../common/types'; import type * as channels from '@protocol/channels'; import { kBrowserOrContextClosedError } from '../common/errors'; -import { assert, headersObjectToArray, isFilePayload, isString, objectToArray } from '../utils'; +import { assert, headersObjectToArray, isString } from '../utils'; import { mkdirIfNeeded } from '../utils/fileUtils'; import { ChannelOwner } from './channelOwner'; import { RawHeaders } from './network'; @@ -336,4 +336,17 @@ function isJsonContentType(headers?: HeadersArray): boolean { return value === 'application/json'; } return false; -} \ No newline at end of file +} + +function objectToArray(map?: { [key: string]: any }): NameValue[] | undefined { + if (!map) + return undefined; + const result = []; + for (const [name, value] of Object.entries(map)) + result.push({ name, value: String(value) }); + return result; +} + +function isFilePayload(value: any): boolean { + return typeof value === 'object' && value['name'] && value['mimeType'] && value['buffer']; +} diff --git a/packages/playwright-core/src/client/frame.ts b/packages/playwright-core/src/client/frame.ts index a539828d3e..0d2ceda9dc 100644 --- a/packages/playwright-core/src/client/frame.ts +++ b/packages/playwright-core/src/client/frame.ts @@ -32,7 +32,7 @@ import { Waiter } from './waiter'; import { Events } from './events'; import type { LifecycleEvent, URLMatch, SelectOption, SelectOptionOptions, FilePayload, WaitForFunctionOptions, StrictOptions } from './types'; import { kLifecycleEvents } from './types'; -import { urlMatches } from '../common/netUtils'; +import { urlMatches } from '../utils/network'; import type * as api from '../../types/types'; import type * as structs from '../../types/structs'; import { debugLogger } from '../common/debugLogger'; diff --git a/packages/playwright-core/src/client/network.ts b/packages/playwright-core/src/client/network.ts index a84cdf5166..77d89ecddd 100644 --- a/packages/playwright-core/src/client/network.ts +++ b/packages/playwright-core/src/client/network.ts @@ -29,7 +29,7 @@ import type { Page } from './page'; import { Waiter } from './waiter'; import type * as api from '../../types/types'; import type { HeadersArray, URLMatch } from '../common/types'; -import { urlMatches } from '../common/netUtils'; +import { urlMatches } from '../utils/network'; import { MultiMap } from '../utils/multimap'; import { APIResponse } from './fetch'; import type { Serializable } from '../../types/structs'; diff --git a/packages/playwright-core/src/client/page.ts b/packages/playwright-core/src/client/page.ts index 0692ac9209..de57040960 100644 --- a/packages/playwright-core/src/client/page.ts +++ b/packages/playwright-core/src/client/page.ts @@ -20,7 +20,7 @@ import path from 'path'; import type * as structs from '../../types/structs'; import type * as api from '../../types/types'; import { isSafeCloseError } from '../common/errors'; -import { urlMatches } from '../common/netUtils'; +import { urlMatches } from '../utils/network'; import { TimeoutSettings } from '../common/timeoutSettings'; import type * as channels from '@protocol/channels'; import { parseError, serializeError } from '../protocol/serializers'; diff --git a/packages/playwright-core/src/common/socksProxy.ts b/packages/playwright-core/src/common/socksProxy.ts index 68dc3c97dc..dcc9879965 100644 --- a/packages/playwright-core/src/common/socksProxy.ts +++ b/packages/playwright-core/src/common/socksProxy.ts @@ -20,8 +20,8 @@ import type { AddressInfo } from 'net'; import net from 'net'; import util from 'util'; import { debugLogger } from './debugLogger'; -import { createSocket } from './netUtils'; -import { assert, createGuid } from '../utils'; +import { createSocket } from '../utils/network'; +import { assert, createGuid, } from '../utils'; const dnsLookupAsync = util.promisify(dns.lookup); diff --git a/packages/playwright-core/src/containers/docker.ts b/packages/playwright-core/src/containers/docker.ts index 79ffbe16da..920909d62a 100644 --- a/packages/playwright-core/src/containers/docker.ts +++ b/packages/playwright-core/src/containers/docker.ts @@ -18,7 +18,7 @@ import path from 'path'; import { spawnAsync } from '../utils/spawnAsync'; import * as utils from '../utils'; -import { getPlaywrightVersion, getUserAgent } from '../common/userAgent'; +import { getPlaywrightVersion, getUserAgent } from '../utils/userAgent'; import { urlToWSEndpoint } from '../server/dispatchers/localUtilsDispatcher'; import { WebSocketTransport } from '../server/transport'; import { SocksInterceptor } from '../server/socksInterceptor'; diff --git a/packages/playwright-core/src/grid/gridAgent.ts b/packages/playwright-core/src/grid/gridAgent.ts index a9daa422d7..39b79165b9 100644 --- a/packages/playwright-core/src/grid/gridAgent.ts +++ b/packages/playwright-core/src/grid/gridAgent.ts @@ -17,7 +17,7 @@ import { debug } from '../utilsBundle'; import { ws as WebSocket } from '../utilsBundle'; import { fork } from 'child_process'; -import { getPlaywrightVersion } from '../common/userAgent'; +import { getPlaywrightVersion } from '../utils/userAgent'; export function launchGridAgent(agentId: string, gridURL: string, runId: string | undefined) { const log = debug(`pw:grid:agent:${agentId}`); diff --git a/packages/playwright-core/src/grid/gridServer.ts b/packages/playwright-core/src/grid/gridServer.ts index 22e1790836..22ab7d0d5b 100644 --- a/packages/playwright-core/src/grid/gridServer.ts +++ b/packages/playwright-core/src/grid/gridServer.ts @@ -20,7 +20,7 @@ import { URL } from 'url'; import type { WebSocketServer, WebSocket, WebSocketRawData } from '../utilsBundle'; import { HttpServer } from '../utils/httpServer'; import { assert, createGuid } from '../utils'; -import { getPlaywrightVersion } from '../common/userAgent'; +import { getPlaywrightVersion } from '../utils/userAgent'; const defaultOS = 'linux'; diff --git a/packages/playwright-core/src/server/chromium/chromium.ts b/packages/playwright-core/src/server/chromium/chromium.ts index 7e2b24458c..8aa3d8edec 100644 --- a/packages/playwright-core/src/server/chromium/chromium.ts +++ b/packages/playwright-core/src/server/chromium/chromium.ts @@ -18,6 +18,7 @@ import fs from 'fs'; import os from 'os'; import path from 'path'; +import type stream from 'stream'; import { CRBrowser } from './crBrowser'; import type { Env } from '../../utils/processLauncher'; import { gracefullyCloseSet } from '../../utils/processLauncher'; @@ -31,11 +32,12 @@ import type { BrowserOptions, BrowserProcess, PlaywrightOptions } from '../brows import { Browser } from '../browser'; import type * as types from '../types'; import type * as channels from '@protocol/channels'; -import type { HTTPRequestParams } from '../../common/netUtils'; -import { NET_DEFAULT_TIMEOUT } from '../../common/netUtils'; -import { fetchData } from '../../common/netUtils'; -import { getUserAgent } from '../../common/userAgent'; -import { debugMode, headersArrayToObject, streamToString, wrapInASCIIBox } from '../../utils'; +import type { HTTPRequestParams } from '../../utils/network'; +import { NET_DEFAULT_TIMEOUT } from '../../utils/network'; +import { fetchData } from '../../utils/network'; +import { getUserAgent } from '../../utils/userAgent'; +import { wrapInASCIIBox } from '../../utils/ascii'; +import { debugMode, headersArrayToObject, } from '../../utils'; import { removeFolders } from '../../utils/fileUtils'; import { RecentLogsCollector } from '../../common/debugLogger'; import type { Progress } from '../progress'; @@ -364,3 +366,12 @@ function addProtocol(url: string) { return 'http://' + url; return url; } + +function streamToString(stream: stream.Readable): Promise { + return new Promise((resolve, reject) => { + const chunks: Buffer[] = []; + stream.on('data', chunk => chunks.push(Buffer.from(chunk))); + stream.on('error', reject); + stream.on('end', () => resolve(Buffer.concat(chunks).toString('utf8'))); + }); +} diff --git a/packages/playwright-core/src/server/dispatchers/localUtilsDispatcher.ts b/packages/playwright-core/src/server/dispatchers/localUtilsDispatcher.ts index 3979847247..c61f7c3837 100644 --- a/packages/playwright-core/src/server/dispatchers/localUtilsDispatcher.ts +++ b/packages/playwright-core/src/server/dispatchers/localUtilsDispatcher.ts @@ -30,11 +30,11 @@ import { JsonPipeDispatcher } from '../dispatchers/jsonPipeDispatcher'; import { WebSocketTransport } from '../transport'; import { SocksInterceptor } from '../socksInterceptor'; import type { CallMetadata } from '../instrumentation'; -import { getUserAgent } from '../../common/userAgent'; +import { getUserAgent } from '../../utils/userAgent'; import type { Progress } from '../progress'; import { ProgressController } from '../progress'; -import { fetchData } from '../../common/netUtils'; -import type { HTTPRequestParams } from '../../common/netUtils'; +import { fetchData } from '../../utils/network'; +import type { HTTPRequestParams } from '../../utils/network'; import type http from 'http'; import type { Playwright } from '../playwright'; import { SdkObject } from '../../server/instrumentation'; diff --git a/packages/playwright-core/src/server/fetch.ts b/packages/playwright-core/src/server/fetch.ts index 1bda7e2e44..ae04287919 100644 --- a/packages/playwright-core/src/server/fetch.ts +++ b/packages/playwright-core/src/server/fetch.ts @@ -24,7 +24,7 @@ import url from 'url'; import zlib from 'zlib'; import type { HTTPCredentials } from '../../types/types'; import { TimeoutSettings } from '../common/timeoutSettings'; -import { getUserAgent } from '../common/userAgent'; +import { getUserAgent } from '../utils/userAgent'; import { assert, createGuid, monotonicTime } from '../utils'; import { HttpsProxyAgent, SocksProxyAgent } from '../utilsBundle'; import { BrowserContext } from './browserContext'; diff --git a/packages/playwright-core/src/server/har/harTracer.ts b/packages/playwright-core/src/server/har/harTracer.ts index a57d27e0df..60a44ddf65 100644 --- a/packages/playwright-core/src/server/har/harTracer.ts +++ b/packages/playwright-core/src/server/har/harTracer.ts @@ -27,8 +27,8 @@ import type { RegisteredListener } from '../../utils/eventsHelper'; import { eventsHelper } from '../../utils/eventsHelper'; import { mime } from '../../utilsBundle'; import { ManualPromise } from '../../utils/manualPromise'; -import { getPlaywrightVersion } from '../../common/userAgent'; -import { urlMatches } from '../../common/netUtils'; +import { getPlaywrightVersion } from '../../utils/userAgent'; +import { urlMatches } from '../../utils/network'; import { Frame } from '../frames'; import type { HeadersArray, LifecycleEvent } from '../types'; import { isTextualMimeType } from '../../utils/mimeType'; diff --git a/packages/playwright-core/src/server/registry/browserFetcher.ts b/packages/playwright-core/src/server/registry/browserFetcher.ts index 89aa058547..5ab80f472c 100644 --- a/packages/playwright-core/src/server/registry/browserFetcher.ts +++ b/packages/playwright-core/src/server/registry/browserFetcher.ts @@ -19,7 +19,7 @@ import fs from 'fs'; import os from 'os'; import path from 'path'; import childProcess from 'child_process'; -import { getUserAgent } from '../../common/userAgent'; +import { getUserAgent } from '../../utils/userAgent'; import { existsAsync } from '../../utils/fileUtils'; import { debugLogger } from '../../common/debugLogger'; import { extract } from '../../zipBundle'; diff --git a/packages/playwright-core/src/server/registry/dependencies.ts b/packages/playwright-core/src/server/registry/dependencies.ts index 28d534c96b..9fabe13e8d 100644 --- a/packages/playwright-core/src/server/registry/dependencies.ts +++ b/packages/playwright-core/src/server/registry/dependencies.ts @@ -23,7 +23,7 @@ import { spawnAsync } from '../../utils/spawnAsync'; import { hostPlatform } from '../../utils/hostPlatform'; import { buildPlaywrightCLICommand } from '.'; import { deps } from './nativeDeps'; -import { getPlaywrightVersion } from '../../common/userAgent'; +import { getPlaywrightVersion } from '../../utils/userAgent'; const BIN_DIRECTORY = path.join(__dirname, '..', '..', '..', 'bin'); const languageBindingVersion = process.env.PW_CLI_DISPLAY_VERSION || require('../../../package.json').version; diff --git a/packages/playwright-core/src/server/registry/index.ts b/packages/playwright-core/src/server/registry/index.ts index 52d2eeff04..d9ddd89445 100644 --- a/packages/playwright-core/src/server/registry/index.ts +++ b/packages/playwright-core/src/server/registry/index.ts @@ -21,8 +21,8 @@ import * as util from 'util'; import * as fs from 'fs'; import { lockfile } from '../../utilsBundle'; import { getLinuxDistributionInfo } from '../../utils/linuxUtils'; -import { fetchData } from '../../common/netUtils'; -import { getEmbedderName } from '../../common/userAgent'; +import { fetchData } from '../../utils/network'; +import { getEmbedderName } from '../../utils/userAgent'; import { getFromENV, getAsBooleanFromENV, calculateSha1, wrapInASCIIBox } from '../../utils'; import { removeFolders, existsAsync, canAccessFile } from '../../utils/fileUtils'; import { hostPlatform } from '../../utils/hostPlatform'; diff --git a/packages/playwright-core/src/server/registry/oopDownloadMain.ts b/packages/playwright-core/src/server/registry/oopDownloadMain.ts index ee91819b27..290e8de70a 100644 --- a/packages/playwright-core/src/server/registry/oopDownloadMain.ts +++ b/packages/playwright-core/src/server/registry/oopDownloadMain.ts @@ -16,7 +16,7 @@ import fs from 'fs'; import { progress as ProgressBar } from '../../utilsBundle'; -import { httpRequest } from '../../common/netUtils'; +import { httpRequest } from '../../utils/network'; import { ManualPromise } from '../../utils/manualPromise'; type OnProgressCallback = (downloadedBytes: number, totalBytes: number) => void; diff --git a/packages/playwright-core/src/utils/ascii.ts b/packages/playwright-core/src/utils/ascii.ts new file mode 100644 index 0000000000..91291ec18a --- /dev/null +++ b/packages/playwright-core/src/utils/ascii.ts @@ -0,0 +1,25 @@ +/** + * 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 wrapInASCIIBox(text: string, padding = 0): string { + const lines = text.split('\n'); + const maxLength = Math.max(...lines.map(line => line.length)); + return [ + '╔' + '═'.repeat(maxLength + padding * 2) + '╗', + ...lines.map(line => '║' + ' '.repeat(padding) + line + ' '.repeat(maxLength - line.length + padding) + '║'), + '╚' + '═'.repeat(maxLength + padding * 2) + '╝', + ].join('\n'); +} diff --git a/packages/playwright-core/src/utils/crypto.ts b/packages/playwright-core/src/utils/crypto.ts new file mode 100644 index 0000000000..f3e47f6993 --- /dev/null +++ b/packages/playwright-core/src/utils/crypto.ts @@ -0,0 +1,27 @@ +/** + * 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 crypto from 'crypto'; + +export function createGuid(): string { + return crypto.randomBytes(16).toString('hex'); +} + +export function calculateSha1(buffer: Buffer | string): string { + const hash = crypto.createHash('sha1'); + hash.update(buffer); + return hash.digest('hex'); +} diff --git a/packages/playwright-core/src/utils/debug.ts b/packages/playwright-core/src/utils/debug.ts new file mode 100644 index 0000000000..e8a3a44060 --- /dev/null +++ b/packages/playwright-core/src/utils/debug.ts @@ -0,0 +1,45 @@ +/** + * 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 { getFromENV } from './env'; + +export function assert(value: any, message?: string): asserts value { + if (!value) + throw new Error(message || 'Assertion error'); +} + +export function debugAssert(value: any, message?: string): asserts value { + if (isUnderTest() && !value) + throw new Error(message); +} + +const debugEnv = getFromENV('PWDEBUG') || ''; +export function debugMode() { + if (debugEnv === 'console') + return 'console'; + if (debugEnv === '0' || debugEnv === 'false') + return ''; + return debugEnv ? 'inspector' : ''; +} + +let _isUnderTest = false; +export function setUnderTest() { + _isUnderTest = true; +} + +export function isUnderTest(): boolean { + return _isUnderTest; +} diff --git a/packages/playwright-core/src/utils/env.ts b/packages/playwright-core/src/utils/env.ts new file mode 100644 index 0000000000..d9a553896b --- /dev/null +++ b/packages/playwright-core/src/utils/env.ts @@ -0,0 +1,27 @@ +/** + * 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 getFromENV(name: string): string | undefined { + let value = process.env[name]; + value = value === undefined ? process.env[`npm_config_${name.toLowerCase()}`] : value; + value = value === undefined ? process.env[`npm_package_config_${name.toLowerCase()}`] : value; + return value; +} + +export function getAsBooleanFromENV(name: string): boolean { + const value = getFromENV(name); + return !!value && value !== 'false' && value !== '0'; +} diff --git a/packages/playwright-core/src/utils/glob.ts b/packages/playwright-core/src/utils/glob.ts new file mode 100644 index 0000000000..37fd223204 --- /dev/null +++ b/packages/playwright-core/src/utils/glob.ts @@ -0,0 +1,73 @@ +/** + * 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. + */ + +const escapeGlobChars = new Set(['/', '$', '^', '+', '.', '(', ')', '=', '!', '|']); + +export function globToRegex(glob: string): RegExp { + const tokens = ['^']; + let inGroup; + for (let i = 0; i < glob.length; ++i) { + const c = glob[i]; + if (escapeGlobChars.has(c)) { + tokens.push('\\' + c); + continue; + } + if (c === '*') { + const beforeDeep = glob[i - 1]; + let starCount = 1; + while (glob[i + 1] === '*') { + starCount++; + i++; + } + const afterDeep = glob[i + 1]; + const isDeep = starCount > 1 && + (beforeDeep === '/' || beforeDeep === undefined) && + (afterDeep === '/' || afterDeep === undefined); + if (isDeep) { + tokens.push('((?:[^/]*(?:\/|$))*)'); + i++; + } else { + tokens.push('([^/]*)'); + } + continue; + } + + switch (c) { + case '?': + tokens.push('.'); + break; + case '{': + inGroup = true; + tokens.push('('); + break; + case '}': + inGroup = false; + tokens.push(')'); + break; + case ',': + if (inGroup) { + tokens.push('|'); + break; + } + tokens.push('\\' + c); + break; + default: + tokens.push(c); + } + } + tokens.push('$'); + return new RegExp(tokens.join('')); +} diff --git a/packages/playwright-core/src/utils/headers.ts b/packages/playwright-core/src/utils/headers.ts new file mode 100644 index 0000000000..e228e5312f --- /dev/null +++ b/packages/playwright-core/src/utils/headers.ts @@ -0,0 +1,44 @@ +/** + * 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. + */ + +type HeadersArray = { name: string, value: string }[]; +type HeadersObject = { [key: string]: string }; + +export function headersObjectToArray(headers: HeadersObject, separator?: string, setCookieSeparator?: string): HeadersArray { + if (!setCookieSeparator) + setCookieSeparator = separator; + const result: HeadersArray = []; + for (const name in headers) { + const values = headers[name]; + if (values === undefined) + continue; + if (separator) { + const sep = name.toLowerCase() === 'set-cookie' ? setCookieSeparator : separator; + for (const value of values.split(sep!)) + result.push({ name, value: value.trim() }); + } else { + result.push({ name, value: values }); + } + } + return result; +} + +export function headersArrayToObject(headers: HeadersArray, lowerCase: boolean): HeadersObject { + const result: HeadersObject = {}; + for (const { name, value } of headers) + result[lowerCase ? name.toLowerCase() : name] = value; + return result; +} diff --git a/packages/playwright-core/src/utils/index.ts b/packages/playwright-core/src/utils/index.ts index a84512a92d..62d3049de7 100644 --- a/packages/playwright-core/src/utils/index.ts +++ b/packages/playwright-core/src/utils/index.ts @@ -14,206 +14,25 @@ * limitations under the License. */ -import * as crypto from 'crypto'; -import type stream from 'stream'; -import * as URL from 'url'; -import v8 from 'v8'; - -type NameValue = { - name: string, - value: string, -}; - -// See https://joel.tools/microtasks/ -export function makeWaitForNextTask() { - // As of Mar 2021, Electron v12 doesn't create new task with `setImmediate` despite - // using Node 14 internally, so we fallback to `setTimeout(0)` instead. - // @see https://github.com/electron/electron/issues/28261 - if ((process.versions as any).electron) - return (callback: () => void) => setTimeout(callback, 0); - if (parseInt(process.versions.node, 10) >= 11) - return setImmediate; - - // Unlike Node 11, Node 10 and less have a bug with Task and MicroTask execution order: - // - https://github.com/nodejs/node/issues/22257 - // - // So we can't simply run setImmediate to dispatch code in a following task. - // However, we can run setImmediate from-inside setImmediate to make sure we're getting - // in the following task. - - let spinning = false; - const callbacks: (() => void)[] = []; - const loop = () => { - const callback = callbacks.shift(); - if (!callback) { - spinning = false; - return; - } - setImmediate(loop); - // Make sure to call callback() as the last thing since it's - // untrusted code that might throw. - callback(); - }; - - return (callback: () => void) => { - callbacks.push(callback); - if (!spinning) { - spinning = true; - setImmediate(loop); - } - }; -} - -export function assert(value: any, message?: string): asserts value { - if (!value) - throw new Error(message || 'Assertion error'); -} - -export function debugAssert(value: any, message?: string): asserts value { - if (isUnderTest() && !value) - throw new Error(message); -} - -export function isString(obj: any): obj is string { - return typeof obj === 'string' || obj instanceof String; -} - -export function isRegExp(obj: any): obj is RegExp { - return obj instanceof RegExp || Object.prototype.toString.call(obj) === '[object RegExp]'; -} - -export function isObject(obj: any): obj is NonNullable { - return typeof obj === 'object' && obj !== null; -} - -export function isError(obj: any): obj is Error { - return obj instanceof Error || (obj && Object.getPrototypeOf(obj)?.name === 'Error'); -} - -const debugEnv = getFromENV('PWDEBUG') || ''; -export function debugMode() { - if (debugEnv === 'console') - return 'console'; - if (debugEnv === '0' || debugEnv === 'false') - return ''; - return debugEnv ? 'inspector' : ''; -} - -let _isUnderTest = false; -export function setUnderTest() { - _isUnderTest = true; -} -export function isUnderTest(): boolean { - return _isUnderTest; -} - -export function getFromENV(name: string): string | undefined { - let value = process.env[name]; - value = value === undefined ? process.env[`npm_config_${name.toLowerCase()}`] : value; - value = value === undefined ? process.env[`npm_package_config_${name.toLowerCase()}`] : value; - return value; -} - -export function getAsBooleanFromENV(name: string): boolean { - const value = getFromENV(name); - return !!value && value !== 'false' && value !== '0'; -} - -type HeadersArray = { name: string, value: string }[]; -type HeadersObject = { [key: string]: string }; - -export function headersObjectToArray(headers: HeadersObject, separator?: string, setCookieSeparator?: string): HeadersArray { - if (!setCookieSeparator) - setCookieSeparator = separator; - const result: HeadersArray = []; - for (const name in headers) { - const values = headers[name]; - if (values === undefined) - continue; - if (separator) { - const sep = name.toLowerCase() === 'set-cookie' ? setCookieSeparator : separator; - for (const value of values.split(sep!)) - result.push({ name, value: value.trim() }); - } else { - result.push({ name, value: values }); - } - } - return result; -} - -export function headersArrayToObject(headers: HeadersArray, lowerCase: boolean): HeadersObject { - const result: HeadersObject = {}; - for (const { name, value } of headers) - result[lowerCase ? name.toLowerCase() : name] = value; - return result; -} - -export function monotonicTime(): number { - const [seconds, nanoseconds] = process.hrtime(); - return seconds * 1000 + (nanoseconds / 1000 | 0) / 1000; -} - -export function objectToArray(map?: { [key: string]: any }): NameValue[] | undefined { - if (!map) - return undefined; - const result = []; - for (const [name, value] of Object.entries(map)) - result.push({ name, value: String(value) }); - return result; -} - -export function arrayToObject(array?: NameValue[]): { [key: string]: string } | undefined { - if (!array) - return undefined; - const result: { [key: string]: string } = {}; - for (const { name, value } of array) - result[name] = value; - return result; -} - -export function calculateSha1(buffer: Buffer | string): string { - const hash = crypto.createHash('sha1'); - hash.update(buffer); - return hash.digest('hex'); -} - -export function createGuid(): string { - return crypto.randomBytes(16).toString('hex'); -} - -export function constructURLBasedOnBaseURL(baseURL: string | undefined, givenURL: string): string { - try { - return (new URL.URL(givenURL, baseURL)).toString(); - } catch (e) { - return givenURL; - } -} - -export function wrapInASCIIBox(text: string, padding = 0): string { - const lines = text.split('\n'); - const maxLength = Math.max(...lines.map(line => line.length)); - return [ - '╔' + '═'.repeat(maxLength + padding * 2) + '╗', - ...lines.map(line => '║' + ' '.repeat(padding) + line + ' '.repeat(maxLength - line.length + padding) + '║'), - '╚' + '═'.repeat(maxLength + padding * 2) + '╝', - ].join('\n'); -} - -export function isFilePayload(value: any): boolean { - return typeof value === 'object' && value['name'] && value['mimeType'] && value['buffer']; -} - -export function streamToString(stream: stream.Readable): Promise { - return new Promise((resolve, reject) => { - const chunks: Buffer[] = []; - stream.on('data', chunk => chunks.push(Buffer.from(chunk))); - stream.on('error', reject); - stream.on('end', () => resolve(Buffer.concat(chunks).toString('utf8'))); - }); -} - -export const isLikelyNpxGlobal = () => process.argv.length >= 2 && process.argv[1].includes('_npx'); - -export function deepCopy(obj: T): T { - return v8.deserialize(v8.serialize(obj)); -} +export * from './ascii'; +export * from './comparators'; +export * from './crypto'; +export * from './debug'; +export * from './env'; +export * from './fileUtils'; +export * from './glob'; +export * from './headers'; +export * from './httpServer'; +export * from './manualPromise'; +export * from './mimeType'; +export * from './multimap'; +export * from './network'; +export * from './processLauncher'; +export * from './rtti'; +export * from './spawnAsync'; +export * from './stackTrace'; +export * from './task'; +export * from './time'; +export * from './timeoutRunner'; +export * from './userAgent'; +export * from './zipFile'; diff --git a/packages/playwright-core/src/common/netUtils.ts b/packages/playwright-core/src/utils/network.ts similarity index 75% rename from packages/playwright-core/src/common/netUtils.ts rename to packages/playwright-core/src/utils/network.ts index 4092ab1385..1bb8ede297 100644 --- a/packages/playwright-core/src/common/netUtils.ts +++ b/packages/playwright-core/src/utils/network.ts @@ -14,14 +14,16 @@ * limitations under the License. */ + import http from 'http'; import https from 'https'; import net from 'net'; import { getProxyForUrl } from '../utilsBundle'; import { HttpsProxyAgent } from '../utilsBundle'; import * as URL from 'url'; -import type { URLMatch } from './types'; -import { isString, constructURLBasedOnBaseURL, isRegExp } from '../utils'; +import type { URLMatch } from '../common/types'; +import { isString, isRegExp } from './rtti'; +import { globToRegex } from './glob'; export async function createSocket(host: string, port: number): Promise { return new Promise((resolve, reject) => { @@ -137,61 +139,10 @@ function parsedURL(url: string): URL | null { } } -const escapeGlobChars = new Set(['/', '$', '^', '+', '.', '(', ')', '=', '!', '|']); - -// Note: this function is exported so it can be unit-tested. -export function globToRegex(glob: string): RegExp { - const tokens = ['^']; - let inGroup; - for (let i = 0; i < glob.length; ++i) { - const c = glob[i]; - if (escapeGlobChars.has(c)) { - tokens.push('\\' + c); - continue; - } - if (c === '*') { - const beforeDeep = glob[i - 1]; - let starCount = 1; - while (glob[i + 1] === '*') { - starCount++; - i++; - } - const afterDeep = glob[i + 1]; - const isDeep = starCount > 1 && - (beforeDeep === '/' || beforeDeep === undefined) && - (afterDeep === '/' || afterDeep === undefined); - if (isDeep) { - tokens.push('((?:[^/]*(?:\/|$))*)'); - i++; - } else { - tokens.push('([^/]*)'); - } - continue; - } - - switch (c) { - case '?': - tokens.push('.'); - break; - case '{': - inGroup = true; - tokens.push('('); - break; - case '}': - inGroup = false; - tokens.push(')'); - break; - case ',': - if (inGroup) { - tokens.push('|'); - break; - } - tokens.push('\\' + c); - break; - default: - tokens.push(c); - } +export function constructURLBasedOnBaseURL(baseURL: string | undefined, givenURL: string): string { + try { + return (new URL.URL(givenURL, baseURL)).toString(); + } catch (e) { + return givenURL; } - tokens.push('$'); - return new RegExp(tokens.join('')); } diff --git a/packages/playwright-core/src/utils/rtti.ts b/packages/playwright-core/src/utils/rtti.ts new file mode 100644 index 0000000000..f096ae8ee4 --- /dev/null +++ b/packages/playwright-core/src/utils/rtti.ts @@ -0,0 +1,33 @@ +/** + * 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 isString(obj: any): obj is string { + return typeof obj === 'string' || obj instanceof String; +} + +export function isRegExp(obj: any): obj is RegExp { + return obj instanceof RegExp || Object.prototype.toString.call(obj) === '[object RegExp]'; +} + +export function isObject(obj: any): obj is NonNullable { + return typeof obj === 'object' && obj !== null; +} + +export function isError(obj: any): obj is Error { + return obj instanceof Error || (obj && Object.getPrototypeOf(obj)?.name === 'Error'); +} + +export const isLikelyNpxGlobal = () => process.argv.length >= 2 && process.argv[1].includes('_npx'); diff --git a/packages/playwright-core/src/utils/task.ts b/packages/playwright-core/src/utils/task.ts new file mode 100644 index 0000000000..b00e9f1000 --- /dev/null +++ b/packages/playwright-core/src/utils/task.ts @@ -0,0 +1,55 @@ +/** + * 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. + */ + +// See https://joel.tools/microtasks/ +export function makeWaitForNextTask() { + // As of Mar 2021, Electron v12 doesn't create new task with `setImmediate` despite + // using Node 14 internally, so we fallback to `setTimeout(0)` instead. + // @see https://github.com/electron/electron/issues/28261 + if ((process.versions as any).electron) + return (callback: () => void) => setTimeout(callback, 0); + if (parseInt(process.versions.node, 10) >= 11) + return setImmediate; + + // Unlike Node 11, Node 10 and less have a bug with Task and MicroTask execution order: + // - https://github.com/nodejs/node/issues/22257 + // + // So we can't simply run setImmediate to dispatch code in a following task. + // However, we can run setImmediate from-inside setImmediate to make sure we're getting + // in the following task. + + let spinning = false; + const callbacks: (() => void)[] = []; + const loop = () => { + const callback = callbacks.shift(); + if (!callback) { + spinning = false; + return; + } + setImmediate(loop); + // Make sure to call callback() as the last thing since it's + // untrusted code that might throw. + callback(); + }; + + return (callback: () => void) => { + callbacks.push(callback); + if (!spinning) { + spinning = true; + setImmediate(loop); + } + }; +} diff --git a/packages/playwright-core/src/utils/time.ts b/packages/playwright-core/src/utils/time.ts new file mode 100644 index 0000000000..9f0aba31a9 --- /dev/null +++ b/packages/playwright-core/src/utils/time.ts @@ -0,0 +1,20 @@ +/** + * 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 { + const [seconds, nanoseconds] = process.hrtime(); + return seconds * 1000 + (nanoseconds / 1000 | 0) / 1000; +} diff --git a/packages/playwright-core/src/common/userAgent.ts b/packages/playwright-core/src/utils/userAgent.ts similarity index 100% rename from packages/playwright-core/src/common/userAgent.ts rename to packages/playwright-core/src/utils/userAgent.ts diff --git a/packages/playwright-test/src/dispatcher.ts b/packages/playwright-test/src/dispatcher.ts index 6f10231c25..6cb3f7bd28 100644 --- a/packages/playwright-test/src/dispatcher.ts +++ b/packages/playwright-test/src/dispatcher.ts @@ -22,7 +22,7 @@ import type { TestResult, Reporter, TestStep, TestError } from '../types/testRep import type { Suite } from './test'; import type { Loader } from './loader'; import { TestCase } from './test'; -import { ManualPromise } from 'playwright-core/lib/utils/manualPromise'; +import { ManualPromise } from 'playwright-core/lib/utils'; import { TestTypeImpl } from './testType'; export type TestGroup = { diff --git a/packages/playwright-test/src/expect.ts b/packages/playwright-test/src/expect.ts index 2a553d65ea..cd0a6405a1 100644 --- a/packages/playwright-test/src/expect.ts +++ b/packages/playwright-test/src/expect.ts @@ -14,7 +14,7 @@ * limitations under the License. */ -import { pollAgainstTimeout } from 'playwright-core/lib/utils/timeoutRunner'; +import { pollAgainstTimeout } from 'playwright-core/lib/utils'; import path from 'path'; import { toBeChecked, diff --git a/packages/playwright-test/src/fixtures.ts b/packages/playwright-test/src/fixtures.ts index 0fa43c3900..402d64f347 100644 --- a/packages/playwright-test/src/fixtures.ts +++ b/packages/playwright-test/src/fixtures.ts @@ -17,7 +17,7 @@ import { formatLocation, debugTest } from './util'; import * as crypto from 'crypto'; import type { FixturesWithLocation, Location, WorkerInfo } from './types'; -import { ManualPromise } from 'playwright-core/lib/utils/manualPromise'; +import { ManualPromise } from 'playwright-core/lib/utils'; import type { TestInfoImpl } from './testInfo'; import type { FixtureDescription, TimeoutManager } from './timeoutManager'; import { addFatalError } from './globals'; diff --git a/packages/playwright-test/src/index.ts b/packages/playwright-test/src/index.ts index c9d72a10cc..4f892f7365 100644 --- a/packages/playwright-test/src/index.ts +++ b/packages/playwright-test/src/index.ts @@ -18,8 +18,7 @@ import * as fs from 'fs'; import * as path from 'path'; import type { APIRequestContext, BrowserContext, BrowserContextOptions, LaunchOptions, Page, Tracing, Video } from 'playwright-core'; import * as playwrightLibrary from 'playwright-core'; -import { createGuid, debugMode } from 'playwright-core/lib/utils'; -import { removeFolders } from 'playwright-core/lib/utils/fileUtils'; +import { createGuid, debugMode, removeFolders } from 'playwright-core/lib/utils'; import type { Fixtures, PlaywrightTestArgs, PlaywrightTestOptions, PlaywrightWorkerArgs, PlaywrightWorkerOptions, ScreenshotMode, TestInfo, TestType, TraceMode, VideoMode } from '../types/test'; import { store as _baseStore } from './store'; import type { TestInfoImpl } from './testInfo'; diff --git a/packages/playwright-test/src/matchers/matchers.ts b/packages/playwright-test/src/matchers/matchers.ts index b6884cc2c6..c61802caff 100644 --- a/packages/playwright-test/src/matchers/matchers.ts +++ b/packages/playwright-test/src/matchers/matchers.ts @@ -17,15 +17,13 @@ import type { Locator, Page, APIResponse } from 'playwright-core'; import type { FrameExpectOptions } from 'playwright-core/lib/client/types'; import { colors } from 'playwright-core/lib/utilsBundle'; -import { constructURLBasedOnBaseURL } from 'playwright-core/lib/utils'; import type { Expect } from '../types'; import { expectTypes, callLogText } from '../util'; import { toBeTruthy } from './toBeTruthy'; import { toEqual } from './toEqual'; import { toExpectedTextValues, toMatchText } from './toMatchText'; -import type { ParsedStackTrace } from 'playwright-core/lib/utils/stackTrace'; -import { isTextualMimeType } from 'playwright-core/lib/utils/mimeType'; -import { pollAgainstTimeout } from 'playwright-core/lib/utils/timeoutRunner'; +import type { ParsedStackTrace } from 'playwright-core/lib/utils'; +import { constructURLBasedOnBaseURL, isTextualMimeType, pollAgainstTimeout } from 'playwright-core/lib/utils'; interface LocatorEx extends Locator { _expect(customStackTrace: ParsedStackTrace, expression: string, options: Omit & { expectedValue?: any }): Promise<{ matches: boolean, received?: any, log?: string[], timedOut?: boolean }>; diff --git a/packages/playwright-test/src/matchers/toEqual.ts b/packages/playwright-test/src/matchers/toEqual.ts index c0b1c50630..8cf522396c 100644 --- a/packages/playwright-test/src/matchers/toEqual.ts +++ b/packages/playwright-test/src/matchers/toEqual.ts @@ -17,8 +17,8 @@ import type { Expect } from '../types'; import { expectTypes } from '../util'; import { callLogText, currentExpectTimeout } from '../util'; -import type { ParsedStackTrace } from 'playwright-core/lib/utils/stackTrace'; -import { captureStackTrace } from 'playwright-core/lib/utils/stackTrace'; +import type { ParsedStackTrace } from 'playwright-core/lib/utils'; +import { captureStackTrace } from 'playwright-core/lib/utils'; import { matcherHint } from './matcherHint'; // Omit colon and one or more spaces, so can call getLabelPrinter. diff --git a/packages/playwright-test/src/matchers/toMatchSnapshot.ts b/packages/playwright-test/src/matchers/toMatchSnapshot.ts index 2e083cc259..c8c3fb7593 100644 --- a/packages/playwright-test/src/matchers/toMatchSnapshot.ts +++ b/packages/playwright-test/src/matchers/toMatchSnapshot.ts @@ -19,8 +19,8 @@ import type { Page as PageEx } from 'playwright-core/lib/client/page'; import type { Locator as LocatorEx } from 'playwright-core/lib/client/locator'; import type { Expect } from '../types'; import { currentTestInfo } from '../globals'; -import type { ImageComparatorOptions, Comparator } from 'playwright-core/lib/utils/comparators'; -import { getComparator } from 'playwright-core/lib/utils/comparators'; +import type { ImageComparatorOptions, Comparator } from 'playwright-core/lib/utils'; +import { getComparator } from 'playwright-core/lib/utils'; import type { PageScreenshotOptions } from 'playwright-core/types/types'; import { addSuffixToFilePath, serializeError, sanitizeForFilePath, diff --git a/packages/playwright-test/src/plugins/gitCommitInfoPlugin.ts b/packages/playwright-test/src/plugins/gitCommitInfoPlugin.ts index 2c0aacf09f..4c55a3eab3 100644 --- a/packages/playwright-test/src/plugins/gitCommitInfoPlugin.ts +++ b/packages/playwright-test/src/plugins/gitCommitInfoPlugin.ts @@ -14,8 +14,7 @@ * limitations under the License. */ -import { createGuid } from 'playwright-core/lib/utils'; -import { spawnAsync } from 'playwright-core/lib/utils/spawnAsync'; +import { createGuid, spawnAsync } from 'playwright-core/lib/utils'; import type { TestRunnerPlugin } from './'; import type { FullConfig } from '../../types/testReporter'; diff --git a/packages/playwright-test/src/plugins/vitePlugin.ts b/packages/playwright-test/src/plugins/vitePlugin.ts index 08800fa9b6..8ab189c24e 100644 --- a/packages/playwright-test/src/plugins/vitePlugin.ts +++ b/packages/playwright-test/src/plugins/vitePlugin.ts @@ -26,7 +26,7 @@ import { collectComponentUsages, componentInfo } from '../tsxTransform'; import type { FullConfig } from '../types'; import { assert, calculateSha1 } from 'playwright-core/lib/utils'; import type { AddressInfo } from 'net'; -import { getPlaywrightVersion } from 'playwright-core/lib/common/userAgent'; +import { getPlaywrightVersion } from 'playwright-core/lib/utils'; import type { PlaywrightTestConfig as BasePlaywrightTestConfig } from '@playwright/test'; let stoppableServer: any; diff --git a/packages/playwright-test/src/plugins/webServerPlugin.ts b/packages/playwright-test/src/plugins/webServerPlugin.ts index 6a3f5b5b97..c2ee57c669 100644 --- a/packages/playwright-test/src/plugins/webServerPlugin.ts +++ b/packages/playwright-test/src/plugins/webServerPlugin.ts @@ -19,8 +19,7 @@ import path from 'path'; import net from 'net'; import { debug } from 'playwright-core/lib/utilsBundle'; -import { raceAgainstTimeout } from 'playwright-core/lib/utils/timeoutRunner'; -import { launchProcess } from 'playwright-core/lib/utils/processLauncher'; +import { raceAgainstTimeout, launchProcess } from 'playwright-core/lib/utils'; import type { FullConfig, Reporter, Suite } from '../../types/testReporter'; import type { TestRunnerPlugin } from '.'; diff --git a/packages/playwright-test/src/reporters/html.ts b/packages/playwright-test/src/reporters/html.ts index 8c2ef35fa5..c800bc22ad 100644 --- a/packages/playwright-test/src/reporters/html.ts +++ b/packages/playwright-test/src/reporters/html.ts @@ -21,9 +21,7 @@ import path from 'path'; import type { TransformCallback } from 'stream'; import { Transform } from 'stream'; import type { FullConfig, Suite } from '../../types/testReporter'; -import { HttpServer } from 'playwright-core/lib/utils/httpServer'; -import { assert, calculateSha1, monotonicTime } from 'playwright-core/lib/utils'; -import { copyFileAndMakeWritable, removeFolders } from 'playwright-core/lib/utils/fileUtils'; +import { HttpServer, assert, calculateSha1, monotonicTime, copyFileAndMakeWritable, removeFolders } from 'playwright-core/lib/utils'; import type { JsonAttachment, JsonReport, JsonSuite, JsonTestCase, JsonTestResult, JsonTestStep } from './raw'; import RawReporter from './raw'; import { stripAnsiEscapes } from './base'; diff --git a/packages/playwright-test/src/reporters/json.ts b/packages/playwright-test/src/reporters/json.ts index 1ad9ac33c1..6f7cb71322 100644 --- a/packages/playwright-test/src/reporters/json.ts +++ b/packages/playwright-test/src/reporters/json.ts @@ -18,7 +18,7 @@ import fs from 'fs'; import path from 'path'; import type { FullConfig, TestCase, Suite, TestResult, TestError, TestStep, FullResult, Location, Reporter, JSONReport, JSONReportSuite, JSONReportSpec, JSONReportTest, JSONReportTestResult, JSONReportTestStep, JSONReportError } from '../../types/testReporter'; import { formatError, prepareErrorStack } from './base'; -import { MultiMap } from 'playwright-core/lib/utils/multimap'; +import { MultiMap } from 'playwright-core/lib/utils'; import { assert } from 'playwright-core/lib/utils'; export function toPosixPath(aPath: string): string { diff --git a/packages/playwright-test/src/reporters/raw.ts b/packages/playwright-test/src/reporters/raw.ts index 4c320c3160..7ecbd193db 100644 --- a/packages/playwright-test/src/reporters/raw.ts +++ b/packages/playwright-test/src/reporters/raw.ts @@ -21,7 +21,7 @@ import { assert } from 'playwright-core/lib/utils'; import { sanitizeForFilePath } from '../util'; import { formatResultFailure } from './base'; import { toPosixPath, serializePatterns } from './json'; -import { MultiMap } from 'playwright-core/lib/utils/multimap'; +import { MultiMap } from 'playwright-core/lib/utils'; import { codeFrameColumns } from '../babelBundle'; import type { Metadata } from '../types'; diff --git a/packages/playwright-test/src/runner.ts b/packages/playwright-test/src/runner.ts index 0c91dd6830..3d6597cb1e 100644 --- a/packages/playwright-test/src/runner.ts +++ b/packages/playwright-test/src/runner.ts @@ -17,7 +17,7 @@ import * as fs from 'fs'; import * as path from 'path'; -import { raceAgainstTimeout } from 'playwright-core/lib/utils/timeoutRunner'; +import { raceAgainstTimeout } from 'playwright-core/lib/utils'; import { colors, minimatch, rimraf } from 'playwright-core/lib/utilsBundle'; import { promisify } from 'util'; import type { FullResult, Reporter, TestError } from '../types/testReporter'; diff --git a/packages/playwright-test/src/timeoutManager.ts b/packages/playwright-test/src/timeoutManager.ts index 4ca41b61e1..9fe8a149ed 100644 --- a/packages/playwright-test/src/timeoutManager.ts +++ b/packages/playwright-test/src/timeoutManager.ts @@ -15,7 +15,7 @@ */ import { colors } from 'playwright-core/lib/utilsBundle'; -import { TimeoutRunner, TimeoutRunnerError } from 'playwright-core/lib/utils/timeoutRunner'; +import { TimeoutRunner, TimeoutRunnerError } from 'playwright-core/lib/utils'; import type { Location, TestInfoError } from './types'; export type TimeSlot = { diff --git a/packages/playwright-test/src/util.ts b/packages/playwright-test/src/util.ts index ff4aac5370..9a59bcc28b 100644 --- a/packages/playwright-test/src/util.ts +++ b/packages/playwright-test/src/util.ts @@ -21,11 +21,10 @@ import path from 'path'; import url from 'url'; import { colors, debug, minimatch } from 'playwright-core/lib/utilsBundle'; import type { TestInfoError, Location } from './types'; -import { calculateSha1, isRegExp, isString } from 'playwright-core/lib/utils'; -import { isInternalFileName } from 'playwright-core/lib/utils/stackTrace'; +import { calculateSha1, isRegExp, isString, captureStackTrace as coreCaptureStackTrace } from 'playwright-core/lib/utils'; +import { isInternalFileName } from 'playwright-core/lib/utils'; import { currentTestInfo } from './globals'; -import type { ParsedStackTrace } from 'playwright-core/lib/utils/stackTrace'; -import { captureStackTrace as coreCaptureStackTrace } from 'playwright-core/lib/utils/stackTrace'; +import type { ParsedStackTrace } from 'playwright-core/lib/utils'; export type { ParsedStackTrace }; diff --git a/packages/playwright-test/src/workerRunner.ts b/packages/playwright-test/src/workerRunner.ts index 9793776858..5c9bbf68fd 100644 --- a/packages/playwright-test/src/workerRunner.ts +++ b/packages/playwright-test/src/workerRunner.ts @@ -24,7 +24,7 @@ import { Loader } from './loader'; import type { Suite, TestCase } from './test'; import type { Annotation, FullProjectInternal, TestInfoError } from './types'; import { FixtureRunner } from './fixtures'; -import { ManualPromise } from 'playwright-core/lib/utils/manualPromise'; +import { ManualPromise } from 'playwright-core/lib/utils'; import { TestInfoImpl } from './testInfo'; import type { TimeSlot } from './timeoutManager'; import { TimeoutManager } from './timeoutManager'; diff --git a/tests/config/comparator.ts b/tests/config/comparator.ts index 1308033aa1..4a87bf4bb5 100644 --- a/tests/config/comparator.ts +++ b/tests/config/comparator.ts @@ -14,7 +14,7 @@ * limitations under the License. */ -import { getComparator } from 'playwright-core/lib/utils/comparators'; +import { getComparator } from '../../packages/playwright-core/lib/utils/comparators'; const pngComparator = getComparator('image/png'); type ComparatorResult = { diff?: Buffer; errorMessage: string; } | null; diff --git a/tests/electron/electronTest.ts b/tests/electron/electronTest.ts index b74c153d11..881e245b99 100644 --- a/tests/electron/electronTest.ts +++ b/tests/electron/electronTest.ts @@ -22,7 +22,7 @@ import type { TraceViewerFixtures } from '../config/traceViewerFixtures'; import { traceViewerFixtures } from '../config/traceViewerFixtures'; export { expect } from '@playwright/test'; import e2c from 'electron-to-chromium'; -import { assert } from 'playwright-core/lib/utils'; +import { assert } from '../../packages/playwright-core/lib/utils/debug'; type ElectronTestFixtures = PageTestFixtures & { electronApp: ElectronApplication; diff --git a/tests/installation/globalSetup.ts b/tests/installation/globalSetup.ts index 0518517e65..ce4e753125 100644 --- a/tests/installation/globalSetup.ts +++ b/tests/installation/globalSetup.ts @@ -14,7 +14,7 @@ * limitations under the License. */ import path from 'path'; -import { spawnAsync } from 'playwright-core/lib/utils/spawnAsync'; +import { spawnAsync } from '../../packages/playwright-core/lib/utils/spawnAsync'; import { rimraf } from 'playwright-core/lib/utilsBundle'; import { promisify } from 'util'; import fs from 'fs'; diff --git a/tests/library/browsertype-connect.spec.ts b/tests/library/browsertype-connect.spec.ts index c6ad447409..a5ab14b691 100644 --- a/tests/library/browsertype-connect.spec.ts +++ b/tests/library/browsertype-connect.spec.ts @@ -20,7 +20,7 @@ import os from 'os'; import http from 'http'; import type net from 'net'; import * as path from 'path'; -import { getUserAgent } from '../../packages/playwright-core/lib/common/userAgent'; +import { getUserAgent } from '../../packages/playwright-core/lib/utils/userAgent'; import WebSocket from 'ws'; import { expect, playwrightTest } from '../config/browserTest'; import { parseTrace, suppressCertificateWarning } from '../config/utils'; diff --git a/tests/library/chromium/chromium.spec.ts b/tests/library/chromium/chromium.spec.ts index 13aa59d625..05cd1fee44 100644 --- a/tests/library/chromium/chromium.spec.ts +++ b/tests/library/chromium/chromium.spec.ts @@ -19,7 +19,7 @@ import { contextTest as test, expect } from '../../config/browserTest'; import { playwrightTest } from '../../config/browserTest'; import http from 'http'; import fs from 'fs'; -import { getUserAgent } from '../../../packages/playwright-core/lib/common/userAgent'; +import { getUserAgent } from '../../../packages/playwright-core/lib/utils/userAgent'; import { suppressCertificateWarning } from '../../config/utils'; test('should create a worker from a service worker', async ({ page, server }) => { diff --git a/tests/library/debug-controller.spec.ts b/tests/library/debug-controller.spec.ts index 855709a11a..843e01f1d9 100644 --- a/tests/library/debug-controller.spec.ts +++ b/tests/library/debug-controller.spec.ts @@ -16,7 +16,7 @@ import { expect, playwrightTest as baseTest } from '../config/browserTest'; import { PlaywrightServer } from '../../packages/playwright-core/lib/remote/playwrightServer'; -import { createGuid } from '../../packages/playwright-core/lib/utils'; +import { createGuid } from '../../packages/playwright-core/lib/utils/crypto'; import { Backend } from '../config/debugControllerBackend'; import type { Browser, BrowserContext } from '@playwright/test'; diff --git a/tests/library/global-fetch.spec.ts b/tests/library/global-fetch.spec.ts index cc92df4e8a..194eb773e2 100644 --- a/tests/library/global-fetch.spec.ts +++ b/tests/library/global-fetch.spec.ts @@ -16,7 +16,7 @@ import os from 'os'; import * as util from 'util'; -import { getPlaywrightVersion } from '../../packages/playwright-core/lib/common/userAgent'; +import { getPlaywrightVersion } from '../../packages/playwright-core/lib/utils/userAgent'; import { expect, playwrightTest as it } from '../config/browserTest'; it.skip(({ mode }) => mode !== 'default'); diff --git a/tests/page/interception.spec.ts b/tests/page/interception.spec.ts index 4b0149a540..be58911d1a 100644 --- a/tests/page/interception.spec.ts +++ b/tests/page/interception.spec.ts @@ -16,7 +16,7 @@ */ import { test as it, expect } from './pageTest'; -import { globToRegex } from '../../packages/playwright-core/lib/common/netUtils'; +import { globToRegex } from '../../packages/playwright-core/lib/utils/glob'; import vm from 'vm'; it('should work with navigation @smoke', async ({ page, server }) => { diff --git a/tests/playwright-test/playwright.trace.spec.ts b/tests/playwright-test/playwright.trace.spec.ts index db5255aef6..88fe34b46e 100644 --- a/tests/playwright-test/playwright.trace.spec.ts +++ b/tests/playwright-test/playwright.trace.spec.ts @@ -15,7 +15,7 @@ */ import { test, expect } from './playwright-test-fixtures'; -import { ZipFile } from '../../packages/playwright-core/lib/utils/zipFile'; +import { ZipFile } from '../../packages/playwright-core/lib/utils'; import fs from 'fs'; test('should stop tracing with trace: on-first-retry, when not retrying', async ({ runInlineTest }, testInfo) => { diff --git a/tests/playwright-test/reporter-html.spec.ts b/tests/playwright-test/reporter-html.spec.ts index b2713f8bac..921cb86452 100644 --- a/tests/playwright-test/reporter-html.spec.ts +++ b/tests/playwright-test/reporter-html.spec.ts @@ -18,9 +18,9 @@ import fs from 'fs'; import path from 'path'; import url from 'url'; import { test as baseTest, expect, createImage, stripAnsi } from './playwright-test-fixtures'; -import type { HttpServer } from '../../packages/playwright-core/lib/utils/httpServer'; +import type { HttpServer } from '../../packages/playwright-core/lib/utils'; import { startHtmlReportServer } from '../../packages/playwright-test/lib/reporters/html'; -import { spawnAsync } from 'playwright-core/lib/utils/spawnAsync'; +import { spawnAsync } from 'playwright-core/lib/utils'; const test = baseTest.extend<{ showReport: () => Promise }>({ showReport: async ({ page }, use, testInfo) => { diff --git a/utils/doclint/since.js b/utils/doclint/since.js index b7008c9165..5f97ec5630 100644 --- a/utils/doclint/since.js +++ b/utils/doclint/since.js @@ -1,6 +1,6 @@ const fs = require('fs'); const path = require('path'); -const { ZipFile } = require('../../packages/playwright-core/lib/utils/zipFile'); +const { ZipFile } = require('../../packages/playwright-core/lib/utils'); (async () => { // Extract API.json