Merge branch 'main' into page-snapshot-option
This commit is contained in:
commit
8158c79d44
|
|
@ -1,6 +1,6 @@
|
||||||
# 🎭 Playwright
|
# 🎭 Playwright
|
||||||
|
|
||||||
[](https://www.npmjs.com/package/playwright) <!-- GEN:chromium-version-badge -->[](https://www.chromium.org/Home)<!-- GEN:stop --> <!-- GEN:firefox-version-badge -->[](https://www.mozilla.org/en-US/firefox/new/)<!-- GEN:stop --> <!-- GEN:webkit-version-badge -->[](https://webkit.org/)<!-- GEN:stop --> [](https://aka.ms/playwright/discord)
|
[](https://www.npmjs.com/package/playwright) <!-- GEN:chromium-version-badge -->[](https://www.chromium.org/Home)<!-- GEN:stop --> <!-- GEN:firefox-version-badge -->[](https://www.mozilla.org/en-US/firefox/new/)<!-- GEN:stop --> <!-- GEN:webkit-version-badge -->[](https://webkit.org/)<!-- GEN:stop --> [](https://aka.ms/playwright/discord)
|
||||||
|
|
||||||
## [Documentation](https://playwright.dev) | [API reference](https://playwright.dev/docs/api/class-playwright)
|
## [Documentation](https://playwright.dev) | [API reference](https://playwright.dev/docs/api/class-playwright)
|
||||||
|
|
||||||
|
|
@ -8,9 +8,9 @@ Playwright is a framework for Web Testing and Automation. It allows testing [Chr
|
||||||
|
|
||||||
| | Linux | macOS | Windows |
|
| | Linux | macOS | Windows |
|
||||||
| :--- | :---: | :---: | :---: |
|
| :--- | :---: | :---: | :---: |
|
||||||
| Chromium <!-- GEN:chromium-version -->133.0.6943.35<!-- GEN:stop --> | :white_check_mark: | :white_check_mark: | :white_check_mark: |
|
| Chromium <!-- GEN:chromium-version -->134.0.6998.3<!-- GEN:stop --> | :white_check_mark: | :white_check_mark: | :white_check_mark: |
|
||||||
| WebKit <!-- GEN:webkit-version -->18.2<!-- GEN:stop --> | :white_check_mark: | :white_check_mark: | :white_check_mark: |
|
| WebKit <!-- GEN:webkit-version -->18.2<!-- GEN:stop --> | :white_check_mark: | :white_check_mark: | :white_check_mark: |
|
||||||
| Firefox <!-- GEN:firefox-version -->134.0<!-- GEN:stop --> | :white_check_mark: | :white_check_mark: | :white_check_mark: |
|
| Firefox <!-- GEN:firefox-version -->135.0<!-- GEN:stop --> | :white_check_mark: | :white_check_mark: | :white_check_mark: |
|
||||||
|
|
||||||
Headless execution is supported for all browsers on all platforms. Check out [system requirements](https://playwright.dev/docs/intro#system-requirements) for details.
|
Headless execution is supported for all browsers on all platforms. Check out [system requirements](https://playwright.dev/docs/intro#system-requirements) for details.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -81,7 +81,7 @@ Methods like [`method: APIRequestContext.get`] take the base URL into considerat
|
||||||
- `records` <[Array]<[Object]>>
|
- `records` <[Array]<[Object]>>
|
||||||
- `key` ?<[Object]>
|
- `key` ?<[Object]>
|
||||||
- `keyEncoded` ?<[Object]> if `key` is not JSON-serializable, this contains an encoded version that preserves types.
|
- `keyEncoded` ?<[Object]> if `key` is not JSON-serializable, this contains an encoded version that preserves types.
|
||||||
- `value` <[Object]>
|
- `value` ?<[Object]>
|
||||||
- `valueEncoded` ?<[Object]> if `value` is not JSON-serializable, this contains an encoded version that preserves types.
|
- `valueEncoded` ?<[Object]> if `value` is not JSON-serializable, this contains an encoded version that preserves types.
|
||||||
|
|
||||||
Populates context with given storage state. This option can be used to initialize context with logged-in information
|
Populates context with given storage state. This option can be used to initialize context with logged-in information
|
||||||
|
|
|
||||||
|
|
@ -897,7 +897,7 @@ context cookies from the response. The method will automatically follow redirect
|
||||||
- `records` <[Array]<[Object]>>
|
- `records` <[Array]<[Object]>>
|
||||||
- `key` ?<[Object]>
|
- `key` ?<[Object]>
|
||||||
- `keyEncoded` ?<[Object]> if `key` is not JSON-serializable, this contains an encoded version that preserves types.
|
- `keyEncoded` ?<[Object]> if `key` is not JSON-serializable, this contains an encoded version that preserves types.
|
||||||
- `value` <[Object]>
|
- `value` ?<[Object]>
|
||||||
- `valueEncoded` ?<[Object]> if `value` is not JSON-serializable, this contains an encoded version that preserves types.
|
- `valueEncoded` ?<[Object]> if `value` is not JSON-serializable, this contains an encoded version that preserves types.
|
||||||
|
|
||||||
Returns storage state for this request context, contains current cookies and local storage snapshot if it was passed to the constructor.
|
Returns storage state for this request context, contains current cookies and local storage snapshot if it was passed to the constructor.
|
||||||
|
|
|
||||||
|
|
@ -1528,7 +1528,7 @@ Whether to emulate network being offline for the browser context.
|
||||||
- `records` <[Array]<[Object]>>
|
- `records` <[Array]<[Object]>>
|
||||||
- `key` ?<[Object]>
|
- `key` ?<[Object]>
|
||||||
- `keyEncoded` ?<[Object]> if `key` is not JSON-serializable, this contains an encoded version that preserves types.
|
- `keyEncoded` ?<[Object]> if `key` is not JSON-serializable, this contains an encoded version that preserves types.
|
||||||
- `value` <[Object]>
|
- `value` ?<[Object]>
|
||||||
- `valueEncoded` ?<[Object]> if `value` is not JSON-serializable, this contains an encoded version that preserves types.
|
- `valueEncoded` ?<[Object]> if `value` is not JSON-serializable, this contains an encoded version that preserves types.
|
||||||
|
|
||||||
Returns storage state for this browser context, contains current cookies, local storage snapshot and IndexedDB snapshot.
|
Returns storage state for this browser context, contains current cookies, local storage snapshot and IndexedDB snapshot.
|
||||||
|
|
|
||||||
|
|
@ -281,7 +281,7 @@ Specify environment variables that will be visible to the browser. Defaults to `
|
||||||
- `records` <[Array]<[Object]>>
|
- `records` <[Array]<[Object]>>
|
||||||
- `key` ?<[Object]>
|
- `key` ?<[Object]>
|
||||||
- `keyEncoded` ?<[Object]> if `key` is not JSON-serializable, this contains an encoded version that preserves types.
|
- `keyEncoded` ?<[Object]> if `key` is not JSON-serializable, this contains an encoded version that preserves types.
|
||||||
- `value` <[Object]>
|
- `value` ?<[Object]>
|
||||||
- `valueEncoded` ?<[Object]> if `value` is not JSON-serializable, this contains an encoded version that preserves types.
|
- `valueEncoded` ?<[Object]> if `value` is not JSON-serializable, this contains an encoded version that preserves types.
|
||||||
|
|
||||||
Learn more about [storage state and auth](../auth.md).
|
Learn more about [storage state and auth](../auth.md).
|
||||||
|
|
|
||||||
|
|
@ -47,7 +47,7 @@ Create `tests/auth.setup.ts` that will prepare authenticated browser state for a
|
||||||
|
|
||||||
```js title="tests/auth.setup.ts"
|
```js title="tests/auth.setup.ts"
|
||||||
import { test as setup, expect } from '@playwright/test';
|
import { test as setup, expect } from '@playwright/test';
|
||||||
import path from 'path';
|
import * as path from 'path';
|
||||||
|
|
||||||
const authFile = path.join(__dirname, '../playwright/.auth/user.json');
|
const authFile = path.join(__dirname, '../playwright/.auth/user.json');
|
||||||
|
|
||||||
|
|
@ -143,8 +143,8 @@ Create `playwright/fixtures.ts` file that will [override `storageState` fixture]
|
||||||
|
|
||||||
```js title="playwright/fixtures.ts"
|
```js title="playwright/fixtures.ts"
|
||||||
import { test as baseTest, expect } from '@playwright/test';
|
import { test as baseTest, expect } from '@playwright/test';
|
||||||
import fs from 'fs';
|
import * as fs from 'fs';
|
||||||
import path from 'path';
|
import * as path from 'path';
|
||||||
|
|
||||||
export * from '@playwright/test';
|
export * from '@playwright/test';
|
||||||
export const test = baseTest.extend<{}, { workerStorageState: string }>({
|
export const test = baseTest.extend<{}, { workerStorageState: string }>({
|
||||||
|
|
@ -348,8 +348,8 @@ Alternatively, in a [worker fixture](#moderate-one-account-per-parallel-worker):
|
||||||
|
|
||||||
```js title="playwright/fixtures.ts"
|
```js title="playwright/fixtures.ts"
|
||||||
import { test as baseTest, request } from '@playwright/test';
|
import { test as baseTest, request } from '@playwright/test';
|
||||||
import fs from 'fs';
|
import * as fs from 'fs';
|
||||||
import path from 'path';
|
import * as path from 'path';
|
||||||
|
|
||||||
export * from '@playwright/test';
|
export * from '@playwright/test';
|
||||||
export const test = baseTest.extend<{}, { workerStorageState: string }>({
|
export const test = baseTest.extend<{}, { workerStorageState: string }>({
|
||||||
|
|
|
||||||
|
|
@ -109,7 +109,7 @@ First, add fixtures that will load the extension:
|
||||||
|
|
||||||
```js title="fixtures.ts"
|
```js title="fixtures.ts"
|
||||||
import { test as base, chromium, type BrowserContext } from '@playwright/test';
|
import { test as base, chromium, type BrowserContext } from '@playwright/test';
|
||||||
import path from 'path';
|
import * as path from 'path';
|
||||||
|
|
||||||
export const test = base.extend<{
|
export const test = base.extend<{
|
||||||
context: BrowserContext;
|
context: BrowserContext;
|
||||||
|
|
|
||||||
|
|
@ -389,7 +389,7 @@ Next, add init script to the page.
|
||||||
|
|
||||||
```js
|
```js
|
||||||
import { test, expect } from '@playwright/test';
|
import { test, expect } from '@playwright/test';
|
||||||
import path from 'path';
|
import * as path from 'path';
|
||||||
|
|
||||||
test.beforeEach(async ({ page }) => {
|
test.beforeEach(async ({ page }) => {
|
||||||
// Add script for every test in the beforeEach hook.
|
// Add script for every test in the beforeEach hook.
|
||||||
|
|
|
||||||
|
|
@ -291,7 +291,7 @@ Here is an example that uses [`method: TestInfo.outputPath`] to create a tempora
|
||||||
|
|
||||||
```js
|
```js
|
||||||
import { test, expect } from '@playwright/test';
|
import { test, expect } from '@playwright/test';
|
||||||
import fs from 'fs';
|
import * as fs from 'fs';
|
||||||
|
|
||||||
test('example test', async ({}, testInfo) => {
|
test('example test', async ({}, testInfo) => {
|
||||||
const file = testInfo.outputPath('temporary-file.txt');
|
const file = testInfo.outputPath('temporary-file.txt');
|
||||||
|
|
|
||||||
|
|
@ -254,7 +254,7 @@ Returns a path inside the [`property: TestInfo.outputDir`] where the test can sa
|
||||||
|
|
||||||
```js
|
```js
|
||||||
import { test, expect } from '@playwright/test';
|
import { test, expect } from '@playwright/test';
|
||||||
import fs from 'fs';
|
import * as fs from 'fs';
|
||||||
|
|
||||||
test('example test', async ({}, testInfo) => {
|
test('example test', async ({}, testInfo) => {
|
||||||
const file = testInfo.outputPath('dir', 'temporary-file.txt');
|
const file = testInfo.outputPath('dir', 'temporary-file.txt');
|
||||||
|
|
|
||||||
|
|
@ -212,7 +212,7 @@ Here is an example that uses [`method: TestInfo.outputPath`] to create a tempora
|
||||||
|
|
||||||
```js
|
```js
|
||||||
import { test, expect } from '@playwright/test';
|
import { test, expect } from '@playwright/test';
|
||||||
import fs from 'fs';
|
import * as fs from 'fs';
|
||||||
|
|
||||||
test('example test', async ({}, testInfo) => {
|
test('example test', async ({}, testInfo) => {
|
||||||
const file = testInfo.outputPath('temporary-file.txt');
|
const file = testInfo.outputPath('temporary-file.txt');
|
||||||
|
|
|
||||||
|
|
@ -262,7 +262,7 @@ To make environment variables easier to manage, consider something like `.env` f
|
||||||
```js title="playwright.config.ts"
|
```js title="playwright.config.ts"
|
||||||
import { defineConfig } from '@playwright/test';
|
import { defineConfig } from '@playwright/test';
|
||||||
import dotenv from 'dotenv';
|
import dotenv from 'dotenv';
|
||||||
import path from 'path';
|
import * as path from 'path';
|
||||||
|
|
||||||
// Read from ".env" file.
|
// Read from ".env" file.
|
||||||
dotenv.config({ path: path.resolve(__dirname, '.env') });
|
dotenv.config({ path: path.resolve(__dirname, '.env') });
|
||||||
|
|
@ -309,8 +309,8 @@ See for example this CSV file, in our example `input.csv`:
|
||||||
Based on this we'll generate some tests by using the [csv-parse](https://www.npmjs.com/package/csv-parse) library from NPM:
|
Based on this we'll generate some tests by using the [csv-parse](https://www.npmjs.com/package/csv-parse) library from NPM:
|
||||||
|
|
||||||
```js title="test.spec.ts"
|
```js title="test.spec.ts"
|
||||||
import fs from 'fs';
|
import * as fs from 'fs';
|
||||||
import path from 'path';
|
import * as path from 'path';
|
||||||
import { test } from '@playwright/test';
|
import { test } from '@playwright/test';
|
||||||
import { parse } from 'csv-parse/sync';
|
import { parse } from 'csv-parse/sync';
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -18,9 +18,10 @@ UI Mode lets you explore, run, and debug tests with a time travel experience com
|
||||||
|
|
||||||
To open UI mode, run the following command in your terminal:
|
To open UI mode, run the following command in your terminal:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
npx playwright test --ui
|
npx playwright test --ui
|
||||||
```
|
```
|
||||||
|
|
||||||
## Running your tests
|
## Running your tests
|
||||||
|
|
||||||
Once you launch UI Mode you will see a list of all your test files. You can run all your tests by clicking the triangle icon in the sidebar. You can also run a single test file, a block of tests or a single test by hovering over the name and clicking on the triangle next to it.
|
Once you launch UI Mode you will see a list of all your test files. You can run all your tests by clicking the triangle icon in the sidebar. You can also run a single test file, a block of tests or a single test by hovering over the name and clicking on the triangle next to it.
|
||||||
|
|
@ -33,14 +34,12 @@ Filter tests by text or `@tag` or by passed, failed or skipped tests. You can al
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
|
|
||||||
## Timeline view
|
## Timeline view
|
||||||
|
|
||||||
At the top of the trace you can see a timeline view of your test with different colors to highlight navigation and actions. Hover back and forth to see an image snapshot for each action. Double click on an action to see the time range for that action. You can use the slider in the timeline to increase the actions selected and these will be shown in the Actions tab and all console logs and network logs will be filtered to only show the logs for the actions selected.
|
At the top of the trace you can see a timeline view of your test with different colors to highlight navigation and actions. Hover back and forth to see an image snapshot for each action. Double click on an action to see the time range for that action. You can use the slider in the timeline to increase the actions selected and these will be shown in the Actions tab and all console logs and network logs will be filtered to only show the logs for the actions selected.
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
|
|
||||||
## Actions
|
## Actions
|
||||||
|
|
||||||
In the Actions tab you can see what locator was used for every action and how long each one took to run. Hover over each action of your test and visually see the change in the DOM snapshot. Go back and forward in time and click an action to inspect and debug. Use the Before and After tabs to visually see what happened before and after the action.
|
In the Actions tab you can see what locator was used for every action and how long each one took to run. Hover over each action of your test and visually see the change in the DOM snapshot. Go back and forward in time and click an action to inspect and debug. Use the Before and After tabs to visually see what happened before and after the action.
|
||||||
|
|
@ -60,7 +59,7 @@ Click on the pick locator button and hover over the DOM snapshot to see the loca
|
||||||
|
|
||||||
## Source
|
## Source
|
||||||
|
|
||||||
As you hover over each action of your test the line of code for that action is highlighted in the source panel.
|
As you hover over each action of your test the line of code for that action is highlighted in the source panel. The button "Open in VSCode" is at the top-right of this section. Upon clicking the button, it will open your test in VS Code right at the line of code that you clicked on.
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
|
|
@ -108,7 +107,7 @@ Next to the Actions tab you will find the Metadata tab which will show you more
|
||||||
|
|
||||||
## Watch mode
|
## Watch mode
|
||||||
|
|
||||||
Next to the name of each test in the sidebar you will find an eye icon. Clicking on the icon will activate watch mode which will re-run the test when you make changes to it. You can watch a number of tests at the same time be clicking the eye icon next to each one or all tests by clicking the eye icon at the top of the sidebar. If you are using VS Code then you can easily open your test by clicking on the file icon next to the eye icon. This will open your test in VS Code right at the line of code that you clicked on.
|
Next to the name of each test in the sidebar you will find an eye icon. Clicking on the icon will activate watch mode which will re-run the test when you make changes to it. You can watch a number of tests at the same time be clicking the eye icon next to each one or all tests by clicking the eye icon at the top of the sidebar.
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -72,9 +72,9 @@ Using the following, Playwright will run your WebView2 application as a sub-proc
|
||||||
|
|
||||||
```js title="webView2Test.ts"
|
```js title="webView2Test.ts"
|
||||||
import { test as base } from '@playwright/test';
|
import { test as base } from '@playwright/test';
|
||||||
import fs from 'fs';
|
import * as fs from 'fs';
|
||||||
import os from 'os';
|
import * as os from 'os';
|
||||||
import path from 'path';
|
import * as path from 'path';
|
||||||
import childProcess from 'child_process';
|
import childProcess from 'child_process';
|
||||||
|
|
||||||
const EXECUTABLE_PATH = path.join(
|
const EXECUTABLE_PATH = path.join(
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,7 @@ import notice from 'eslint-plugin-notice';
|
||||||
import path from 'path';
|
import path from 'path';
|
||||||
import { fileURLToPath } from 'url';
|
import { fileURLToPath } from 'url';
|
||||||
import stylistic from '@stylistic/eslint-plugin';
|
import stylistic from '@stylistic/eslint-plugin';
|
||||||
|
import importRules from 'eslint-plugin-import';
|
||||||
|
|
||||||
const __filename = fileURLToPath(import.meta.url);
|
const __filename = fileURLToPath(import.meta.url);
|
||||||
const __dirname = path.dirname(__filename);
|
const __dirname = path.dirname(__filename);
|
||||||
|
|
@ -28,6 +29,7 @@ const plugins = {
|
||||||
'@stylistic': stylistic,
|
'@stylistic': stylistic,
|
||||||
'@typescript-eslint': typescriptEslint,
|
'@typescript-eslint': typescriptEslint,
|
||||||
notice,
|
notice,
|
||||||
|
import: importRules,
|
||||||
};
|
};
|
||||||
|
|
||||||
const ignores = [
|
const ignores = [
|
||||||
|
|
@ -57,7 +59,7 @@ const ignores = [
|
||||||
|
|
||||||
export const baseRules = {
|
export const baseRules = {
|
||||||
'@typescript-eslint/no-unused-vars': [2, { args: 'none', caughtErrors: 'none' }],
|
'@typescript-eslint/no-unused-vars': [2, { args: 'none', caughtErrors: 'none' }],
|
||||||
'@typescript-eslint/consistent-type-imports': [2, { disallowTypeAnnotations: false }],
|
|
||||||
/**
|
/**
|
||||||
* Enforced rules
|
* Enforced rules
|
||||||
*/
|
*/
|
||||||
|
|
@ -184,6 +186,19 @@ const noRestrictedGlobalsRules = {
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const importOrderRules = {
|
||||||
|
'import/order': [2, {
|
||||||
|
'alphabetize': {
|
||||||
|
'order': 'asc',
|
||||||
|
'caseInsensitive': false
|
||||||
|
},
|
||||||
|
'named': true,
|
||||||
|
'groups': ['builtin', 'external', 'internal', ['parent', 'sibling'], 'index', 'type'],
|
||||||
|
'newlines-between': 'always',
|
||||||
|
}],
|
||||||
|
'import/consistent-type-specifier-style': [2, 'prefer-top-level']
|
||||||
|
};
|
||||||
|
|
||||||
const languageOptions = {
|
const languageOptions = {
|
||||||
parser: tsParser,
|
parser: tsParser,
|
||||||
ecmaVersion: 9,
|
ecmaVersion: 9,
|
||||||
|
|
@ -217,6 +232,13 @@ export default [{
|
||||||
'message': 'Please use gracefullyProcessExitDoNotHang function to exit the process.',
|
'message': 'Please use gracefullyProcessExitDoNotHang function to exit the process.',
|
||||||
}],
|
}],
|
||||||
}
|
}
|
||||||
|
}, {
|
||||||
|
files: [
|
||||||
|
'packages/**/*.ts',
|
||||||
|
],
|
||||||
|
rules: {
|
||||||
|
...importOrderRules
|
||||||
|
},
|
||||||
}, {
|
}, {
|
||||||
files: ['packages/playwright/**/*.ts'],
|
files: ['packages/playwright/**/*.ts'],
|
||||||
rules: {
|
rules: {
|
||||||
|
|
|
||||||
263
package-lock.json
generated
263
package-lock.json
generated
|
|
@ -52,6 +52,7 @@
|
||||||
"electron": "^30.1.2",
|
"electron": "^30.1.2",
|
||||||
"esbuild": "^0.18.11",
|
"esbuild": "^0.18.11",
|
||||||
"eslint": "^9.19.0",
|
"eslint": "^9.19.0",
|
||||||
|
"eslint-plugin-import": "^2.31.0",
|
||||||
"eslint-plugin-notice": "^1.0.0",
|
"eslint-plugin-notice": "^1.0.0",
|
||||||
"eslint-plugin-react": "^7.37.4",
|
"eslint-plugin-react": "^7.37.4",
|
||||||
"eslint-plugin-react-hooks": "^5.1.0",
|
"eslint-plugin-react-hooks": "^5.1.0",
|
||||||
|
|
@ -1817,6 +1818,13 @@
|
||||||
"win32"
|
"win32"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
"node_modules/@rtsao/scc": {
|
||||||
|
"version": "1.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@rtsao/scc/-/scc-1.1.0.tgz",
|
||||||
|
"integrity": "sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/@sindresorhus/is": {
|
"node_modules/@sindresorhus/is": {
|
||||||
"version": "4.6.0",
|
"version": "4.6.0",
|
||||||
"resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.6.0.tgz",
|
"resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.6.0.tgz",
|
||||||
|
|
@ -2019,6 +2027,13 @@
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"node_modules/@types/json5": {
|
||||||
|
"version": "0.0.29",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz",
|
||||||
|
"integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/@types/keyv": {
|
"node_modules/@types/keyv": {
|
||||||
"version": "3.1.4",
|
"version": "3.1.4",
|
||||||
"resolved": "https://registry.npmjs.org/@types/keyv/-/keyv-3.1.4.tgz",
|
"resolved": "https://registry.npmjs.org/@types/keyv/-/keyv-3.1.4.tgz",
|
||||||
|
|
@ -2717,6 +2732,27 @@
|
||||||
"url": "https://github.com/sponsors/ljharb"
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/array.prototype.findlastindex": {
|
||||||
|
"version": "1.2.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.5.tgz",
|
||||||
|
"integrity": "sha512-zfETvRFA8o7EiNn++N5f/kaCw221hrpGsDmcpndVupkPzEc1Wuf3VgC0qby1BbHs7f5DVYjgtEU2LLh5bqeGfQ==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"call-bind": "^1.0.7",
|
||||||
|
"define-properties": "^1.2.1",
|
||||||
|
"es-abstract": "^1.23.2",
|
||||||
|
"es-errors": "^1.3.0",
|
||||||
|
"es-object-atoms": "^1.0.0",
|
||||||
|
"es-shim-unscopables": "^1.0.2"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.4"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/array.prototype.flat": {
|
"node_modules/array.prototype.flat": {
|
||||||
"version": "1.3.2",
|
"version": "1.3.2",
|
||||||
"resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.2.tgz",
|
"resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.2.tgz",
|
||||||
|
|
@ -3536,6 +3572,19 @@
|
||||||
"wrappy": "1"
|
"wrappy": "1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/doctrine": {
|
||||||
|
"version": "2.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz",
|
||||||
|
"integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "Apache-2.0",
|
||||||
|
"dependencies": {
|
||||||
|
"esutils": "^2.0.2"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.10.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/dotenv": {
|
"node_modules/dotenv": {
|
||||||
"version": "16.4.5",
|
"version": "16.4.5",
|
||||||
"resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.5.tgz",
|
"resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.5.tgz",
|
||||||
|
|
@ -3920,6 +3969,145 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/eslint-import-resolver-node": {
|
||||||
|
"version": "0.3.9",
|
||||||
|
"resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz",
|
||||||
|
"integrity": "sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"debug": "^3.2.7",
|
||||||
|
"is-core-module": "^2.13.0",
|
||||||
|
"resolve": "^1.22.4"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/eslint-import-resolver-node/node_modules/debug": {
|
||||||
|
"version": "3.2.7",
|
||||||
|
"resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz",
|
||||||
|
"integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"ms": "^2.1.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/eslint-import-resolver-node/node_modules/resolve": {
|
||||||
|
"version": "1.22.10",
|
||||||
|
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.10.tgz",
|
||||||
|
"integrity": "sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"is-core-module": "^2.16.0",
|
||||||
|
"path-parse": "^1.0.7",
|
||||||
|
"supports-preserve-symlinks-flag": "^1.0.0"
|
||||||
|
},
|
||||||
|
"bin": {
|
||||||
|
"resolve": "bin/resolve"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.4"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/eslint-module-utils": {
|
||||||
|
"version": "2.12.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.12.0.tgz",
|
||||||
|
"integrity": "sha512-wALZ0HFoytlyh/1+4wuZ9FJCD/leWHQzzrxJ8+rebyReSLk7LApMyd3WJaLVoN+D5+WIdJyDK1c6JnE65V4Zyg==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"debug": "^3.2.7"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=4"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"eslint": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/eslint-module-utils/node_modules/debug": {
|
||||||
|
"version": "3.2.7",
|
||||||
|
"resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz",
|
||||||
|
"integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"ms": "^2.1.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/eslint-plugin-import": {
|
||||||
|
"version": "2.31.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.31.0.tgz",
|
||||||
|
"integrity": "sha512-ixmkI62Rbc2/w8Vfxyh1jQRTdRTF52VxwRVHl/ykPAmqG+Nb7/kNn+byLP0LxPgI7zWA16Jt82SybJInmMia3A==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@rtsao/scc": "^1.1.0",
|
||||||
|
"array-includes": "^3.1.8",
|
||||||
|
"array.prototype.findlastindex": "^1.2.5",
|
||||||
|
"array.prototype.flat": "^1.3.2",
|
||||||
|
"array.prototype.flatmap": "^1.3.2",
|
||||||
|
"debug": "^3.2.7",
|
||||||
|
"doctrine": "^2.1.0",
|
||||||
|
"eslint-import-resolver-node": "^0.3.9",
|
||||||
|
"eslint-module-utils": "^2.12.0",
|
||||||
|
"hasown": "^2.0.2",
|
||||||
|
"is-core-module": "^2.15.1",
|
||||||
|
"is-glob": "^4.0.3",
|
||||||
|
"minimatch": "^3.1.2",
|
||||||
|
"object.fromentries": "^2.0.8",
|
||||||
|
"object.groupby": "^1.0.3",
|
||||||
|
"object.values": "^1.2.0",
|
||||||
|
"semver": "^6.3.1",
|
||||||
|
"string.prototype.trimend": "^1.0.8",
|
||||||
|
"tsconfig-paths": "^3.15.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=4"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 || ^9"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/eslint-plugin-import/node_modules/brace-expansion": {
|
||||||
|
"version": "1.1.11",
|
||||||
|
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
|
||||||
|
"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"balanced-match": "^1.0.0",
|
||||||
|
"concat-map": "0.0.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/eslint-plugin-import/node_modules/debug": {
|
||||||
|
"version": "3.2.7",
|
||||||
|
"resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz",
|
||||||
|
"integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"ms": "^2.1.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/eslint-plugin-import/node_modules/minimatch": {
|
||||||
|
"version": "3.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
|
||||||
|
"integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "ISC",
|
||||||
|
"dependencies": {
|
||||||
|
"brace-expansion": "^1.1.7"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": "*"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/eslint-plugin-notice": {
|
"node_modules/eslint-plugin-notice": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/eslint-plugin-notice/-/eslint-plugin-notice-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/eslint-plugin-notice/-/eslint-plugin-notice-1.0.0.tgz",
|
||||||
|
|
@ -3991,18 +4179,6 @@
|
||||||
"concat-map": "0.0.1"
|
"concat-map": "0.0.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/eslint-plugin-react/node_modules/doctrine": {
|
|
||||||
"version": "2.1.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz",
|
|
||||||
"integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==",
|
|
||||||
"dev": true,
|
|
||||||
"dependencies": {
|
|
||||||
"esutils": "^2.0.2"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=0.10.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/eslint-plugin-react/node_modules/minimatch": {
|
"node_modules/eslint-plugin-react/node_modules/minimatch": {
|
||||||
"version": "3.1.2",
|
"version": "3.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
|
||||||
|
|
@ -5105,12 +5281,16 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/is-core-module": {
|
"node_modules/is-core-module": {
|
||||||
"version": "2.13.1",
|
"version": "2.16.1",
|
||||||
"resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz",
|
"resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz",
|
||||||
"integrity": "sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==",
|
"integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"hasown": "^2.0.0"
|
"hasown": "^2.0.2"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.4"
|
||||||
},
|
},
|
||||||
"funding": {
|
"funding": {
|
||||||
"url": "https://github.com/sponsors/ljharb"
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
|
|
@ -6104,6 +6284,21 @@
|
||||||
"url": "https://github.com/sponsors/ljharb"
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/object.groupby": {
|
||||||
|
"version": "1.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/object.groupby/-/object.groupby-1.0.3.tgz",
|
||||||
|
"integrity": "sha512-+Lhy3TQTuzXI5hevh8sBGqbmurHbbIjAi0Z4S63nthVLmLxfbj4T54a4CfZrXIrt9iP4mVAPYMo/v99taj3wjQ==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"call-bind": "^1.0.7",
|
||||||
|
"define-properties": "^1.2.1",
|
||||||
|
"es-abstract": "^1.23.2"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.4"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/object.values": {
|
"node_modules/object.values": {
|
||||||
"version": "1.2.1",
|
"version": "1.2.1",
|
||||||
"resolved": "https://registry.npmjs.org/object.values/-/object.values-1.2.1.tgz",
|
"resolved": "https://registry.npmjs.org/object.values/-/object.values-1.2.1.tgz",
|
||||||
|
|
@ -7287,6 +7482,16 @@
|
||||||
"node": ">=8"
|
"node": ">=8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/strip-bom": {
|
||||||
|
"version": "3.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz",
|
||||||
|
"integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=4"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/strip-json-comments": {
|
"node_modules/strip-json-comments": {
|
||||||
"version": "3.1.1",
|
"version": "3.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz",
|
||||||
|
|
@ -7424,6 +7629,32 @@
|
||||||
"typescript": ">=4.8.4"
|
"typescript": ">=4.8.4"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/tsconfig-paths": {
|
||||||
|
"version": "3.15.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz",
|
||||||
|
"integrity": "sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@types/json5": "^0.0.29",
|
||||||
|
"json5": "^1.0.2",
|
||||||
|
"minimist": "^1.2.6",
|
||||||
|
"strip-bom": "^3.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/tsconfig-paths/node_modules/json5": {
|
||||||
|
"version": "1.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz",
|
||||||
|
"integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"minimist": "^1.2.0"
|
||||||
|
},
|
||||||
|
"bin": {
|
||||||
|
"json5": "lib/cli.js"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/tslib": {
|
"node_modules/tslib": {
|
||||||
"version": "1.14.1",
|
"version": "1.14.1",
|
||||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
|
"resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
|
||||||
|
|
|
||||||
|
|
@ -91,6 +91,7 @@
|
||||||
"electron": "^30.1.2",
|
"electron": "^30.1.2",
|
||||||
"esbuild": "^0.18.11",
|
"esbuild": "^0.18.11",
|
||||||
"eslint": "^9.19.0",
|
"eslint": "^9.19.0",
|
||||||
|
"eslint-plugin-import": "^2.31.0",
|
||||||
"eslint-plugin-notice": "^1.0.0",
|
"eslint-plugin-notice": "^1.0.0",
|
||||||
"eslint-plugin-react": "^7.37.4",
|
"eslint-plugin-react": "^7.37.4",
|
||||||
"eslint-plugin-react-hooks": "^5.1.0",
|
"eslint-plugin-react-hooks": "^5.1.0",
|
||||||
|
|
|
||||||
|
|
@ -14,8 +14,8 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import fs from 'fs';
|
import * as fs from 'fs';
|
||||||
import path from 'path';
|
import * as path from 'path';
|
||||||
import type { Plugin, UserConfig } from 'vite';
|
import type { Plugin, UserConfig } from 'vite';
|
||||||
|
|
||||||
export function bundle(): Plugin {
|
export function bundle(): Plugin {
|
||||||
|
|
|
||||||
|
|
@ -15,8 +15,8 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { devices, defineConfig } from '@playwright/experimental-ct-react';
|
import { devices, defineConfig } from '@playwright/experimental-ct-react';
|
||||||
import path from 'path';
|
import * as path from 'path';
|
||||||
import url from 'url';
|
import * as url from 'url';
|
||||||
|
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
testDir: 'src',
|
testDir: 'src',
|
||||||
|
|
|
||||||
|
|
@ -26,9 +26,25 @@ import { linkifyText } from '@web/renderUtils';
|
||||||
|
|
||||||
type MetadataEntries = [string, unknown][];
|
type MetadataEntries = [string, unknown][];
|
||||||
|
|
||||||
export function filterMetadata(metadata: Metadata): MetadataEntries {
|
export const MetadataContext = React.createContext<MetadataEntries>([]);
|
||||||
// TODO: do not plumb actualWorkers through metadata.
|
|
||||||
return Object.entries(metadata).filter(([key]) => key !== 'actualWorkers');
|
export function MetadataProvider({ metadata, children }: React.PropsWithChildren<{ metadata: Metadata }>) {
|
||||||
|
const entries = React.useMemo(() => {
|
||||||
|
// TODO: do not plumb actualWorkers through metadata.
|
||||||
|
|
||||||
|
return Object.entries(metadata).filter(([key]) => key !== 'actualWorkers');
|
||||||
|
}, [metadata]);
|
||||||
|
|
||||||
|
return <MetadataContext.Provider value={entries}>{children}</MetadataContext.Provider>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function useMetadata() {
|
||||||
|
return React.useContext(MetadataContext);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function useGitCommitInfo() {
|
||||||
|
const metadataEntries = useMetadata();
|
||||||
|
return metadataEntries.find(([key]) => key === 'git.commit.info')?.[1] as GitCommitInfo | undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
class ErrorBoundary extends React.Component<React.PropsWithChildren<{}>, { error: Error | null, errorInfo: React.ErrorInfo | null }> {
|
class ErrorBoundary extends React.Component<React.PropsWithChildren<{}>, { error: Error | null, errorInfo: React.ErrorInfo | null }> {
|
||||||
|
|
@ -57,12 +73,13 @@ class ErrorBoundary extends React.Component<React.PropsWithChildren<{}>, { error
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const MetadataView: React.FC<{ metadataEntries: MetadataEntries }> = ({ metadataEntries }) => {
|
export const MetadataView = () => {
|
||||||
return <ErrorBoundary><InnerMetadataView metadataEntries={metadataEntries}/></ErrorBoundary>;
|
return <ErrorBoundary><InnerMetadataView/></ErrorBoundary>;
|
||||||
};
|
};
|
||||||
|
|
||||||
const InnerMetadataView: React.FC<{ metadataEntries: MetadataEntries }> = ({ metadataEntries }) => {
|
const InnerMetadataView = () => {
|
||||||
const gitCommitInfo = metadataEntries.find(([key]) => key === 'git.commit.info')?.[1] as GitCommitInfo | undefined;
|
const metadataEntries = useMetadata();
|
||||||
|
const gitCommitInfo = useGitCommitInfo();
|
||||||
const entries = metadataEntries.filter(([key]) => key !== 'git.commit.info');
|
const entries = metadataEntries.filter(([key]) => key !== 'git.commit.info');
|
||||||
if (!gitCommitInfo && !entries.length)
|
if (!gitCommitInfo && !entries.length)
|
||||||
return null;
|
return null;
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,7 @@ import './reportView.css';
|
||||||
import { TestCaseView } from './testCaseView';
|
import { TestCaseView } from './testCaseView';
|
||||||
import { TestFilesHeader, TestFilesView } from './testFilesView';
|
import { TestFilesHeader, TestFilesView } from './testFilesView';
|
||||||
import './theme.css';
|
import './theme.css';
|
||||||
|
import { MetadataProvider } from './metadataView';
|
||||||
|
|
||||||
declare global {
|
declare global {
|
||||||
interface Window {
|
interface Window {
|
||||||
|
|
@ -72,7 +73,7 @@ export const ReportView: React.FC<{
|
||||||
return result;
|
return result;
|
||||||
}, [report, filter]);
|
}, [report, filter]);
|
||||||
|
|
||||||
return <div className='htmlreport vbox px-4 pb-4'>
|
return <MetadataProvider metadata={report?.json().metadata ?? {}}><div className='htmlreport vbox px-4 pb-4'>
|
||||||
<main>
|
<main>
|
||||||
{report?.json() && <HeaderView stats={report.json().stats} filterText={filterText} setFilterText={setFilterText}></HeaderView>}
|
{report?.json() && <HeaderView stats={report.json().stats} filterText={filterText} setFilterText={setFilterText}></HeaderView>}
|
||||||
<Route predicate={testFilesRoutePredicate}>
|
<Route predicate={testFilesRoutePredicate}>
|
||||||
|
|
@ -88,7 +89,7 @@ export const ReportView: React.FC<{
|
||||||
{!!report && <TestCaseViewLoader report={report} tests={filteredTests.tests} testIdToFileIdMap={testIdToFileIdMap} />}
|
{!!report && <TestCaseViewLoader report={report} tests={filteredTests.tests} testIdToFileIdMap={testIdToFileIdMap} />}
|
||||||
</Route>
|
</Route>
|
||||||
</main>
|
</main>
|
||||||
</div>;
|
</div></MetadataProvider>;
|
||||||
};
|
};
|
||||||
|
|
||||||
const TestCaseViewLoader: React.FC<{
|
const TestCaseViewLoader: React.FC<{
|
||||||
|
|
|
||||||
|
|
@ -16,18 +16,47 @@
|
||||||
|
|
||||||
@import '@web/third_party/vscode/colors.css';
|
@import '@web/third_party/vscode/colors.css';
|
||||||
|
|
||||||
.test-error-view {
|
.test-error-container {
|
||||||
white-space: pre;
|
white-space: pre;
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
flex: none;
|
flex: none;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
background-color: var(--color-canvas-subtle);
|
background-color: var(--color-canvas-subtle);
|
||||||
border-radius: 6px;
|
border-radius: 6px;
|
||||||
padding: 16px;
|
|
||||||
line-height: initial;
|
line-height: initial;
|
||||||
margin-bottom: 6px;
|
margin-bottom: 6px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.test-error-view {
|
||||||
|
padding: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
.test-error-text {
|
.test-error-text {
|
||||||
font-family: monospace;
|
font-family: monospace;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.prompt-button {
|
||||||
|
flex: none;
|
||||||
|
height: 24px;
|
||||||
|
width: 80px;
|
||||||
|
border: 1px solid var(--color-btn-border);
|
||||||
|
outline: none;
|
||||||
|
color: var(--color-btn-text);
|
||||||
|
background: var(--color-btn-bg);
|
||||||
|
padding: 4px;
|
||||||
|
cursor: pointer;
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.prompt-button svg {
|
||||||
|
color: var(--color-fg-subtle);
|
||||||
|
}
|
||||||
|
|
||||||
|
.prompt-button:not(:disabled):hover {
|
||||||
|
border-color: var(--color-btn-hover-border);
|
||||||
|
background-color: var(--color-btn-hover-bg);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -17,15 +17,57 @@
|
||||||
import { ansi2html } from '@web/ansi2html';
|
import { ansi2html } from '@web/ansi2html';
|
||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
import './testErrorView.css';
|
import './testErrorView.css';
|
||||||
|
import * as icons from './icons';
|
||||||
import type { ImageDiff } from '@web/shared/imageDiffView';
|
import type { ImageDiff } from '@web/shared/imageDiffView';
|
||||||
import { ImageDiffView } from '@web/shared/imageDiffView';
|
import { ImageDiffView } from '@web/shared/imageDiffView';
|
||||||
|
import type { TestResult } from './types';
|
||||||
|
import { fixTestPrompt } from '@web/components/prompts';
|
||||||
|
import { useGitCommitInfo } from './metadataView';
|
||||||
|
|
||||||
export const TestErrorView: React.FC<{
|
export const TestErrorView: React.FC<{ error: string; testId?: string; result?: TestResult }> = ({ error, testId, result }) => {
|
||||||
|
return (
|
||||||
|
<CodeSnippet code={error} testId={testId}>
|
||||||
|
<div style={{ float: 'right', padding: '5px' }}>
|
||||||
|
<PromptButton error={error} result={result} />
|
||||||
|
</div>
|
||||||
|
</CodeSnippet>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const CodeSnippet = ({ code, children, testId }: React.PropsWithChildren<{ code: string; testId?: string; }>) => {
|
||||||
|
const html = React.useMemo(() => ansiErrorToHtml(code), [code]);
|
||||||
|
return (
|
||||||
|
<div className='test-error-container test-error-text' data-testid={testId}>
|
||||||
|
{children}
|
||||||
|
<div className='test-error-view' dangerouslySetInnerHTML={{ __html: html || '' }}></div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const PromptButton: React.FC<{
|
||||||
error: string;
|
error: string;
|
||||||
testId?: string;
|
result?: TestResult;
|
||||||
}> = ({ error, testId }) => {
|
}> = ({ error, result }) => {
|
||||||
const html = React.useMemo(() => ansiErrorToHtml(error), [error]);
|
const gitCommitInfo = useGitCommitInfo();
|
||||||
return <div className='test-error-view test-error-text' data-testid={testId} dangerouslySetInnerHTML={{ __html: html || '' }}></div>;
|
const prompt = React.useMemo(() => fixTestPrompt(
|
||||||
|
error,
|
||||||
|
gitCommitInfo?.['pull.diff'] ?? gitCommitInfo?.['revision.diff'],
|
||||||
|
result?.attachments.find(a => a.name === 'pageSnapshot')?.body
|
||||||
|
), [gitCommitInfo, result, error]);
|
||||||
|
|
||||||
|
const [copied, setCopied] = React.useState(false);
|
||||||
|
|
||||||
|
return <button
|
||||||
|
className='prompt-button'
|
||||||
|
onClick={async () => {
|
||||||
|
await navigator.clipboard.writeText(prompt);
|
||||||
|
setCopied(true);
|
||||||
|
setTimeout(() => {
|
||||||
|
setCopied(false);
|
||||||
|
}, 3000);
|
||||||
|
}}>
|
||||||
|
{copied ? <span className='prompt-button-copied'>Copied <icons.copy/></span> : 'Fix with AI'}
|
||||||
|
</button>;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const TestScreenshotErrorView: React.FC<{
|
export const TestScreenshotErrorView: React.FC<{
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,7 @@ import { msToString } from './utils';
|
||||||
import { AutoChip } from './chip';
|
import { AutoChip } from './chip';
|
||||||
import { TestErrorView } from './testErrorView';
|
import { TestErrorView } from './testErrorView';
|
||||||
import * as icons from './icons';
|
import * as icons from './icons';
|
||||||
import { filterMetadata, MetadataView } from './metadataView';
|
import { MetadataView, useMetadata } from './metadataView';
|
||||||
|
|
||||||
export const TestFilesView: React.FC<{
|
export const TestFilesView: React.FC<{
|
||||||
tests: TestFileSummary[],
|
tests: TestFileSummary[],
|
||||||
|
|
@ -67,9 +67,9 @@ export const TestFilesHeader: React.FC<{
|
||||||
metadataVisible: boolean,
|
metadataVisible: boolean,
|
||||||
toggleMetadataVisible: () => void,
|
toggleMetadataVisible: () => void,
|
||||||
}> = ({ report, filteredStats, metadataVisible, toggleMetadataVisible }) => {
|
}> = ({ report, filteredStats, metadataVisible, toggleMetadataVisible }) => {
|
||||||
|
const metadataEntries = useMetadata();
|
||||||
if (!report)
|
if (!report)
|
||||||
return;
|
return;
|
||||||
const metadataEntries = filterMetadata(report.metadata || {});
|
|
||||||
return <>
|
return <>
|
||||||
<div className='mx-1' style={{ display: 'flex', marginTop: 10 }}>
|
<div className='mx-1' style={{ display: 'flex', marginTop: 10 }}>
|
||||||
{metadataEntries.length > 0 && <div className='metadata-toggle' role='button' onClick={toggleMetadataVisible} title={metadataVisible ? 'Hide metadata' : 'Show metadata'}>
|
{metadataEntries.length > 0 && <div className='metadata-toggle' role='button' onClick={toggleMetadataVisible} title={metadataVisible ? 'Hide metadata' : 'Show metadata'}>
|
||||||
|
|
@ -81,7 +81,7 @@ export const TestFilesHeader: React.FC<{
|
||||||
<div data-testid='overall-time' style={{ color: 'var(--color-fg-subtle)', marginRight: '10px' }}>{report ? new Date(report.startTime).toLocaleString() : ''}</div>
|
<div data-testid='overall-time' style={{ color: 'var(--color-fg-subtle)', marginRight: '10px' }}>{report ? new Date(report.startTime).toLocaleString() : ''}</div>
|
||||||
<div data-testid='overall-duration' style={{ color: 'var(--color-fg-subtle)' }}>Total time: {msToString(report.duration ?? 0)}</div>
|
<div data-testid='overall-duration' style={{ color: 'var(--color-fg-subtle)' }}>Total time: {msToString(report.duration ?? 0)}</div>
|
||||||
</div>
|
</div>
|
||||||
{metadataVisible && <MetadataView metadataEntries={metadataEntries}/>}
|
{metadataVisible && <MetadataView/>}
|
||||||
{!!report.errors.length && <AutoChip header='Errors' dataTestId='report-errors'>
|
{!!report.errors.length && <AutoChip header='Errors' dataTestId='report-errors'>
|
||||||
{report.errors.map((error, index) => <TestErrorView key={'test-report-error-message-' + index} error={error}></TestErrorView>)}
|
{report.errors.map((error, index) => <TestErrorView key={'test-report-error-message-' + index} error={error}></TestErrorView>)}
|
||||||
</AutoChip>}
|
</AutoChip>}
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,7 @@ import { Anchor, AttachmentLink, generateTraceUrl, testResultHref } from './link
|
||||||
import { statusIcon } from './statusIcon';
|
import { statusIcon } from './statusIcon';
|
||||||
import type { ImageDiff } from '@web/shared/imageDiffView';
|
import type { ImageDiff } from '@web/shared/imageDiffView';
|
||||||
import { ImageDiffView } from '@web/shared/imageDiffView';
|
import { ImageDiffView } from '@web/shared/imageDiffView';
|
||||||
import { TestErrorView, TestScreenshotErrorView } from './testErrorView';
|
import { CodeSnippet, TestErrorView, TestScreenshotErrorView } from './testErrorView';
|
||||||
import * as icons from './icons';
|
import * as icons from './icons';
|
||||||
import './testResultView.css';
|
import './testResultView.css';
|
||||||
|
|
||||||
|
|
@ -90,7 +90,7 @@ export const TestResultView: React.FC<{
|
||||||
{errors.map((error, index) => {
|
{errors.map((error, index) => {
|
||||||
if (error.type === 'screenshot')
|
if (error.type === 'screenshot')
|
||||||
return <TestScreenshotErrorView key={'test-result-error-message-' + index} errorPrefix={error.errorPrefix} diff={error.diff!} errorSuffix={error.errorSuffix}></TestScreenshotErrorView>;
|
return <TestScreenshotErrorView key={'test-result-error-message-' + index} errorPrefix={error.errorPrefix} diff={error.diff!} errorSuffix={error.errorSuffix}></TestScreenshotErrorView>;
|
||||||
return <TestErrorView key={'test-result-error-message-' + index} error={error.error!}></TestErrorView>;
|
return <TestErrorView key={'test-result-error-message-' + index} error={error.error!} result={result}></TestErrorView>;
|
||||||
})}
|
})}
|
||||||
</AutoChip>}
|
</AutoChip>}
|
||||||
{!!result.steps.length && <AutoChip header='Test Steps'>
|
{!!result.steps.length && <AutoChip header='Test Steps'>
|
||||||
|
|
@ -182,7 +182,7 @@ const StepTreeItem: React.FC<{
|
||||||
{step.count > 1 && <> ✕ <span className='test-result-counter'>{step.count}</span></>}
|
{step.count > 1 && <> ✕ <span className='test-result-counter'>{step.count}</span></>}
|
||||||
{step.location && <span className='test-result-path'>— {step.location.file}:{step.location.line}</span>}
|
{step.location && <span className='test-result-path'>— {step.location.file}:{step.location.line}</span>}
|
||||||
</span>} loadChildren={step.steps.length || step.snippet ? () => {
|
</span>} loadChildren={step.steps.length || step.snippet ? () => {
|
||||||
const snippet = step.snippet ? [<TestErrorView testId='test-snippet' key='line' error={step.snippet}/>] : [];
|
const snippet = step.snippet ? [<CodeSnippet testId='test-snippet' key='line' code={step.snippet} />] : [];
|
||||||
const steps = step.steps.map((s, i) => <StepTreeItem key={i} step={s} depth={depth + 1} result={result} test={test} />);
|
const steps = step.steps.map((s, i) => <StepTreeItem key={i} step={s} depth={depth + 1} result={result} test={test} />);
|
||||||
return snippet.concat(steps);
|
return snippet.concat(steps);
|
||||||
} : undefined} depth={depth}/>;
|
} : undefined} depth={depth}/>;
|
||||||
|
|
|
||||||
|
|
@ -3,33 +3,33 @@
|
||||||
"browsers": [
|
"browsers": [
|
||||||
{
|
{
|
||||||
"name": "chromium",
|
"name": "chromium",
|
||||||
"revision": "1157",
|
"revision": "1158",
|
||||||
"installByDefault": true,
|
"installByDefault": true,
|
||||||
"browserVersion": "133.0.6943.35"
|
"browserVersion": "134.0.6998.3"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "chromium-headless-shell",
|
"name": "chromium-headless-shell",
|
||||||
"revision": "1157",
|
"revision": "1158",
|
||||||
"installByDefault": true,
|
"installByDefault": true,
|
||||||
"browserVersion": "133.0.6943.35"
|
"browserVersion": "134.0.6998.3"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "chromium-tip-of-tree",
|
"name": "chromium-tip-of-tree",
|
||||||
"revision": "1300",
|
"revision": "1301",
|
||||||
"installByDefault": false,
|
"installByDefault": false,
|
||||||
"browserVersion": "134.0.6998.0"
|
"browserVersion": "135.0.7000.0"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "chromium-tip-of-tree-headless-shell",
|
"name": "chromium-tip-of-tree-headless-shell",
|
||||||
"revision": "1300",
|
"revision": "1301",
|
||||||
"installByDefault": false,
|
"installByDefault": false,
|
||||||
"browserVersion": "134.0.6998.0"
|
"browserVersion": "135.0.7000.0"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "firefox",
|
"name": "firefox",
|
||||||
"revision": "1474",
|
"revision": "1475",
|
||||||
"installByDefault": true,
|
"installByDefault": true,
|
||||||
"browserVersion": "134.0"
|
"browserVersion": "135.0"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "firefox-beta",
|
"name": "firefox-beta",
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,8 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/* eslint-disable import/order */
|
||||||
|
|
||||||
import colorsLibrary from 'colors/safe';
|
import colorsLibrary from 'colors/safe';
|
||||||
export const colors = colorsLibrary;
|
export const colors = colorsLibrary;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -14,13 +14,14 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import type { LaunchAndroidServerOptions } from './client/types';
|
|
||||||
import { ws } from './utilsBundle';
|
|
||||||
import type { WebSocketEventEmitter } from './utilsBundle';
|
|
||||||
import type { BrowserServer } from './client/browserType';
|
|
||||||
import { createGuid } from './utils';
|
|
||||||
import { createPlaywright } from './server/playwright';
|
|
||||||
import { PlaywrightServer } from './remote/playwrightServer';
|
import { PlaywrightServer } from './remote/playwrightServer';
|
||||||
|
import { createPlaywright } from './server/playwright';
|
||||||
|
import { createGuid } from './utils';
|
||||||
|
import { ws } from './utilsBundle';
|
||||||
|
|
||||||
|
import type { BrowserServer } from './client/browserType';
|
||||||
|
import type { LaunchAndroidServerOptions } from './client/types';
|
||||||
|
import type { WebSocketEventEmitter } from './utilsBundle';
|
||||||
|
|
||||||
export class AndroidServerLauncherImpl {
|
export class AndroidServerLauncherImpl {
|
||||||
async launchServer(options: LaunchAndroidServerOptions = {}): Promise<BrowserServer> {
|
async launchServer(options: LaunchAndroidServerOptions = {}): Promise<BrowserServer> {
|
||||||
|
|
|
||||||
|
|
@ -14,19 +14,20 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import type { LaunchServerOptions, Logger } from './client/types';
|
|
||||||
import { ws } from './utilsBundle';
|
|
||||||
import type { WebSocketEventEmitter } from './utilsBundle';
|
|
||||||
import type { BrowserServerLauncher, BrowserServer } from './client/browserType';
|
|
||||||
import { envObjectToArray } from './client/clientHelper';
|
import { envObjectToArray } from './client/clientHelper';
|
||||||
import { createGuid } from './utils';
|
import { SocksProxy } from './common/socksProxy';
|
||||||
import type { ProtocolLogger } from './server/types';
|
|
||||||
import { serverSideCallMetadata } from './server/instrumentation';
|
|
||||||
import { createPlaywright } from './server/playwright';
|
|
||||||
import { PlaywrightServer } from './remote/playwrightServer';
|
import { PlaywrightServer } from './remote/playwrightServer';
|
||||||
import { helper } from './server/helper';
|
import { helper } from './server/helper';
|
||||||
|
import { serverSideCallMetadata } from './server/instrumentation';
|
||||||
|
import { createPlaywright } from './server/playwright';
|
||||||
|
import { createGuid } from './utils';
|
||||||
import { rewriteErrorMessage } from './utils/stackTrace';
|
import { rewriteErrorMessage } from './utils/stackTrace';
|
||||||
import { SocksProxy } from './common/socksProxy';
|
import { ws } from './utilsBundle';
|
||||||
|
|
||||||
|
import type { BrowserServer, BrowserServerLauncher } from './client/browserType';
|
||||||
|
import type { LaunchServerOptions, Logger } from './client/types';
|
||||||
|
import type { ProtocolLogger } from './server/types';
|
||||||
|
import type { WebSocketEventEmitter } from './utilsBundle';
|
||||||
|
|
||||||
export class BrowserServerLauncherImpl implements BrowserServerLauncher {
|
export class BrowserServerLauncherImpl implements BrowserServerLauncher {
|
||||||
private _browserName: 'chromium' | 'firefox' | 'webkit' | 'bidiFirefox' | 'bidiChromium';
|
private _browserName: 'chromium' | 'firefox' | 'webkit' | 'bidiFirefox' | 'bidiChromium';
|
||||||
|
|
|
||||||
|
|
@ -16,15 +16,17 @@
|
||||||
|
|
||||||
/* eslint-disable no-console */
|
/* eslint-disable no-console */
|
||||||
|
|
||||||
import fs from 'fs';
|
import * as fs from 'fs';
|
||||||
|
|
||||||
import * as playwright from '../..';
|
import * as playwright from '../..';
|
||||||
import type { BrowserType } from '../client/browserType';
|
|
||||||
import type { LaunchServerOptions } from '../client/types';
|
|
||||||
import { createPlaywright, DispatcherConnection, RootDispatcher, PlaywrightDispatcher } from '../server';
|
|
||||||
import { PipeTransport } from '../protocol/transport';
|
import { PipeTransport } from '../protocol/transport';
|
||||||
import { PlaywrightServer } from '../remote/playwrightServer';
|
import { PlaywrightServer } from '../remote/playwrightServer';
|
||||||
|
import { DispatcherConnection, PlaywrightDispatcher, RootDispatcher, createPlaywright } from '../server';
|
||||||
import { gracefullyProcessExitDoNotHang } from '../utils/processLauncher';
|
import { gracefullyProcessExitDoNotHang } from '../utils/processLauncher';
|
||||||
|
|
||||||
|
import type { BrowserType } from '../client/browserType';
|
||||||
|
import type { LaunchServerOptions } from '../client/types';
|
||||||
|
|
||||||
export function printApiJson() {
|
export function printApiJson() {
|
||||||
// Note: this file is generated by build-playwright-driver.sh
|
// Note: this file is generated by build-playwright-driver.sh
|
||||||
console.log(JSON.stringify(require('../../api.json')));
|
console.log(JSON.stringify(require('../../api.json')));
|
||||||
|
|
|
||||||
|
|
@ -16,25 +16,28 @@
|
||||||
|
|
||||||
/* eslint-disable no-console */
|
/* eslint-disable no-console */
|
||||||
|
|
||||||
import fs from 'fs';
|
import * as fs from 'fs';
|
||||||
import os from 'os';
|
import * as os from 'os';
|
||||||
import path from 'path';
|
import * as path from 'path';
|
||||||
import type { Command } from '../utilsBundle';
|
|
||||||
import { program, dotenv } from '../utilsBundle';
|
|
||||||
export { program } from '../utilsBundle';
|
|
||||||
import { runDriver, runServer, printApiJson, launchBrowserServer } from './driver';
|
|
||||||
import { runTraceInBrowser, runTraceViewerApp } from '../server/trace/viewer/traceViewer';
|
|
||||||
import type { TraceViewerServerOptions } from '../server/trace/viewer/traceViewer';
|
|
||||||
import * as playwright from '../..';
|
import * as playwright from '../..';
|
||||||
import type { BrowserContext } from '../client/browserContext';
|
|
||||||
import type { Browser } from '../client/browser';
|
|
||||||
import type { Page } from '../client/page';
|
|
||||||
import type { BrowserType } from '../client/browserType';
|
|
||||||
import type { BrowserContextOptions, LaunchOptions } from '../client/types';
|
|
||||||
import { wrapInASCIIBox, isLikelyNpxGlobal, assert, gracefullyProcessExitDoNotHang, getPackageManagerExecCommand } from '../utils';
|
|
||||||
import type { Executable } from '../server';
|
|
||||||
import { registry, writeDockerVersion } from '../server';
|
import { registry, writeDockerVersion } from '../server';
|
||||||
|
import { launchBrowserServer, printApiJson, runDriver, runServer } from './driver';
|
||||||
import { isTargetClosedError } from '../client/errors';
|
import { isTargetClosedError } from '../client/errors';
|
||||||
|
import { runTraceInBrowser, runTraceViewerApp } from '../server/trace/viewer/traceViewer';
|
||||||
|
import { assert, getPackageManagerExecCommand, gracefullyProcessExitDoNotHang, isLikelyNpxGlobal, wrapInASCIIBox } from '../utils';
|
||||||
|
import { dotenv, program } from '../utilsBundle';
|
||||||
|
|
||||||
|
import type { Browser } from '../client/browser';
|
||||||
|
import type { BrowserContext } from '../client/browserContext';
|
||||||
|
import type { BrowserType } from '../client/browserType';
|
||||||
|
import type { Page } from '../client/page';
|
||||||
|
import type { BrowserContextOptions, LaunchOptions } from '../client/types';
|
||||||
|
import type { Executable } from '../server';
|
||||||
|
import type { TraceViewerServerOptions } from '../server/trace/viewer/traceViewer';
|
||||||
|
import type { Command } from '../utilsBundle';
|
||||||
|
|
||||||
|
export { program } from '../utilsBundle';
|
||||||
|
|
||||||
const packageJSON = require('../../package.json');
|
const packageJSON = require('../../package.json');
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -15,9 +15,9 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import type * as channels from '@protocol/channels';
|
|
||||||
import type { ElementHandle } from './elementHandle';
|
import type { ElementHandle } from './elementHandle';
|
||||||
import type * as api from '../../types/types';
|
import type * as api from '../../types/types';
|
||||||
|
import type * as channels from '@protocol/channels';
|
||||||
|
|
||||||
type SerializedAXNode = Omit<channels.AXNode, 'valueString' | 'valueNumber' | 'children' | 'checked' | 'pressed'> & {
|
type SerializedAXNode = Omit<channels.AXNode, 'valueString' | 'valueNumber' | 'children' | 'checked' | 'pressed'> & {
|
||||||
value?: string|number,
|
value?: string|number,
|
||||||
|
|
|
||||||
|
|
@ -14,22 +14,24 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import fs from 'fs';
|
import { EventEmitter } from 'events';
|
||||||
import { isString, isRegExp, monotonicTime } from '../utils';
|
import * as fs from 'fs';
|
||||||
import type * as channels from '@protocol/channels';
|
|
||||||
import { Events } from './events';
|
import { isRegExp, isString, monotonicTime } from '../utils';
|
||||||
import { BrowserContext, prepareBrowserContextParams } from './browserContext';
|
import { BrowserContext, prepareBrowserContextParams } from './browserContext';
|
||||||
import { ChannelOwner } from './channelOwner';
|
import { ChannelOwner } from './channelOwner';
|
||||||
import type * as api from '../../types/types';
|
|
||||||
import type * as types from './types';
|
|
||||||
import type { Page } from './page';
|
|
||||||
import { TimeoutSettings } from '../common/timeoutSettings';
|
|
||||||
import { Waiter } from './waiter';
|
|
||||||
import { EventEmitter } from 'events';
|
|
||||||
import { Connection } from './connection';
|
import { Connection } from './connection';
|
||||||
import { isTargetClosedError, TargetClosedError } from './errors';
|
import { TargetClosedError, isTargetClosedError } from './errors';
|
||||||
|
import { Events } from './events';
|
||||||
|
import { Waiter } from './waiter';
|
||||||
|
import { TimeoutSettings } from '../common/timeoutSettings';
|
||||||
import { raceAgainstDeadline } from '../utils/timeoutRunner';
|
import { raceAgainstDeadline } from '../utils/timeoutRunner';
|
||||||
|
|
||||||
|
import type { Page } from './page';
|
||||||
|
import type * as types from './types';
|
||||||
|
import type * as api from '../../types/types';
|
||||||
import type { AndroidServerLauncherImpl } from '../androidServerImpl';
|
import type { AndroidServerLauncherImpl } from '../androidServerImpl';
|
||||||
|
import type * as channels from '@protocol/channels';
|
||||||
|
|
||||||
type Direction = 'down' | 'up' | 'left' | 'right';
|
type Direction = 'down' | 'up' | 'left' | 'right';
|
||||||
type SpeedOptions = { speed?: number };
|
type SpeedOptions = { speed?: number };
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
export { Accessibility } from './accessibility';
|
export { Accessibility } from './accessibility';
|
||||||
export { Android, AndroidDevice, AndroidWebView, AndroidInput, AndroidSocket } from './android';
|
export { Android, AndroidDevice, AndroidInput, AndroidSocket, AndroidWebView } from './android';
|
||||||
export { Browser } from './browser';
|
export { Browser } from './browser';
|
||||||
export { BrowserContext } from './browserContext';
|
export { BrowserContext } from './browserContext';
|
||||||
export type { BrowserServer } from './browserType';
|
export type { BrowserServer } from './browserType';
|
||||||
|
|
@ -26,7 +26,7 @@ export { Coverage } from './coverage';
|
||||||
export { Dialog } from './dialog';
|
export { Dialog } from './dialog';
|
||||||
export { Download } from './download';
|
export { Download } from './download';
|
||||||
export { Electron, ElectronApplication } from './electron';
|
export { Electron, ElectronApplication } from './electron';
|
||||||
export { Locator, FrameLocator } from './locator';
|
export { FrameLocator, Locator } from './locator';
|
||||||
export { ElementHandle } from './elementHandle';
|
export { ElementHandle } from './elementHandle';
|
||||||
export { FileChooser } from './fileChooser';
|
export { FileChooser } from './fileChooser';
|
||||||
export type { Logger } from './types';
|
export type { Logger } from './types';
|
||||||
|
|
|
||||||
|
|
@ -14,11 +14,13 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import type * as channels from '@protocol/channels';
|
|
||||||
import * as fs from 'fs';
|
import * as fs from 'fs';
|
||||||
|
|
||||||
|
import { ChannelOwner } from './channelOwner';
|
||||||
import { Stream } from './stream';
|
import { Stream } from './stream';
|
||||||
import { mkdirIfNeeded } from '../utils/fileUtils';
|
import { mkdirIfNeeded } from '../utils/fileUtils';
|
||||||
import { ChannelOwner } from './channelOwner';
|
|
||||||
|
import type * as channels from '@protocol/channels';
|
||||||
import type { Readable } from 'stream';
|
import type { Readable } from 'stream';
|
||||||
|
|
||||||
export class Artifact extends ChannelOwner<channels.ArtifactChannel> {
|
export class Artifact extends ChannelOwner<channels.ArtifactChannel> {
|
||||||
|
|
|
||||||
|
|
@ -14,20 +14,22 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import fs from 'fs';
|
import * as fs from 'fs';
|
||||||
import type * as channels from '@protocol/channels';
|
|
||||||
import { BrowserContext, prepareBrowserContextParams } from './browserContext';
|
|
||||||
import type { Page } from './page';
|
|
||||||
import { ChannelOwner } from './channelOwner';
|
|
||||||
import { Events } from './events';
|
|
||||||
import type { LaunchOptions, BrowserContextOptions, HeadersArray } from './types';
|
|
||||||
import { isTargetClosedError } from './errors';
|
|
||||||
import type * as api from '../../types/types';
|
|
||||||
import { CDPSession } from './cdpSession';
|
|
||||||
import type { BrowserType } from './browserType';
|
|
||||||
import { Artifact } from './artifact';
|
import { Artifact } from './artifact';
|
||||||
|
import { BrowserContext, prepareBrowserContextParams } from './browserContext';
|
||||||
|
import { CDPSession } from './cdpSession';
|
||||||
|
import { ChannelOwner } from './channelOwner';
|
||||||
|
import { isTargetClosedError } from './errors';
|
||||||
|
import { Events } from './events';
|
||||||
import { mkdirIfNeeded } from '../utils';
|
import { mkdirIfNeeded } from '../utils';
|
||||||
|
|
||||||
|
import type { BrowserType } from './browserType';
|
||||||
|
import type { Page } from './page';
|
||||||
|
import type { BrowserContextOptions, HeadersArray, LaunchOptions } from './types';
|
||||||
|
import type * as api from '../../types/types';
|
||||||
|
import type * as channels from '@protocol/channels';
|
||||||
|
|
||||||
export class Browser extends ChannelOwner<channels.BrowserChannel> implements api.Browser {
|
export class Browser extends ChannelOwner<channels.BrowserChannel> implements api.Browser {
|
||||||
readonly _contexts = new Set<BrowserContext>();
|
readonly _contexts = new Set<BrowserContext>();
|
||||||
private _isConnected = true;
|
private _isConnected = true;
|
||||||
|
|
|
||||||
|
|
@ -15,35 +15,38 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { Page, BindingCall } from './page';
|
import * as fs from 'fs';
|
||||||
import { Frame } from './frame';
|
import * as path from 'path';
|
||||||
import * as network from './network';
|
|
||||||
import type * as channels from '@protocol/channels';
|
import { Artifact } from './artifact';
|
||||||
import fs from 'fs';
|
import { Browser } from './browser';
|
||||||
import path from 'path';
|
import { CDPSession } from './cdpSession';
|
||||||
import { ChannelOwner } from './channelOwner';
|
import { ChannelOwner } from './channelOwner';
|
||||||
import { evaluationScript } from './clientHelper';
|
import { evaluationScript } from './clientHelper';
|
||||||
import { Browser } from './browser';
|
import { Clock } from './clock';
|
||||||
import { Worker } from './worker';
|
|
||||||
import { Events } from './events';
|
|
||||||
import { TimeoutSettings } from '../common/timeoutSettings';
|
|
||||||
import { Waiter } from './waiter';
|
|
||||||
import type { Headers, WaitForEventOptions, BrowserContextOptions, LaunchOptions, StorageState } from './types';
|
|
||||||
import { type URLMatch, headersObjectToArray, isRegExp, isString, urlMatchesEqual, mkdirIfNeeded } from '../utils';
|
|
||||||
import type * as api from '../../types/types';
|
|
||||||
import type * as structs from '../../types/structs';
|
|
||||||
import { CDPSession } from './cdpSession';
|
|
||||||
import { Tracing } from './tracing';
|
|
||||||
import type { BrowserType } from './browserType';
|
|
||||||
import { Artifact } from './artifact';
|
|
||||||
import { APIRequestContext } from './fetch';
|
|
||||||
import { rewriteErrorMessage } from '../utils/stackTrace';
|
|
||||||
import { HarRouter } from './harRouter';
|
|
||||||
import { ConsoleMessage } from './consoleMessage';
|
import { ConsoleMessage } from './consoleMessage';
|
||||||
import { Dialog } from './dialog';
|
import { Dialog } from './dialog';
|
||||||
import { WebError } from './webError';
|
|
||||||
import { TargetClosedError, parseError } from './errors';
|
import { TargetClosedError, parseError } from './errors';
|
||||||
import { Clock } from './clock';
|
import { Events } from './events';
|
||||||
|
import { APIRequestContext } from './fetch';
|
||||||
|
import { Frame } from './frame';
|
||||||
|
import { HarRouter } from './harRouter';
|
||||||
|
import * as network from './network';
|
||||||
|
import { BindingCall, Page } from './page';
|
||||||
|
import { Tracing } from './tracing';
|
||||||
|
import { Waiter } from './waiter';
|
||||||
|
import { WebError } from './webError';
|
||||||
|
import { Worker } from './worker';
|
||||||
|
import { TimeoutSettings } from '../common/timeoutSettings';
|
||||||
|
import { headersObjectToArray, isRegExp, isString, mkdirIfNeeded, urlMatchesEqual } from '../utils';
|
||||||
|
import { rewriteErrorMessage } from '../utils/stackTrace';
|
||||||
|
|
||||||
|
import type { BrowserType } from './browserType';
|
||||||
|
import type { BrowserContextOptions, Headers, LaunchOptions, StorageState, WaitForEventOptions } from './types';
|
||||||
|
import type * as structs from '../../types/structs';
|
||||||
|
import type * as api from '../../types/types';
|
||||||
|
import type { URLMatch } from '../utils';
|
||||||
|
import type * as channels from '@protocol/channels';
|
||||||
|
|
||||||
export class BrowserContext extends ChannelOwner<channels.BrowserContextChannel> implements api.BrowserContext {
|
export class BrowserContext extends ChannelOwner<channels.BrowserContextChannel> implements api.BrowserContext {
|
||||||
_pages = new Set<Page>();
|
_pages = new Set<Page>();
|
||||||
|
|
|
||||||
|
|
@ -14,19 +14,20 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import type * as channels from '@protocol/channels';
|
|
||||||
import { Browser } from './browser';
|
import { Browser } from './browser';
|
||||||
import { BrowserContext, prepareBrowserContextParams } from './browserContext';
|
import { BrowserContext, prepareBrowserContextParams } from './browserContext';
|
||||||
import { ChannelOwner } from './channelOwner';
|
import { ChannelOwner } from './channelOwner';
|
||||||
import type { LaunchOptions, LaunchServerOptions, ConnectOptions, LaunchPersistentContextOptions, Logger } from './types';
|
import { envObjectToArray } from './clientHelper';
|
||||||
import { Connection } from './connection';
|
import { Connection } from './connection';
|
||||||
import { Events } from './events';
|
import { Events } from './events';
|
||||||
import type { ChildProcess } from 'child_process';
|
|
||||||
import { envObjectToArray } from './clientHelper';
|
|
||||||
import { assert, headersObjectToArray, monotonicTime } from '../utils';
|
import { assert, headersObjectToArray, monotonicTime } from '../utils';
|
||||||
import type * as api from '../../types/types';
|
|
||||||
import { raceAgainstDeadline } from '../utils/timeoutRunner';
|
import { raceAgainstDeadline } from '../utils/timeoutRunner';
|
||||||
|
|
||||||
import type { Playwright } from './playwright';
|
import type { Playwright } from './playwright';
|
||||||
|
import type { ConnectOptions, LaunchOptions, LaunchPersistentContextOptions, LaunchServerOptions, Logger } from './types';
|
||||||
|
import type * as api from '../../types/types';
|
||||||
|
import type * as channels from '@protocol/channels';
|
||||||
|
import type { ChildProcess } from 'child_process';
|
||||||
|
|
||||||
export interface BrowserServerLauncher {
|
export interface BrowserServerLauncher {
|
||||||
launchServer(options?: LaunchServerOptions): Promise<api.BrowserServer>;
|
launchServer(options?: LaunchServerOptions): Promise<api.BrowserServer>;
|
||||||
|
|
|
||||||
|
|
@ -14,10 +14,11 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import type * as channels from '@protocol/channels';
|
|
||||||
import { ChannelOwner } from './channelOwner';
|
import { ChannelOwner } from './channelOwner';
|
||||||
import type { Protocol } from '../server/chromium/protocol';
|
|
||||||
import type * as api from '../../types/types';
|
import type * as api from '../../types/types';
|
||||||
|
import type { Protocol } from '../server/chromium/protocol';
|
||||||
|
import type * as channels from '@protocol/channels';
|
||||||
|
|
||||||
export class CDPSession extends ChannelOwner<channels.CDPSessionChannel> implements api.CDPSession {
|
export class CDPSession extends ChannelOwner<channels.CDPSessionChannel> implements api.CDPSession {
|
||||||
static from(cdpSession: channels.CDPSessionChannel): CDPSession {
|
static from(cdpSession: channels.CDPSessionChannel): CDPSession {
|
||||||
|
|
|
||||||
|
|
@ -15,15 +15,17 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { EventEmitter } from './eventEmitter';
|
import { EventEmitter } from './eventEmitter';
|
||||||
import type * as channels from '@protocol/channels';
|
import { ValidationError, maybeFindValidator } from '../protocol/validator';
|
||||||
import { maybeFindValidator, ValidationError, type ValidatorContext } from '../protocol/validator';
|
import { isUnderTest } from '../utils';
|
||||||
import { debugLogger } from '../utils/debugLogger';
|
import { debugLogger } from '../utils/debugLogger';
|
||||||
import { captureLibraryStackTrace, stringifyStackFrames } from '../utils/stackTrace';
|
import { captureLibraryStackTrace, stringifyStackFrames } from '../utils/stackTrace';
|
||||||
import { isUnderTest } from '../utils';
|
|
||||||
import { zones } from '../utils/zones';
|
import { zones } from '../utils/zones';
|
||||||
|
|
||||||
import type { ClientInstrumentation } from './clientInstrumentation';
|
import type { ClientInstrumentation } from './clientInstrumentation';
|
||||||
import type { Connection } from './connection';
|
import type { Connection } from './connection';
|
||||||
import type { Logger } from './types';
|
import type { Logger } from './types';
|
||||||
|
import type { ValidatorContext } from '../protocol/validator';
|
||||||
|
import type * as channels from '@protocol/channels';
|
||||||
|
|
||||||
type Listener = (...args: any[]) => void;
|
type Listener = (...args: any[]) => void;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -15,10 +15,12 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import type * as types from './types';
|
import * as fs from 'fs';
|
||||||
import fs from 'fs';
|
|
||||||
import { isString } from '../utils';
|
import { isString } from '../utils';
|
||||||
|
|
||||||
|
import type * as types from './types';
|
||||||
|
|
||||||
export function envObjectToArray(env: types.Env): { name: string, value: string }[] {
|
export function envObjectToArray(env: types.Env): { name: string, value: string }[] {
|
||||||
const result: { name: string, value: string }[] = [];
|
const result: { name: string, value: string }[] = [];
|
||||||
for (const name in env) {
|
for (const name in env) {
|
||||||
|
|
|
||||||
|
|
@ -14,9 +14,9 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import type { StackFrame } from '@protocol/channels';
|
|
||||||
import type { BrowserContext } from './browserContext';
|
import type { BrowserContext } from './browserContext';
|
||||||
import type { APIRequestContext } from './fetch';
|
import type { APIRequestContext } from './fetch';
|
||||||
|
import type { StackFrame } from '@protocol/channels';
|
||||||
|
|
||||||
// Instrumentation can mutate the data, for example change apiName or stepId.
|
// Instrumentation can mutate the data, for example change apiName or stepId.
|
||||||
export interface ApiCallData {
|
export interface ApiCallData {
|
||||||
|
|
|
||||||
|
|
@ -14,8 +14,8 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import type * as api from '../../types/types';
|
|
||||||
import type { BrowserContext } from './browserContext';
|
import type { BrowserContext } from './browserContext';
|
||||||
|
import type * as api from '../../types/types';
|
||||||
|
|
||||||
export class Clock implements api.Clock {
|
export class Clock implements api.Clock {
|
||||||
private _browserContext: BrowserContext;
|
private _browserContext: BrowserContext;
|
||||||
|
|
|
||||||
|
|
@ -14,37 +14,40 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import { EventEmitter } from 'events';
|
||||||
|
|
||||||
|
import { Android, AndroidDevice, AndroidSocket } from './android';
|
||||||
|
import { Artifact } from './artifact';
|
||||||
import { Browser } from './browser';
|
import { Browser } from './browser';
|
||||||
import { BrowserContext } from './browserContext';
|
import { BrowserContext } from './browserContext';
|
||||||
import { BrowserType } from './browserType';
|
import { BrowserType } from './browserType';
|
||||||
|
import { CDPSession } from './cdpSession';
|
||||||
import { ChannelOwner } from './channelOwner';
|
import { ChannelOwner } from './channelOwner';
|
||||||
|
import { createInstrumentation } from './clientInstrumentation';
|
||||||
|
import { Dialog } from './dialog';
|
||||||
|
import { Electron, ElectronApplication } from './electron';
|
||||||
import { ElementHandle } from './elementHandle';
|
import { ElementHandle } from './elementHandle';
|
||||||
|
import { TargetClosedError, parseError } from './errors';
|
||||||
|
import { APIRequestContext } from './fetch';
|
||||||
import { Frame } from './frame';
|
import { Frame } from './frame';
|
||||||
import { JSHandle } from './jsHandle';
|
import { JSHandle } from './jsHandle';
|
||||||
import { Request, Response, Route, WebSocket, WebSocketRoute } from './network';
|
|
||||||
import { Page, BindingCall } from './page';
|
|
||||||
import { Worker } from './worker';
|
|
||||||
import { Dialog } from './dialog';
|
|
||||||
import { parseError, TargetClosedError } from './errors';
|
|
||||||
import { CDPSession } from './cdpSession';
|
|
||||||
import { Playwright } from './playwright';
|
|
||||||
import { Electron, ElectronApplication } from './electron';
|
|
||||||
import type * as channels from '@protocol/channels';
|
|
||||||
import { Stream } from './stream';
|
|
||||||
import { WritableStream } from './writableStream';
|
|
||||||
import { debugLogger } from '../utils/debugLogger';
|
|
||||||
import { SelectorsOwner } from './selectors';
|
|
||||||
import { Android, AndroidSocket, AndroidDevice } from './android';
|
|
||||||
import { Artifact } from './artifact';
|
|
||||||
import { EventEmitter } from 'events';
|
|
||||||
import { JsonPipe } from './jsonPipe';
|
import { JsonPipe } from './jsonPipe';
|
||||||
import { APIRequestContext } from './fetch';
|
|
||||||
import { LocalUtils } from './localUtils';
|
import { LocalUtils } from './localUtils';
|
||||||
|
import { Request, Response, Route, WebSocket, WebSocketRoute } from './network';
|
||||||
|
import { BindingCall, Page } from './page';
|
||||||
|
import { Playwright } from './playwright';
|
||||||
|
import { SelectorsOwner } from './selectors';
|
||||||
|
import { Stream } from './stream';
|
||||||
import { Tracing } from './tracing';
|
import { Tracing } from './tracing';
|
||||||
import { findValidator, ValidationError, type ValidatorContext } from '../protocol/validator';
|
import { Worker } from './worker';
|
||||||
import { createInstrumentation } from './clientInstrumentation';
|
import { WritableStream } from './writableStream';
|
||||||
import type { ClientInstrumentation } from './clientInstrumentation';
|
import { ValidationError, findValidator } from '../protocol/validator';
|
||||||
import { formatCallLog, rewriteErrorMessage, zones } from '../utils';
|
import { formatCallLog, rewriteErrorMessage, zones } from '../utils';
|
||||||
|
import { debugLogger } from '../utils/debugLogger';
|
||||||
|
|
||||||
|
import type { ClientInstrumentation } from './clientInstrumentation';
|
||||||
|
import type { ValidatorContext } from '../protocol/validator';
|
||||||
|
import type * as channels from '@protocol/channels';
|
||||||
|
|
||||||
class Root extends ChannelOwner<channels.RootChannel> {
|
class Root extends ChannelOwner<channels.RootChannel> {
|
||||||
constructor(connection: Connection) {
|
constructor(connection: Connection) {
|
||||||
|
|
|
||||||
|
|
@ -15,11 +15,13 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import * as util from 'util';
|
import * as util from 'util';
|
||||||
|
|
||||||
import { JSHandle } from './jsHandle';
|
import { JSHandle } from './jsHandle';
|
||||||
import type * as channels from '@protocol/channels';
|
|
||||||
import type * as api from '../../types/types';
|
|
||||||
import { Page } from './page';
|
import { Page } from './page';
|
||||||
|
|
||||||
|
import type * as api from '../../types/types';
|
||||||
|
import type * as channels from '@protocol/channels';
|
||||||
|
|
||||||
type ConsoleMessageLocation = channels.BrowserContextConsoleEvent['location'];
|
type ConsoleMessageLocation = channels.BrowserContextConsoleEvent['location'];
|
||||||
|
|
||||||
export class ConsoleMessage implements api.ConsoleMessage {
|
export class ConsoleMessage implements api.ConsoleMessage {
|
||||||
|
|
|
||||||
|
|
@ -14,8 +14,8 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import type * as channels from '@protocol/channels';
|
|
||||||
import type * as api from '../../types/types';
|
import type * as api from '../../types/types';
|
||||||
|
import type * as channels from '@protocol/channels';
|
||||||
|
|
||||||
export class Coverage implements api.Coverage {
|
export class Coverage implements api.Coverage {
|
||||||
private _channel: channels.PageChannel;
|
private _channel: channels.PageChannel;
|
||||||
|
|
|
||||||
|
|
@ -14,11 +14,13 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import type * as channels from '@protocol/channels';
|
|
||||||
import { ChannelOwner } from './channelOwner';
|
import { ChannelOwner } from './channelOwner';
|
||||||
import type * as api from '../../types/types';
|
|
||||||
import { Page } from './page';
|
import { Page } from './page';
|
||||||
|
|
||||||
|
import type * as api from '../../types/types';
|
||||||
|
import type * as channels from '@protocol/channels';
|
||||||
|
|
||||||
|
|
||||||
export class Dialog extends ChannelOwner<channels.DialogChannel> implements api.Dialog {
|
export class Dialog extends ChannelOwner<channels.DialogChannel> implements api.Dialog {
|
||||||
static from(dialog: channels.DialogChannel): Dialog {
|
static from(dialog: channels.DialogChannel): Dialog {
|
||||||
return (dialog as any)._object;
|
return (dialog as any)._object;
|
||||||
|
|
|
||||||
|
|
@ -14,10 +14,10 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import type { Readable } from 'stream';
|
|
||||||
import type * as api from '../../types/types';
|
|
||||||
import type { Artifact } from './artifact';
|
import type { Artifact } from './artifact';
|
||||||
import type { Page } from './page';
|
import type { Page } from './page';
|
||||||
|
import type * as api from '../../types/types';
|
||||||
|
import type { Readable } from 'stream';
|
||||||
|
|
||||||
export class Download implements api.Download {
|
export class Download implements api.Download {
|
||||||
private _page: Page;
|
private _page: Page;
|
||||||
|
|
|
||||||
|
|
@ -14,22 +14,23 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import type { BrowserWindow } from 'electron';
|
|
||||||
import type * as childProcess from 'child_process';
|
|
||||||
import type * as structs from '../../types/structs';
|
|
||||||
import type * as api from '../../types/types';
|
|
||||||
import type * as channels from '@protocol/channels';
|
|
||||||
import { TimeoutSettings } from '../common/timeoutSettings';
|
|
||||||
import { BrowserContext, prepareBrowserContextParams } from './browserContext';
|
import { BrowserContext, prepareBrowserContextParams } from './browserContext';
|
||||||
import { ChannelOwner } from './channelOwner';
|
import { ChannelOwner } from './channelOwner';
|
||||||
import { envObjectToArray } from './clientHelper';
|
import { envObjectToArray } from './clientHelper';
|
||||||
|
import { ConsoleMessage } from './consoleMessage';
|
||||||
|
import { TargetClosedError, isTargetClosedError } from './errors';
|
||||||
import { Events } from './events';
|
import { Events } from './events';
|
||||||
import { JSHandle, parseResult, serializeArgument } from './jsHandle';
|
import { JSHandle, parseResult, serializeArgument } from './jsHandle';
|
||||||
import type { Page } from './page';
|
|
||||||
import { ConsoleMessage } from './consoleMessage';
|
|
||||||
import type { Env, WaitForEventOptions, Headers, BrowserContextOptions } from './types';
|
|
||||||
import { Waiter } from './waiter';
|
import { Waiter } from './waiter';
|
||||||
import { TargetClosedError, isTargetClosedError } from './errors';
|
import { TimeoutSettings } from '../common/timeoutSettings';
|
||||||
|
|
||||||
|
import type { Page } from './page';
|
||||||
|
import type { BrowserContextOptions, Env, Headers, WaitForEventOptions } from './types';
|
||||||
|
import type * as structs from '../../types/structs';
|
||||||
|
import type * as api from '../../types/types';
|
||||||
|
import type * as channels from '@protocol/channels';
|
||||||
|
import type * as childProcess from 'child_process';
|
||||||
|
import type { BrowserWindow } from 'electron';
|
||||||
|
|
||||||
type ElectronOptions = Omit<channels.ElectronLaunchOptions, 'env'|'extraHTTPHeaders'|'recordHar'|'colorScheme'|'acceptDownloads'> & {
|
type ElectronOptions = Omit<channels.ElectronLaunchOptions, 'env'|'extraHTTPHeaders'|'recordHar'|'colorScheme'|'acceptDownloads'> & {
|
||||||
env?: Env,
|
env?: Env,
|
||||||
|
|
|
||||||
|
|
@ -14,24 +14,26 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import type * as channels from '@protocol/channels';
|
import * as fs from 'fs';
|
||||||
import { Frame } from './frame';
|
import * as path from 'path';
|
||||||
import type { Locator } from './locator';
|
|
||||||
import { JSHandle, serializeArgument, parseResult } from './jsHandle';
|
|
||||||
import type { ChannelOwner } from './channelOwner';
|
|
||||||
import type { SelectOption, FilePayload, Rect, SelectOptionOptions } from './types';
|
|
||||||
import fs from 'fs';
|
|
||||||
import { mime } from '../utilsBundle';
|
|
||||||
import path from 'path';
|
|
||||||
import { assert, isString } from '../utils';
|
|
||||||
import { fileUploadSizeLimit, mkdirIfNeeded } from '../utils/fileUtils';
|
|
||||||
import type * as api from '../../types/types';
|
|
||||||
import type * as structs from '../../types/structs';
|
|
||||||
import type { BrowserContext } from './browserContext';
|
|
||||||
import { WritableStream } from './writableStream';
|
|
||||||
import { pipeline } from 'stream';
|
import { pipeline } from 'stream';
|
||||||
import { promisify } from 'util';
|
import { promisify } from 'util';
|
||||||
|
|
||||||
|
import { Frame } from './frame';
|
||||||
|
import { JSHandle, parseResult, serializeArgument } from './jsHandle';
|
||||||
|
import { assert, isString } from '../utils';
|
||||||
|
import { fileUploadSizeLimit, mkdirIfNeeded } from '../utils/fileUtils';
|
||||||
|
import { mime } from '../utilsBundle';
|
||||||
|
import { WritableStream } from './writableStream';
|
||||||
|
|
||||||
|
import type { BrowserContext } from './browserContext';
|
||||||
|
import type { ChannelOwner } from './channelOwner';
|
||||||
|
import type { Locator } from './locator';
|
||||||
|
import type { FilePayload, Rect, SelectOption, SelectOptionOptions } from './types';
|
||||||
|
import type * as structs from '../../types/structs';
|
||||||
|
import type * as api from '../../types/types';
|
||||||
|
import type * as channels from '@protocol/channels';
|
||||||
|
|
||||||
const pipelineAsync = promisify(pipeline);
|
const pipelineAsync = promisify(pipeline);
|
||||||
|
|
||||||
export class ElementHandle<T extends Node = Node> extends JSHandle<T> implements api.ElementHandle {
|
export class ElementHandle<T extends Node = Node> extends JSHandle<T> implements api.ElementHandle {
|
||||||
|
|
|
||||||
|
|
@ -14,9 +14,10 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import type { SerializedError } from '@protocol/channels';
|
|
||||||
import { isError } from '../utils';
|
|
||||||
import { parseSerializedValue, serializeValue } from '../protocol/serializers';
|
import { parseSerializedValue, serializeValue } from '../protocol/serializers';
|
||||||
|
import { isError } from '../utils';
|
||||||
|
|
||||||
|
import type { SerializedError } from '@protocol/channels';
|
||||||
|
|
||||||
export class TimeoutError extends Error {
|
export class TimeoutError extends Error {
|
||||||
constructor(message: string) {
|
constructor(message: string) {
|
||||||
|
|
|
||||||
|
|
@ -22,12 +22,15 @@
|
||||||
* USE OR OTHER DEALINGS IN THE SOFTWARE.
|
* USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import { EventEmitter as OriginalEventEmitter } from 'events';
|
||||||
|
|
||||||
|
import { isUnderTest } from '../utils';
|
||||||
|
|
||||||
|
import type { EventEmitter as EventEmitterType } from 'events';
|
||||||
|
|
||||||
type EventType = string | symbol;
|
type EventType = string | symbol;
|
||||||
type Listener = (...args: any[]) => any;
|
type Listener = (...args: any[]) => any;
|
||||||
type EventMap = Record<EventType, Listener | Listener[]>;
|
type EventMap = Record<EventType, Listener | Listener[]>;
|
||||||
import { EventEmitter as OriginalEventEmitter } from 'events';
|
|
||||||
import type { EventEmitter as EventEmitterType } from 'events';
|
|
||||||
import { isUnderTest } from '../utils';
|
|
||||||
|
|
||||||
export class EventEmitter implements EventEmitterType {
|
export class EventEmitter implements EventEmitterType {
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -14,22 +14,24 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import fs from 'fs';
|
import * as fs from 'fs';
|
||||||
import path from 'path';
|
import * as path from 'path';
|
||||||
import * as util from 'util';
|
import * as util from 'util';
|
||||||
|
|
||||||
|
import { assert, headersObjectToArray, isString } from '../utils';
|
||||||
|
import { toClientCertificatesProtocol } from './browserContext';
|
||||||
|
import { ChannelOwner } from './channelOwner';
|
||||||
|
import { TargetClosedError, isTargetClosedError } from './errors';
|
||||||
|
import { RawHeaders } from './network';
|
||||||
|
import { Tracing } from './tracing';
|
||||||
|
import { mkdirIfNeeded } from '../utils/fileUtils';
|
||||||
|
|
||||||
|
import type { Playwright } from './playwright';
|
||||||
|
import type { ClientCertificate, FilePayload, Headers, SetStorageState, StorageState } from './types';
|
||||||
import type { Serializable } from '../../types/structs';
|
import type { Serializable } from '../../types/structs';
|
||||||
import type * as api from '../../types/types';
|
import type * as api from '../../types/types';
|
||||||
import type { HeadersArray, NameValue } from '../common/types';
|
import type { HeadersArray, NameValue } from '../common/types';
|
||||||
import type * as channels from '@protocol/channels';
|
import type * as channels from '@protocol/channels';
|
||||||
import { assert, headersObjectToArray, isString } from '../utils';
|
|
||||||
import { mkdirIfNeeded } from '../utils/fileUtils';
|
|
||||||
import { ChannelOwner } from './channelOwner';
|
|
||||||
import { RawHeaders } from './network';
|
|
||||||
import type { ClientCertificate, FilePayload, Headers, SetStorageState, StorageState } from './types';
|
|
||||||
import type { Playwright } from './playwright';
|
|
||||||
import { Tracing } from './tracing';
|
|
||||||
import { TargetClosedError, isTargetClosedError } from './errors';
|
|
||||||
import { toClientCertificatesProtocol } from './browserContext';
|
|
||||||
|
|
||||||
export type FetchOptions = {
|
export type FetchOptions = {
|
||||||
params?: { [key: string]: string | number | boolean; } | URLSearchParams | string,
|
params?: { [key: string]: string | number | boolean; } | URLSearchParams | string,
|
||||||
|
|
|
||||||
|
|
@ -17,8 +17,8 @@
|
||||||
import type { ElementHandle } from './elementHandle';
|
import type { ElementHandle } from './elementHandle';
|
||||||
import type { Page } from './page';
|
import type { Page } from './page';
|
||||||
import type { FilePayload } from './types';
|
import type { FilePayload } from './types';
|
||||||
import type * as channels from '@protocol/channels';
|
|
||||||
import type * as api from '../../types/types';
|
import type * as api from '../../types/types';
|
||||||
|
import type * as channels from '@protocol/channels';
|
||||||
|
|
||||||
export class FileChooser implements api.FileChooser {
|
export class FileChooser implements api.FileChooser {
|
||||||
private _page: Page;
|
private _page: Page;
|
||||||
|
|
|
||||||
|
|
@ -15,27 +15,30 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { assert } from '../utils';
|
import { EventEmitter } from 'events';
|
||||||
import type * as channels from '@protocol/channels';
|
import * as fs from 'fs';
|
||||||
|
|
||||||
import { ChannelOwner } from './channelOwner';
|
import { ChannelOwner } from './channelOwner';
|
||||||
import { FrameLocator, Locator, testIdAttributeName } from './locator';
|
import { FrameLocator, Locator, testIdAttributeName } from './locator';
|
||||||
import type { LocatorOptions } from './locator';
|
import { assert } from '../utils';
|
||||||
import { getByAltTextSelector, getByLabelSelector, getByPlaceholderSelector, getByRoleSelector, getByTestIdSelector, getByTextSelector, getByTitleSelector } from '../utils/isomorphic/locatorUtils';
|
import { urlMatches } from '../utils';
|
||||||
import type { ByRoleOptions } from '../utils/isomorphic/locatorUtils';
|
|
||||||
import { ElementHandle, convertSelectOptionValues, convertInputFiles } from './elementHandle';
|
|
||||||
import { assertMaxArguments, JSHandle, serializeArgument, parseResult } from './jsHandle';
|
|
||||||
import fs from 'fs';
|
|
||||||
import * as network from './network';
|
|
||||||
import type { Page } from './page';
|
|
||||||
import { EventEmitter } from 'events';
|
|
||||||
import { Waiter } from './waiter';
|
|
||||||
import { Events } from './events';
|
|
||||||
import type { LifecycleEvent, SelectOption, SelectOptionOptions, FilePayload, WaitForFunctionOptions, StrictOptions } from './types';
|
|
||||||
import { kLifecycleEvents } from './types';
|
|
||||||
import { type URLMatch, urlMatches } from '../utils';
|
|
||||||
import type * as api from '../../types/types';
|
|
||||||
import type * as structs from '../../types/structs';
|
|
||||||
import { addSourceUrlToScript } from './clientHelper';
|
import { addSourceUrlToScript } from './clientHelper';
|
||||||
|
import { ElementHandle, convertInputFiles, convertSelectOptionValues } from './elementHandle';
|
||||||
|
import { Events } from './events';
|
||||||
|
import { JSHandle, assertMaxArguments, parseResult, serializeArgument } from './jsHandle';
|
||||||
|
import * as network from './network';
|
||||||
|
import { kLifecycleEvents } from './types';
|
||||||
|
import { Waiter } from './waiter';
|
||||||
|
import { getByAltTextSelector, getByLabelSelector, getByPlaceholderSelector, getByRoleSelector, getByTestIdSelector, getByTextSelector, getByTitleSelector } from '../utils/isomorphic/locatorUtils';
|
||||||
|
|
||||||
|
import type { LocatorOptions } from './locator';
|
||||||
|
import type { Page } from './page';
|
||||||
|
import type { FilePayload, LifecycleEvent, SelectOption, SelectOptionOptions, StrictOptions, WaitForFunctionOptions } from './types';
|
||||||
|
import type * as structs from '../../types/structs';
|
||||||
|
import type * as api from '../../types/types';
|
||||||
|
import type { URLMatch } from '../utils';
|
||||||
|
import type { ByRoleOptions } from '../utils/isomorphic/locatorUtils';
|
||||||
|
import type * as channels from '@protocol/channels';
|
||||||
|
|
||||||
export type WaitForNavigationOptions = {
|
export type WaitForNavigationOptions = {
|
||||||
timeout?: number,
|
timeout?: number,
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { debugLogger } from '../utils/debugLogger';
|
import { debugLogger } from '../utils/debugLogger';
|
||||||
|
|
||||||
import type { BrowserContext } from './browserContext';
|
import type { BrowserContext } from './browserContext';
|
||||||
import type { LocalUtils } from './localUtils';
|
import type { LocalUtils } from './localUtils';
|
||||||
import type { Route } from './network';
|
import type { Route } from './network';
|
||||||
|
|
|
||||||
|
|
@ -15,9 +15,9 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import type * as channels from '@protocol/channels';
|
|
||||||
import type * as api from '../../types/types';
|
|
||||||
import type { Page } from './page';
|
import type { Page } from './page';
|
||||||
|
import type * as api from '../../types/types';
|
||||||
|
import type * as channels from '@protocol/channels';
|
||||||
|
|
||||||
export class Keyboard implements api.Keyboard {
|
export class Keyboard implements api.Keyboard {
|
||||||
private _page: Page;
|
private _page: Page;
|
||||||
|
|
|
||||||
|
|
@ -14,12 +14,14 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import type * as channels from '@protocol/channels';
|
|
||||||
import { ChannelOwner } from './channelOwner';
|
import { ChannelOwner } from './channelOwner';
|
||||||
import { parseSerializedValue, serializeValue } from '../protocol/serializers';
|
|
||||||
import type * as api from '../../types/types';
|
|
||||||
import type * as structs from '../../types/structs';
|
|
||||||
import { isTargetClosedError } from './errors';
|
import { isTargetClosedError } from './errors';
|
||||||
|
import { parseSerializedValue, serializeValue } from '../protocol/serializers';
|
||||||
|
|
||||||
|
import type * as structs from '../../types/structs';
|
||||||
|
import type * as api from '../../types/types';
|
||||||
|
import type * as channels from '@protocol/channels';
|
||||||
|
|
||||||
|
|
||||||
export class JSHandle<T = any> extends ChannelOwner<channels.JSHandleChannel> implements api.JSHandle {
|
export class JSHandle<T = any> extends ChannelOwner<channels.JSHandleChannel> implements api.JSHandle {
|
||||||
private _preview: string;
|
private _preview: string;
|
||||||
|
|
|
||||||
|
|
@ -14,9 +14,10 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import type * as channels from '@protocol/channels';
|
|
||||||
import { ChannelOwner } from './channelOwner';
|
import { ChannelOwner } from './channelOwner';
|
||||||
|
|
||||||
|
import type * as channels from '@protocol/channels';
|
||||||
|
|
||||||
export class JsonPipe extends ChannelOwner<channels.JsonPipeChannel> {
|
export class JsonPipe extends ChannelOwner<channels.JsonPipeChannel> {
|
||||||
static from(jsonPipe: channels.JsonPipeChannel): JsonPipe {
|
static from(jsonPipe: channels.JsonPipeChannel): JsonPipe {
|
||||||
return (jsonPipe as any)._object;
|
return (jsonPipe as any)._object;
|
||||||
|
|
|
||||||
|
|
@ -14,9 +14,10 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import type * as channels from '@protocol/channels';
|
|
||||||
import { ChannelOwner } from './channelOwner';
|
import { ChannelOwner } from './channelOwner';
|
||||||
|
|
||||||
import type { Size } from './types';
|
import type { Size } from './types';
|
||||||
|
import type * as channels from '@protocol/channels';
|
||||||
|
|
||||||
type DeviceDescriptor = {
|
type DeviceDescriptor = {
|
||||||
userAgent: string,
|
userAgent: string,
|
||||||
|
|
|
||||||
|
|
@ -14,18 +14,21 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import type * as structs from '../../types/structs';
|
|
||||||
import type * as api from '../../types/types';
|
|
||||||
import type * as channels from '@protocol/channels';
|
|
||||||
import * as util from 'util';
|
import * as util from 'util';
|
||||||
|
|
||||||
import { asLocator, isString, monotonicTime } from '../utils';
|
import { asLocator, isString, monotonicTime } from '../utils';
|
||||||
import { ElementHandle } from './elementHandle';
|
import { ElementHandle } from './elementHandle';
|
||||||
|
import { parseResult, serializeArgument } from './jsHandle';
|
||||||
|
import { getByAltTextSelector, getByLabelSelector, getByPlaceholderSelector, getByRoleSelector, getByTestIdSelector, getByTextSelector, getByTitleSelector } from '../utils/isomorphic/locatorUtils';
|
||||||
|
import { escapeForTextSelector } from '../utils/isomorphic/stringUtils';
|
||||||
|
|
||||||
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';
|
||||||
import { parseResult, serializeArgument } from './jsHandle';
|
import type * as structs from '../../types/structs';
|
||||||
import { escapeForTextSelector } from '../utils/isomorphic/stringUtils';
|
import type * as api from '../../types/types';
|
||||||
import type { ByRoleOptions } from '../utils/isomorphic/locatorUtils';
|
import type { ByRoleOptions } from '../utils/isomorphic/locatorUtils';
|
||||||
import { getByAltTextSelector, getByLabelSelector, getByPlaceholderSelector, getByRoleSelector, getByTestIdSelector, getByTextSelector, getByTitleSelector } from '../utils/isomorphic/locatorUtils';
|
import type * as channels from '@protocol/channels';
|
||||||
|
|
||||||
|
|
||||||
export type LocatorOptions = {
|
export type LocatorOptions = {
|
||||||
hasText?: string | RegExp;
|
hasText?: string | RegExp;
|
||||||
|
|
|
||||||
|
|
@ -14,26 +14,28 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import * as fs from 'fs';
|
||||||
import { URLSearchParams } from 'url';
|
import { URLSearchParams } from 'url';
|
||||||
import type * as channels from '@protocol/channels';
|
|
||||||
import { ChannelOwner } from './channelOwner';
|
import { ChannelOwner } from './channelOwner';
|
||||||
|
import { isTargetClosedError } from './errors';
|
||||||
|
import { Events } from './events';
|
||||||
|
import { APIResponse } from './fetch';
|
||||||
import { Frame } from './frame';
|
import { Frame } from './frame';
|
||||||
import { Worker } from './worker';
|
import { Worker } from './worker';
|
||||||
import type { Headers, RemoteAddr, SecurityDetails, WaitForEventOptions } from './types';
|
import { MultiMap, assert, headersObjectToArray, isRegExp, isString, rewriteErrorMessage, urlMatches, zones } from '../utils';
|
||||||
import fs from 'fs';
|
|
||||||
import { mime } from '../utilsBundle';
|
|
||||||
import { assert, isString, headersObjectToArray, isRegExp, rewriteErrorMessage, MultiMap, urlMatches, zones } from '../utils';
|
|
||||||
import type { URLMatch, Zone } from '../utils';
|
|
||||||
import { ManualPromise, LongStandingScope } from '../utils/manualPromise';
|
|
||||||
import { Events } from './events';
|
|
||||||
import type { Page } from './page';
|
|
||||||
import { Waiter } from './waiter';
|
import { Waiter } from './waiter';
|
||||||
|
import { LongStandingScope, ManualPromise } from '../utils/manualPromise';
|
||||||
|
import { mime } from '../utilsBundle';
|
||||||
|
|
||||||
|
import type { Headers, RemoteAddr, SecurityDetails, WaitForEventOptions } from './types';
|
||||||
|
import type { URLMatch, Zone } from '../utils';
|
||||||
|
import type { BrowserContext } from './browserContext';
|
||||||
|
import type { Page } from './page';
|
||||||
|
import type { Serializable } from '../../types/structs';
|
||||||
import type * as api from '../../types/types';
|
import type * as api from '../../types/types';
|
||||||
import type { HeadersArray } from '../common/types';
|
import type { HeadersArray } from '../common/types';
|
||||||
import { APIResponse } from './fetch';
|
import type * as channels from '@protocol/channels';
|
||||||
import type { Serializable } from '../../types/structs';
|
|
||||||
import type { BrowserContext } from './browserContext';
|
|
||||||
import { isTargetClosedError } from './errors';
|
|
||||||
|
|
||||||
export type NetworkCookie = {
|
export type NetworkCookie = {
|
||||||
name: string,
|
name: string,
|
||||||
|
|
|
||||||
|
|
@ -15,38 +15,42 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import fs from 'fs';
|
import * as fs from 'fs';
|
||||||
import path from 'path';
|
import * as path from 'path';
|
||||||
import type * as structs from '../../types/structs';
|
|
||||||
import type * as api from '../../types/types';
|
import { TargetClosedError, isTargetClosedError, serializeError } from './errors';
|
||||||
import { serializeError, isTargetClosedError, TargetClosedError } from './errors';
|
|
||||||
import { TimeoutSettings } from '../common/timeoutSettings';
|
import { TimeoutSettings } from '../common/timeoutSettings';
|
||||||
import type * as channels from '@protocol/channels';
|
import { LongStandingScope, assert, headersObjectToArray, isObject, isRegExp, isString, mkdirIfNeeded, trimStringWithEllipsis, urlMatches, urlMatchesEqual } from '../utils';
|
||||||
import { assert, headersObjectToArray, isObject, isRegExp, isString, LongStandingScope, urlMatches, urlMatchesEqual, mkdirIfNeeded, trimStringWithEllipsis, type URLMatch } from '../utils';
|
|
||||||
import { Accessibility } from './accessibility';
|
import { Accessibility } from './accessibility';
|
||||||
import { Artifact } from './artifact';
|
import { Artifact } from './artifact';
|
||||||
import type { BrowserContext } from './browserContext';
|
|
||||||
import { ChannelOwner } from './channelOwner';
|
import { ChannelOwner } from './channelOwner';
|
||||||
import { evaluationScript } from './clientHelper';
|
import { evaluationScript } from './clientHelper';
|
||||||
import { Coverage } from './coverage';
|
import { Coverage } from './coverage';
|
||||||
import { Download } from './download';
|
import { Download } from './download';
|
||||||
import { determineScreenshotType, ElementHandle } from './elementHandle';
|
import { ElementHandle, determineScreenshotType } from './elementHandle';
|
||||||
import { Events } from './events';
|
import { Events } from './events';
|
||||||
import type { APIRequestContext } from './fetch';
|
|
||||||
import { FileChooser } from './fileChooser';
|
import { FileChooser } from './fileChooser';
|
||||||
import type { WaitForNavigationOptions } from './frame';
|
|
||||||
import { Frame, verifyLoadState } from './frame';
|
import { Frame, verifyLoadState } from './frame';
|
||||||
|
import { HarRouter } from './harRouter';
|
||||||
import { Keyboard, Mouse, Touchscreen } from './input';
|
import { Keyboard, Mouse, Touchscreen } from './input';
|
||||||
import { assertMaxArguments, JSHandle, parseResult, serializeArgument } from './jsHandle';
|
import { JSHandle, assertMaxArguments, parseResult, serializeArgument } from './jsHandle';
|
||||||
import type { FrameLocator, Locator, LocatorOptions } from './locator';
|
import { Response, Route, RouteHandler, WebSocket, WebSocketRoute, WebSocketRouteHandler, validateHeaders } from './network';
|
||||||
import type { ByRoleOptions } from '../utils/isomorphic/locatorUtils';
|
|
||||||
import { type RouteHandlerCallback, type Request, Response, Route, RouteHandler, validateHeaders, WebSocket, type WebSocketRouteHandlerCallback, WebSocketRoute, WebSocketRouteHandler } from './network';
|
|
||||||
import type { FilePayload, Headers, LifecycleEvent, SelectOption, SelectOptionOptions, Size, WaitForEventOptions, WaitForFunctionOptions } from './types';
|
|
||||||
import { Video } from './video';
|
import { Video } from './video';
|
||||||
import { Waiter } from './waiter';
|
import { Waiter } from './waiter';
|
||||||
import { Worker } from './worker';
|
import { Worker } from './worker';
|
||||||
import { HarRouter } from './harRouter';
|
|
||||||
|
import type { BrowserContext } from './browserContext';
|
||||||
import type { Clock } from './clock';
|
import type { Clock } from './clock';
|
||||||
|
import type { APIRequestContext } from './fetch';
|
||||||
|
import type { WaitForNavigationOptions } from './frame';
|
||||||
|
import type { FrameLocator, Locator, LocatorOptions } from './locator';
|
||||||
|
import type { Request, RouteHandlerCallback, WebSocketRouteHandlerCallback } from './network';
|
||||||
|
import type { FilePayload, Headers, LifecycleEvent, SelectOption, SelectOptionOptions, Size, WaitForEventOptions, WaitForFunctionOptions } from './types';
|
||||||
|
import type * as structs from '../../types/structs';
|
||||||
|
import type * as api from '../../types/types';
|
||||||
|
import type { URLMatch } from '../utils';
|
||||||
|
import type { ByRoleOptions } from '../utils/isomorphic/locatorUtils';
|
||||||
|
import type * as channels from '@protocol/channels';
|
||||||
|
|
||||||
type PDFOptions = Omit<channels.PagePdfParams, 'width' | 'height' | 'margin'> & {
|
type PDFOptions = Omit<channels.PagePdfParams, 'width' | 'height' | 'margin'> & {
|
||||||
width?: string | number,
|
width?: string | number,
|
||||||
|
|
@ -573,12 +577,13 @@ export class Page extends ChannelOwner<channels.PageChannel> implements api.Page
|
||||||
await this._channel.setWebSocketInterceptionPatterns({ patterns });
|
await this._channel.setWebSocketInterceptionPatterns({ patterns });
|
||||||
}
|
}
|
||||||
|
|
||||||
async screenshot(options: Omit<channels.PageScreenshotOptions, 'mask'> & { path?: string, mask?: Locator[] } = {}): Promise<Buffer> {
|
async screenshot(options: Omit<channels.PageScreenshotOptions, 'mask'> & { path?: string, mask?: api.Locator[] } = {}): Promise<Buffer> {
|
||||||
|
const mask = options.mask as Locator[] | undefined;
|
||||||
const copy: channels.PageScreenshotOptions = { ...options, mask: undefined };
|
const copy: channels.PageScreenshotOptions = { ...options, mask: undefined };
|
||||||
if (!copy.type)
|
if (!copy.type)
|
||||||
copy.type = determineScreenshotType(options);
|
copy.type = determineScreenshotType(options);
|
||||||
if (options.mask) {
|
if (mask) {
|
||||||
copy.mask = options.mask.map(locator => ({
|
copy.mask = mask.map(locator => ({
|
||||||
frame: locator._frame._channel,
|
frame: locator._frame._channel,
|
||||||
selector: locator._selector,
|
selector: locator._selector,
|
||||||
}));
|
}));
|
||||||
|
|
|
||||||
|
|
@ -14,14 +14,15 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import type * as channels from '@protocol/channels';
|
|
||||||
import { TimeoutError } from './errors';
|
|
||||||
import { Android } from './android';
|
import { Android } from './android';
|
||||||
import { BrowserType } from './browserType';
|
import { BrowserType } from './browserType';
|
||||||
import { ChannelOwner } from './channelOwner';
|
import { ChannelOwner } from './channelOwner';
|
||||||
import { Electron } from './electron';
|
import { Electron } from './electron';
|
||||||
|
import { TimeoutError } from './errors';
|
||||||
import { APIRequest } from './fetch';
|
import { APIRequest } from './fetch';
|
||||||
import { Selectors, SelectorsOwner } from './selectors';
|
import { Selectors, SelectorsOwner } from './selectors';
|
||||||
|
|
||||||
|
import type * as channels from '@protocol/channels';
|
||||||
import type { BrowserContextOptions, LaunchOptions } from 'playwright-core';
|
import type { BrowserContextOptions, LaunchOptions } from 'playwright-core';
|
||||||
|
|
||||||
export class Playwright extends ChannelOwner<channels.PlaywrightChannel> {
|
export class Playwright extends ChannelOwner<channels.PlaywrightChannel> {
|
||||||
|
|
|
||||||
|
|
@ -14,12 +14,14 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { evaluationScript } from './clientHelper';
|
|
||||||
import type * as channels from '@protocol/channels';
|
|
||||||
import { ChannelOwner } from './channelOwner';
|
import { ChannelOwner } from './channelOwner';
|
||||||
|
import { evaluationScript } from './clientHelper';
|
||||||
|
import { setTestIdAttribute, testIdAttributeName } from './locator';
|
||||||
|
|
||||||
import type { SelectorEngine } from './types';
|
import type { SelectorEngine } from './types';
|
||||||
import type * as api from '../../types/types';
|
import type * as api from '../../types/types';
|
||||||
import { setTestIdAttribute, testIdAttributeName } from './locator';
|
import type * as channels from '@protocol/channels';
|
||||||
|
|
||||||
|
|
||||||
export class Selectors implements api.Selectors {
|
export class Selectors implements api.Selectors {
|
||||||
private _channels = new Set<SelectorsOwner>();
|
private _channels = new Set<SelectorsOwner>();
|
||||||
|
|
|
||||||
|
|
@ -15,9 +15,11 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { Readable } from 'stream';
|
import { Readable } from 'stream';
|
||||||
import type * as channels from '@protocol/channels';
|
|
||||||
import { ChannelOwner } from './channelOwner';
|
import { ChannelOwner } from './channelOwner';
|
||||||
|
|
||||||
|
import type * as channels from '@protocol/channels';
|
||||||
|
|
||||||
export class Stream extends ChannelOwner<channels.StreamChannel> {
|
export class Stream extends ChannelOwner<channels.StreamChannel> {
|
||||||
static from(Stream: channels.StreamChannel): Stream {
|
static from(Stream: channels.StreamChannel): Stream {
|
||||||
return (Stream as any)._object;
|
return (Stream as any)._object;
|
||||||
|
|
|
||||||
|
|
@ -14,11 +14,12 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import type * as api from '../../types/types';
|
|
||||||
import type * as channels from '@protocol/channels';
|
|
||||||
import { Artifact } from './artifact';
|
import { Artifact } from './artifact';
|
||||||
import { ChannelOwner } from './channelOwner';
|
import { ChannelOwner } from './channelOwner';
|
||||||
|
|
||||||
|
import type * as api from '../../types/types';
|
||||||
|
import type * as channels from '@protocol/channels';
|
||||||
|
|
||||||
export class Tracing extends ChannelOwner<channels.TracingChannel> implements api.Tracing {
|
export class Tracing extends ChannelOwner<channels.TracingChannel> implements api.Tracing {
|
||||||
private _includeSources = false;
|
private _includeSources = false;
|
||||||
_tracesDir: string | undefined;
|
_tracesDir: string | undefined;
|
||||||
|
|
|
||||||
|
|
@ -15,9 +15,9 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import type * as channels from '@protocol/channels';
|
|
||||||
import type { Size } from '../common/types';
|
import type { Size } from '../common/types';
|
||||||
export type { Size, Point, Rect, Quad, TimeoutOptions, HeadersArray } from '../common/types';
|
import type * as channels from '@protocol/channels';
|
||||||
|
export type { HeadersArray, Point, Quad, Rect, Size, TimeoutOptions } from '../common/types';
|
||||||
|
|
||||||
type LoggerSeverity = 'verbose' | 'info' | 'warning' | 'error';
|
type LoggerSeverity = 'verbose' | 'info' | 'warning' | 'error';
|
||||||
export interface Logger {
|
export interface Logger {
|
||||||
|
|
@ -37,7 +37,7 @@ export type SelectOptionOptions = { force?: boolean, timeout?: number };
|
||||||
export type FilePayload = { name: string, mimeType: string, buffer: Buffer };
|
export type FilePayload = { name: string, mimeType: string, buffer: Buffer };
|
||||||
export type StorageState = {
|
export type StorageState = {
|
||||||
cookies: channels.NetworkCookie[],
|
cookies: channels.NetworkCookie[],
|
||||||
origins: channels.OriginStorage[]
|
origins: channels.OriginStorage[],
|
||||||
};
|
};
|
||||||
export type SetStorageState = {
|
export type SetStorageState = {
|
||||||
cookies?: channels.SetNetworkCookie[],
|
cookies?: channels.SetNetworkCookie[],
|
||||||
|
|
|
||||||
|
|
@ -14,11 +14,12 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import type { Page } from './page';
|
import { ManualPromise } from '../utils';
|
||||||
import type * as api from '../../types/types';
|
|
||||||
import type { Artifact } from './artifact';
|
import type { Artifact } from './artifact';
|
||||||
import type { Connection } from './connection';
|
import type { Connection } from './connection';
|
||||||
import { ManualPromise } from '../utils';
|
import type { Page } from './page';
|
||||||
|
import type * as api from '../../types/types';
|
||||||
|
|
||||||
export class Video implements api.Video {
|
export class Video implements api.Video {
|
||||||
private _artifact: Promise<Artifact | null> | null = null;
|
private _artifact: Promise<Artifact | null> | null = null;
|
||||||
|
|
|
||||||
|
|
@ -14,13 +14,14 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import type { EventEmitter } from 'events';
|
|
||||||
import { rewriteErrorMessage } from '../utils/stackTrace';
|
|
||||||
import { TimeoutError } from './errors';
|
import { TimeoutError } from './errors';
|
||||||
import { createGuid, zones } from '../utils';
|
import { createGuid, zones } from '../utils';
|
||||||
|
import { rewriteErrorMessage } from '../utils/stackTrace';
|
||||||
|
|
||||||
import type { Zone } from '../utils';
|
import type { Zone } from '../utils';
|
||||||
import type * as channels from '@protocol/channels';
|
|
||||||
import type { ChannelOwner } from './channelOwner';
|
import type { ChannelOwner } from './channelOwner';
|
||||||
|
import type * as channels from '@protocol/channels';
|
||||||
|
import type { EventEmitter } from 'events';
|
||||||
|
|
||||||
export class Waiter {
|
export class Waiter {
|
||||||
private _dispose: (() => void)[];
|
private _dispose: (() => void)[];
|
||||||
|
|
|
||||||
|
|
@ -14,8 +14,8 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import type * as api from '../../types/types';
|
|
||||||
import type { Page } from './page';
|
import type { Page } from './page';
|
||||||
|
import type * as api from '../../types/types';
|
||||||
|
|
||||||
export class WebError implements api.WebError {
|
export class WebError implements api.WebError {
|
||||||
private _page: Page | null;
|
private _page: Page | null;
|
||||||
|
|
|
||||||
|
|
@ -14,17 +14,19 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { Events } from './events';
|
|
||||||
import type * as channels from '@protocol/channels';
|
|
||||||
import { ChannelOwner } from './channelOwner';
|
import { ChannelOwner } from './channelOwner';
|
||||||
import { assertMaxArguments, JSHandle, parseResult, serializeArgument } from './jsHandle';
|
import { Events } from './events';
|
||||||
import type { Page } from './page';
|
import { JSHandle, assertMaxArguments, parseResult, serializeArgument } from './jsHandle';
|
||||||
import type { BrowserContext } from './browserContext';
|
|
||||||
import type * as api from '../../types/types';
|
|
||||||
import type * as structs from '../../types/structs';
|
|
||||||
import { LongStandingScope } from '../utils';
|
import { LongStandingScope } from '../utils';
|
||||||
import { TargetClosedError } from './errors';
|
import { TargetClosedError } from './errors';
|
||||||
|
|
||||||
|
import type { BrowserContext } from './browserContext';
|
||||||
|
import type { Page } from './page';
|
||||||
|
import type * as structs from '../../types/structs';
|
||||||
|
import type * as api from '../../types/types';
|
||||||
|
import type * as channels from '@protocol/channels';
|
||||||
|
|
||||||
|
|
||||||
export class Worker extends ChannelOwner<channels.WorkerChannel> implements api.Worker {
|
export class Worker extends ChannelOwner<channels.WorkerChannel> implements api.Worker {
|
||||||
_page: Page | undefined; // Set for web workers.
|
_page: Page | undefined; // Set for web workers.
|
||||||
_context: BrowserContext | undefined; // Set for service workers.
|
_context: BrowserContext | undefined; // Set for service workers.
|
||||||
|
|
|
||||||
|
|
@ -15,9 +15,11 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { Writable } from 'stream';
|
import { Writable } from 'stream';
|
||||||
import type * as channels from '@protocol/channels';
|
|
||||||
import { ChannelOwner } from './channelOwner';
|
import { ChannelOwner } from './channelOwner';
|
||||||
|
|
||||||
|
import type * as channels from '@protocol/channels';
|
||||||
|
|
||||||
export class WritableStream extends ChannelOwner<channels.WritableStreamChannel> {
|
export class WritableStream extends ChannelOwner<channels.WritableStreamChannel> {
|
||||||
static from(Stream: channels.WritableStreamChannel): WritableStream {
|
static from(Stream: channels.WritableStreamChannel): WritableStream {
|
||||||
return (Stream as any)._object;
|
return (Stream as any)._object;
|
||||||
|
|
|
||||||
|
|
@ -15,11 +15,13 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import EventEmitter from 'events';
|
import EventEmitter from 'events';
|
||||||
import type { AddressInfo } from 'net';
|
import * as net from 'net';
|
||||||
import net from 'net';
|
|
||||||
|
import { assert, createGuid, } from '../utils';
|
||||||
import { debugLogger } from '../utils/debugLogger';
|
import { debugLogger } from '../utils/debugLogger';
|
||||||
import { createSocket } from '../utils/happy-eyeballs';
|
import { createSocket } from '../utils/happy-eyeballs';
|
||||||
import { assert, createGuid, } from '../utils';
|
|
||||||
|
import type { AddressInfo } from 'net';
|
||||||
|
|
||||||
// https://tools.ietf.org/html/rfc1928
|
// https://tools.ietf.org/html/rfc1928
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@
|
||||||
|
|
||||||
import { blendWithWhite, colorDeltaE94, rgb2gray } from './colorUtils';
|
import { blendWithWhite, colorDeltaE94, rgb2gray } from './colorUtils';
|
||||||
import { ImageChannel } from './imageChannel';
|
import { ImageChannel } from './imageChannel';
|
||||||
import { ssim, FastStats } from './stats';
|
import { FastStats, ssim } from './stats';
|
||||||
|
|
||||||
const SSIM_WINDOW_RADIUS = 15;
|
const SSIM_WINDOW_RADIUS = 15;
|
||||||
const VARIANCE_WINDOW_RADIUS = 1;
|
const VARIANCE_WINDOW_RADIUS = 1;
|
||||||
|
|
|
||||||
|
|
@ -14,11 +14,12 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import type { Playwright as PlaywrightAPI } from './client/playwright';
|
|
||||||
import { createPlaywright, DispatcherConnection, RootDispatcher, PlaywrightDispatcher } from './server';
|
|
||||||
import { Connection } from './client/connection';
|
|
||||||
import { BrowserServerLauncherImpl } from './browserServerImpl';
|
|
||||||
import { AndroidServerLauncherImpl } from './androidServerImpl';
|
import { AndroidServerLauncherImpl } from './androidServerImpl';
|
||||||
|
import { BrowserServerLauncherImpl } from './browserServerImpl';
|
||||||
|
import { Connection } from './client/connection';
|
||||||
|
import { DispatcherConnection, PlaywrightDispatcher, RootDispatcher, createPlaywright } from './server';
|
||||||
|
|
||||||
|
import type { Playwright as PlaywrightAPI } from './client/playwright';
|
||||||
import type { Language } from './utils';
|
import type { Language } from './utils';
|
||||||
|
|
||||||
export function createInProcessPlaywright(): PlaywrightAPI {
|
export function createInProcessPlaywright(): PlaywrightAPI {
|
||||||
|
|
|
||||||
|
|
@ -14,13 +14,16 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { Connection } from './client/connection';
|
|
||||||
import { PipeTransport } from './protocol/transport';
|
|
||||||
import type { Playwright } from './client/playwright';
|
|
||||||
import * as childProcess from 'child_process';
|
import * as childProcess from 'child_process';
|
||||||
import * as path from 'path';
|
import * as path from 'path';
|
||||||
|
|
||||||
|
import { Connection } from './client/connection';
|
||||||
|
import { PipeTransport } from './protocol/transport';
|
||||||
import { ManualPromise } from './utils/manualPromise';
|
import { ManualPromise } from './utils/manualPromise';
|
||||||
|
|
||||||
|
import type { Playwright } from './client/playwright';
|
||||||
|
|
||||||
|
|
||||||
export async function start(env: any = {}): Promise<{ playwright: Playwright, stop: () => Promise<void> }> {
|
export async function start(env: any = {}): Promise<{ playwright: Playwright, stop: () => Promise<void> }> {
|
||||||
const client = new PlaywrightClient(env);
|
const client = new PlaywrightClient(env);
|
||||||
const playwright = await client._playwright;
|
const playwright = await client._playwright;
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,7 @@
|
||||||
|
|
||||||
// This file is generated by generate_channels.js, do not edit manually.
|
// This file is generated by generate_channels.js, do not edit manually.
|
||||||
|
|
||||||
|
/* eslint-disable import/order */
|
||||||
import { scheme, tOptional, tObject, tBoolean, tNumber, tString, tAny, tEnum, tArray, tBinary, tChannel, tType } from './validatorPrimitives';
|
import { scheme, tOptional, tObject, tBoolean, tNumber, tString, tAny, tEnum, tArray, tBinary, tChannel, tType } from './validatorPrimitives';
|
||||||
export type { Validator, ValidatorContext } from './validatorPrimitives';
|
export type { Validator, ValidatorContext } from './validatorPrimitives';
|
||||||
export { ValidationError, findValidator, maybeFindValidator, createMetadataValidator } from './validatorPrimitives';
|
export { ValidationError, findValidator, maybeFindValidator, createMetadataValidator } from './validatorPrimitives';
|
||||||
|
|
|
||||||
|
|
@ -14,21 +14,22 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import type { WebSocket } from '../utilsBundle';
|
|
||||||
import type { DispatcherScope, Playwright } from '../server';
|
|
||||||
import type * as channels from '@protocol/channels';
|
|
||||||
import { createPlaywright, DispatcherConnection, RootDispatcher, PlaywrightDispatcher } from '../server';
|
|
||||||
import { Browser } from '../server/browser';
|
|
||||||
import { serverSideCallMetadata } from '../server/instrumentation';
|
|
||||||
import { SocksProxy } from '../common/socksProxy';
|
import { SocksProxy } from '../common/socksProxy';
|
||||||
import { assert, isUnderTest } from '../utils';
|
import { DispatcherConnection, PlaywrightDispatcher, RootDispatcher, createPlaywright } from '../server';
|
||||||
import type { LaunchOptions } from '../server/types';
|
|
||||||
import { AndroidDevice } from '../server/android/android';
|
import { AndroidDevice } from '../server/android/android';
|
||||||
|
import { Browser } from '../server/browser';
|
||||||
import { DebugControllerDispatcher } from '../server/dispatchers/debugControllerDispatcher';
|
import { DebugControllerDispatcher } from '../server/dispatchers/debugControllerDispatcher';
|
||||||
|
import { serverSideCallMetadata } from '../server/instrumentation';
|
||||||
|
import { assert, isUnderTest } from '../utils';
|
||||||
import { startProfiling, stopProfiling } from '../utils';
|
import { startProfiling, stopProfiling } from '../utils';
|
||||||
import { monotonicTime } from '../utils';
|
import { monotonicTime } from '../utils';
|
||||||
import { debugLogger } from '../utils/debugLogger';
|
import { debugLogger } from '../utils/debugLogger';
|
||||||
|
|
||||||
|
import type { DispatcherScope, Playwright } from '../server';
|
||||||
|
import type { LaunchOptions } from '../server/types';
|
||||||
|
import type { WebSocket } from '../utilsBundle';
|
||||||
|
import type * as channels from '@protocol/channels';
|
||||||
|
|
||||||
export type ClientType = 'controller' | 'launch-browser' | 'reuse-browser' | 'pre-launched-browser-or-android';
|
export type ClientType = 'controller' | 'launch-browser' | 'reuse-browser' | 'pre-launched-browser-or-android';
|
||||||
|
|
||||||
type Options = {
|
type Options = {
|
||||||
|
|
|
||||||
|
|
@ -14,18 +14,20 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import { PlaywrightConnection } from './playwrightConnection';
|
||||||
|
import { createPlaywright } from '../server/playwright';
|
||||||
|
import { userAgentVersionMatchesErrorMessage } from '../utils';
|
||||||
|
import { debugLogger } from '../utils/debugLogger';
|
||||||
|
import { Semaphore } from '../utils/semaphore';
|
||||||
|
import { WSServer } from '../utils/wsServer';
|
||||||
|
|
||||||
|
import type { ClientType } from './playwrightConnection';
|
||||||
|
import type { SocksProxy } from '../common/socksProxy';
|
||||||
|
import type { AndroidDevice } from '../server/android/android';
|
||||||
import type { Browser } from '../server/browser';
|
import type { Browser } from '../server/browser';
|
||||||
import type { Playwright } from '../server/playwright';
|
import type { Playwright } from '../server/playwright';
|
||||||
import { createPlaywright } from '../server/playwright';
|
|
||||||
import { PlaywrightConnection } from './playwrightConnection';
|
|
||||||
import type { ClientType } from './playwrightConnection';
|
|
||||||
import type { LaunchOptions } from '../server/types';
|
import type { LaunchOptions } from '../server/types';
|
||||||
import { Semaphore } from '../utils/semaphore';
|
|
||||||
import type { AndroidDevice } from '../server/android/android';
|
|
||||||
import type { SocksProxy } from '../common/socksProxy';
|
|
||||||
import { debugLogger } from '../utils/debugLogger';
|
|
||||||
import { userAgentVersionMatchesErrorMessage } from '../utils';
|
|
||||||
import { WSServer } from '../utils/wsServer';
|
|
||||||
|
|
||||||
type ServerOptions = {
|
type ServerOptions = {
|
||||||
path: string;
|
path: string;
|
||||||
|
|
|
||||||
|
|
@ -14,31 +14,33 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { debug } from '../../utilsBundle';
|
|
||||||
import { EventEmitter } from 'events';
|
import { EventEmitter } from 'events';
|
||||||
import fs from 'fs';
|
import * as fs from 'fs';
|
||||||
import os from 'os';
|
import * as os from 'os';
|
||||||
import path from 'path';
|
import * as path from 'path';
|
||||||
import type * as stream from 'stream';
|
|
||||||
import { wsReceiver, wsSender } from '../../utilsBundle';
|
import { TimeoutSettings } from '../../common/timeoutSettings';
|
||||||
import { createGuid, makeWaitForNextTask, isUnderTest, getPackageManagerExecCommand } from '../../utils';
|
import { PipeTransport } from '../../protocol/transport';
|
||||||
|
import { createGuid, getPackageManagerExecCommand, isUnderTest, makeWaitForNextTask } from '../../utils';
|
||||||
|
import { RecentLogsCollector } from '../../utils/debugLogger';
|
||||||
import { removeFolders } from '../../utils/fileUtils';
|
import { removeFolders } from '../../utils/fileUtils';
|
||||||
import type { BrowserOptions, BrowserProcess } from '../browser';
|
import { gracefullyCloseSet } from '../../utils/processLauncher';
|
||||||
import type { BrowserContext } from '../browserContext';
|
import { debug } from '../../utilsBundle';
|
||||||
|
import { wsReceiver, wsSender } from '../../utilsBundle';
|
||||||
import { validateBrowserContextOptions } from '../browserContext';
|
import { validateBrowserContextOptions } from '../browserContext';
|
||||||
import { ProgressController } from '../progress';
|
import { chromiumSwitches } from '../chromium/chromiumSwitches';
|
||||||
import { CRBrowser } from '../chromium/crBrowser';
|
import { CRBrowser } from '../chromium/crBrowser';
|
||||||
import { helper } from '../helper';
|
import { helper } from '../helper';
|
||||||
import type * as types from '../types';
|
|
||||||
import { PipeTransport } from '../../protocol/transport';
|
|
||||||
import { RecentLogsCollector } from '../../utils/debugLogger';
|
|
||||||
import { gracefullyCloseSet } from '../../utils/processLauncher';
|
|
||||||
import { TimeoutSettings } from '../../common/timeoutSettings';
|
|
||||||
import type * as channels from '@protocol/channels';
|
|
||||||
import { SdkObject, serverSideCallMetadata } from '../instrumentation';
|
import { SdkObject, serverSideCallMetadata } from '../instrumentation';
|
||||||
import { chromiumSwitches } from '../chromium/chromiumSwitches';
|
import { ProgressController } from '../progress';
|
||||||
import { registry } from '../registry';
|
import { registry } from '../registry';
|
||||||
|
|
||||||
|
import type { BrowserOptions, BrowserProcess } from '../browser';
|
||||||
|
import type { BrowserContext } from '../browserContext';
|
||||||
|
import type * as types from '../types';
|
||||||
|
import type * as channels from '@protocol/channels';
|
||||||
|
import type * as stream from 'stream';
|
||||||
|
|
||||||
const ARTIFACTS_FOLDER = path.join(os.tmpdir(), 'playwright-artifacts-');
|
const ARTIFACTS_FOLDER = path.join(os.tmpdir(), 'playwright-artifacts-');
|
||||||
|
|
||||||
export interface Backend {
|
export interface Backend {
|
||||||
|
|
|
||||||
|
|
@ -14,12 +14,15 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { debug } from '../../utilsBundle';
|
|
||||||
import type * as channels from '@protocol/channels';
|
|
||||||
import * as net from 'net';
|
|
||||||
import { EventEmitter } from 'events';
|
import { EventEmitter } from 'events';
|
||||||
import type { Backend, DeviceBackend, SocketBackend } from './android';
|
import * as net from 'net';
|
||||||
|
|
||||||
import { assert, createGuid } from '../../utils';
|
import { assert, createGuid } from '../../utils';
|
||||||
|
import { debug } from '../../utilsBundle';
|
||||||
|
|
||||||
|
import type { Backend, DeviceBackend, SocketBackend } from './android';
|
||||||
|
import type * as channels from '@protocol/channels';
|
||||||
|
|
||||||
|
|
||||||
export class AdbBackend implements Backend {
|
export class AdbBackend implements Backend {
|
||||||
async devices(options: channels.AndroidDevicesOptions = {}): Promise<DeviceBackend[]> {
|
async devices(options: channels.AndroidDevicesOptions = {}): Promise<DeviceBackend[]> {
|
||||||
|
|
|
||||||
|
|
@ -14,11 +14,12 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import fs from 'fs';
|
import * as fs from 'fs';
|
||||||
|
|
||||||
import { assert } from '../utils';
|
import { assert } from '../utils';
|
||||||
import { ManualPromise } from '../utils/manualPromise';
|
|
||||||
import { SdkObject } from './instrumentation';
|
|
||||||
import { TargetClosedError } from './errors';
|
import { TargetClosedError } from './errors';
|
||||||
|
import { SdkObject } from './instrumentation';
|
||||||
|
import { ManualPromise } from '../utils/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,23 +14,25 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import type * as channels from '@protocol/channels';
|
|
||||||
import type { RegisteredListener } from '../../utils/eventsHelper';
|
|
||||||
import { eventsHelper } from '../../utils/eventsHelper';
|
import { eventsHelper } from '../../utils/eventsHelper';
|
||||||
import type { BrowserOptions } from '../browser';
|
|
||||||
import { Browser } from '../browser';
|
import { Browser } from '../browser';
|
||||||
import { assertBrowserContextIsNotOwned, BrowserContext } from '../browserContext';
|
import { BrowserContext, assertBrowserContextIsNotOwned } from '../browserContext';
|
||||||
import type { SdkObject } from '../instrumentation';
|
|
||||||
import * as network from '../network';
|
import * as network from '../network';
|
||||||
import type { InitScript, Page } from '../page';
|
|
||||||
import type { ConnectionTransport } from '../transport';
|
|
||||||
import type * as types from '../types';
|
|
||||||
import type { BidiSession } from './bidiConnection';
|
|
||||||
import { BidiConnection } from './bidiConnection';
|
import { BidiConnection } from './bidiConnection';
|
||||||
import { bidiBytesValueToString } from './bidiNetworkManager';
|
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 { BrowserOptions } from '../browser';
|
||||||
|
import type { SdkObject } from '../instrumentation';
|
||||||
|
import type { InitScript, Page } from '../page';
|
||||||
|
import type { ConnectionTransport } from '../transport';
|
||||||
|
import type * as types from '../types';
|
||||||
|
import type { BidiSession } from './bidiConnection';
|
||||||
|
import type * as channels from '@protocol/channels';
|
||||||
|
|
||||||
|
|
||||||
export class BidiBrowser extends Browser {
|
export class BidiBrowser extends Browser {
|
||||||
private readonly _connection: BidiConnection;
|
private readonly _connection: BidiConnection;
|
||||||
readonly _browserSession: BidiSession;
|
readonly _browserSession: BidiSession;
|
||||||
|
|
|
||||||
|
|
@ -14,18 +14,21 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import os from 'os';
|
import * as os from 'os';
|
||||||
|
|
||||||
import { assert, wrapInASCIIBox } from '../../utils';
|
import { assert, wrapInASCIIBox } from '../../utils';
|
||||||
|
import { BrowserReadyState, BrowserType, kNoXServerRunningError } from '../browserType';
|
||||||
|
import { BidiBrowser } from './bidiBrowser';
|
||||||
|
import { kBrowserCloseMessageId } from './bidiConnection';
|
||||||
|
import { chromiumSwitches } from '../chromium/chromiumSwitches';
|
||||||
|
|
||||||
import type { Env } from '../../utils/processLauncher';
|
import type { Env } from '../../utils/processLauncher';
|
||||||
import type { BrowserOptions } from '../browser';
|
import type { BrowserOptions } from '../browser';
|
||||||
import { BrowserReadyState, BrowserType, kNoXServerRunningError } from '../browserType';
|
|
||||||
import { chromiumSwitches } from '../chromium/chromiumSwitches';
|
|
||||||
import type { SdkObject } from '../instrumentation';
|
import type { SdkObject } from '../instrumentation';
|
||||||
import type { ProtocolError } from '../protocolError';
|
import type { ProtocolError } from '../protocolError';
|
||||||
import type { ConnectionTransport } from '../transport';
|
import type { ConnectionTransport } from '../transport';
|
||||||
import type * as types from '../types';
|
import type * as types from '../types';
|
||||||
import { BidiBrowser } from './bidiBrowser';
|
|
||||||
import { kBrowserCloseMessageId } from './bidiConnection';
|
|
||||||
|
|
||||||
export class BidiChromium extends BrowserType {
|
export class BidiChromium extends BrowserType {
|
||||||
constructor(parent: SdkObject) {
|
constructor(parent: SdkObject) {
|
||||||
|
|
|
||||||
|
|
@ -15,14 +15,16 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { EventEmitter } from 'events';
|
import { EventEmitter } from 'events';
|
||||||
import type { ConnectionTransport, ProtocolRequest, ProtocolResponse } from '../transport';
|
|
||||||
import type { RecentLogsCollector } from '../../utils/debugLogger';
|
|
||||||
import { debugLogger } from '../../utils/debugLogger';
|
import { debugLogger } from '../../utils/debugLogger';
|
||||||
import type { ProtocolLogger } from '../types';
|
|
||||||
import { helper } from '../helper';
|
import { helper } from '../helper';
|
||||||
import { ProtocolError } from '../protocolError';
|
import { ProtocolError } from '../protocolError';
|
||||||
import type * as bidi from './third_party/bidiProtocol';
|
|
||||||
|
import type { RecentLogsCollector } from '../../utils/debugLogger';
|
||||||
|
import type { ConnectionTransport, ProtocolRequest, ProtocolResponse } from '../transport';
|
||||||
|
import type { ProtocolLogger } from '../types';
|
||||||
import type * as bidiCommands from './third_party/bidiCommands';
|
import type * as bidiCommands from './third_party/bidiCommands';
|
||||||
|
import type * as bidi from './third_party/bidiProtocol';
|
||||||
|
|
||||||
// BidiPlaywright uses this special id to issue Browser.close command which we
|
// BidiPlaywright uses this special id to issue Browser.close command which we
|
||||||
// should ignore.
|
// should ignore.
|
||||||
|
|
|
||||||
|
|
@ -16,11 +16,12 @@
|
||||||
|
|
||||||
import { parseEvaluationResultValue } from '../isomorphic/utilityScriptSerializers';
|
import { parseEvaluationResultValue } from '../isomorphic/utilityScriptSerializers';
|
||||||
import * as js from '../javascript';
|
import * as js from '../javascript';
|
||||||
import type { BidiSession } from './bidiConnection';
|
|
||||||
import { BidiDeserializer } from './third_party/bidiDeserializer';
|
import { BidiDeserializer } from './third_party/bidiDeserializer';
|
||||||
import * as bidi from './third_party/bidiProtocol';
|
import * as bidi from './third_party/bidiProtocol';
|
||||||
import { BidiSerializer } from './third_party/bidiSerializer';
|
import { BidiSerializer } from './third_party/bidiSerializer';
|
||||||
|
|
||||||
|
import type { BidiSession } from './bidiConnection';
|
||||||
|
|
||||||
export class BidiExecutionContext implements js.ExecutionContextDelegate {
|
export class BidiExecutionContext implements js.ExecutionContextDelegate {
|
||||||
private readonly _session: BidiSession;
|
private readonly _session: BidiSession;
|
||||||
readonly _target: bidi.Script.Target;
|
readonly _target: bidi.Script.Target;
|
||||||
|
|
|
||||||
|
|
@ -14,19 +14,22 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import os from 'os';
|
import * as os from 'os';
|
||||||
import path from 'path';
|
import * as path from 'path';
|
||||||
|
|
||||||
import { assert, wrapInASCIIBox } from '../../utils';
|
import { assert, wrapInASCIIBox } from '../../utils';
|
||||||
|
import { BrowserReadyState, BrowserType, kNoXServerRunningError } from '../browserType';
|
||||||
|
import { BidiBrowser } from './bidiBrowser';
|
||||||
|
import { kBrowserCloseMessageId } from './bidiConnection';
|
||||||
|
import { createProfile } from './third_party/firefoxPrefs';
|
||||||
|
|
||||||
import type { Env } from '../../utils/processLauncher';
|
import type { Env } from '../../utils/processLauncher';
|
||||||
import type { BrowserOptions } from '../browser';
|
import type { BrowserOptions } from '../browser';
|
||||||
import { BrowserReadyState, BrowserType, kNoXServerRunningError } from '../browserType';
|
|
||||||
import type { SdkObject } from '../instrumentation';
|
import type { SdkObject } from '../instrumentation';
|
||||||
import type { ProtocolError } from '../protocolError';
|
import type { ProtocolError } from '../protocolError';
|
||||||
import type { ConnectionTransport } from '../transport';
|
import type { ConnectionTransport } from '../transport';
|
||||||
import type * as types from '../types';
|
import type * as types from '../types';
|
||||||
import { BidiBrowser } from './bidiBrowser';
|
|
||||||
import { kBrowserCloseMessageId } from './bidiConnection';
|
|
||||||
import { createProfile } from './third_party/firefoxPrefs';
|
|
||||||
|
|
||||||
export class BidiFirefox extends BrowserType {
|
export class BidiFirefox extends BrowserType {
|
||||||
constructor(parent: SdkObject) {
|
constructor(parent: SdkObject) {
|
||||||
|
|
|
||||||
|
|
@ -14,12 +14,13 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import { resolveSmartModifierString } from '../input';
|
||||||
|
import { getBidiKeyValue } from './third_party/bidiKeyboard';
|
||||||
|
import * as bidi from './third_party/bidiProtocol';
|
||||||
|
|
||||||
import type * as input from '../input';
|
import type * as input from '../input';
|
||||||
import type * as types from '../types';
|
import type * as types from '../types';
|
||||||
import type { BidiSession } from './bidiConnection';
|
import type { BidiSession } from './bidiConnection';
|
||||||
import * as bidi from './third_party/bidiProtocol';
|
|
||||||
import { getBidiKeyValue } from './third_party/bidiKeyboard';
|
|
||||||
import { resolveSmartModifierString } from '../input';
|
|
||||||
|
|
||||||
export class RawKeyboardImpl implements input.RawKeyboard {
|
export class RawKeyboardImpl implements input.RawKeyboard {
|
||||||
private _session: BidiSession;
|
private _session: BidiSession;
|
||||||
|
|
|
||||||
|
|
@ -14,15 +14,16 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import type { RegisteredListener } from '../../utils/eventsHelper';
|
|
||||||
import { eventsHelper } from '../../utils/eventsHelper';
|
import { eventsHelper } from '../../utils/eventsHelper';
|
||||||
import type { Page } from '../page';
|
|
||||||
import * as network from '../network';
|
|
||||||
import type * as frames from '../frames';
|
|
||||||
import type * as types from '../types';
|
|
||||||
import * as bidi from './third_party/bidiProtocol';
|
|
||||||
import type { BidiSession } from './bidiConnection';
|
|
||||||
import { parseRawCookie } from '../cookieStore';
|
import { parseRawCookie } from '../cookieStore';
|
||||||
|
import * as network from '../network';
|
||||||
|
import * as bidi from './third_party/bidiProtocol';
|
||||||
|
|
||||||
|
import type { RegisteredListener } from '../../utils/eventsHelper';
|
||||||
|
import type * as frames from '../frames';
|
||||||
|
import type { Page } from '../page';
|
||||||
|
import type * as types from '../types';
|
||||||
|
import type { BidiSession } from './bidiConnection';
|
||||||
|
|
||||||
|
|
||||||
export class BidiNetworkManager {
|
export class BidiNetworkManager {
|
||||||
|
|
|
||||||
|
|
@ -16,11 +16,13 @@
|
||||||
|
|
||||||
import * as bidiMapper from 'chromium-bidi/lib/cjs/bidiMapper/BidiMapper';
|
import * as bidiMapper from 'chromium-bidi/lib/cjs/bidiMapper/BidiMapper';
|
||||||
import * as bidiCdpConnection from 'chromium-bidi/lib/cjs/cdp/CdpConnection';
|
import * as bidiCdpConnection from 'chromium-bidi/lib/cjs/cdp/CdpConnection';
|
||||||
import type * as bidiTransport from 'chromium-bidi/lib/cjs/utils/transport';
|
|
||||||
import type { ChromiumBidi } from 'chromium-bidi/lib/cjs/protocol/protocol';
|
|
||||||
import type { ConnectionTransport, ProtocolRequest, ProtocolResponse } from '../transport';
|
|
||||||
import { debugLogger } from '../../utils/debugLogger';
|
import { debugLogger } from '../../utils/debugLogger';
|
||||||
|
|
||||||
|
import type { ConnectionTransport, ProtocolRequest, ProtocolResponse } from '../transport';
|
||||||
|
import type { ChromiumBidi } from 'chromium-bidi/lib/cjs/protocol/protocol';
|
||||||
|
import type * as bidiTransport from 'chromium-bidi/lib/cjs/utils/transport';
|
||||||
|
|
||||||
const bidiServerLogger = (prefix: string, ...args: unknown[]): void => {
|
const bidiServerLogger = (prefix: string, ...args: unknown[]): void => {
|
||||||
debugLogger.log(prefix as any, args);
|
debugLogger.log(prefix as any, args);
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -14,26 +14,27 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import type { RegisteredListener } from '../../utils/eventsHelper';
|
|
||||||
import { eventsHelper } from '../../utils/eventsHelper';
|
|
||||||
import { assert } from '../../utils';
|
import { assert } from '../../utils';
|
||||||
import type * as accessibility from '../accessibility';
|
import { eventsHelper } from '../../utils/eventsHelper';
|
||||||
import * as dom from '../dom';
|
import { BrowserContext } from '../browserContext';
|
||||||
import * as dialog from '../dialog';
|
import * as dialog from '../dialog';
|
||||||
import type * as frames from '../frames';
|
import * as dom from '../dom';
|
||||||
import { Page } from '../page';
|
import { Page } from '../page';
|
||||||
import type * as channels from '@protocol/channels';
|
import { BidiExecutionContext } from './bidiExecutionContext';
|
||||||
|
import { RawKeyboardImpl, RawMouseImpl, RawTouchscreenImpl } from './bidiInput';
|
||||||
|
import { BidiNetworkManager } from './bidiNetworkManager';
|
||||||
|
import { BidiPDF } from './bidiPdf';
|
||||||
|
import * as bidi from './third_party/bidiProtocol';
|
||||||
|
|
||||||
|
import type { RegisteredListener } from '../../utils/eventsHelper';
|
||||||
|
import type * as accessibility from '../accessibility';
|
||||||
|
import type * as frames from '../frames';
|
||||||
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';
|
||||||
import type { BidiBrowserContext } from './bidiBrowser';
|
import type { BidiBrowserContext } from './bidiBrowser';
|
||||||
import type { BidiSession } from './bidiConnection';
|
import type { BidiSession } from './bidiConnection';
|
||||||
import { RawKeyboardImpl, RawMouseImpl, RawTouchscreenImpl } from './bidiInput';
|
import type * as channels from '@protocol/channels';
|
||||||
import * as bidi from './third_party/bidiProtocol';
|
|
||||||
import { BidiExecutionContext } from './bidiExecutionContext';
|
|
||||||
import { BidiNetworkManager } from './bidiNetworkManager';
|
|
||||||
import { BrowserContext } from '../browserContext';
|
|
||||||
import { BidiPDF } from './bidiPdf';
|
|
||||||
|
|
||||||
const UTILITY_WORLD_NAME = '__playwright_utility_world__';
|
const UTILITY_WORLD_NAME = '__playwright_utility_world__';
|
||||||
const kPlaywrightBindingChannel = 'playwrightChannel';
|
const kPlaywrightBindingChannel = 'playwrightChannel';
|
||||||
|
|
|
||||||
|
|
@ -16,8 +16,9 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { assert } from '../../utils';
|
import { assert } from '../../utils';
|
||||||
import type * as channels from '@protocol/channels';
|
|
||||||
import type { BidiSession } from './bidiConnection';
|
import type { BidiSession } from './bidiConnection';
|
||||||
|
import type * as channels from '@protocol/channels';
|
||||||
|
|
||||||
const PagePaperFormats: { [key: string]: { width: number, height: number }} = {
|
const PagePaperFormats: { [key: string]: { width: number, height: number }} = {
|
||||||
letter: { width: 8.5, height: 11 },
|
letter: { width: 8.5, height: 11 },
|
||||||
|
|
|
||||||
|
|
@ -4,8 +4,8 @@
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import fs from 'fs';
|
import * as fs from 'fs';
|
||||||
import path from 'path';
|
import * as path from 'path';
|
||||||
|
|
||||||
/* eslint-disable curly, indent */
|
/* eslint-disable curly, indent */
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -14,19 +14,21 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import type * as types from './types';
|
|
||||||
import type * as channels from '@protocol/channels';
|
|
||||||
import { BrowserContext, validateBrowserContextOptions } from './browserContext';
|
|
||||||
import { Page } from './page';
|
|
||||||
import { Download } from './download';
|
|
||||||
import type { ProxySettings } from './types';
|
|
||||||
import type { ChildProcess } from 'child_process';
|
|
||||||
import type { RecentLogsCollector } from '../utils/debugLogger';
|
|
||||||
import type { CallMetadata } from './instrumentation';
|
|
||||||
import { SdkObject } from './instrumentation';
|
|
||||||
import { Artifact } from './artifact';
|
import { Artifact } from './artifact';
|
||||||
|
import { BrowserContext, validateBrowserContextOptions } from './browserContext';
|
||||||
|
import { Download } from './download';
|
||||||
|
import { SdkObject } from './instrumentation';
|
||||||
|
import { Page } from './page';
|
||||||
import { ClientCertificatesProxy } from './socksClientCertificatesInterceptor';
|
import { ClientCertificatesProxy } from './socksClientCertificatesInterceptor';
|
||||||
|
|
||||||
|
import type { CallMetadata } from './instrumentation';
|
||||||
|
import type * as types from './types';
|
||||||
|
import type { ProxySettings } from './types';
|
||||||
|
import type { RecentLogsCollector } from '../utils/debugLogger';
|
||||||
|
import type * as channels from '@protocol/channels';
|
||||||
|
import type { ChildProcess } from 'child_process';
|
||||||
|
|
||||||
|
|
||||||
export interface BrowserProcess {
|
export interface BrowserProcess {
|
||||||
onclose?: ((exitCode: number | null, signal: string | null) => void);
|
onclose?: ((exitCode: number | null, signal: string | null) => void);
|
||||||
process?: ChildProcess;
|
process?: ChildProcess;
|
||||||
|
|
|
||||||
|
|
@ -15,36 +15,38 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import * as fs from 'fs';
|
||||||
|
import * as path from 'path';
|
||||||
|
|
||||||
import { TimeoutSettings } from '../common/timeoutSettings';
|
import { TimeoutSettings } from '../common/timeoutSettings';
|
||||||
import { createGuid, debugMode } from '../utils';
|
import { createGuid, debugMode } from '../utils';
|
||||||
import { mkdirIfNeeded } from '../utils/fileUtils';
|
import { Clock } from './clock';
|
||||||
import type { Browser, BrowserOptions } from './browser';
|
import { Debugger } from './debugger';
|
||||||
import type { Download } from './download';
|
import { BrowserContextAPIRequestContext } from './fetch';
|
||||||
import type * as frames from './frames';
|
import { HarRecorder } from './har/harRecorder';
|
||||||
import { helper } from './helper';
|
import { helper } from './helper';
|
||||||
|
import { SdkObject, serverSideCallMetadata } from './instrumentation';
|
||||||
|
import * as utilityScriptSerializers from './isomorphic/utilityScriptSerializers';
|
||||||
import * as network from './network';
|
import * as network from './network';
|
||||||
import { InitScript } from './page';
|
import { InitScript } from './page';
|
||||||
import { Page, PageBinding } from './page';
|
import { Page, PageBinding } from './page';
|
||||||
|
import { Recorder } from './recorder';
|
||||||
|
import * as storageScript from './storageScript';
|
||||||
|
import { mkdirIfNeeded } from '../utils/fileUtils';
|
||||||
|
import { RecorderApp } from './recorder/recorderApp';
|
||||||
|
import * as consoleApiSource from '../generated/consoleApiSource';
|
||||||
|
import { Tracing } from './trace/recorder/tracing';
|
||||||
|
|
||||||
|
import type { Artifact } from './artifact';
|
||||||
|
import type { Browser, BrowserOptions } from './browser';
|
||||||
|
import type { Download } from './download';
|
||||||
|
import type * as frames from './frames';
|
||||||
|
import type { CallMetadata } from './instrumentation';
|
||||||
import type { Progress, ProgressController } from './progress';
|
import type { Progress, ProgressController } from './progress';
|
||||||
import type { Selectors } from './selectors';
|
import type { Selectors } from './selectors';
|
||||||
|
import type { ClientCertificatesProxy } from './socksClientCertificatesInterceptor';
|
||||||
import type * as types from './types';
|
import type * as types from './types';
|
||||||
import type * as channels from '@protocol/channels';
|
import type * as channels from '@protocol/channels';
|
||||||
import path from 'path';
|
|
||||||
import fs from 'fs';
|
|
||||||
import type { CallMetadata } from './instrumentation';
|
|
||||||
import { serverSideCallMetadata, SdkObject } from './instrumentation';
|
|
||||||
import { Debugger } from './debugger';
|
|
||||||
import { Tracing } from './trace/recorder/tracing';
|
|
||||||
import { HarRecorder } from './har/harRecorder';
|
|
||||||
import { Recorder } from './recorder';
|
|
||||||
import * as consoleApiSource from '../generated/consoleApiSource';
|
|
||||||
import { BrowserContextAPIRequestContext } from './fetch';
|
|
||||||
import type { Artifact } from './artifact';
|
|
||||||
import { Clock } from './clock';
|
|
||||||
import type { ClientCertificatesProxy } from './socksClientCertificatesInterceptor';
|
|
||||||
import { RecorderApp } from './recorder/recorderApp';
|
|
||||||
import * as storageScript from './storageScript';
|
|
||||||
import * as utilityScriptSerializers from './isomorphic/utilityScriptSerializers';
|
|
||||||
|
|
||||||
export abstract class BrowserContext extends SdkObject {
|
export abstract class BrowserContext extends SdkObject {
|
||||||
static Events = {
|
static Events = {
|
||||||
|
|
|
||||||
|
|
@ -14,32 +14,35 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import fs from 'fs';
|
import * as fs from 'fs';
|
||||||
import * as os from 'os';
|
import * as os from 'os';
|
||||||
import path from 'path';
|
import * as path from 'path';
|
||||||
import type { BrowserContext } from './browserContext';
|
|
||||||
import { normalizeProxySettings, validateBrowserContextOptions } from './browserContext';
|
import { normalizeProxySettings, validateBrowserContextOptions } from './browserContext';
|
||||||
import type { BrowserName } from './registry';
|
|
||||||
import { registry } from './registry';
|
|
||||||
import type { ConnectionTransport } from './transport';
|
|
||||||
import { WebSocketTransport } from './transport';
|
|
||||||
import type { BrowserOptions, Browser, BrowserProcess } from './browser';
|
|
||||||
import type { Env } from '../utils/processLauncher';
|
|
||||||
import { launchProcess, envArrayToObject } from '../utils/processLauncher';
|
|
||||||
import { PipeTransport } from './pipeTransport';
|
|
||||||
import type { Progress } from './progress';
|
|
||||||
import { ProgressController } from './progress';
|
|
||||||
import type * as types from './types';
|
|
||||||
import type * as channels from '@protocol/channels';
|
|
||||||
import { DEFAULT_TIMEOUT, TimeoutSettings } from '../common/timeoutSettings';
|
import { DEFAULT_TIMEOUT, TimeoutSettings } from '../common/timeoutSettings';
|
||||||
import { debugMode, ManualPromise } from '../utils';
|
import { ManualPromise, debugMode } from '../utils';
|
||||||
import { existsAsync } from '../utils/fileUtils';
|
|
||||||
import { helper } from './helper';
|
import { helper } from './helper';
|
||||||
import { RecentLogsCollector } from '../utils/debugLogger';
|
|
||||||
import type { CallMetadata } from './instrumentation';
|
|
||||||
import { SdkObject } from './instrumentation';
|
import { SdkObject } from './instrumentation';
|
||||||
import { type ProtocolError, isProtocolError } from './protocolError';
|
import { PipeTransport } from './pipeTransport';
|
||||||
|
import { ProgressController } from './progress';
|
||||||
|
import { isProtocolError } from './protocolError';
|
||||||
|
import { registry } from './registry';
|
||||||
import { ClientCertificatesProxy } from './socksClientCertificatesInterceptor';
|
import { ClientCertificatesProxy } from './socksClientCertificatesInterceptor';
|
||||||
|
import { WebSocketTransport } from './transport';
|
||||||
|
import { RecentLogsCollector } from '../utils/debugLogger';
|
||||||
|
import { existsAsync } from '../utils/fileUtils';
|
||||||
|
import { envArrayToObject, launchProcess } from '../utils/processLauncher';
|
||||||
|
|
||||||
|
import type { Browser, BrowserOptions, BrowserProcess } from './browser';
|
||||||
|
import type { BrowserContext } from './browserContext';
|
||||||
|
import type { CallMetadata } from './instrumentation';
|
||||||
|
import type { Progress } from './progress';
|
||||||
|
import type { ProtocolError } from './protocolError';
|
||||||
|
import type { BrowserName } from './registry';
|
||||||
|
import type { ConnectionTransport } from './transport';
|
||||||
|
import type * as types from './types';
|
||||||
|
import type { Env } from '../utils/processLauncher';
|
||||||
|
import type * as channels from '@protocol/channels';
|
||||||
|
|
||||||
export const kNoXServerRunningError = 'Looks like you launched a headed browser without having a XServer running.\n' +
|
export const kNoXServerRunningError = 'Looks like you launched a headed browser without having a XServer running.\n' +
|
||||||
'Set either \'headless: true\' or use \'xvfb-run <your-playwright-app>\' before running Playwright.\n\n<3 Playwright Team';
|
'Set either \'headless: true\' or use \'xvfb-run <your-playwright-app>\' before running Playwright.\n\n<3 Playwright Team';
|
||||||
|
|
|
||||||
|
|
@ -15,40 +15,42 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import fs from 'fs';
|
import * as fs from 'fs';
|
||||||
import os from 'os';
|
import * as os from 'os';
|
||||||
import path from 'path';
|
import * as path from 'path';
|
||||||
import type stream from 'stream';
|
|
||||||
|
import { chromiumSwitches } from './chromiumSwitches';
|
||||||
import { CRBrowser } from './crBrowser';
|
import { CRBrowser } from './crBrowser';
|
||||||
import type { Env } from '../../utils/processLauncher';
|
|
||||||
import { gracefullyCloseSet } from '../../utils/processLauncher';
|
|
||||||
import { kBrowserCloseMessageId } from './crConnection';
|
import { kBrowserCloseMessageId } from './crConnection';
|
||||||
|
import { TimeoutSettings } from '../../common/timeoutSettings';
|
||||||
|
import { debugMode, headersArrayToObject, headersObjectToArray, } from '../../utils';
|
||||||
|
import { wrapInASCIIBox } from '../../utils/ascii';
|
||||||
|
import { RecentLogsCollector } from '../../utils/debugLogger';
|
||||||
|
import { removeFolders } from '../../utils/fileUtils';
|
||||||
|
import { ManualPromise } from '../../utils/manualPromise';
|
||||||
|
import { fetchData } from '../../utils/network';
|
||||||
|
import { gracefullyCloseSet } from '../../utils/processLauncher';
|
||||||
|
import { getUserAgent } from '../../utils/userAgent';
|
||||||
|
import { validateBrowserContextOptions } from '../browserContext';
|
||||||
import { BrowserType, kNoXServerRunningError } from '../browserType';
|
import { BrowserType, kNoXServerRunningError } from '../browserType';
|
||||||
import { BrowserReadyState } from '../browserType';
|
import { BrowserReadyState } from '../browserType';
|
||||||
import type { ConnectionTransport, ProtocolRequest } from '../transport';
|
import { helper } from '../helper';
|
||||||
|
import { registry } from '../registry';
|
||||||
import { WebSocketTransport } from '../transport';
|
import { WebSocketTransport } from '../transport';
|
||||||
import { CRDevTools } from './crDevTools';
|
import { CRDevTools } from './crDevTools';
|
||||||
import type { BrowserOptions, BrowserProcess } from '../browser';
|
|
||||||
import { Browser } from '../browser';
|
import { Browser } from '../browser';
|
||||||
import type * as types from '../types';
|
|
||||||
import type { HTTPRequestParams } from '../../utils/network';
|
|
||||||
import { fetchData } from '../../utils/network';
|
|
||||||
import { getUserAgent } from '../../utils/userAgent';
|
|
||||||
import { wrapInASCIIBox } from '../../utils/ascii';
|
|
||||||
import { debugMode, headersArrayToObject, headersObjectToArray, } from '../../utils';
|
|
||||||
import { removeFolders } from '../../utils/fileUtils';
|
|
||||||
import { RecentLogsCollector } from '../../utils/debugLogger';
|
|
||||||
import type { Progress } from '../progress';
|
|
||||||
import { ProgressController } from '../progress';
|
import { ProgressController } from '../progress';
|
||||||
import { TimeoutSettings } from '../../common/timeoutSettings';
|
|
||||||
import { helper } from '../helper';
|
import type { HTTPRequestParams } from '../../utils/network';
|
||||||
|
import type { Env } from '../../utils/processLauncher';
|
||||||
|
import type { BrowserOptions, BrowserProcess } from '../browser';
|
||||||
import type { CallMetadata, SdkObject } from '../instrumentation';
|
import type { CallMetadata, SdkObject } from '../instrumentation';
|
||||||
import type http from 'http';
|
import type { Progress } from '../progress';
|
||||||
import { registry } from '../registry';
|
|
||||||
import { ManualPromise } from '../../utils/manualPromise';
|
|
||||||
import { validateBrowserContextOptions } from '../browserContext';
|
|
||||||
import { chromiumSwitches } from './chromiumSwitches';
|
|
||||||
import type { ProtocolError } from '../protocolError';
|
import type { ProtocolError } from '../protocolError';
|
||||||
|
import type { ConnectionTransport, ProtocolRequest } from '../transport';
|
||||||
|
import type * as types from '../types';
|
||||||
|
import type http from 'http';
|
||||||
|
import type stream from 'stream';
|
||||||
|
|
||||||
const ARTIFACTS_FOLDER = path.join(os.tmpdir(), 'playwright-artifacts-');
|
const ARTIFACTS_FOLDER = path.join(os.tmpdir(), 'playwright-artifacts-');
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -17,8 +17,8 @@
|
||||||
|
|
||||||
import type { CRSession } from './crConnection';
|
import type { CRSession } from './crConnection';
|
||||||
import type { Protocol } from './protocol';
|
import type { Protocol } from './protocol';
|
||||||
import type * as dom from '../dom';
|
|
||||||
import type * as accessibility from '../accessibility';
|
import type * as accessibility from '../accessibility';
|
||||||
|
import type * as dom from '../dom';
|
||||||
import type * as channels from '@protocol/channels';
|
import type * as channels from '@protocol/channels';
|
||||||
|
|
||||||
export async function getAccessibilityTree(client: CRSession, needle?: dom.ElementHandle): Promise<{tree: accessibility.AXNode, needle: accessibility.AXNode | null}> {
|
export async function getAccessibilityTree(client: CRSession, needle?: dom.ElementHandle): Promise<{tree: accessibility.AXNode, needle: accessibility.AXNode | null}> {
|
||||||
|
|
|
||||||
|
|
@ -15,28 +15,30 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import type { BrowserOptions } from '../browser';
|
import * as path from 'path';
|
||||||
import path from 'path';
|
|
||||||
import { Browser } from '../browser';
|
|
||||||
import { assertBrowserContextIsNotOwned, BrowserContext, verifyGeolocation } from '../browserContext';
|
|
||||||
import { assert, createGuid } from '../../utils';
|
import { assert, createGuid } from '../../utils';
|
||||||
import * as network from '../network';
|
import { Artifact } from '../artifact';
|
||||||
import type { InitScript, Worker } from '../page';
|
import { Browser } from '../browser';
|
||||||
import { Page } from '../page';
|
import { BrowserContext, assertBrowserContextIsNotOwned, verifyGeolocation } from '../browserContext';
|
||||||
import { Frame } from '../frames';
|
import { Frame } from '../frames';
|
||||||
import type { Dialog } from '../dialog';
|
import * as network from '../network';
|
||||||
import type { ConnectionTransport } from '../transport';
|
import { Page } from '../page';
|
||||||
import type * as types from '../types';
|
import { CRConnection, ConnectionEvents } from './crConnection';
|
||||||
import type * as channels from '@protocol/channels';
|
|
||||||
import type { CRSession, CDPSession } from './crConnection';
|
|
||||||
import { ConnectionEvents, CRConnection } from './crConnection';
|
|
||||||
import { CRPage } from './crPage';
|
import { CRPage } from './crPage';
|
||||||
import { saveProtocolStream } from './crProtocolHelper';
|
import { saveProtocolStream } from './crProtocolHelper';
|
||||||
import type { Protocol } from './protocol';
|
|
||||||
import type { CRDevTools } from './crDevTools';
|
|
||||||
import { CRServiceWorker } from './crServiceWorker';
|
import { CRServiceWorker } from './crServiceWorker';
|
||||||
|
|
||||||
|
import type { Dialog } from '../dialog';
|
||||||
|
import type { InitScript, Worker } from '../page';
|
||||||
|
import type { ConnectionTransport } from '../transport';
|
||||||
|
import type * as types from '../types';
|
||||||
|
import type { CDPSession, CRSession } from './crConnection';
|
||||||
|
import type { CRDevTools } from './crDevTools';
|
||||||
|
import type { Protocol } from './protocol';
|
||||||
|
import type { BrowserOptions } from '../browser';
|
||||||
import type { SdkObject } from '../instrumentation';
|
import type { SdkObject } from '../instrumentation';
|
||||||
import { Artifact } from '../artifact';
|
import type * as channels from '@protocol/channels';
|
||||||
|
|
||||||
export class CRBrowser extends Browser {
|
export class CRBrowser extends Browser {
|
||||||
readonly _connection: CRConnection;
|
readonly _connection: CRConnection;
|
||||||
|
|
|
||||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue