Compare commits
18 commits
main
...
release-1.
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4743420999 | ||
|
|
c41012b055 | ||
|
|
ed619b6fcb | ||
|
|
abf9df39cf | ||
|
|
35d8604f8d | ||
|
|
6cc43d81c5 | ||
|
|
2a577a5caf | ||
|
|
ed919f3dda | ||
|
|
476b74f7c4 | ||
|
|
0861364c28 | ||
|
|
9271ba9495 | ||
|
|
da997ee8c0 | ||
|
|
94b6fe1bdb | ||
|
|
55cf8eae25 | ||
|
|
a0a099fe4a | ||
|
|
cd8b12c0d5 | ||
|
|
9981f1418a | ||
|
|
5f78f27a7a |
|
|
@ -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://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 -->
|
||||||
|
|
||||||
## [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,7 +8,7 @@ Playwright is a framework for Web Testing and Automation. It allows testing [Chr
|
||||||
|
|
||||||
| | Linux | macOS | Windows |
|
| | Linux | macOS | Windows |
|
||||||
| :--- | :---: | :---: | :---: |
|
| :--- | :---: | :---: | :---: |
|
||||||
| Chromium <!-- GEN:chromium-version -->117.0.5938.48<!-- GEN:stop --> | :white_check_mark: | :white_check_mark: | :white_check_mark: |
|
| Chromium <!-- GEN:chromium-version -->117.0.5938.62<!-- GEN:stop --> | :white_check_mark: | :white_check_mark: | :white_check_mark: |
|
||||||
| WebKit <!-- GEN:webkit-version -->17.0<!-- GEN:stop --> | :white_check_mark: | :white_check_mark: | :white_check_mark: |
|
| WebKit <!-- GEN:webkit-version -->17.0<!-- GEN:stop --> | :white_check_mark: | :white_check_mark: | :white_check_mark: |
|
||||||
| Firefox <!-- GEN:firefox-version -->117.0<!-- GEN:stop --> | :white_check_mark: | :white_check_mark: | :white_check_mark: |
|
| Firefox <!-- GEN:firefox-version -->117.0<!-- GEN:stop --> | :white_check_mark: | :white_check_mark: | :white_check_mark: |
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,75 +2,24 @@
|
||||||
* since: v1.20
|
* since: v1.20
|
||||||
* langs: js
|
* langs: js
|
||||||
|
|
||||||
:::tip
|
Playwright provides methods for comparing page and element screenshots with
|
||||||
For visual regression testing, use [`method: PageAssertions.toHaveScreenshot#1`] and [`method: LocatorAssertions.toHaveScreenshot#1`] instead.
|
expected values stored in files.
|
||||||
:::
|
|
||||||
|
|
||||||
Playwright provides methods for comparing text values with expected values stored in snapshot files.
|
|
||||||
|
|
||||||
```js
|
```js
|
||||||
expect(text).toMatchSnapshot('snapshot.txt');
|
expect(screenshot).toMatchSnapshot('landing-page.png');
|
||||||
```
|
```
|
||||||
|
|
||||||
## method: SnapshotAssertions.toMatchSnapshot#1
|
## method: SnapshotAssertions.toMatchSnapshot#1
|
||||||
* since: v1.22
|
* since: v1.22
|
||||||
|
|
||||||
Ensures that the passed [string] matches the expected snapshot stored in the test snapshots directory.
|
:::caution
|
||||||
|
To compare screenshots, use [`method: PageAssertions.toHaveScreenshot#1`] instead.
|
||||||
**Usage**
|
:::
|
||||||
|
|
||||||
```js
|
|
||||||
// Basic usage.
|
|
||||||
expect(await page.title()).toMatchSnapshot('page-title.txt');
|
|
||||||
|
|
||||||
// Bring some structure to your snapshot files by passing file path segments.
|
|
||||||
expect(await page.title()).toMatchSnapshot(['page-title', 'step1.txt']);
|
|
||||||
expect(await page.title()).toMatchSnapshot(['page-title', 'step2.txt']);
|
|
||||||
```
|
|
||||||
|
|
||||||
Note that matching snapshots only work with Playwright test runner.
|
|
||||||
|
|
||||||
### param: SnapshotAssertions.toMatchSnapshot#1.name
|
|
||||||
* since: v1.22
|
|
||||||
- `name` <[string]|[Array]<[string]>>
|
|
||||||
|
|
||||||
Snapshot name.
|
|
||||||
|
|
||||||
## method: SnapshotAssertions.toMatchSnapshot#2
|
|
||||||
* since: v1.22
|
|
||||||
|
|
||||||
Ensures that passed value, either a [string] or a [Buffer], matches the expected snapshot stored in the test snapshots directory.
|
Ensures that passed value, either a [string] or a [Buffer], matches the expected snapshot stored in the test snapshots directory.
|
||||||
|
|
||||||
**Usage**
|
**Usage**
|
||||||
|
|
||||||
```js
|
|
||||||
// Basic usage.
|
|
||||||
expect(await page.title()).toMatchSnapshot();
|
|
||||||
|
|
||||||
// Configure the snapshot name.
|
|
||||||
expect(await page.title()).toMatchSnapshot({
|
|
||||||
name: 'page-title.txt',
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
Note that matching snapshots only work with Playwright test runner.
|
|
||||||
|
|
||||||
### option: SnapshotAssertions.toMatchSnapshot#2.name
|
|
||||||
* since: v1.22
|
|
||||||
- `name` <[string]|[Array]<[string]>>
|
|
||||||
|
|
||||||
Snapshot name. If not passed, the test name and ordinals are used when called multiple times.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## method: SnapshotAssertions.toMatchSnapshot#3
|
|
||||||
* deprecated: To avoid flakiness, use [`method: PageAssertions.toHaveScreenshot#1`] instead.
|
|
||||||
* since: v1.22
|
|
||||||
|
|
||||||
Ensures that the passed [Buffer] matches the expected snapshot stored in the test snapshots directory.
|
|
||||||
|
|
||||||
**Usage**
|
|
||||||
|
|
||||||
```js
|
```js
|
||||||
// Basic usage.
|
// Basic usage.
|
||||||
expect(await page.screenshot()).toMatchSnapshot('landing-page.png');
|
expect(await page.screenshot()).toMatchSnapshot('landing-page.png');
|
||||||
|
|
@ -92,26 +41,29 @@ Learn more about [visual comparisons](../test-snapshots.md).
|
||||||
|
|
||||||
Note that matching snapshots only work with Playwright test runner.
|
Note that matching snapshots only work with Playwright test runner.
|
||||||
|
|
||||||
### param: SnapshotAssertions.toMatchSnapshot#3.name
|
### param: SnapshotAssertions.toMatchSnapshot#1.name
|
||||||
* since: v1.22
|
* since: v1.22
|
||||||
- `name` <[string]|[Array]<[string]>>
|
- `name` <[string]|[Array]<[string]>>
|
||||||
|
|
||||||
Snapshot name.
|
Snapshot name.
|
||||||
|
|
||||||
### option: SnapshotAssertions.toMatchSnapshot#3.maxDiffPixels = %%-assertions-max-diff-pixels-%%
|
### option: SnapshotAssertions.toMatchSnapshot#1.maxDiffPixels = %%-assertions-max-diff-pixels-%%
|
||||||
* since: v1.22
|
* since: v1.22
|
||||||
|
|
||||||
### option: SnapshotAssertions.toMatchSnapshot#3.maxDiffPixelRatio = %%-assertions-max-diff-pixel-ratio-%%
|
### option: SnapshotAssertions.toMatchSnapshot#1.maxDiffPixelRatio = %%-assertions-max-diff-pixel-ratio-%%
|
||||||
* since: v1.22
|
* since: v1.22
|
||||||
|
|
||||||
### option: SnapshotAssertions.toMatchSnapshot#3.threshold = %%-assertions-threshold-%%
|
### option: SnapshotAssertions.toMatchSnapshot#1.threshold = %%-assertions-threshold-%%
|
||||||
* since: v1.22
|
* since: v1.22
|
||||||
|
|
||||||
## method: SnapshotAssertions.toMatchSnapshot#4
|
## method: SnapshotAssertions.toMatchSnapshot#2
|
||||||
* deprecated: To avoid flakiness, use [`method: PageAssertions.toHaveScreenshot#1`] instead.
|
|
||||||
* since: v1.22
|
* since: v1.22
|
||||||
|
|
||||||
Ensures that the passed [Buffer] matches the expected snapshot stored in the test snapshots directory.
|
:::caution
|
||||||
|
To compare screenshots, use [`method: PageAssertions.toHaveScreenshot#2`] instead.
|
||||||
|
:::
|
||||||
|
|
||||||
|
Ensures that passed value, either a [string] or a [Buffer], matches the expected snapshot stored in the test snapshots directory.
|
||||||
|
|
||||||
**Usage**
|
**Usage**
|
||||||
|
|
||||||
|
|
@ -135,18 +87,17 @@ Learn more about [visual comparisons](../test-snapshots.md).
|
||||||
|
|
||||||
Note that matching snapshots only work with Playwright test runner.
|
Note that matching snapshots only work with Playwright test runner.
|
||||||
|
|
||||||
### option: SnapshotAssertions.toMatchSnapshot#4.maxDiffPixels = %%-assertions-max-diff-pixels-%%
|
### option: SnapshotAssertions.toMatchSnapshot#2.maxDiffPixels = %%-assertions-max-diff-pixels-%%
|
||||||
* since: v1.22
|
* since: v1.22
|
||||||
|
|
||||||
### option: SnapshotAssertions.toMatchSnapshot#4.maxDiffPixelRatio = %%-assertions-max-diff-pixel-ratio-%%
|
### option: SnapshotAssertions.toMatchSnapshot#2.maxDiffPixelRatio = %%-assertions-max-diff-pixel-ratio-%%
|
||||||
* since: v1.22
|
* since: v1.22
|
||||||
|
|
||||||
### option: SnapshotAssertions.toMatchSnapshot#4.name
|
### option: SnapshotAssertions.toMatchSnapshot#2.name
|
||||||
* since: v1.22
|
* since: v1.22
|
||||||
- `name` <[string]|[Array]<[string]>>
|
- `name` <[string]|[Array]<[string]>>
|
||||||
|
|
||||||
Snapshot name. If not passed, the test name and ordinals are used when called multiple times.
|
Snapshot name. If not passed, the test name and ordinals are used when called multiple times.
|
||||||
|
|
||||||
### option: SnapshotAssertions.toMatchSnapshot#4.threshold = %%-assertions-threshold-%%
|
### option: SnapshotAssertions.toMatchSnapshot#2.threshold = %%-assertions-threshold-%%
|
||||||
* since: v1.22
|
* since: v1.22
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,39 @@ title: "Release notes"
|
||||||
toc_max_heading_level: 2
|
toc_max_heading_level: 2
|
||||||
---
|
---
|
||||||
|
|
||||||
|
## Version 1.38
|
||||||
|
|
||||||
|
### Trace Viewer Updates
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
1. Zoom into time range.
|
||||||
|
1. Network panel redesign.
|
||||||
|
|
||||||
|
### New APIs
|
||||||
|
|
||||||
|
- [`event: BrowserContext.webError`]
|
||||||
|
- [`method: Locator.pressSequentially`]
|
||||||
|
|
||||||
|
### Deprecations
|
||||||
|
|
||||||
|
* The following methods were deprecated: [`method: Page.type`], [`method: Frame.type`],
|
||||||
|
[`method: Locator.type`] and [`method: ElementHandle.type`].
|
||||||
|
Please use [`method: Locator.fill`] instead which is much faster. Use
|
||||||
|
[`method: Locator.pressSequentially`] only if there is a special keyboard
|
||||||
|
handling on the page, and you need to press keys one-by-one.
|
||||||
|
|
||||||
|
### Browser Versions
|
||||||
|
|
||||||
|
* Chromium 117.0.5938.62
|
||||||
|
* Mozilla Firefox 117.0
|
||||||
|
* WebKit 17.0
|
||||||
|
|
||||||
|
This version was also tested against the following stable channels:
|
||||||
|
|
||||||
|
* Google Chrome 116
|
||||||
|
* Microsoft Edge 116
|
||||||
|
|
||||||
## Version 1.37
|
## Version 1.37
|
||||||
|
|
||||||
### 📚 Debian 12 Bookworm Support
|
### 📚 Debian 12 Bookworm Support
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,39 @@ title: "Release notes"
|
||||||
toc_max_heading_level: 2
|
toc_max_heading_level: 2
|
||||||
---
|
---
|
||||||
|
|
||||||
|
## Version 1.38
|
||||||
|
|
||||||
|
### Trace Viewer Updates
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
1. Zoom into time range.
|
||||||
|
1. Network panel redesign.
|
||||||
|
|
||||||
|
### New APIs
|
||||||
|
|
||||||
|
- [`event: BrowserContext.webError`]
|
||||||
|
- [`method: Locator.pressSequentially`]
|
||||||
|
|
||||||
|
### Deprecations
|
||||||
|
|
||||||
|
* The following methods were deprecated: [`method: Page.type`], [`method: Frame.type`],
|
||||||
|
[`method: Locator.type`] and [`method: ElementHandle.type`].
|
||||||
|
Please use [`method: Locator.fill`] instead which is much faster. Use
|
||||||
|
[`method: Locator.pressSequentially`] only if there is a special keyboard
|
||||||
|
handling on the page, and you need to press keys one-by-one.
|
||||||
|
|
||||||
|
### Browser Versions
|
||||||
|
|
||||||
|
* Chromium 117.0.5938.62
|
||||||
|
* Mozilla Firefox 117.0
|
||||||
|
* WebKit 17.0
|
||||||
|
|
||||||
|
This version was also tested against the following stable channels:
|
||||||
|
|
||||||
|
* Google Chrome 116
|
||||||
|
* Microsoft Edge 116
|
||||||
|
|
||||||
## Version 1.37
|
## Version 1.37
|
||||||
|
|
||||||
### New APIs
|
### New APIs
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,81 @@ toc_max_heading_level: 2
|
||||||
|
|
||||||
import LiteYouTube from '@site/src/components/LiteYouTube';
|
import LiteYouTube from '@site/src/components/LiteYouTube';
|
||||||
|
|
||||||
|
## Version 1.38
|
||||||
|
|
||||||
|
### UI Mode Updates
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
1. Zoom into time range.
|
||||||
|
1. Network panel redesign.
|
||||||
|
|
||||||
|
### New APIs
|
||||||
|
|
||||||
|
- [`event: BrowserContext.webError`]
|
||||||
|
- [`method: Locator.pressSequentially`]
|
||||||
|
- The [`method: Reporter.onEnd`] now reports `startTime` and total run `duration`.
|
||||||
|
|
||||||
|
### Deprecations
|
||||||
|
|
||||||
|
* The following methods were deprecated: [`method: Page.type`], [`method: Frame.type`],
|
||||||
|
[`method: Locator.type`] and [`method: ElementHandle.type`].
|
||||||
|
Please use [`method: Locator.fill`] instead which is much faster. Use
|
||||||
|
[`method: Locator.pressSequentially`] only if there is a special keyboard
|
||||||
|
handling on the page, and you need to press keys one-by-one.
|
||||||
|
|
||||||
|
### Breaking Changes: Playwright no longer downloads browsers automatically
|
||||||
|
|
||||||
|
> **Note**: If you are using `@playwright/test` package, this change does not affect you.
|
||||||
|
|
||||||
|
Playwright recommends to use `@playwright/test` package and download browsers via `npx playwright install` command. If you are following this recommendation, nothing has changed for you.
|
||||||
|
|
||||||
|
However, up to v1.38, installing the `playwright` package instead of `@playwright/test` did automatically download browsers. This is no longer the case, and we recommend to explicitly download browsers via `npx playwright install` command.
|
||||||
|
|
||||||
|
**v1.37 and earlier**
|
||||||
|
|
||||||
|
`playwright` package was downloading browsers during `npm install`, while `@playwright/test` was not.
|
||||||
|
|
||||||
|
**v1.38 and later**
|
||||||
|
|
||||||
|
`playwright` and `@playwright/test` packages do not download browsers during `npm install`.
|
||||||
|
|
||||||
|
**Recommended migration**
|
||||||
|
|
||||||
|
Run `npx playwright install` to download browsers after `npm install`. For example, in your CI configuration:
|
||||||
|
|
||||||
|
```yml
|
||||||
|
- run: npm ci
|
||||||
|
- run: npx playwright install --with-deps
|
||||||
|
```
|
||||||
|
|
||||||
|
**Alternative migration option - not recommended**
|
||||||
|
|
||||||
|
Add `@playwright/browser-chromium`, `@playwright/browser-firefox` and `@playwright/browser-webkit` as a dependency. These packages download respective browsers during `npm install`. Make sure you keep the version of all playwright packages in sync:
|
||||||
|
|
||||||
|
```json
|
||||||
|
// package.json
|
||||||
|
{
|
||||||
|
"devDependencies": {
|
||||||
|
"playwright": "1.38.0",
|
||||||
|
"@playwright/browser-chromium": "1.38.0",
|
||||||
|
"@playwright/browser-firefox": "1.38.0",
|
||||||
|
"@playwright/browser-webkit": "1.38.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Browser Versions
|
||||||
|
|
||||||
|
* Chromium 117.0.5938.62
|
||||||
|
* Mozilla Firefox 117.0
|
||||||
|
* WebKit 17.0
|
||||||
|
|
||||||
|
This version was also tested against the following stable channels:
|
||||||
|
|
||||||
|
* Google Chrome 116
|
||||||
|
* Microsoft Edge 116
|
||||||
|
|
||||||
## Version 1.37
|
## Version 1.37
|
||||||
|
|
||||||
<LiteYouTube
|
<LiteYouTube
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,39 @@ title: "Release notes"
|
||||||
toc_max_heading_level: 2
|
toc_max_heading_level: 2
|
||||||
---
|
---
|
||||||
|
|
||||||
|
## Version 1.38
|
||||||
|
|
||||||
|
### Trace Viewer Updates
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
1. Zoom into time range.
|
||||||
|
1. Network panel redesign.
|
||||||
|
|
||||||
|
### New APIs
|
||||||
|
|
||||||
|
- [`event: BrowserContext.webError`]
|
||||||
|
- [`method: Locator.pressSequentially`]
|
||||||
|
|
||||||
|
### Deprecations
|
||||||
|
|
||||||
|
* The following methods were deprecated: [`method: Page.type`], [`method: Frame.type`],
|
||||||
|
[`method: Locator.type`] and [`method: ElementHandle.type`].
|
||||||
|
Please use [`method: Locator.fill`] instead which is much faster. Use
|
||||||
|
[`method: Locator.pressSequentially`] only if there is a special keyboard
|
||||||
|
handling on the page, and you need to press keys one-by-one.
|
||||||
|
|
||||||
|
### Browser Versions
|
||||||
|
|
||||||
|
* Chromium 117.0.5938.62
|
||||||
|
* Mozilla Firefox 117.0
|
||||||
|
* WebKit 17.0
|
||||||
|
|
||||||
|
This version was also tested against the following stable channels:
|
||||||
|
|
||||||
|
* Google Chrome 116
|
||||||
|
* Microsoft Edge 116
|
||||||
|
|
||||||
## Version 1.37
|
## Version 1.37
|
||||||
|
|
||||||
### Highlights
|
### Highlights
|
||||||
|
|
|
||||||
|
|
@ -41,18 +41,18 @@ export default defineConfig({
|
||||||
- type: ?<[Object]>
|
- type: ?<[Object]>
|
||||||
- `timeout` ?<[int]> Default timeout for async expect matchers in milliseconds, defaults to 5000ms.
|
- `timeout` ?<[int]> Default timeout for async expect matchers in milliseconds, defaults to 5000ms.
|
||||||
- `toHaveScreenshot` ?<[Object]> Configuration for the [`method: PageAssertions.toHaveScreenshot#1`] method.
|
- `toHaveScreenshot` ?<[Object]> Configuration for the [`method: PageAssertions.toHaveScreenshot#1`] method.
|
||||||
- `threshold` ?<[float]> An acceptable perceived color difference between the same pixel in compared images, ranging from `0` (strict) and `1` (lax). `"pixelmatch"` comparator computes color difference in [YIQ color space](https://en.wikipedia.org/wiki/YIQ) and defaults `threshold` value to `0.2`.
|
- `threshold` ?<[float]> an acceptable perceived color difference between the same pixel in compared images, ranging from `0` (strict) and `1` (lax). `"pixelmatch"` comparator computes color difference in [YIQ color space](https://en.wikipedia.org/wiki/YIQ) and defaults `threshold` value to `0.2`.
|
||||||
- `maxDiffPixels` ?<[int]> An acceptable amount of pixels that could be different, unset by default.
|
- `maxDiffPixels` ?<[int]> an acceptable amount of pixels that could be different, unset by default.
|
||||||
- `maxDiffPixelRatio` ?<[float]> An acceptable ratio of pixels that are different to the total amount of pixels, between `0` and `1` , unset by default.
|
- `maxDiffPixelRatio` ?<[float]> an acceptable ratio of pixels that are different to the total amount of pixels, between `0` and `1` , unset by default.
|
||||||
- `animations` ?<[ScreenshotAnimations]<"allow"|"disabled">> See [`option: animations`] in [`method: Page.screenshot`]. Defaults to `"disabled"`.
|
- `animations` ?<[ScreenshotAnimations]<"allow"|"disabled">> See [`option: animations`] in [`method: Page.screenshot`]. Defaults to `"disabled"`.
|
||||||
- `caret` ?<[ScreenshotCaret]<"hide"|"initial">> See [`option: caret`] in [`method: Page.screenshot`]. Defaults to `"hide"`.
|
- `caret` ?<[ScreenshotCaret]<"hide"|"initial">> See [`option: caret`] in [`method: Page.screenshot`]. Defaults to `"hide"`.
|
||||||
- `scale` ?<[ScreenshotScale]<"css"|"device">> See [`option: scale`] in [`method: Page.screenshot`]. Defaults to `"css"`.
|
- `scale` ?<[ScreenshotScale]<"css"|"device">> See [`option: scale`] in [`method: Page.screenshot`]. Defaults to `"css"`.
|
||||||
- `toMatchSnapshot` ?<[Object]> Configuration for the [`method: SnapshotAssertions.toMatchSnapshot#1`] method.
|
- `toMatchSnapshot` ?<[Object]> Configuration for the [`method: SnapshotAssertions.toMatchSnapshot#1`] method.
|
||||||
- `threshold` ?<[float]> **Deprecated.** An acceptable perceived color difference between the same pixel in compared images, ranging from `0` (strict) and `1` (lax). `"pixelmatch"` comparator computes color difference in [YIQ color space](https://en.wikipedia.org/wiki/YIQ) and defaults `threshold` value to `0.2`.
|
- `threshold` ?<[float]> an acceptable perceived color difference between the same pixel in compared images, ranging from `0` (strict) and `1` (lax). `"pixelmatch"` comparator computes color difference in [YIQ color space](https://en.wikipedia.org/wiki/YIQ) and defaults `threshold` value to `0.2`.
|
||||||
- `maxDiffPixels` ?<[int]> **Deprecated.** An acceptable amount of pixels that could be different, unset by default.
|
- `maxDiffPixels` ?<[int]> an acceptable amount of pixels that could be different, unset by default.
|
||||||
- `maxDiffPixelRatio` ?<[float]> **Deprecated.** An acceptable ratio of pixels that are different to the total amount of pixels, between `0` and `1` , unset by default.
|
- `maxDiffPixelRatio` ?<[float]> an acceptable ratio of pixels that are different to the total amount of pixels, between `0` and `1` , unset by default.
|
||||||
|
|
||||||
Configuration for the `expect` assertion library. Learn more about [test configuration](../test-configuration.md#expect-options).
|
Configuration for the `expect` assertion library. Learn more about [various timeouts](../test-timeouts.md).
|
||||||
|
|
||||||
**Usage**
|
**Usage**
|
||||||
|
|
||||||
|
|
@ -62,7 +62,7 @@ import { defineConfig } from '@playwright/test';
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
expect: {
|
expect: {
|
||||||
timeout: 10000,
|
timeout: 10000,
|
||||||
toHaveScreenshot: {
|
toMatchSnapshot: {
|
||||||
maxDiffPixels: 10,
|
maxDiffPixels: 10,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
@ -196,7 +196,7 @@ export default defineConfig({
|
||||||
* since: v1.26
|
* since: v1.26
|
||||||
- type: ?<[boolean]>
|
- type: ?<[boolean]>
|
||||||
|
|
||||||
Whether to skip snapshot expectations, such as [`method: PageAssertions.toHaveScreenshot#1`] and [`method: SnapshotAssertions.toMatchSnapshot#1`].
|
Whether to skip snapshot expectations, such as `expect(value).toMatchSnapshot()` and `await expect(page).toHaveScreenshot()`.
|
||||||
|
|
||||||
**Usage**
|
**Usage**
|
||||||
|
|
||||||
|
|
@ -296,7 +296,7 @@ test('example test', async ({}, testInfo) => {
|
||||||
* discouraged: Use [`property: TestConfig.snapshotPathTemplate`] to configure snapshot paths.
|
* discouraged: Use [`property: TestConfig.snapshotPathTemplate`] to configure snapshot paths.
|
||||||
- type: ?<[string]>
|
- type: ?<[string]>
|
||||||
|
|
||||||
The base directory, relative to the config file, for screenshot files created with [`method: PageAssertions.toHaveScreenshot#1`]. Defaults to [`property: TestConfig.testDir`].
|
The base directory, relative to the config file, for snapshot files created with `toMatchSnapshot`. Defaults to [`property: TestConfig.testDir`].
|
||||||
|
|
||||||
**Usage**
|
**Usage**
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -397,7 +397,7 @@ Use of [`property: TestInfo.snapshotSuffix`] is discouraged. Please use [`proper
|
||||||
snapshot paths.
|
snapshot paths.
|
||||||
:::
|
:::
|
||||||
|
|
||||||
Suffix used to differentiate snapshots between multiple test configurations. For example, if snapshots depend on the platform, you can set `testInfo.snapshotSuffix` equal to `process.platform`. In this case [`method: PageAssertions.toHaveScreenshot#1`] will use different snapshots depending on the platform. Learn more about [snapshots](../test-snapshots.md).
|
Suffix used to differentiate snapshots between multiple test configurations. For example, if snapshots depend on the platform, you can set `testInfo.snapshotSuffix` equal to `process.platform`. In this case `expect(value).toMatchSnapshot(snapshotName)` will use different snapshots depending on the platform. Learn more about [snapshots](../test-snapshots.md).
|
||||||
|
|
||||||
## property: TestInfo.status
|
## property: TestInfo.status
|
||||||
* since: v1.10
|
* since: v1.10
|
||||||
|
|
|
||||||
|
|
@ -91,16 +91,16 @@ export default defineConfig({
|
||||||
- type: ?<[Object]>
|
- type: ?<[Object]>
|
||||||
- `timeout` ?<[int]> Default timeout for async expect matchers in milliseconds, defaults to 5000ms.
|
- `timeout` ?<[int]> Default timeout for async expect matchers in milliseconds, defaults to 5000ms.
|
||||||
- `toHaveScreenshot` ?<[Object]> Configuration for the [`method: PageAssertions.toHaveScreenshot#1`] method.
|
- `toHaveScreenshot` ?<[Object]> Configuration for the [`method: PageAssertions.toHaveScreenshot#1`] method.
|
||||||
- `threshold` ?<[float]> An acceptable perceived color difference between the same pixel in compared images, ranging from `0` (strict) and `1` (lax). `"pixelmatch"` comparator computes color difference in [YIQ color space](https://en.wikipedia.org/wiki/YIQ) and defaults `threshold` value to `0.2`.
|
- `threshold` ?<[float]> an acceptable perceived color difference between the same pixel in compared images, ranging from `0` (strict) and `1` (lax). `"pixelmatch"` comparator computes color difference in [YIQ color space](https://en.wikipedia.org/wiki/YIQ) and defaults `threshold` value to `0.2`.
|
||||||
- `maxDiffPixels` ?<[int]> An acceptable amount of pixels that could be different, unset by default.
|
- `maxDiffPixels` ?<[int]> an acceptable amount of pixels that could be different, unset by default.
|
||||||
- `maxDiffPixelRatio` ?<[float]> An acceptable ratio of pixels that are different to the total amount of pixels, between `0` and `1` , unset by default.
|
- `maxDiffPixelRatio` ?<[float]> an acceptable ratio of pixels that are different to the total amount of pixels, between `0` and `1` , unset by default.
|
||||||
- `animations` ?<[ScreenshotAnimations]<"allow"|"disabled">> See [`option: animations`] in [`method: Page.screenshot`]. Defaults to `"disabled"`.
|
- `animations` ?<[ScreenshotAnimations]<"allow"|"disabled">> See [`option: animations`] in [`method: Page.screenshot`]. Defaults to `"disabled"`.
|
||||||
- `caret` ?<[ScreenshotCaret]<"hide"|"initial">> See [`option: caret`] in [`method: Page.screenshot`]. Defaults to `"hide"`.
|
- `caret` ?<[ScreenshotCaret]<"hide"|"initial">> See [`option: caret`] in [`method: Page.screenshot`]. Defaults to `"hide"`.
|
||||||
- `scale` ?<[ScreenshotScale]<"css"|"device">> See [`option: scale`] in [`method: Page.screenshot`]. Defaults to `"css"`.
|
- `scale` ?<[ScreenshotScale]<"css"|"device">> See [`option: scale`] in [`method: Page.screenshot`]. Defaults to `"css"`.
|
||||||
- `toMatchSnapshot` ?<[Object]> Configuration for the [`method: SnapshotAssertions.toMatchSnapshot#1`] method.
|
- `toMatchSnapshot` ?<[Object]> Configuration for the [`method: SnapshotAssertions.toMatchSnapshot#1`] method.
|
||||||
- `threshold` ?<[float]> **Deprecated.** An acceptable perceived color difference between the same pixel in compared images, ranging from `0` (strict) and `1` (lax). `"pixelmatch"` comparator computes color difference in [YIQ color space](https://en.wikipedia.org/wiki/YIQ) and defaults `threshold` value to `0.2`.
|
- `threshold` ?<[float]> an acceptable perceived color difference between the same pixel in compared images, ranging from `0` (strict) and `1` (lax). `"pixelmatch"` comparator computes color difference in [YIQ color space](https://en.wikipedia.org/wiki/YIQ) and defaults `threshold` value to `0.2`.
|
||||||
- `maxDiffPixels` ?<[int]> **Deprecated.** An acceptable amount of pixels that could be different, unset by default.
|
- `maxDiffPixels` ?<[int]> an acceptable amount of pixels that could be different, unset by default.
|
||||||
- `maxDiffPixelRatio` ?<[float]> **Deprecated.** An acceptable ratio of pixels that are different to the total amount of pixels, between `0` and `1` , unset by default.
|
- `maxDiffPixelRatio` ?<[float]> an acceptable ratio of pixels that are different to the total amount of pixels, between `0` and `1` , unset by default.
|
||||||
|
|
||||||
Configuration for the `expect` assertion library.
|
Configuration for the `expect` assertion library.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -82,7 +82,6 @@ Prefer [auto-retrying](#auto-retrying-assertions) assertions whenever possible.
|
||||||
| [`method: GenericAssertions.toHaveProperty`] | Object has a property |
|
| [`method: GenericAssertions.toHaveProperty`] | Object has a property |
|
||||||
| [`method: GenericAssertions.toMatch`] | String matches a regular expression |
|
| [`method: GenericAssertions.toMatch`] | String matches a regular expression |
|
||||||
| [`method: GenericAssertions.toMatchObject`] | Object contains specified properties |
|
| [`method: GenericAssertions.toMatchObject`] | Object contains specified properties |
|
||||||
| [`method: SnapshotAssertions.toMatchSnapshot#1`] | String equals a reference value, stored in a snapshot file |
|
|
||||||
| [`method: GenericAssertions.toStrictEqual`] | Value is similar, including property types |
|
| [`method: GenericAssertions.toStrictEqual`] | Value is similar, including property types |
|
||||||
| [`method: GenericAssertions.toThrow`] | Function throws an error |
|
| [`method: GenericAssertions.toThrow`] | Function throws an error |
|
||||||
| [`method: GenericAssertions.any`] | Matches any instance of a class/primitive |
|
| [`method: GenericAssertions.any`] | Matches any instance of a class/primitive |
|
||||||
|
|
|
||||||
|
|
@ -131,6 +131,12 @@ export default defineConfig({
|
||||||
// An acceptable amount of pixels that could be different, unset by default.
|
// An acceptable amount of pixels that could be different, unset by default.
|
||||||
maxDiffPixels: 10,
|
maxDiffPixels: 10,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
toMatchSnapshot: {
|
||||||
|
// An acceptable ratio of pixels that are different to the
|
||||||
|
// total amount of pixels, between 0 and 1.
|
||||||
|
maxDiffPixelRatio: 0.1,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
@ -138,8 +144,9 @@ export default defineConfig({
|
||||||
|
|
||||||
| Option | Description |
|
| Option | Description |
|
||||||
| :- | :- |
|
| :- | :- |
|
||||||
| `expect.timeout` | [Web first assertions](./test-assertions.md) like `expect(locator).toHaveText()` have a separate timeout of 5 seconds by default. This is the maximum time the `expect()` should wait for the condition to be met. Learn more about [test and expect timeouts](./test-timeouts.md) and how to set them for a single test. |
|
| [`property: TestConfig.expect`] | [Web first assertions](./test-assertions.md) like `expect(locator).toHaveText()` have a separate timeout of 5 seconds by default. This is the maximum time the `expect()` should wait for the condition to be met. Learn more about [test and expect timeouts](./test-timeouts.md) and how to set them for a single test. |
|
||||||
| `expect.toHaveScreenshot` | Configuration for [`method: PageAssertions.toHaveScreenshot#1`] and [`method: LocatorAssertions.toHaveScreenshot#1`] methods. |
|
| [`method: PageAssertions.toHaveScreenshot#1`] | Configuration for the `expect(locator).toHaveScreeshot()` method. |
|
||||||
|
| [`method: SnapshotAssertions.toMatchSnapshot#1`]| Configuration for the `expect(locator).toMatchSnapshot()` method.|
|
||||||
|
|
||||||
|
|
||||||
### Add custom matchers using expect.extend
|
### Add custom matchers using expect.extend
|
||||||
|
|
|
||||||
|
|
@ -112,11 +112,11 @@ Called after all tests have been run, or testing has been interrupted. Note that
|
||||||
### param: Reporter.onEnd.result
|
### param: Reporter.onEnd.result
|
||||||
* since: v1.10
|
* since: v1.10
|
||||||
- `result` <[Object]>
|
- `result` <[Object]>
|
||||||
- `status` <[FullStatus]<"passed"|"failed"|"timedout"|"interrupted">>
|
- `status` <[FullStatus]<"passed"|"failed"|"timedout"|"interrupted">> Test run status.
|
||||||
- `startTime` <[Date]>
|
- `startTime` <[Date]> Test run start wall time.
|
||||||
- `duration` <[int]>
|
- `duration` <[int]> Test run duration in milliseconds.
|
||||||
|
|
||||||
Result of the full test run.
|
Result of the full test run, `status` can be one of:
|
||||||
* `'passed'` - Everything went as expected.
|
* `'passed'` - Everything went as expected.
|
||||||
* `'failed'` - Any test has failed.
|
* `'failed'` - Any test has failed.
|
||||||
* `'timedout'` - The [`property: TestConfig.globalTimeout`] has been reached.
|
* `'timedout'` - The [`property: TestConfig.globalTimeout`] has been reached.
|
||||||
|
|
|
||||||
|
|
@ -20,10 +20,10 @@ When you run above for the first time, test runner will say:
|
||||||
Error: A snapshot doesn't exist at example.spec.ts-snapshots/example-test-1-chromium-darwin.png, writing actual.
|
Error: A snapshot doesn't exist at example.spec.ts-snapshots/example-test-1-chromium-darwin.png, writing actual.
|
||||||
```
|
```
|
||||||
|
|
||||||
That's because there was no reference screenshot yet. This method took a bunch of screenshots until two consecutive
|
That's because there was no golden file yet. This method took a bunch of screenshots until two consecutive
|
||||||
screenshots matched, and saved the last screenshot to file system. It is now ready to be added to the repository. You should review any changes to the reference screenshots to make sure they are expected.
|
screenshots matched, and saved the last screenshot to file system. It is now ready to be added to the repository.
|
||||||
|
|
||||||
The name of the folder with the reference screenshots starts with the name of your test file:
|
The name of the folder with the golden expectations starts with the name of your test file:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
drwxr-xr-x 5 user group 160 Jun 4 11:46 .
|
drwxr-xr-x 5 user group 160 Jun 4 11:46 .
|
||||||
|
|
@ -32,7 +32,7 @@ drwxr-xr-x 6 user group 192 Jun 4 11:45 ..
|
||||||
drwxr-xr-x 3 user group 96 Jun 4 11:46 example.spec.ts-snapshots
|
drwxr-xr-x 3 user group 96 Jun 4 11:46 example.spec.ts-snapshots
|
||||||
```
|
```
|
||||||
|
|
||||||
The name of the reference screenshot `example-test-1-chromium-darwin.png` consists of a few parts:
|
The snapshot name `example-test-1-chromium-darwin.png` consists of a few parts:
|
||||||
- `example-test-1.png` - an auto-generated name of the snapshot. Alternatively you can specify snapshot name as the first argument of the `toHaveScreenshot()` method:
|
- `example-test-1.png` - an auto-generated name of the snapshot. Alternatively you can specify snapshot name as the first argument of the `toHaveScreenshot()` method:
|
||||||
```js
|
```js
|
||||||
await expect(page).toHaveScreenshot('landing.png');
|
await expect(page).toHaveScreenshot('landing.png');
|
||||||
|
|
@ -40,7 +40,13 @@ The name of the reference screenshot `example-test-1-chromium-darwin.png` consis
|
||||||
|
|
||||||
- `chromium-darwin` - the browser name and the platform. Screenshots differ between browsers and platforms due to different rendering, fonts and more, so you will need different snapshots for them. If you use multiple projects in your [configuration file](./test-configuration.md), project name will be used instead of `chromium`.
|
- `chromium-darwin` - the browser name and the platform. Screenshots differ between browsers and platforms due to different rendering, fonts and more, so you will need different snapshots for them. If you use multiple projects in your [configuration file](./test-configuration.md), project name will be used instead of `chromium`.
|
||||||
|
|
||||||
You can customize the name and the path of the reference screnshot by modifying [`property: TestProject.snapshotPathTemplate`] property in the config file.
|
If you are not on the same operating system as your CI system, you can use Docker to generate/update the screenshots:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker run --rm --network host -v $(pwd):/work/ -w /work/ -it mcr.microsoft.com/playwright:v%%VERSION%%-jammy /bin/bash
|
||||||
|
npm install
|
||||||
|
npx playwright test --update-snapshots
|
||||||
|
```
|
||||||
|
|
||||||
Sometimes you need to update the reference screenshot, for example when the page has changed. Do this with the `--update-snapshots` flag.
|
Sometimes you need to update the reference screenshot, for example when the page has changed. Do this with the `--update-snapshots` flag.
|
||||||
|
|
||||||
|
|
@ -48,6 +54,9 @@ Sometimes you need to update the reference screenshot, for example when the page
|
||||||
npx playwright test --update-snapshots
|
npx playwright test --update-snapshots
|
||||||
```
|
```
|
||||||
|
|
||||||
|
> Note that `snapshotName` also accepts an array of path segments to the snapshot file such as `expect().toHaveScreenshot(['relative', 'path', 'to', 'snapshot.png'])`.
|
||||||
|
> However, this path must stay within the snapshots directory for each test file (i.e. `a.spec.js-snapshots`), otherwise it will throw.
|
||||||
|
|
||||||
Playwright Test uses the [pixelmatch](https://github.com/mapbox/pixelmatch) library. You can [pass various options](./api/class-pageassertions.md#page-assertions-to-have-screenshot-1) to modify its behavior:
|
Playwright Test uses the [pixelmatch](https://github.com/mapbox/pixelmatch) library. You can [pass various options](./api/class-pageassertions.md#page-assertions-to-have-screenshot-1) to modify its behavior:
|
||||||
|
|
||||||
```js title="example.spec.ts"
|
```js title="example.spec.ts"
|
||||||
|
|
@ -70,10 +79,17 @@ export default defineConfig({
|
||||||
});
|
});
|
||||||
```
|
```
|
||||||
|
|
||||||
If you are not on the same operating system as your CI system, you can use Docker to generate/update the screenshots:
|
Apart from screenshots, you can use `expect(value).toMatchSnapshot(snapshotName)` to compare text or arbitrary binary data. Playwright Test auto-detects the content type and uses the appropriate comparison algorithm.
|
||||||
|
|
||||||
```bash
|
Here we compare text content against the reference.
|
||||||
docker run --rm --network host -v $(pwd):/work/ -w /work/ -it mcr.microsoft.com/playwright:v%%VERSION%%-jammy /bin/bash
|
|
||||||
npm install
|
```js title="example.spec.ts"
|
||||||
npx playwright test --update-snapshots
|
import { test, expect } from '@playwright/test';
|
||||||
|
|
||||||
|
test('example test', async ({ page }) => {
|
||||||
|
await page.goto('https://playwright.dev');
|
||||||
|
expect(await page.textContent('.hero__title')).toMatchSnapshot('hero.txt');
|
||||||
|
});
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Snapshots are stored next to the test file, in a separate directory. For example, `my.spec.ts` file will produce and store snapshots in the `my.spec.ts-snapshots` directory. You should commit this directory to your version control (e.g. `git`), and review any changes to it.
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,6 @@
|
||||||
"author": "",
|
"author": "",
|
||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@playwright/test": "^1.27.0"
|
"@playwright/test": "^1.38.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
100
package-lock.json
generated
100
package-lock.json
generated
|
|
@ -1,12 +1,12 @@
|
||||||
{
|
{
|
||||||
"name": "playwright-internal",
|
"name": "playwright-internal",
|
||||||
"version": "1.38.0-next",
|
"version": "1.38.1",
|
||||||
"lockfileVersion": 2,
|
"lockfileVersion": 2,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "playwright-internal",
|
"name": "playwright-internal",
|
||||||
"version": "1.38.0-next",
|
"version": "1.38.1",
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"workspaces": [
|
"workspaces": [
|
||||||
"packages/*"
|
"packages/*"
|
||||||
|
|
@ -6290,10 +6290,10 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"packages/playwright": {
|
"packages/playwright": {
|
||||||
"version": "1.38.0-next",
|
"version": "1.38.1",
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"playwright-core": "1.38.0-next"
|
"playwright-core": "1.38.1"
|
||||||
},
|
},
|
||||||
"bin": {
|
"bin": {
|
||||||
"playwright": "cli.js"
|
"playwright": "cli.js"
|
||||||
|
|
@ -6307,11 +6307,11 @@
|
||||||
},
|
},
|
||||||
"packages/playwright-browser-chromium": {
|
"packages/playwright-browser-chromium": {
|
||||||
"name": "@playwright/browser-chromium",
|
"name": "@playwright/browser-chromium",
|
||||||
"version": "1.38.0-next",
|
"version": "1.38.1",
|
||||||
"hasInstallScript": true,
|
"hasInstallScript": true,
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"playwright-core": "1.38.0-next"
|
"playwright-core": "1.38.1"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=16"
|
"node": ">=16"
|
||||||
|
|
@ -6319,11 +6319,11 @@
|
||||||
},
|
},
|
||||||
"packages/playwright-browser-firefox": {
|
"packages/playwright-browser-firefox": {
|
||||||
"name": "@playwright/browser-firefox",
|
"name": "@playwright/browser-firefox",
|
||||||
"version": "1.38.0-next",
|
"version": "1.38.1",
|
||||||
"hasInstallScript": true,
|
"hasInstallScript": true,
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"playwright-core": "1.38.0-next"
|
"playwright-core": "1.38.1"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=16"
|
"node": ">=16"
|
||||||
|
|
@ -6331,22 +6331,22 @@
|
||||||
},
|
},
|
||||||
"packages/playwright-browser-webkit": {
|
"packages/playwright-browser-webkit": {
|
||||||
"name": "@playwright/browser-webkit",
|
"name": "@playwright/browser-webkit",
|
||||||
"version": "1.38.0-next",
|
"version": "1.38.1",
|
||||||
"hasInstallScript": true,
|
"hasInstallScript": true,
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"playwright-core": "1.38.0-next"
|
"playwright-core": "1.38.1"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=16"
|
"node": ">=16"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"packages/playwright-chromium": {
|
"packages/playwright-chromium": {
|
||||||
"version": "1.38.0-next",
|
"version": "1.38.1",
|
||||||
"hasInstallScript": true,
|
"hasInstallScript": true,
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"playwright-core": "1.38.0-next"
|
"playwright-core": "1.38.1"
|
||||||
},
|
},
|
||||||
"bin": {
|
"bin": {
|
||||||
"playwright": "cli.js"
|
"playwright": "cli.js"
|
||||||
|
|
@ -6356,7 +6356,7 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"packages/playwright-core": {
|
"packages/playwright-core": {
|
||||||
"version": "1.38.0-next",
|
"version": "1.38.1",
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"bin": {
|
"bin": {
|
||||||
"playwright-core": "cli.js"
|
"playwright-core": "cli.js"
|
||||||
|
|
@ -6367,11 +6367,11 @@
|
||||||
},
|
},
|
||||||
"packages/playwright-ct-core": {
|
"packages/playwright-ct-core": {
|
||||||
"name": "@playwright/experimental-ct-core",
|
"name": "@playwright/experimental-ct-core",
|
||||||
"version": "1.38.0-next",
|
"version": "1.38.1",
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"playwright": "1.38.0-next",
|
"playwright": "1.38.1",
|
||||||
"playwright-core": "1.38.0-next",
|
"playwright-core": "1.38.1",
|
||||||
"vite": "^4.3.9"
|
"vite": "^4.3.9"
|
||||||
},
|
},
|
||||||
"bin": {
|
"bin": {
|
||||||
|
|
@ -6383,10 +6383,10 @@
|
||||||
},
|
},
|
||||||
"packages/playwright-ct-react": {
|
"packages/playwright-ct-react": {
|
||||||
"name": "@playwright/experimental-ct-react",
|
"name": "@playwright/experimental-ct-react",
|
||||||
"version": "1.38.0-next",
|
"version": "1.38.1",
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@playwright/experimental-ct-core": "1.38.0-next",
|
"@playwright/experimental-ct-core": "1.38.1",
|
||||||
"@vitejs/plugin-react": "^4.0.0"
|
"@vitejs/plugin-react": "^4.0.0"
|
||||||
},
|
},
|
||||||
"bin": {
|
"bin": {
|
||||||
|
|
@ -6415,10 +6415,10 @@
|
||||||
},
|
},
|
||||||
"packages/playwright-ct-react17": {
|
"packages/playwright-ct-react17": {
|
||||||
"name": "@playwright/experimental-ct-react17",
|
"name": "@playwright/experimental-ct-react17",
|
||||||
"version": "1.38.0-next",
|
"version": "1.38.1",
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@playwright/experimental-ct-core": "1.38.0-next",
|
"@playwright/experimental-ct-core": "1.38.1",
|
||||||
"@vitejs/plugin-react": "^4.0.0"
|
"@vitejs/plugin-react": "^4.0.0"
|
||||||
},
|
},
|
||||||
"bin": {
|
"bin": {
|
||||||
|
|
@ -6447,10 +6447,10 @@
|
||||||
},
|
},
|
||||||
"packages/playwright-ct-solid": {
|
"packages/playwright-ct-solid": {
|
||||||
"name": "@playwright/experimental-ct-solid",
|
"name": "@playwright/experimental-ct-solid",
|
||||||
"version": "1.38.0-next",
|
"version": "1.38.1",
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@playwright/experimental-ct-core": "1.38.0-next",
|
"@playwright/experimental-ct-core": "1.38.1",
|
||||||
"vite-plugin-solid": "^2.7.0"
|
"vite-plugin-solid": "^2.7.0"
|
||||||
},
|
},
|
||||||
"bin": {
|
"bin": {
|
||||||
|
|
@ -6465,10 +6465,10 @@
|
||||||
},
|
},
|
||||||
"packages/playwright-ct-svelte": {
|
"packages/playwright-ct-svelte": {
|
||||||
"name": "@playwright/experimental-ct-svelte",
|
"name": "@playwright/experimental-ct-svelte",
|
||||||
"version": "1.38.0-next",
|
"version": "1.38.1",
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@playwright/experimental-ct-core": "1.38.0-next",
|
"@playwright/experimental-ct-core": "1.38.1",
|
||||||
"@sveltejs/vite-plugin-svelte": "^2.1.1"
|
"@sveltejs/vite-plugin-svelte": "^2.1.1"
|
||||||
},
|
},
|
||||||
"bin": {
|
"bin": {
|
||||||
|
|
@ -6483,10 +6483,10 @@
|
||||||
},
|
},
|
||||||
"packages/playwright-ct-vue": {
|
"packages/playwright-ct-vue": {
|
||||||
"name": "@playwright/experimental-ct-vue",
|
"name": "@playwright/experimental-ct-vue",
|
||||||
"version": "1.38.0-next",
|
"version": "1.38.1",
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@playwright/experimental-ct-core": "1.38.0-next",
|
"@playwright/experimental-ct-core": "1.38.1",
|
||||||
"@vitejs/plugin-vue": "^4.2.1"
|
"@vitejs/plugin-vue": "^4.2.1"
|
||||||
},
|
},
|
||||||
"bin": {
|
"bin": {
|
||||||
|
|
@ -6534,10 +6534,10 @@
|
||||||
},
|
},
|
||||||
"packages/playwright-ct-vue2": {
|
"packages/playwright-ct-vue2": {
|
||||||
"name": "@playwright/experimental-ct-vue2",
|
"name": "@playwright/experimental-ct-vue2",
|
||||||
"version": "1.38.0-next",
|
"version": "1.38.1",
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@playwright/experimental-ct-core": "1.38.0-next",
|
"@playwright/experimental-ct-core": "1.38.1",
|
||||||
"@vitejs/plugin-vue2": "^2.2.0"
|
"@vitejs/plugin-vue2": "^2.2.0"
|
||||||
},
|
},
|
||||||
"bin": {
|
"bin": {
|
||||||
|
|
@ -6551,11 +6551,11 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"packages/playwright-firefox": {
|
"packages/playwright-firefox": {
|
||||||
"version": "1.38.0-next",
|
"version": "1.38.1",
|
||||||
"hasInstallScript": true,
|
"hasInstallScript": true,
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"playwright-core": "1.38.0-next"
|
"playwright-core": "1.38.1"
|
||||||
},
|
},
|
||||||
"bin": {
|
"bin": {
|
||||||
"playwright": "cli.js"
|
"playwright": "cli.js"
|
||||||
|
|
@ -6589,10 +6589,10 @@
|
||||||
},
|
},
|
||||||
"packages/playwright-test": {
|
"packages/playwright-test": {
|
||||||
"name": "@playwright/test",
|
"name": "@playwright/test",
|
||||||
"version": "1.38.0-next",
|
"version": "1.38.1",
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"playwright": "1.38.0-next"
|
"playwright": "1.38.1"
|
||||||
},
|
},
|
||||||
"bin": {
|
"bin": {
|
||||||
"playwright": "cli.js"
|
"playwright": "cli.js"
|
||||||
|
|
@ -6602,11 +6602,11 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"packages/playwright-webkit": {
|
"packages/playwright-webkit": {
|
||||||
"version": "1.38.0-next",
|
"version": "1.38.1",
|
||||||
"hasInstallScript": true,
|
"hasInstallScript": true,
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"playwright-core": "1.38.0-next"
|
"playwright-core": "1.38.1"
|
||||||
},
|
},
|
||||||
"bin": {
|
"bin": {
|
||||||
"playwright": "cli.js"
|
"playwright": "cli.js"
|
||||||
|
|
@ -7451,33 +7451,33 @@
|
||||||
"@playwright/browser-chromium": {
|
"@playwright/browser-chromium": {
|
||||||
"version": "file:packages/playwright-browser-chromium",
|
"version": "file:packages/playwright-browser-chromium",
|
||||||
"requires": {
|
"requires": {
|
||||||
"playwright-core": "1.38.0-next"
|
"playwright-core": "1.38.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@playwright/browser-firefox": {
|
"@playwright/browser-firefox": {
|
||||||
"version": "file:packages/playwright-browser-firefox",
|
"version": "file:packages/playwright-browser-firefox",
|
||||||
"requires": {
|
"requires": {
|
||||||
"playwright-core": "1.38.0-next"
|
"playwright-core": "1.38.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@playwright/browser-webkit": {
|
"@playwright/browser-webkit": {
|
||||||
"version": "file:packages/playwright-browser-webkit",
|
"version": "file:packages/playwright-browser-webkit",
|
||||||
"requires": {
|
"requires": {
|
||||||
"playwright-core": "1.38.0-next"
|
"playwright-core": "1.38.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@playwright/experimental-ct-core": {
|
"@playwright/experimental-ct-core": {
|
||||||
"version": "file:packages/playwright-ct-core",
|
"version": "file:packages/playwright-ct-core",
|
||||||
"requires": {
|
"requires": {
|
||||||
"playwright": "1.38.0-next",
|
"playwright": "1.38.1",
|
||||||
"playwright-core": "1.38.0-next",
|
"playwright-core": "1.38.1",
|
||||||
"vite": "^4.3.9"
|
"vite": "^4.3.9"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@playwright/experimental-ct-react": {
|
"@playwright/experimental-ct-react": {
|
||||||
"version": "file:packages/playwright-ct-react",
|
"version": "file:packages/playwright-ct-react",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@playwright/experimental-ct-core": "1.38.0-next",
|
"@playwright/experimental-ct-core": "1.38.1",
|
||||||
"@vitejs/plugin-react": "^4.0.0"
|
"@vitejs/plugin-react": "^4.0.0"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
|
@ -7497,7 +7497,7 @@
|
||||||
"@playwright/experimental-ct-react17": {
|
"@playwright/experimental-ct-react17": {
|
||||||
"version": "file:packages/playwright-ct-react17",
|
"version": "file:packages/playwright-ct-react17",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@playwright/experimental-ct-core": "1.38.0-next",
|
"@playwright/experimental-ct-core": "1.38.1",
|
||||||
"@vitejs/plugin-react": "^4.0.0"
|
"@vitejs/plugin-react": "^4.0.0"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
|
@ -7517,7 +7517,7 @@
|
||||||
"@playwright/experimental-ct-solid": {
|
"@playwright/experimental-ct-solid": {
|
||||||
"version": "file:packages/playwright-ct-solid",
|
"version": "file:packages/playwright-ct-solid",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@playwright/experimental-ct-core": "1.38.0-next",
|
"@playwright/experimental-ct-core": "1.38.1",
|
||||||
"solid-js": "^1.7.0",
|
"solid-js": "^1.7.0",
|
||||||
"vite-plugin-solid": "^2.7.0"
|
"vite-plugin-solid": "^2.7.0"
|
||||||
}
|
}
|
||||||
|
|
@ -7525,7 +7525,7 @@
|
||||||
"@playwright/experimental-ct-svelte": {
|
"@playwright/experimental-ct-svelte": {
|
||||||
"version": "file:packages/playwright-ct-svelte",
|
"version": "file:packages/playwright-ct-svelte",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@playwright/experimental-ct-core": "1.38.0-next",
|
"@playwright/experimental-ct-core": "1.38.1",
|
||||||
"@sveltejs/vite-plugin-svelte": "^2.1.1",
|
"@sveltejs/vite-plugin-svelte": "^2.1.1",
|
||||||
"svelte": "^3.55.1"
|
"svelte": "^3.55.1"
|
||||||
}
|
}
|
||||||
|
|
@ -7533,7 +7533,7 @@
|
||||||
"@playwright/experimental-ct-vue": {
|
"@playwright/experimental-ct-vue": {
|
||||||
"version": "file:packages/playwright-ct-vue",
|
"version": "file:packages/playwright-ct-vue",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@playwright/experimental-ct-core": "1.38.0-next",
|
"@playwright/experimental-ct-core": "1.38.1",
|
||||||
"@vitejs/plugin-vue": "^4.2.1"
|
"@vitejs/plugin-vue": "^4.2.1"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
|
@ -7567,7 +7567,7 @@
|
||||||
"@playwright/experimental-ct-vue2": {
|
"@playwright/experimental-ct-vue2": {
|
||||||
"version": "file:packages/playwright-ct-vue2",
|
"version": "file:packages/playwright-ct-vue2",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@playwright/experimental-ct-core": "1.38.0-next",
|
"@playwright/experimental-ct-core": "1.38.1",
|
||||||
"@vitejs/plugin-vue2": "^2.2.0",
|
"@vitejs/plugin-vue2": "^2.2.0",
|
||||||
"vue": "^2.7.14"
|
"vue": "^2.7.14"
|
||||||
}
|
}
|
||||||
|
|
@ -7575,7 +7575,7 @@
|
||||||
"@playwright/test": {
|
"@playwright/test": {
|
||||||
"version": "file:packages/playwright-test",
|
"version": "file:packages/playwright-test",
|
||||||
"requires": {
|
"requires": {
|
||||||
"playwright": "1.38.0-next"
|
"playwright": "1.38.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@sindresorhus/is": {
|
"@sindresorhus/is": {
|
||||||
|
|
@ -9885,13 +9885,13 @@
|
||||||
"version": "file:packages/playwright",
|
"version": "file:packages/playwright",
|
||||||
"requires": {
|
"requires": {
|
||||||
"fsevents": "2.3.2",
|
"fsevents": "2.3.2",
|
||||||
"playwright-core": "1.38.0-next"
|
"playwright-core": "1.38.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"playwright-chromium": {
|
"playwright-chromium": {
|
||||||
"version": "file:packages/playwright-chromium",
|
"version": "file:packages/playwright-chromium",
|
||||||
"requires": {
|
"requires": {
|
||||||
"playwright-core": "1.38.0-next"
|
"playwright-core": "1.38.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"playwright-core": {
|
"playwright-core": {
|
||||||
|
|
@ -9900,13 +9900,13 @@
|
||||||
"playwright-firefox": {
|
"playwright-firefox": {
|
||||||
"version": "file:packages/playwright-firefox",
|
"version": "file:packages/playwright-firefox",
|
||||||
"requires": {
|
"requires": {
|
||||||
"playwright-core": "1.38.0-next"
|
"playwright-core": "1.38.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"playwright-webkit": {
|
"playwright-webkit": {
|
||||||
"version": "file:packages/playwright-webkit",
|
"version": "file:packages/playwright-webkit",
|
||||||
"requires": {
|
"requires": {
|
||||||
"playwright-core": "1.38.0-next"
|
"playwright-core": "1.38.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"postcss": {
|
"postcss": {
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
{
|
{
|
||||||
"name": "playwright-internal",
|
"name": "playwright-internal",
|
||||||
"private": true,
|
"private": true,
|
||||||
"version": "1.38.0-next",
|
"version": "1.38.1",
|
||||||
"description": "A high-level API to automate web browsers",
|
"description": "A high-level API to automate web browsers",
|
||||||
"repository": "github:Microsoft/playwright",
|
"repository": "github:Microsoft/playwright",
|
||||||
"homepage": "https://playwright.dev",
|
"homepage": "https://playwright.dev",
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "@playwright/browser-chromium",
|
"name": "@playwright/browser-chromium",
|
||||||
"version": "1.38.0-next",
|
"version": "1.38.1",
|
||||||
"description": "Playwright package that automatically installs Chromium",
|
"description": "Playwright package that automatically installs Chromium",
|
||||||
"repository": "github:Microsoft/playwright",
|
"repository": "github:Microsoft/playwright",
|
||||||
"homepage": "https://playwright.dev",
|
"homepage": "https://playwright.dev",
|
||||||
|
|
@ -24,6 +24,6 @@
|
||||||
"install": "node install.js"
|
"install": "node install.js"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"playwright-core": "1.38.0-next"
|
"playwright-core": "1.38.1"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "@playwright/browser-firefox",
|
"name": "@playwright/browser-firefox",
|
||||||
"version": "1.38.0-next",
|
"version": "1.38.1",
|
||||||
"description": "Playwright package that automatically installs Firefox",
|
"description": "Playwright package that automatically installs Firefox",
|
||||||
"repository": "github:Microsoft/playwright",
|
"repository": "github:Microsoft/playwright",
|
||||||
"homepage": "https://playwright.dev",
|
"homepage": "https://playwright.dev",
|
||||||
|
|
@ -24,6 +24,6 @@
|
||||||
"install": "node install.js"
|
"install": "node install.js"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"playwright-core": "1.38.0-next"
|
"playwright-core": "1.38.1"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "@playwright/browser-webkit",
|
"name": "@playwright/browser-webkit",
|
||||||
"version": "1.38.0-next",
|
"version": "1.38.1",
|
||||||
"description": "Playwright package that automatically installs WebKit",
|
"description": "Playwright package that automatically installs WebKit",
|
||||||
"repository": "github:Microsoft/playwright",
|
"repository": "github:Microsoft/playwright",
|
||||||
"homepage": "https://playwright.dev",
|
"homepage": "https://playwright.dev",
|
||||||
|
|
@ -24,6 +24,6 @@
|
||||||
"install": "node install.js"
|
"install": "node install.js"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"playwright-core": "1.38.0-next"
|
"playwright-core": "1.38.1"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "playwright-chromium",
|
"name": "playwright-chromium",
|
||||||
"version": "1.38.0-next",
|
"version": "1.38.1",
|
||||||
"description": "A high-level API to automate Chromium",
|
"description": "A high-level API to automate Chromium",
|
||||||
"repository": "github:Microsoft/playwright",
|
"repository": "github:Microsoft/playwright",
|
||||||
"homepage": "https://playwright.dev",
|
"homepage": "https://playwright.dev",
|
||||||
|
|
@ -27,6 +27,6 @@
|
||||||
"install": "node install.js"
|
"install": "node install.js"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"playwright-core": "1.38.0-next"
|
"playwright-core": "1.38.1"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,15 +3,15 @@
|
||||||
"browsers": [
|
"browsers": [
|
||||||
{
|
{
|
||||||
"name": "chromium",
|
"name": "chromium",
|
||||||
"revision": "1079",
|
"revision": "1080",
|
||||||
"installByDefault": true,
|
"installByDefault": true,
|
||||||
"browserVersion": "117.0.5938.48"
|
"browserVersion": "117.0.5938.62"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "chromium-with-symbols",
|
"name": "chromium-with-symbols",
|
||||||
"revision": "1079",
|
"revision": "1080",
|
||||||
"installByDefault": false,
|
"installByDefault": false,
|
||||||
"browserVersion": "117.0.5938.48"
|
"browserVersion": "117.0.5938.62"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "chromium-tip-of-tree",
|
"name": "chromium-tip-of-tree",
|
||||||
|
|
@ -39,7 +39,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "webkit",
|
"name": "webkit",
|
||||||
"revision": "1907",
|
"revision": "1908",
|
||||||
"installByDefault": true,
|
"installByDefault": true,
|
||||||
"revisionOverrides": {
|
"revisionOverrides": {
|
||||||
"mac10.14": "1446",
|
"mac10.14": "1446",
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "playwright-core",
|
"name": "playwright-core",
|
||||||
"version": "1.38.0-next",
|
"version": "1.38.1",
|
||||||
"description": "A high-level API to automate web browsers",
|
"description": "A high-level API to automate web browsers",
|
||||||
"repository": "github:Microsoft/playwright",
|
"repository": "github:Microsoft/playwright",
|
||||||
"homepage": "https://playwright.dev",
|
"homepage": "https://playwright.dev",
|
||||||
|
|
|
||||||
|
|
@ -75,10 +75,6 @@ function innerParseSerializedValue(value: SerializedValue, handles: any[] | unde
|
||||||
return BigInt(value.bi);
|
return BigInt(value.bi);
|
||||||
if (value.r !== undefined)
|
if (value.r !== undefined)
|
||||||
return new RegExp(value.r.p, value.r.f);
|
return new RegExp(value.r.p, value.r.f);
|
||||||
if (value.m !== undefined)
|
|
||||||
return new Map(innerParseSerializedValue(value.m, handles, refs));
|
|
||||||
if (value.se !== undefined)
|
|
||||||
return new Set(innerParseSerializedValue(value.se, handles, refs));
|
|
||||||
|
|
||||||
if (value.a !== undefined) {
|
if (value.a !== undefined) {
|
||||||
const result: any[] = [];
|
const result: any[] = [];
|
||||||
|
|
@ -149,10 +145,6 @@ function innerSerializeValue(value: any, handleSerializer: (value: any) => Handl
|
||||||
}
|
}
|
||||||
return { s: `${error.name}: ${error.message}\n${error.stack}` };
|
return { s: `${error.name}: ${error.message}\n${error.stack}` };
|
||||||
}
|
}
|
||||||
if (isMap(value))
|
|
||||||
return { m: innerSerializeValue(Array.from(value), handleSerializer, visitorInfo) };
|
|
||||||
if (isSet(value))
|
|
||||||
return { se: innerSerializeValue(Array.from(value), handleSerializer, visitorInfo) };
|
|
||||||
if (isDate(value))
|
if (isDate(value))
|
||||||
return { d: value.toJSON() };
|
return { d: value.toJSON() };
|
||||||
if (isURL(value))
|
if (isURL(value))
|
||||||
|
|
@ -183,14 +175,6 @@ function innerSerializeValue(value: any, handleSerializer: (value: any) => Handl
|
||||||
throw new Error('Unexpected value');
|
throw new Error('Unexpected value');
|
||||||
}
|
}
|
||||||
|
|
||||||
function isMap(obj: any): obj is Map<any, any> {
|
|
||||||
return obj instanceof Map || Object.prototype.toString.call(obj) === '[object Map]';
|
|
||||||
}
|
|
||||||
|
|
||||||
function isSet(obj: any): obj is Set<any> {
|
|
||||||
return obj instanceof Set || Object.prototype.toString.call(obj) === '[object Set]';
|
|
||||||
}
|
|
||||||
|
|
||||||
function isRegExp(obj: any): obj is RegExp {
|
function isRegExp(obj: any): obj is RegExp {
|
||||||
return obj instanceof RegExp || Object.prototype.toString.call(obj) === '[object RegExp]';
|
return obj instanceof RegExp || Object.prototype.toString.call(obj) === '[object RegExp]';
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -58,8 +58,6 @@ scheme.SerializedValue = tObject({
|
||||||
d: tOptional(tString),
|
d: tOptional(tString),
|
||||||
u: tOptional(tString),
|
u: tOptional(tString),
|
||||||
bi: tOptional(tString),
|
bi: tOptional(tString),
|
||||||
m: tOptional(tType('SerializedValue')),
|
|
||||||
se: tOptional(tType('SerializedValue')),
|
|
||||||
r: tOptional(tObject({
|
r: tOptional(tObject({
|
||||||
p: tString,
|
p: tString,
|
||||||
f: tString,
|
f: tString,
|
||||||
|
|
|
||||||
|
|
@ -110,7 +110,7 @@
|
||||||
"defaultBrowserType": "webkit"
|
"defaultBrowserType": "webkit"
|
||||||
},
|
},
|
||||||
"Galaxy S5": {
|
"Galaxy S5": {
|
||||||
"userAgent": "Mozilla/5.0 (Linux; Android 5.0; SM-G900P Build/LRX21T) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.5938.48 Mobile Safari/537.36",
|
"userAgent": "Mozilla/5.0 (Linux; Android 5.0; SM-G900P Build/LRX21T) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.5938.62 Mobile Safari/537.36",
|
||||||
"viewport": {
|
"viewport": {
|
||||||
"width": 360,
|
"width": 360,
|
||||||
"height": 640
|
"height": 640
|
||||||
|
|
@ -121,7 +121,7 @@
|
||||||
"defaultBrowserType": "chromium"
|
"defaultBrowserType": "chromium"
|
||||||
},
|
},
|
||||||
"Galaxy S5 landscape": {
|
"Galaxy S5 landscape": {
|
||||||
"userAgent": "Mozilla/5.0 (Linux; Android 5.0; SM-G900P Build/LRX21T) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.5938.48 Mobile Safari/537.36",
|
"userAgent": "Mozilla/5.0 (Linux; Android 5.0; SM-G900P Build/LRX21T) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.5938.62 Mobile Safari/537.36",
|
||||||
"viewport": {
|
"viewport": {
|
||||||
"width": 640,
|
"width": 640,
|
||||||
"height": 360
|
"height": 360
|
||||||
|
|
@ -132,7 +132,7 @@
|
||||||
"defaultBrowserType": "chromium"
|
"defaultBrowserType": "chromium"
|
||||||
},
|
},
|
||||||
"Galaxy S8": {
|
"Galaxy S8": {
|
||||||
"userAgent": "Mozilla/5.0 (Linux; Android 7.0; SM-G950U Build/NRD90M) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.5938.48 Mobile Safari/537.36",
|
"userAgent": "Mozilla/5.0 (Linux; Android 7.0; SM-G950U Build/NRD90M) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.5938.62 Mobile Safari/537.36",
|
||||||
"viewport": {
|
"viewport": {
|
||||||
"width": 360,
|
"width": 360,
|
||||||
"height": 740
|
"height": 740
|
||||||
|
|
@ -143,7 +143,7 @@
|
||||||
"defaultBrowserType": "chromium"
|
"defaultBrowserType": "chromium"
|
||||||
},
|
},
|
||||||
"Galaxy S8 landscape": {
|
"Galaxy S8 landscape": {
|
||||||
"userAgent": "Mozilla/5.0 (Linux; Android 7.0; SM-G950U Build/NRD90M) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.5938.48 Mobile Safari/537.36",
|
"userAgent": "Mozilla/5.0 (Linux; Android 7.0; SM-G950U Build/NRD90M) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.5938.62 Mobile Safari/537.36",
|
||||||
"viewport": {
|
"viewport": {
|
||||||
"width": 740,
|
"width": 740,
|
||||||
"height": 360
|
"height": 360
|
||||||
|
|
@ -154,7 +154,7 @@
|
||||||
"defaultBrowserType": "chromium"
|
"defaultBrowserType": "chromium"
|
||||||
},
|
},
|
||||||
"Galaxy S9+": {
|
"Galaxy S9+": {
|
||||||
"userAgent": "Mozilla/5.0 (Linux; Android 8.0.0; SM-G965U Build/R16NW) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.5938.48 Mobile Safari/537.36",
|
"userAgent": "Mozilla/5.0 (Linux; Android 8.0.0; SM-G965U Build/R16NW) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.5938.62 Mobile Safari/537.36",
|
||||||
"viewport": {
|
"viewport": {
|
||||||
"width": 320,
|
"width": 320,
|
||||||
"height": 658
|
"height": 658
|
||||||
|
|
@ -165,7 +165,7 @@
|
||||||
"defaultBrowserType": "chromium"
|
"defaultBrowserType": "chromium"
|
||||||
},
|
},
|
||||||
"Galaxy S9+ landscape": {
|
"Galaxy S9+ landscape": {
|
||||||
"userAgent": "Mozilla/5.0 (Linux; Android 8.0.0; SM-G965U Build/R16NW) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.5938.48 Mobile Safari/537.36",
|
"userAgent": "Mozilla/5.0 (Linux; Android 8.0.0; SM-G965U Build/R16NW) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.5938.62 Mobile Safari/537.36",
|
||||||
"viewport": {
|
"viewport": {
|
||||||
"width": 658,
|
"width": 658,
|
||||||
"height": 320
|
"height": 320
|
||||||
|
|
@ -176,7 +176,7 @@
|
||||||
"defaultBrowserType": "chromium"
|
"defaultBrowserType": "chromium"
|
||||||
},
|
},
|
||||||
"Galaxy Tab S4": {
|
"Galaxy Tab S4": {
|
||||||
"userAgent": "Mozilla/5.0 (Linux; Android 8.1.0; SM-T837A) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.5938.48 Safari/537.36",
|
"userAgent": "Mozilla/5.0 (Linux; Android 8.1.0; SM-T837A) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.5938.62 Safari/537.36",
|
||||||
"viewport": {
|
"viewport": {
|
||||||
"width": 712,
|
"width": 712,
|
||||||
"height": 1138
|
"height": 1138
|
||||||
|
|
@ -187,7 +187,7 @@
|
||||||
"defaultBrowserType": "chromium"
|
"defaultBrowserType": "chromium"
|
||||||
},
|
},
|
||||||
"Galaxy Tab S4 landscape": {
|
"Galaxy Tab S4 landscape": {
|
||||||
"userAgent": "Mozilla/5.0 (Linux; Android 8.1.0; SM-T837A) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.5938.48 Safari/537.36",
|
"userAgent": "Mozilla/5.0 (Linux; Android 8.1.0; SM-T837A) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.5938.62 Safari/537.36",
|
||||||
"viewport": {
|
"viewport": {
|
||||||
"width": 1138,
|
"width": 1138,
|
||||||
"height": 712
|
"height": 712
|
||||||
|
|
@ -978,7 +978,7 @@
|
||||||
"defaultBrowserType": "webkit"
|
"defaultBrowserType": "webkit"
|
||||||
},
|
},
|
||||||
"LG Optimus L70": {
|
"LG Optimus L70": {
|
||||||
"userAgent": "Mozilla/5.0 (Linux; U; Android 4.4.2; en-us; LGMS323 Build/KOT49I.MS32310c) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/117.0.5938.48 Mobile Safari/537.36",
|
"userAgent": "Mozilla/5.0 (Linux; U; Android 4.4.2; en-us; LGMS323 Build/KOT49I.MS32310c) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/117.0.5938.62 Mobile Safari/537.36",
|
||||||
"viewport": {
|
"viewport": {
|
||||||
"width": 384,
|
"width": 384,
|
||||||
"height": 640
|
"height": 640
|
||||||
|
|
@ -989,7 +989,7 @@
|
||||||
"defaultBrowserType": "chromium"
|
"defaultBrowserType": "chromium"
|
||||||
},
|
},
|
||||||
"LG Optimus L70 landscape": {
|
"LG Optimus L70 landscape": {
|
||||||
"userAgent": "Mozilla/5.0 (Linux; U; Android 4.4.2; en-us; LGMS323 Build/KOT49I.MS32310c) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/117.0.5938.48 Mobile Safari/537.36",
|
"userAgent": "Mozilla/5.0 (Linux; U; Android 4.4.2; en-us; LGMS323 Build/KOT49I.MS32310c) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/117.0.5938.62 Mobile Safari/537.36",
|
||||||
"viewport": {
|
"viewport": {
|
||||||
"width": 640,
|
"width": 640,
|
||||||
"height": 384
|
"height": 384
|
||||||
|
|
@ -1000,7 +1000,7 @@
|
||||||
"defaultBrowserType": "chromium"
|
"defaultBrowserType": "chromium"
|
||||||
},
|
},
|
||||||
"Microsoft Lumia 550": {
|
"Microsoft Lumia 550": {
|
||||||
"userAgent": "Mozilla/5.0 (Windows Phone 10.0; Android 4.2.1; Microsoft; Lumia 550) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.5938.48 Mobile Safari/537.36 Edge/14.14263",
|
"userAgent": "Mozilla/5.0 (Windows Phone 10.0; Android 4.2.1; Microsoft; Lumia 550) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.5938.62 Mobile Safari/537.36 Edge/14.14263",
|
||||||
"viewport": {
|
"viewport": {
|
||||||
"width": 640,
|
"width": 640,
|
||||||
"height": 360
|
"height": 360
|
||||||
|
|
@ -1011,7 +1011,7 @@
|
||||||
"defaultBrowserType": "chromium"
|
"defaultBrowserType": "chromium"
|
||||||
},
|
},
|
||||||
"Microsoft Lumia 550 landscape": {
|
"Microsoft Lumia 550 landscape": {
|
||||||
"userAgent": "Mozilla/5.0 (Windows Phone 10.0; Android 4.2.1; Microsoft; Lumia 550) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.5938.48 Mobile Safari/537.36 Edge/14.14263",
|
"userAgent": "Mozilla/5.0 (Windows Phone 10.0; Android 4.2.1; Microsoft; Lumia 550) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.5938.62 Mobile Safari/537.36 Edge/14.14263",
|
||||||
"viewport": {
|
"viewport": {
|
||||||
"width": 360,
|
"width": 360,
|
||||||
"height": 640
|
"height": 640
|
||||||
|
|
@ -1022,7 +1022,7 @@
|
||||||
"defaultBrowserType": "chromium"
|
"defaultBrowserType": "chromium"
|
||||||
},
|
},
|
||||||
"Microsoft Lumia 950": {
|
"Microsoft Lumia 950": {
|
||||||
"userAgent": "Mozilla/5.0 (Windows Phone 10.0; Android 4.2.1; Microsoft; Lumia 950) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.5938.48 Mobile Safari/537.36 Edge/14.14263",
|
"userAgent": "Mozilla/5.0 (Windows Phone 10.0; Android 4.2.1; Microsoft; Lumia 950) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.5938.62 Mobile Safari/537.36 Edge/14.14263",
|
||||||
"viewport": {
|
"viewport": {
|
||||||
"width": 360,
|
"width": 360,
|
||||||
"height": 640
|
"height": 640
|
||||||
|
|
@ -1033,7 +1033,7 @@
|
||||||
"defaultBrowserType": "chromium"
|
"defaultBrowserType": "chromium"
|
||||||
},
|
},
|
||||||
"Microsoft Lumia 950 landscape": {
|
"Microsoft Lumia 950 landscape": {
|
||||||
"userAgent": "Mozilla/5.0 (Windows Phone 10.0; Android 4.2.1; Microsoft; Lumia 950) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.5938.48 Mobile Safari/537.36 Edge/14.14263",
|
"userAgent": "Mozilla/5.0 (Windows Phone 10.0; Android 4.2.1; Microsoft; Lumia 950) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.5938.62 Mobile Safari/537.36 Edge/14.14263",
|
||||||
"viewport": {
|
"viewport": {
|
||||||
"width": 640,
|
"width": 640,
|
||||||
"height": 360
|
"height": 360
|
||||||
|
|
@ -1044,7 +1044,7 @@
|
||||||
"defaultBrowserType": "chromium"
|
"defaultBrowserType": "chromium"
|
||||||
},
|
},
|
||||||
"Nexus 10": {
|
"Nexus 10": {
|
||||||
"userAgent": "Mozilla/5.0 (Linux; Android 6.0.1; Nexus 10 Build/MOB31T) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.5938.48 Safari/537.36",
|
"userAgent": "Mozilla/5.0 (Linux; Android 6.0.1; Nexus 10 Build/MOB31T) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.5938.62 Safari/537.36",
|
||||||
"viewport": {
|
"viewport": {
|
||||||
"width": 800,
|
"width": 800,
|
||||||
"height": 1280
|
"height": 1280
|
||||||
|
|
@ -1055,7 +1055,7 @@
|
||||||
"defaultBrowserType": "chromium"
|
"defaultBrowserType": "chromium"
|
||||||
},
|
},
|
||||||
"Nexus 10 landscape": {
|
"Nexus 10 landscape": {
|
||||||
"userAgent": "Mozilla/5.0 (Linux; Android 6.0.1; Nexus 10 Build/MOB31T) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.5938.48 Safari/537.36",
|
"userAgent": "Mozilla/5.0 (Linux; Android 6.0.1; Nexus 10 Build/MOB31T) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.5938.62 Safari/537.36",
|
||||||
"viewport": {
|
"viewport": {
|
||||||
"width": 1280,
|
"width": 1280,
|
||||||
"height": 800
|
"height": 800
|
||||||
|
|
@ -1066,7 +1066,7 @@
|
||||||
"defaultBrowserType": "chromium"
|
"defaultBrowserType": "chromium"
|
||||||
},
|
},
|
||||||
"Nexus 4": {
|
"Nexus 4": {
|
||||||
"userAgent": "Mozilla/5.0 (Linux; Android 4.4.2; Nexus 4 Build/KOT49H) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.5938.48 Mobile Safari/537.36",
|
"userAgent": "Mozilla/5.0 (Linux; Android 4.4.2; Nexus 4 Build/KOT49H) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.5938.62 Mobile Safari/537.36",
|
||||||
"viewport": {
|
"viewport": {
|
||||||
"width": 384,
|
"width": 384,
|
||||||
"height": 640
|
"height": 640
|
||||||
|
|
@ -1077,7 +1077,7 @@
|
||||||
"defaultBrowserType": "chromium"
|
"defaultBrowserType": "chromium"
|
||||||
},
|
},
|
||||||
"Nexus 4 landscape": {
|
"Nexus 4 landscape": {
|
||||||
"userAgent": "Mozilla/5.0 (Linux; Android 4.4.2; Nexus 4 Build/KOT49H) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.5938.48 Mobile Safari/537.36",
|
"userAgent": "Mozilla/5.0 (Linux; Android 4.4.2; Nexus 4 Build/KOT49H) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.5938.62 Mobile Safari/537.36",
|
||||||
"viewport": {
|
"viewport": {
|
||||||
"width": 640,
|
"width": 640,
|
||||||
"height": 384
|
"height": 384
|
||||||
|
|
@ -1088,7 +1088,7 @@
|
||||||
"defaultBrowserType": "chromium"
|
"defaultBrowserType": "chromium"
|
||||||
},
|
},
|
||||||
"Nexus 5": {
|
"Nexus 5": {
|
||||||
"userAgent": "Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.5938.48 Mobile Safari/537.36",
|
"userAgent": "Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.5938.62 Mobile Safari/537.36",
|
||||||
"viewport": {
|
"viewport": {
|
||||||
"width": 360,
|
"width": 360,
|
||||||
"height": 640
|
"height": 640
|
||||||
|
|
@ -1099,7 +1099,7 @@
|
||||||
"defaultBrowserType": "chromium"
|
"defaultBrowserType": "chromium"
|
||||||
},
|
},
|
||||||
"Nexus 5 landscape": {
|
"Nexus 5 landscape": {
|
||||||
"userAgent": "Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.5938.48 Mobile Safari/537.36",
|
"userAgent": "Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.5938.62 Mobile Safari/537.36",
|
||||||
"viewport": {
|
"viewport": {
|
||||||
"width": 640,
|
"width": 640,
|
||||||
"height": 360
|
"height": 360
|
||||||
|
|
@ -1110,7 +1110,7 @@
|
||||||
"defaultBrowserType": "chromium"
|
"defaultBrowserType": "chromium"
|
||||||
},
|
},
|
||||||
"Nexus 5X": {
|
"Nexus 5X": {
|
||||||
"userAgent": "Mozilla/5.0 (Linux; Android 8.0.0; Nexus 5X Build/OPR4.170623.006) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.5938.48 Mobile Safari/537.36",
|
"userAgent": "Mozilla/5.0 (Linux; Android 8.0.0; Nexus 5X Build/OPR4.170623.006) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.5938.62 Mobile Safari/537.36",
|
||||||
"viewport": {
|
"viewport": {
|
||||||
"width": 412,
|
"width": 412,
|
||||||
"height": 732
|
"height": 732
|
||||||
|
|
@ -1121,7 +1121,7 @@
|
||||||
"defaultBrowserType": "chromium"
|
"defaultBrowserType": "chromium"
|
||||||
},
|
},
|
||||||
"Nexus 5X landscape": {
|
"Nexus 5X landscape": {
|
||||||
"userAgent": "Mozilla/5.0 (Linux; Android 8.0.0; Nexus 5X Build/OPR4.170623.006) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.5938.48 Mobile Safari/537.36",
|
"userAgent": "Mozilla/5.0 (Linux; Android 8.0.0; Nexus 5X Build/OPR4.170623.006) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.5938.62 Mobile Safari/537.36",
|
||||||
"viewport": {
|
"viewport": {
|
||||||
"width": 732,
|
"width": 732,
|
||||||
"height": 412
|
"height": 412
|
||||||
|
|
@ -1132,7 +1132,7 @@
|
||||||
"defaultBrowserType": "chromium"
|
"defaultBrowserType": "chromium"
|
||||||
},
|
},
|
||||||
"Nexus 6": {
|
"Nexus 6": {
|
||||||
"userAgent": "Mozilla/5.0 (Linux; Android 7.1.1; Nexus 6 Build/N6F26U) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.5938.48 Mobile Safari/537.36",
|
"userAgent": "Mozilla/5.0 (Linux; Android 7.1.1; Nexus 6 Build/N6F26U) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.5938.62 Mobile Safari/537.36",
|
||||||
"viewport": {
|
"viewport": {
|
||||||
"width": 412,
|
"width": 412,
|
||||||
"height": 732
|
"height": 732
|
||||||
|
|
@ -1143,7 +1143,7 @@
|
||||||
"defaultBrowserType": "chromium"
|
"defaultBrowserType": "chromium"
|
||||||
},
|
},
|
||||||
"Nexus 6 landscape": {
|
"Nexus 6 landscape": {
|
||||||
"userAgent": "Mozilla/5.0 (Linux; Android 7.1.1; Nexus 6 Build/N6F26U) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.5938.48 Mobile Safari/537.36",
|
"userAgent": "Mozilla/5.0 (Linux; Android 7.1.1; Nexus 6 Build/N6F26U) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.5938.62 Mobile Safari/537.36",
|
||||||
"viewport": {
|
"viewport": {
|
||||||
"width": 732,
|
"width": 732,
|
||||||
"height": 412
|
"height": 412
|
||||||
|
|
@ -1154,7 +1154,7 @@
|
||||||
"defaultBrowserType": "chromium"
|
"defaultBrowserType": "chromium"
|
||||||
},
|
},
|
||||||
"Nexus 6P": {
|
"Nexus 6P": {
|
||||||
"userAgent": "Mozilla/5.0 (Linux; Android 8.0.0; Nexus 6P Build/OPP3.170518.006) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.5938.48 Mobile Safari/537.36",
|
"userAgent": "Mozilla/5.0 (Linux; Android 8.0.0; Nexus 6P Build/OPP3.170518.006) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.5938.62 Mobile Safari/537.36",
|
||||||
"viewport": {
|
"viewport": {
|
||||||
"width": 412,
|
"width": 412,
|
||||||
"height": 732
|
"height": 732
|
||||||
|
|
@ -1165,7 +1165,7 @@
|
||||||
"defaultBrowserType": "chromium"
|
"defaultBrowserType": "chromium"
|
||||||
},
|
},
|
||||||
"Nexus 6P landscape": {
|
"Nexus 6P landscape": {
|
||||||
"userAgent": "Mozilla/5.0 (Linux; Android 8.0.0; Nexus 6P Build/OPP3.170518.006) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.5938.48 Mobile Safari/537.36",
|
"userAgent": "Mozilla/5.0 (Linux; Android 8.0.0; Nexus 6P Build/OPP3.170518.006) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.5938.62 Mobile Safari/537.36",
|
||||||
"viewport": {
|
"viewport": {
|
||||||
"width": 732,
|
"width": 732,
|
||||||
"height": 412
|
"height": 412
|
||||||
|
|
@ -1176,7 +1176,7 @@
|
||||||
"defaultBrowserType": "chromium"
|
"defaultBrowserType": "chromium"
|
||||||
},
|
},
|
||||||
"Nexus 7": {
|
"Nexus 7": {
|
||||||
"userAgent": "Mozilla/5.0 (Linux; Android 6.0.1; Nexus 7 Build/MOB30X) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.5938.48 Safari/537.36",
|
"userAgent": "Mozilla/5.0 (Linux; Android 6.0.1; Nexus 7 Build/MOB30X) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.5938.62 Safari/537.36",
|
||||||
"viewport": {
|
"viewport": {
|
||||||
"width": 600,
|
"width": 600,
|
||||||
"height": 960
|
"height": 960
|
||||||
|
|
@ -1187,7 +1187,7 @@
|
||||||
"defaultBrowserType": "chromium"
|
"defaultBrowserType": "chromium"
|
||||||
},
|
},
|
||||||
"Nexus 7 landscape": {
|
"Nexus 7 landscape": {
|
||||||
"userAgent": "Mozilla/5.0 (Linux; Android 6.0.1; Nexus 7 Build/MOB30X) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.5938.48 Safari/537.36",
|
"userAgent": "Mozilla/5.0 (Linux; Android 6.0.1; Nexus 7 Build/MOB30X) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.5938.62 Safari/537.36",
|
||||||
"viewport": {
|
"viewport": {
|
||||||
"width": 960,
|
"width": 960,
|
||||||
"height": 600
|
"height": 600
|
||||||
|
|
@ -1242,7 +1242,7 @@
|
||||||
"defaultBrowserType": "webkit"
|
"defaultBrowserType": "webkit"
|
||||||
},
|
},
|
||||||
"Pixel 2": {
|
"Pixel 2": {
|
||||||
"userAgent": "Mozilla/5.0 (Linux; Android 8.0; Pixel 2 Build/OPD3.170816.012) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.5938.48 Mobile Safari/537.36",
|
"userAgent": "Mozilla/5.0 (Linux; Android 8.0; Pixel 2 Build/OPD3.170816.012) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.5938.62 Mobile Safari/537.36",
|
||||||
"viewport": {
|
"viewport": {
|
||||||
"width": 411,
|
"width": 411,
|
||||||
"height": 731
|
"height": 731
|
||||||
|
|
@ -1253,7 +1253,7 @@
|
||||||
"defaultBrowserType": "chromium"
|
"defaultBrowserType": "chromium"
|
||||||
},
|
},
|
||||||
"Pixel 2 landscape": {
|
"Pixel 2 landscape": {
|
||||||
"userAgent": "Mozilla/5.0 (Linux; Android 8.0; Pixel 2 Build/OPD3.170816.012) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.5938.48 Mobile Safari/537.36",
|
"userAgent": "Mozilla/5.0 (Linux; Android 8.0; Pixel 2 Build/OPD3.170816.012) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.5938.62 Mobile Safari/537.36",
|
||||||
"viewport": {
|
"viewport": {
|
||||||
"width": 731,
|
"width": 731,
|
||||||
"height": 411
|
"height": 411
|
||||||
|
|
@ -1264,7 +1264,7 @@
|
||||||
"defaultBrowserType": "chromium"
|
"defaultBrowserType": "chromium"
|
||||||
},
|
},
|
||||||
"Pixel 2 XL": {
|
"Pixel 2 XL": {
|
||||||
"userAgent": "Mozilla/5.0 (Linux; Android 8.0.0; Pixel 2 XL Build/OPD1.170816.004) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.5938.48 Mobile Safari/537.36",
|
"userAgent": "Mozilla/5.0 (Linux; Android 8.0.0; Pixel 2 XL Build/OPD1.170816.004) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.5938.62 Mobile Safari/537.36",
|
||||||
"viewport": {
|
"viewport": {
|
||||||
"width": 411,
|
"width": 411,
|
||||||
"height": 823
|
"height": 823
|
||||||
|
|
@ -1275,7 +1275,7 @@
|
||||||
"defaultBrowserType": "chromium"
|
"defaultBrowserType": "chromium"
|
||||||
},
|
},
|
||||||
"Pixel 2 XL landscape": {
|
"Pixel 2 XL landscape": {
|
||||||
"userAgent": "Mozilla/5.0 (Linux; Android 8.0.0; Pixel 2 XL Build/OPD1.170816.004) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.5938.48 Mobile Safari/537.36",
|
"userAgent": "Mozilla/5.0 (Linux; Android 8.0.0; Pixel 2 XL Build/OPD1.170816.004) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.5938.62 Mobile Safari/537.36",
|
||||||
"viewport": {
|
"viewport": {
|
||||||
"width": 823,
|
"width": 823,
|
||||||
"height": 411
|
"height": 411
|
||||||
|
|
@ -1286,7 +1286,7 @@
|
||||||
"defaultBrowserType": "chromium"
|
"defaultBrowserType": "chromium"
|
||||||
},
|
},
|
||||||
"Pixel 3": {
|
"Pixel 3": {
|
||||||
"userAgent": "Mozilla/5.0 (Linux; Android 9; Pixel 3 Build/PQ1A.181105.017.A1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.5938.48 Mobile Safari/537.36",
|
"userAgent": "Mozilla/5.0 (Linux; Android 9; Pixel 3 Build/PQ1A.181105.017.A1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.5938.62 Mobile Safari/537.36",
|
||||||
"viewport": {
|
"viewport": {
|
||||||
"width": 393,
|
"width": 393,
|
||||||
"height": 786
|
"height": 786
|
||||||
|
|
@ -1297,7 +1297,7 @@
|
||||||
"defaultBrowserType": "chromium"
|
"defaultBrowserType": "chromium"
|
||||||
},
|
},
|
||||||
"Pixel 3 landscape": {
|
"Pixel 3 landscape": {
|
||||||
"userAgent": "Mozilla/5.0 (Linux; Android 9; Pixel 3 Build/PQ1A.181105.017.A1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.5938.48 Mobile Safari/537.36",
|
"userAgent": "Mozilla/5.0 (Linux; Android 9; Pixel 3 Build/PQ1A.181105.017.A1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.5938.62 Mobile Safari/537.36",
|
||||||
"viewport": {
|
"viewport": {
|
||||||
"width": 786,
|
"width": 786,
|
||||||
"height": 393
|
"height": 393
|
||||||
|
|
@ -1308,7 +1308,7 @@
|
||||||
"defaultBrowserType": "chromium"
|
"defaultBrowserType": "chromium"
|
||||||
},
|
},
|
||||||
"Pixel 4": {
|
"Pixel 4": {
|
||||||
"userAgent": "Mozilla/5.0 (Linux; Android 10; Pixel 4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.5938.48 Mobile Safari/537.36",
|
"userAgent": "Mozilla/5.0 (Linux; Android 10; Pixel 4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.5938.62 Mobile Safari/537.36",
|
||||||
"viewport": {
|
"viewport": {
|
||||||
"width": 353,
|
"width": 353,
|
||||||
"height": 745
|
"height": 745
|
||||||
|
|
@ -1319,7 +1319,7 @@
|
||||||
"defaultBrowserType": "chromium"
|
"defaultBrowserType": "chromium"
|
||||||
},
|
},
|
||||||
"Pixel 4 landscape": {
|
"Pixel 4 landscape": {
|
||||||
"userAgent": "Mozilla/5.0 (Linux; Android 10; Pixel 4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.5938.48 Mobile Safari/537.36",
|
"userAgent": "Mozilla/5.0 (Linux; Android 10; Pixel 4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.5938.62 Mobile Safari/537.36",
|
||||||
"viewport": {
|
"viewport": {
|
||||||
"width": 745,
|
"width": 745,
|
||||||
"height": 353
|
"height": 353
|
||||||
|
|
@ -1330,7 +1330,7 @@
|
||||||
"defaultBrowserType": "chromium"
|
"defaultBrowserType": "chromium"
|
||||||
},
|
},
|
||||||
"Pixel 4a (5G)": {
|
"Pixel 4a (5G)": {
|
||||||
"userAgent": "Mozilla/5.0 (Linux; Android 11; Pixel 4a (5G)) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.5938.48 Mobile Safari/537.36",
|
"userAgent": "Mozilla/5.0 (Linux; Android 11; Pixel 4a (5G)) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.5938.62 Mobile Safari/537.36",
|
||||||
"screen": {
|
"screen": {
|
||||||
"width": 412,
|
"width": 412,
|
||||||
"height": 892
|
"height": 892
|
||||||
|
|
@ -1345,7 +1345,7 @@
|
||||||
"defaultBrowserType": "chromium"
|
"defaultBrowserType": "chromium"
|
||||||
},
|
},
|
||||||
"Pixel 4a (5G) landscape": {
|
"Pixel 4a (5G) landscape": {
|
||||||
"userAgent": "Mozilla/5.0 (Linux; Android 11; Pixel 4a (5G)) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.5938.48 Mobile Safari/537.36",
|
"userAgent": "Mozilla/5.0 (Linux; Android 11; Pixel 4a (5G)) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.5938.62 Mobile Safari/537.36",
|
||||||
"screen": {
|
"screen": {
|
||||||
"height": 892,
|
"height": 892,
|
||||||
"width": 412
|
"width": 412
|
||||||
|
|
@ -1360,7 +1360,7 @@
|
||||||
"defaultBrowserType": "chromium"
|
"defaultBrowserType": "chromium"
|
||||||
},
|
},
|
||||||
"Pixel 5": {
|
"Pixel 5": {
|
||||||
"userAgent": "Mozilla/5.0 (Linux; Android 11; Pixel 5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.5938.48 Mobile Safari/537.36",
|
"userAgent": "Mozilla/5.0 (Linux; Android 11; Pixel 5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.5938.62 Mobile Safari/537.36",
|
||||||
"screen": {
|
"screen": {
|
||||||
"width": 393,
|
"width": 393,
|
||||||
"height": 851
|
"height": 851
|
||||||
|
|
@ -1375,7 +1375,7 @@
|
||||||
"defaultBrowserType": "chromium"
|
"defaultBrowserType": "chromium"
|
||||||
},
|
},
|
||||||
"Pixel 5 landscape": {
|
"Pixel 5 landscape": {
|
||||||
"userAgent": "Mozilla/5.0 (Linux; Android 11; Pixel 5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.5938.48 Mobile Safari/537.36",
|
"userAgent": "Mozilla/5.0 (Linux; Android 11; Pixel 5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.5938.62 Mobile Safari/537.36",
|
||||||
"screen": {
|
"screen": {
|
||||||
"width": 851,
|
"width": 851,
|
||||||
"height": 393
|
"height": 393
|
||||||
|
|
@ -1390,7 +1390,7 @@
|
||||||
"defaultBrowserType": "chromium"
|
"defaultBrowserType": "chromium"
|
||||||
},
|
},
|
||||||
"Moto G4": {
|
"Moto G4": {
|
||||||
"userAgent": "Mozilla/5.0 (Linux; Android 7.0; Moto G (4)) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.5938.48 Mobile Safari/537.36",
|
"userAgent": "Mozilla/5.0 (Linux; Android 7.0; Moto G (4)) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.5938.62 Mobile Safari/537.36",
|
||||||
"viewport": {
|
"viewport": {
|
||||||
"width": 360,
|
"width": 360,
|
||||||
"height": 640
|
"height": 640
|
||||||
|
|
@ -1401,7 +1401,7 @@
|
||||||
"defaultBrowserType": "chromium"
|
"defaultBrowserType": "chromium"
|
||||||
},
|
},
|
||||||
"Moto G4 landscape": {
|
"Moto G4 landscape": {
|
||||||
"userAgent": "Mozilla/5.0 (Linux; Android 7.0; Moto G (4)) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.5938.48 Mobile Safari/537.36",
|
"userAgent": "Mozilla/5.0 (Linux; Android 7.0; Moto G (4)) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.5938.62 Mobile Safari/537.36",
|
||||||
"viewport": {
|
"viewport": {
|
||||||
"width": 640,
|
"width": 640,
|
||||||
"height": 360
|
"height": 360
|
||||||
|
|
@ -1412,7 +1412,7 @@
|
||||||
"defaultBrowserType": "chromium"
|
"defaultBrowserType": "chromium"
|
||||||
},
|
},
|
||||||
"Desktop Chrome HiDPI": {
|
"Desktop Chrome HiDPI": {
|
||||||
"userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.5938.48 Safari/537.36",
|
"userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.5938.62 Safari/537.36",
|
||||||
"screen": {
|
"screen": {
|
||||||
"width": 1792,
|
"width": 1792,
|
||||||
"height": 1120
|
"height": 1120
|
||||||
|
|
@ -1427,7 +1427,7 @@
|
||||||
"defaultBrowserType": "chromium"
|
"defaultBrowserType": "chromium"
|
||||||
},
|
},
|
||||||
"Desktop Edge HiDPI": {
|
"Desktop Edge HiDPI": {
|
||||||
"userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.5938.48 Safari/537.36 Edg/117.0.5938.48",
|
"userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.5938.62 Safari/537.36 Edg/117.0.5938.62",
|
||||||
"screen": {
|
"screen": {
|
||||||
"width": 1792,
|
"width": 1792,
|
||||||
"height": 1120
|
"height": 1120
|
||||||
|
|
@ -1472,7 +1472,7 @@
|
||||||
"defaultBrowserType": "webkit"
|
"defaultBrowserType": "webkit"
|
||||||
},
|
},
|
||||||
"Desktop Chrome": {
|
"Desktop Chrome": {
|
||||||
"userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.5938.48 Safari/537.36",
|
"userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.5938.62 Safari/537.36",
|
||||||
"screen": {
|
"screen": {
|
||||||
"width": 1920,
|
"width": 1920,
|
||||||
"height": 1080
|
"height": 1080
|
||||||
|
|
@ -1487,7 +1487,7 @@
|
||||||
"defaultBrowserType": "chromium"
|
"defaultBrowserType": "chromium"
|
||||||
},
|
},
|
||||||
"Desktop Edge": {
|
"Desktop Edge": {
|
||||||
"userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.5938.48 Safari/537.36 Edg/117.0.5938.48",
|
"userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.5938.62 Safari/537.36 Edg/117.0.5938.62",
|
||||||
"screen": {
|
"screen": {
|
||||||
"width": 1920,
|
"width": 1920,
|
||||||
"height": 1080
|
"height": 1080
|
||||||
|
|
|
||||||
|
|
@ -223,7 +223,7 @@ export class HarTracer {
|
||||||
harEntry.response.cookies = this._options.omitCookies ? [] : event.cookies.map(c => {
|
harEntry.response.cookies = this._options.omitCookies ? [] : event.cookies.map(c => {
|
||||||
return {
|
return {
|
||||||
...c,
|
...c,
|
||||||
expires: c.expires === -1 ? undefined : new Date(c.expires).toISOString()
|
expires: c.expires === -1 ? undefined : safeDateToISOString(c.expires)
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -658,11 +658,11 @@ function parseCookie(c: string): har.Cookie {
|
||||||
if (name === 'Domain')
|
if (name === 'Domain')
|
||||||
cookie.domain = value;
|
cookie.domain = value;
|
||||||
if (name === 'Expires')
|
if (name === 'Expires')
|
||||||
cookie.expires = new Date(value).toISOString();
|
cookie.expires = safeDateToISOString(value);
|
||||||
if (name === 'HttpOnly')
|
if (name === 'HttpOnly')
|
||||||
cookie.httpOnly = true;
|
cookie.httpOnly = true;
|
||||||
if (name === 'Max-Age')
|
if (name === 'Max-Age')
|
||||||
cookie.expires = new Date(Date.now() + (+value) * 1000).toISOString();
|
cookie.expires = safeDateToISOString(Date.now() + (+value) * 1000);
|
||||||
if (name === 'Path')
|
if (name === 'Path')
|
||||||
cookie.path = value;
|
cookie.path = value;
|
||||||
if (name === 'SameSite')
|
if (name === 'SameSite')
|
||||||
|
|
@ -673,4 +673,11 @@ function parseCookie(c: string): har.Cookie {
|
||||||
return cookie;
|
return cookie;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function safeDateToISOString(value: string | number) {
|
||||||
|
try {
|
||||||
|
return new Date(value).toISOString();
|
||||||
|
} catch (e) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const startedDateSymbol = Symbol('startedDate');
|
const startedDateSymbol = Symbol('startedDate');
|
||||||
|
|
@ -20,8 +20,6 @@ export type SerializedValue =
|
||||||
{ d: string } |
|
{ d: string } |
|
||||||
{ u: string } |
|
{ u: string } |
|
||||||
{ bi: string } |
|
{ bi: string } |
|
||||||
{ m: SerializedValue } |
|
|
||||||
{ se: SerializedValue } |
|
|
||||||
{ r: { p: string, f: string} } |
|
{ r: { p: string, f: string} } |
|
||||||
{ a: SerializedValue[], id: number } |
|
{ a: SerializedValue[], id: number } |
|
||||||
{ o: { k: string, v: SerializedValue }[], id: number } |
|
{ o: { k: string, v: SerializedValue }[], id: number } |
|
||||||
|
|
@ -37,14 +35,6 @@ type VisitorInfo = {
|
||||||
|
|
||||||
export function source() {
|
export function source() {
|
||||||
|
|
||||||
function isMap(obj: any): obj is Map<any, any> {
|
|
||||||
return obj instanceof Map || Object.prototype.toString.call(obj) === '[object Map]';
|
|
||||||
}
|
|
||||||
|
|
||||||
function isSet(obj: any): obj is Set<any> {
|
|
||||||
return obj instanceof Set || Object.prototype.toString.call(obj) === '[object Set]';
|
|
||||||
}
|
|
||||||
|
|
||||||
function isRegExp(obj: any): obj is RegExp {
|
function isRegExp(obj: any): obj is RegExp {
|
||||||
try {
|
try {
|
||||||
return obj instanceof RegExp || Object.prototype.toString.call(obj) === '[object RegExp]';
|
return obj instanceof RegExp || Object.prototype.toString.call(obj) === '[object RegExp]';
|
||||||
|
|
@ -104,10 +94,6 @@ export function source() {
|
||||||
return new URL(value.u);
|
return new URL(value.u);
|
||||||
if ('bi' in value)
|
if ('bi' in value)
|
||||||
return BigInt(value.bi);
|
return BigInt(value.bi);
|
||||||
if ('m' in value)
|
|
||||||
return new Map(parseEvaluationResultValue(value.m));
|
|
||||||
if ('se' in value)
|
|
||||||
return new Set(parseEvaluationResultValue(value.se));
|
|
||||||
if ('r' in value)
|
if ('r' in value)
|
||||||
return new RegExp(value.r.p, value.r.f);
|
return new RegExp(value.r.p, value.r.f);
|
||||||
if ('a' in value) {
|
if ('a' in value) {
|
||||||
|
|
@ -177,11 +163,6 @@ export function source() {
|
||||||
if (typeof value === 'bigint')
|
if (typeof value === 'bigint')
|
||||||
return { bi: value.toString() };
|
return { bi: value.toString() };
|
||||||
|
|
||||||
if (isMap(value))
|
|
||||||
return { m: serialize(Array.from(value), handleSerializer, visitorInfo) };
|
|
||||||
if (isSet(value))
|
|
||||||
return { se: serialize(Array.from(value), handleSerializer, visitorInfo) };
|
|
||||||
|
|
||||||
if (isError(value)) {
|
if (isError(value)) {
|
||||||
const error = value;
|
const error = value;
|
||||||
if (error.stack?.startsWith(error.name + ': ' + error.message)) {
|
if (error.stack?.startsWith(error.name + ': ' + error.message)) {
|
||||||
|
|
|
||||||
|
|
@ -464,6 +464,7 @@ export const deps: any = {
|
||||||
'libxtst6'
|
'libxtst6'
|
||||||
],
|
],
|
||||||
webkit: [
|
webkit: [
|
||||||
|
'libsoup-3.0-0',
|
||||||
'libenchant-2-2',
|
'libenchant-2-2',
|
||||||
'gstreamer1.0-libav',
|
'gstreamer1.0-libav',
|
||||||
'gstreamer1.0-plugins-bad',
|
'gstreamer1.0-plugins-bad',
|
||||||
|
|
@ -521,6 +522,7 @@ export const deps: any = {
|
||||||
'libevent-2.1-7',
|
'libevent-2.1-7',
|
||||||
],
|
],
|
||||||
lib2package: {
|
lib2package: {
|
||||||
|
'libsoup-3.0.so.0': 'libsoup-3.0-0',
|
||||||
'libasound.so.2': 'libasound2',
|
'libasound.so.2': 'libasound2',
|
||||||
'libatk-1.0.so.0': 'libatk1.0-0',
|
'libatk-1.0.so.0': 'libatk1.0-0',
|
||||||
'libatk-bridge-2.0.so.0': 'libatk-bridge2.0-0',
|
'libatk-bridge-2.0.so.0': 'libatk-bridge2.0-0',
|
||||||
|
|
@ -885,6 +887,7 @@ export const deps: any = {
|
||||||
'libxtst6'
|
'libxtst6'
|
||||||
],
|
],
|
||||||
webkit: [
|
webkit: [
|
||||||
|
'libsoup-3.0-0',
|
||||||
'gstreamer1.0-libav',
|
'gstreamer1.0-libav',
|
||||||
'gstreamer1.0-plugins-bad',
|
'gstreamer1.0-plugins-bad',
|
||||||
'gstreamer1.0-plugins-base',
|
'gstreamer1.0-plugins-base',
|
||||||
|
|
@ -941,6 +944,7 @@ export const deps: any = {
|
||||||
'libevent-2.1-7',
|
'libevent-2.1-7',
|
||||||
],
|
],
|
||||||
lib2package: {
|
lib2package: {
|
||||||
|
'libsoup-3.0.so.0': 'libsoup-3.0-0',
|
||||||
'libasound.so.2': 'libasound2',
|
'libasound.so.2': 'libasound2',
|
||||||
'libatk-1.0.so.0': 'libatk1.0-0',
|
'libatk-1.0.so.0': 'libatk1.0-0',
|
||||||
'libatk-bridge-2.0.so.0': 'libatk-bridge2.0-0',
|
'libatk-bridge-2.0.so.0': 'libatk-bridge2.0-0',
|
||||||
|
|
|
||||||
|
|
@ -43,7 +43,7 @@ import { Snapshotter } from './snapshotter';
|
||||||
import { yazl } from '../../../zipBundle';
|
import { yazl } from '../../../zipBundle';
|
||||||
import type { ConsoleMessage } from '../../console';
|
import type { ConsoleMessage } from '../../console';
|
||||||
|
|
||||||
const version: trace.VERSION = 4;
|
const version: trace.VERSION = 5;
|
||||||
|
|
||||||
export type TracerOptions = {
|
export type TracerOptions = {
|
||||||
name?: string;
|
name?: string;
|
||||||
|
|
@ -384,7 +384,9 @@ export class Tracing extends SdkObject implements InstrumentationListener, Snaps
|
||||||
onEvent(sdkObject: SdkObject, event: trace.EventTraceEvent) {
|
onEvent(sdkObject: SdkObject, event: trace.EventTraceEvent) {
|
||||||
if (!sdkObject.attribution.context)
|
if (!sdkObject.attribution.context)
|
||||||
return;
|
return;
|
||||||
if (event.method === 'console' || (event.method === '__create__' && event.class === 'ConsoleMessage')) {
|
if (event.method === 'console' ||
|
||||||
|
(event.method === '__create__' && event.class === 'ConsoleMessage') ||
|
||||||
|
(event.method === '__create__' && event.class === 'JSHandle')) {
|
||||||
// Console messages are handled separately.
|
// Console messages are handled separately.
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -427,24 +429,12 @@ export class Tracing extends SdkObject implements InstrumentationListener, Snaps
|
||||||
}
|
}
|
||||||
|
|
||||||
private _onConsoleMessage(message: ConsoleMessage) {
|
private _onConsoleMessage(message: ConsoleMessage) {
|
||||||
const object: trace.ConsoleMessageTraceEvent = {
|
const event: trace.ConsoleMessageTraceEvent = {
|
||||||
type: 'object',
|
type: 'console',
|
||||||
class: 'ConsoleMessage',
|
messageType: message.type(),
|
||||||
guid: message.guid,
|
|
||||||
initializer: {
|
|
||||||
type: message.type(),
|
|
||||||
text: message.text(),
|
text: message.text(),
|
||||||
args: message.args().map(a => ({ preview: a.toString(), value: a.rawValue() })),
|
args: message.args().map(a => ({ preview: a.toString(), value: a.rawValue() })),
|
||||||
location: message.location(),
|
location: message.location(),
|
||||||
},
|
|
||||||
};
|
|
||||||
this._appendTraceEvent(object);
|
|
||||||
|
|
||||||
const event: trace.EventTraceEvent = {
|
|
||||||
type: 'event',
|
|
||||||
class: 'BrowserContext',
|
|
||||||
method: 'console',
|
|
||||||
params: { message: { guid: message.guid } },
|
|
||||||
time: monotonicTime(),
|
time: monotonicTime(),
|
||||||
pageId: message.page().guid,
|
pageId: message.page().guid,
|
||||||
};
|
};
|
||||||
|
|
@ -476,7 +466,7 @@ export class Tracing extends SdkObject implements InstrumentationListener, Snaps
|
||||||
private _appendTraceEvent(event: trace.TraceEvent) {
|
private _appendTraceEvent(event: trace.TraceEvent) {
|
||||||
const visited = visitTraceEvent(event, this._state!.traceSha1s);
|
const visited = visitTraceEvent(event, this._state!.traceSha1s);
|
||||||
// Do not flush (console) events, they are too noisy, unless we are in ui mode (live).
|
// Do not flush (console) events, they are too noisy, unless we are in ui mode (live).
|
||||||
const flush = this._state!.options.live || (event.type !== 'event' && event.type !== 'object');
|
const flush = this._state!.options.live || (event.type !== 'event' && event.type !== 'console');
|
||||||
this._fs.appendFile(this._state!.traceFile, JSON.stringify(visited) + '\n', flush);
|
this._fs.appendFile(this._state!.traceFile, JSON.stringify(visited) + '\n', flush);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -74,6 +74,12 @@ export function normalizeEscapedRegexQuotes(source: string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function escapeRegexForSelector(re: RegExp): string {
|
function escapeRegexForSelector(re: RegExp): string {
|
||||||
|
// Unicode mode does not allow "identity character escapes", so we do not escape and
|
||||||
|
// hope that it does not contain quotes and/or >> signs.
|
||||||
|
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Regular_expressions/Character_escape
|
||||||
|
// TODO: rework RE usages in internal selectors away from literal representation to json, e.g. {source,flags}.
|
||||||
|
if (re.unicode || (re as any).unicodeSets)
|
||||||
|
return String(re);
|
||||||
// Even number of backslashes followed by the quote -> insert a backslash.
|
// Even number of backslashes followed by the quote -> insert a backslash.
|
||||||
return String(re).replace(/(^|[^\\])(\\\\)*(["'`])/g, '$1$2\\$3').replace(/>>/g, '\\>\\>');
|
return String(re).replace(/(^|[^\\])(\\\\)*(["'`])/g, '$1$2\\$3').replace(/>>/g, '\\>\\>');
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "@playwright/experimental-ct-core",
|
"name": "@playwright/experimental-ct-core",
|
||||||
"version": "1.38.0-next",
|
"version": "1.38.1",
|
||||||
"description": "Playwright Component Testing Helpers",
|
"description": "Playwright Component Testing Helpers",
|
||||||
"repository": "github:Microsoft/playwright",
|
"repository": "github:Microsoft/playwright",
|
||||||
"homepage": "https://playwright.dev",
|
"homepage": "https://playwright.dev",
|
||||||
|
|
@ -24,9 +24,9 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"playwright-core": "1.38.0-next",
|
"playwright-core": "1.38.1",
|
||||||
"vite": "^4.3.9",
|
"vite": "^4.3.9",
|
||||||
"playwright": "1.38.0-next"
|
"playwright": "1.38.1"
|
||||||
},
|
},
|
||||||
"bin": {
|
"bin": {
|
||||||
"playwright": "./cli.js"
|
"playwright": "./cli.js"
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "@playwright/experimental-ct-react",
|
"name": "@playwright/experimental-ct-react",
|
||||||
"version": "1.38.0-next",
|
"version": "1.38.1",
|
||||||
"description": "Playwright Component Testing for React",
|
"description": "Playwright Component Testing for React",
|
||||||
"repository": "github:Microsoft/playwright",
|
"repository": "github:Microsoft/playwright",
|
||||||
"homepage": "https://playwright.dev",
|
"homepage": "https://playwright.dev",
|
||||||
|
|
@ -26,7 +26,7 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@playwright/experimental-ct-core": "1.38.0-next",
|
"@playwright/experimental-ct-core": "1.38.1",
|
||||||
"@vitejs/plugin-react": "^4.0.0"
|
"@vitejs/plugin-react": "^4.0.0"
|
||||||
},
|
},
|
||||||
"bin": {
|
"bin": {
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "@playwright/experimental-ct-react17",
|
"name": "@playwright/experimental-ct-react17",
|
||||||
"version": "1.38.0-next",
|
"version": "1.38.1",
|
||||||
"description": "Playwright Component Testing for React",
|
"description": "Playwright Component Testing for React",
|
||||||
"repository": "github:Microsoft/playwright",
|
"repository": "github:Microsoft/playwright",
|
||||||
"homepage": "https://playwright.dev",
|
"homepage": "https://playwright.dev",
|
||||||
|
|
@ -26,7 +26,7 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@playwright/experimental-ct-core": "1.38.0-next",
|
"@playwright/experimental-ct-core": "1.38.1",
|
||||||
"@vitejs/plugin-react": "^4.0.0"
|
"@vitejs/plugin-react": "^4.0.0"
|
||||||
},
|
},
|
||||||
"bin": {
|
"bin": {
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "@playwright/experimental-ct-solid",
|
"name": "@playwright/experimental-ct-solid",
|
||||||
"version": "1.38.0-next",
|
"version": "1.38.1",
|
||||||
"description": "Playwright Component Testing for Solid",
|
"description": "Playwright Component Testing for Solid",
|
||||||
"repository": "github:Microsoft/playwright",
|
"repository": "github:Microsoft/playwright",
|
||||||
"homepage": "https://playwright.dev",
|
"homepage": "https://playwright.dev",
|
||||||
|
|
@ -26,7 +26,7 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@playwright/experimental-ct-core": "1.38.0-next",
|
"@playwright/experimental-ct-core": "1.38.1",
|
||||||
"vite-plugin-solid": "^2.7.0"
|
"vite-plugin-solid": "^2.7.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "@playwright/experimental-ct-svelte",
|
"name": "@playwright/experimental-ct-svelte",
|
||||||
"version": "1.38.0-next",
|
"version": "1.38.1",
|
||||||
"description": "Playwright Component Testing for Svelte",
|
"description": "Playwright Component Testing for Svelte",
|
||||||
"repository": "github:Microsoft/playwright",
|
"repository": "github:Microsoft/playwright",
|
||||||
"homepage": "https://playwright.dev",
|
"homepage": "https://playwright.dev",
|
||||||
|
|
@ -26,7 +26,7 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@playwright/experimental-ct-core": "1.38.0-next",
|
"@playwright/experimental-ct-core": "1.38.1",
|
||||||
"@sveltejs/vite-plugin-svelte": "^2.1.1"
|
"@sveltejs/vite-plugin-svelte": "^2.1.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "@playwright/experimental-ct-vue",
|
"name": "@playwright/experimental-ct-vue",
|
||||||
"version": "1.38.0-next",
|
"version": "1.38.1",
|
||||||
"description": "Playwright Component Testing for Vue",
|
"description": "Playwright Component Testing for Vue",
|
||||||
"repository": "github:Microsoft/playwright",
|
"repository": "github:Microsoft/playwright",
|
||||||
"homepage": "https://playwright.dev",
|
"homepage": "https://playwright.dev",
|
||||||
|
|
@ -26,7 +26,7 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@playwright/experimental-ct-core": "1.38.0-next",
|
"@playwright/experimental-ct-core": "1.38.1",
|
||||||
"@vitejs/plugin-vue": "^4.2.1"
|
"@vitejs/plugin-vue": "^4.2.1"
|
||||||
},
|
},
|
||||||
"bin": {
|
"bin": {
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "@playwright/experimental-ct-vue2",
|
"name": "@playwright/experimental-ct-vue2",
|
||||||
"version": "1.38.0-next",
|
"version": "1.38.1",
|
||||||
"description": "Playwright Component Testing for Vue2",
|
"description": "Playwright Component Testing for Vue2",
|
||||||
"repository": "github:Microsoft/playwright",
|
"repository": "github:Microsoft/playwright",
|
||||||
"homepage": "https://playwright.dev",
|
"homepage": "https://playwright.dev",
|
||||||
|
|
@ -26,7 +26,7 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@playwright/experimental-ct-core": "1.38.0-next",
|
"@playwright/experimental-ct-core": "1.38.1",
|
||||||
"@vitejs/plugin-vue2": "^2.2.0"
|
"@vitejs/plugin-vue2": "^2.2.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "playwright-firefox",
|
"name": "playwright-firefox",
|
||||||
"version": "1.38.0-next",
|
"version": "1.38.1",
|
||||||
"description": "A high-level API to automate Firefox",
|
"description": "A high-level API to automate Firefox",
|
||||||
"repository": "github:Microsoft/playwright",
|
"repository": "github:Microsoft/playwright",
|
||||||
"homepage": "https://playwright.dev",
|
"homepage": "https://playwright.dev",
|
||||||
|
|
@ -27,6 +27,6 @@
|
||||||
"install": "node install.js"
|
"install": "node install.js"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"playwright-core": "1.38.0-next"
|
"playwright-core": "1.38.1"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "@playwright/test",
|
"name": "@playwright/test",
|
||||||
"version": "1.38.0-next",
|
"version": "1.38.1",
|
||||||
"description": "A high-level API to automate web browsers",
|
"description": "A high-level API to automate web browsers",
|
||||||
"repository": "github:Microsoft/playwright",
|
"repository": "github:Microsoft/playwright",
|
||||||
"homepage": "https://playwright.dev",
|
"homepage": "https://playwright.dev",
|
||||||
|
|
@ -25,9 +25,8 @@
|
||||||
"bin": {
|
"bin": {
|
||||||
"playwright": "./cli.js"
|
"playwright": "./cli.js"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {},
|
||||||
},
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"playwright": "1.38.0-next"
|
"playwright": "1.38.1"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "playwright-webkit",
|
"name": "playwright-webkit",
|
||||||
"version": "1.38.0-next",
|
"version": "1.38.1",
|
||||||
"description": "A high-level API to automate WebKit",
|
"description": "A high-level API to automate WebKit",
|
||||||
"repository": "github:Microsoft/playwright",
|
"repository": "github:Microsoft/playwright",
|
||||||
"homepage": "https://playwright.dev",
|
"homepage": "https://playwright.dev",
|
||||||
|
|
@ -27,6 +27,6 @@
|
||||||
"install": "node install.js"
|
"install": "node install.js"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"playwright-core": "1.38.0-next"
|
"playwright-core": "1.38.1"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "playwright",
|
"name": "playwright",
|
||||||
"version": "1.38.0-next",
|
"version": "1.38.1",
|
||||||
"description": "A high-level API to automate web browsers",
|
"description": "A high-level API to automate web browsers",
|
||||||
"repository": "github:Microsoft/playwright",
|
"repository": "github:Microsoft/playwright",
|
||||||
"homepage": "https://playwright.dev",
|
"homepage": "https://playwright.dev",
|
||||||
|
|
@ -51,7 +51,7 @@
|
||||||
},
|
},
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"playwright-core": "1.38.0-next"
|
"playwright-core": "1.38.1"
|
||||||
},
|
},
|
||||||
"optionalDependencies": {
|
"optionalDependencies": {
|
||||||
"fsevents": "2.3.2"
|
"fsevents": "2.3.2"
|
||||||
|
|
|
||||||
|
|
@ -104,4 +104,8 @@ class ListModeReporter extends EmptyReporter {
|
||||||
// eslint-disable-next-line no-console
|
// eslint-disable-next-line no-console
|
||||||
console.error('\n' + formatError(error, false).message);
|
console.error('\n' + formatError(error, false).message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override printsToStdio(): boolean {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
210
packages/playwright/types/test.d.ts
vendored
210
packages/playwright/types/test.d.ts
vendored
|
|
@ -595,8 +595,7 @@ interface TestConfig {
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Configuration for the `expect` assertion library. Learn more about
|
* Configuration for the `expect` assertion library. Learn more about [various timeouts](https://playwright.dev/docs/test-timeouts).
|
||||||
* [test configuration](https://playwright.dev/docs/test-configuration#expect-options).
|
|
||||||
*
|
*
|
||||||
* **Usage**
|
* **Usage**
|
||||||
*
|
*
|
||||||
|
|
@ -607,7 +606,7 @@ interface TestConfig {
|
||||||
* export default defineConfig({
|
* export default defineConfig({
|
||||||
* expect: {
|
* expect: {
|
||||||
* timeout: 10000,
|
* timeout: 10000,
|
||||||
* toHaveScreenshot: {
|
* toMatchSnapshot: {
|
||||||
* maxDiffPixels: 10,
|
* maxDiffPixels: 10,
|
||||||
* },
|
* },
|
||||||
* },
|
* },
|
||||||
|
|
@ -628,19 +627,19 @@ interface TestConfig {
|
||||||
*/
|
*/
|
||||||
toHaveScreenshot?: {
|
toHaveScreenshot?: {
|
||||||
/**
|
/**
|
||||||
* An acceptable perceived color difference between the same pixel in compared images, ranging from `0` (strict) and
|
* an acceptable perceived color difference between the same pixel in compared images, ranging from `0` (strict) and
|
||||||
* `1` (lax). `"pixelmatch"` comparator computes color difference in
|
* `1` (lax). `"pixelmatch"` comparator computes color difference in
|
||||||
* [YIQ color space](https://en.wikipedia.org/wiki/YIQ) and defaults `threshold` value to `0.2`.
|
* [YIQ color space](https://en.wikipedia.org/wiki/YIQ) and defaults `threshold` value to `0.2`.
|
||||||
*/
|
*/
|
||||||
threshold?: number;
|
threshold?: number;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An acceptable amount of pixels that could be different, unset by default.
|
* an acceptable amount of pixels that could be different, unset by default.
|
||||||
*/
|
*/
|
||||||
maxDiffPixels?: number;
|
maxDiffPixels?: number;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An acceptable ratio of pixels that are different to the total amount of pixels, between `0` and `1` , unset by
|
* an acceptable ratio of pixels that are different to the total amount of pixels, between `0` and `1` , unset by
|
||||||
* default.
|
* default.
|
||||||
*/
|
*/
|
||||||
maxDiffPixelRatio?: number;
|
maxDiffPixelRatio?: number;
|
||||||
|
|
@ -666,25 +665,25 @@ interface TestConfig {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Configuration for the
|
* Configuration for the
|
||||||
* [snapshotAssertions.toMatchSnapshot(name)](https://playwright.dev/docs/api/class-snapshotassertions#snapshot-assertions-to-match-snapshot-1)
|
* [snapshotAssertions.toMatchSnapshot(name[, options])](https://playwright.dev/docs/api/class-snapshotassertions#snapshot-assertions-to-match-snapshot-1)
|
||||||
* method.
|
* method.
|
||||||
*/
|
*/
|
||||||
toMatchSnapshot?: {
|
toMatchSnapshot?: {
|
||||||
/**
|
/**
|
||||||
* **Deprecated.** An acceptable perceived color difference between the same pixel in compared images, ranging from
|
* an acceptable perceived color difference between the same pixel in compared images, ranging from `0` (strict) and
|
||||||
* `0` (strict) and `1` (lax). `"pixelmatch"` comparator computes color difference in
|
* `1` (lax). `"pixelmatch"` comparator computes color difference in
|
||||||
* [YIQ color space](https://en.wikipedia.org/wiki/YIQ) and defaults `threshold` value to `0.2`.
|
* [YIQ color space](https://en.wikipedia.org/wiki/YIQ) and defaults `threshold` value to `0.2`.
|
||||||
*/
|
*/
|
||||||
threshold?: number;
|
threshold?: number;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* **Deprecated.** An acceptable amount of pixels that could be different, unset by default.
|
* an acceptable amount of pixels that could be different, unset by default.
|
||||||
*/
|
*/
|
||||||
maxDiffPixels?: number;
|
maxDiffPixels?: number;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* **Deprecated.** An acceptable ratio of pixels that are different to the total amount of pixels, between `0` and `1`
|
* an acceptable ratio of pixels that are different to the total amount of pixels, between `0` and `1` , unset by
|
||||||
* , unset by default.
|
* default.
|
||||||
*/
|
*/
|
||||||
maxDiffPixelRatio?: number;
|
maxDiffPixelRatio?: number;
|
||||||
};
|
};
|
||||||
|
|
@ -834,10 +833,8 @@ interface TestConfig {
|
||||||
grepInvert?: RegExp|Array<RegExp>;
|
grepInvert?: RegExp|Array<RegExp>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Whether to skip snapshot expectations, such as
|
* Whether to skip snapshot expectations, such as `expect(value).toMatchSnapshot()` and `await
|
||||||
* [pageAssertions.toHaveScreenshot(name[, options])](https://playwright.dev/docs/api/class-pageassertions#page-assertions-to-have-screenshot-1)
|
* expect(page).toHaveScreenshot()`.
|
||||||
* and
|
|
||||||
* [snapshotAssertions.toMatchSnapshot(name)](https://playwright.dev/docs/api/class-snapshotassertions#snapshot-assertions-to-match-snapshot-1).
|
|
||||||
*
|
*
|
||||||
* **Usage**
|
* **Usage**
|
||||||
*
|
*
|
||||||
|
|
@ -1106,9 +1103,8 @@ interface TestConfig {
|
||||||
* [testConfig.snapshotPathTemplate](https://playwright.dev/docs/api/class-testconfig#test-config-snapshot-path-template)
|
* [testConfig.snapshotPathTemplate](https://playwright.dev/docs/api/class-testconfig#test-config-snapshot-path-template)
|
||||||
* to configure snapshot paths.
|
* to configure snapshot paths.
|
||||||
*
|
*
|
||||||
* The base directory, relative to the config file, for screenshot files created with
|
* The base directory, relative to the config file, for snapshot files created with `toMatchSnapshot`. Defaults to
|
||||||
* [pageAssertions.toHaveScreenshot(name[, options])](https://playwright.dev/docs/api/class-pageassertions#page-assertions-to-have-screenshot-1).
|
* [testConfig.testDir](https://playwright.dev/docs/api/class-testconfig#test-config-test-dir).
|
||||||
* Defaults to [testConfig.testDir](https://playwright.dev/docs/api/class-testconfig#test-config-test-dir).
|
|
||||||
*
|
*
|
||||||
* **Usage**
|
* **Usage**
|
||||||
*
|
*
|
||||||
|
|
@ -1137,7 +1133,7 @@ interface TestConfig {
|
||||||
* This option configures a template controlling location of snapshots generated by
|
* This option configures a template controlling location of snapshots generated by
|
||||||
* [pageAssertions.toHaveScreenshot(name[, options])](https://playwright.dev/docs/api/class-pageassertions#page-assertions-to-have-screenshot-1)
|
* [pageAssertions.toHaveScreenshot(name[, options])](https://playwright.dev/docs/api/class-pageassertions#page-assertions-to-have-screenshot-1)
|
||||||
* and
|
* and
|
||||||
* [snapshotAssertions.toMatchSnapshot(name)](https://playwright.dev/docs/api/class-snapshotassertions#snapshot-assertions-to-match-snapshot-1).
|
* [snapshotAssertions.toMatchSnapshot(name[, options])](https://playwright.dev/docs/api/class-snapshotassertions#snapshot-assertions-to-match-snapshot-1).
|
||||||
*
|
*
|
||||||
* **Usage**
|
* **Usage**
|
||||||
*
|
*
|
||||||
|
|
@ -2271,8 +2267,8 @@ export interface TestInfo {
|
||||||
*
|
*
|
||||||
* Suffix used to differentiate snapshots between multiple test configurations. For example, if snapshots depend on
|
* Suffix used to differentiate snapshots between multiple test configurations. For example, if snapshots depend on
|
||||||
* the platform, you can set `testInfo.snapshotSuffix` equal to `process.platform`. In this case
|
* the platform, you can set `testInfo.snapshotSuffix` equal to `process.platform`. In this case
|
||||||
* [pageAssertions.toHaveScreenshot(name[, options])](https://playwright.dev/docs/api/class-pageassertions#page-assertions-to-have-screenshot-1)
|
* `expect(value).toMatchSnapshot(snapshotName)` will use different snapshots depending on the platform. Learn more
|
||||||
* will use different snapshots depending on the platform. Learn more about [snapshots](https://playwright.dev/docs/test-snapshots).
|
* about [snapshots](https://playwright.dev/docs/test-snapshots).
|
||||||
*/
|
*/
|
||||||
snapshotSuffix: string;
|
snapshotSuffix: string;
|
||||||
|
|
||||||
|
|
@ -5075,35 +5071,13 @@ type FunctionAssertions = {
|
||||||
toPass(options?: { timeout?: number, intervals?: number[] }): Promise<void>;
|
toPass(options?: { timeout?: number, intervals?: number[] }): Promise<void>;
|
||||||
};
|
};
|
||||||
|
|
||||||
type BufferAssertions = {
|
|
||||||
/**
|
|
||||||
* Ensures that the passed [Buffer] matches the expected snapshot stored in the test snapshots directory.
|
|
||||||
* @deprecated To avoid flakiness, use
|
|
||||||
* [pageAssertions.toHaveScreenshot(name[, options])](https://playwright.dev/docs/api/class-pageassertions#page-assertions-to-have-screenshot-1)
|
|
||||||
* instead.
|
|
||||||
* @param name Snapshot name.
|
|
||||||
* @param options
|
|
||||||
*/
|
|
||||||
toMatchSnapshot(name: string | Array<string>, options?: { maxDiffPixelRatio?: number, maxDiffPixels?: number, threshold?: number }): void;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Ensures that the passed [Buffer] matches the expected snapshot stored in the test snapshots directory.
|
|
||||||
* @deprecated To avoid flakiness, use
|
|
||||||
* [pageAssertions.toHaveScreenshot(name[, options])](https://playwright.dev/docs/api/class-pageassertions#page-assertions-to-have-screenshot-1)
|
|
||||||
* instead.
|
|
||||||
* @param options
|
|
||||||
*/
|
|
||||||
toMatchSnapshot(options?: { maxDiffPixelRatio?: number, maxDiffPixels?: number, name?: string|Array<string>, threshold?: number }): void;
|
|
||||||
};
|
|
||||||
|
|
||||||
type BaseMatchers<R, T> = GenericAssertions<R> & PlaywrightTest.Matchers<R, T> & SnapshotAssertions;
|
type BaseMatchers<R, T> = GenericAssertions<R> & PlaywrightTest.Matchers<R, T> & SnapshotAssertions;
|
||||||
type AllowedGenericMatchers<R> = Pick<GenericAssertions<R>, 'toBe' | 'toBeDefined' | 'toBeFalsy' | 'toBeNull' | 'toBeTruthy' | 'toBeUndefined'>;
|
type AllowedGenericMatchers<R, T> = PlaywrightTest.Matchers<R, T> & Pick<GenericAssertions<R>, 'toBe' | 'toBeDefined' | 'toBeFalsy' | 'toBeNull' | 'toBeTruthy' | 'toBeUndefined'>;
|
||||||
|
|
||||||
type SpecificMatchers<R, T> =
|
type SpecificMatchers<R, T> =
|
||||||
T extends Page ? PageAssertions & AllowedGenericMatchers<R> :
|
T extends Page ? PageAssertions & AllowedGenericMatchers<R, T> :
|
||||||
T extends Locator ? LocatorAssertions & AllowedGenericMatchers<R> :
|
T extends Locator ? LocatorAssertions & AllowedGenericMatchers<R, T> :
|
||||||
T extends APIResponse ? APIResponseAssertions & AllowedGenericMatchers<R> :
|
T extends APIResponse ? APIResponseAssertions & AllowedGenericMatchers<R, T> :
|
||||||
T extends Buffer ? BufferAssertions & GenericAssertions<R> & PlaywrightTest.Matchers<R, T> :
|
|
||||||
BaseMatchers<R, T> & (T extends Function ? FunctionAssertions : {});
|
BaseMatchers<R, T> & (T extends Function ? FunctionAssertions : {});
|
||||||
type AllMatchers<R, T> = PageAssertions & LocatorAssertions & APIResponseAssertions & FunctionAssertions & BaseMatchers<R, T>;
|
type AllMatchers<R, T> = PageAssertions & LocatorAssertions & APIResponseAssertions & FunctionAssertions & BaseMatchers<R, T>;
|
||||||
|
|
||||||
|
|
@ -6247,40 +6221,19 @@ interface PageAssertions {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* **NOTE** For visual regression testing, use
|
* Playwright provides methods for comparing page and element screenshots with expected values stored in files.
|
||||||
* [pageAssertions.toHaveScreenshot(name[, options])](https://playwright.dev/docs/api/class-pageassertions#page-assertions-to-have-screenshot-1)
|
|
||||||
* and
|
|
||||||
* [locatorAssertions.toHaveScreenshot(name[, options])](https://playwright.dev/docs/api/class-locatorassertions#locator-assertions-to-have-screenshot-1)
|
|
||||||
* instead.
|
|
||||||
*
|
|
||||||
* Playwright provides methods for comparing text values with expected values stored in snapshot files.
|
|
||||||
*
|
*
|
||||||
* ```js
|
* ```js
|
||||||
* expect(text).toMatchSnapshot('snapshot.txt');
|
* expect(screenshot).toMatchSnapshot('landing-page.png');
|
||||||
* ```
|
* ```
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
interface SnapshotAssertions {
|
interface SnapshotAssertions {
|
||||||
/**
|
/**
|
||||||
* Ensures that the passed [string] matches the expected snapshot stored in the test snapshots directory.
|
* **NOTE** To compare screenshots, use
|
||||||
|
* [pageAssertions.toHaveScreenshot(name[, options])](https://playwright.dev/docs/api/class-pageassertions#page-assertions-to-have-screenshot-1)
|
||||||
|
* instead.
|
||||||
*
|
*
|
||||||
* **Usage**
|
|
||||||
*
|
|
||||||
* ```js
|
|
||||||
* // Basic usage.
|
|
||||||
* expect(await page.title()).toMatchSnapshot('page-title.txt');
|
|
||||||
*
|
|
||||||
* // Bring some structure to your snapshot files by passing file path segments.
|
|
||||||
* expect(await page.title()).toMatchSnapshot(['page-title', 'step1.txt']);
|
|
||||||
* expect(await page.title()).toMatchSnapshot(['page-title', 'step2.txt']);
|
|
||||||
* ```
|
|
||||||
*
|
|
||||||
* Note that matching snapshots only work with Playwright test runner.
|
|
||||||
* @param name Snapshot name.
|
|
||||||
*/
|
|
||||||
toMatchSnapshot(name: string|Array<string>): void;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Ensures that passed value, either a [string] or a [Buffer], matches the expected snapshot stored in the test
|
* Ensures that passed value, either a [string] or a [Buffer], matches the expected snapshot stored in the test
|
||||||
* snapshots directory.
|
* snapshots directory.
|
||||||
*
|
*
|
||||||
|
|
@ -6288,22 +6241,103 @@ interface SnapshotAssertions {
|
||||||
*
|
*
|
||||||
* ```js
|
* ```js
|
||||||
* // Basic usage.
|
* // Basic usage.
|
||||||
* expect(await page.title()).toMatchSnapshot();
|
* expect(await page.screenshot()).toMatchSnapshot('landing-page.png');
|
||||||
*
|
*
|
||||||
* // Configure the snapshot name.
|
* // Pass options to customize the snapshot comparison and have a generated name.
|
||||||
* expect(await page.title()).toMatchSnapshot({
|
* expect(await page.screenshot()).toMatchSnapshot('landing-page.png', {
|
||||||
* name: 'page-title.txt',
|
* maxDiffPixels: 27, // allow no more than 27 different pixels.
|
||||||
|
* });
|
||||||
|
*
|
||||||
|
* // Configure image matching threshold.
|
||||||
|
* expect(await page.screenshot()).toMatchSnapshot('landing-page.png', { threshold: 0.3 });
|
||||||
|
*
|
||||||
|
* // Bring some structure to your snapshot files by passing file path segments.
|
||||||
|
* expect(await page.screenshot()).toMatchSnapshot(['landing', 'step2.png']);
|
||||||
|
* expect(await page.screenshot()).toMatchSnapshot(['landing', 'step3.png']);
|
||||||
|
* ```
|
||||||
|
*
|
||||||
|
* Learn more about [visual comparisons](https://playwright.dev/docs/test-snapshots).
|
||||||
|
*
|
||||||
|
* Note that matching snapshots only work with Playwright test runner.
|
||||||
|
* @param name Snapshot name.
|
||||||
|
* @param options
|
||||||
|
*/
|
||||||
|
toMatchSnapshot(name: string|Array<string>, options?: {
|
||||||
|
/**
|
||||||
|
* An acceptable ratio of pixels that are different to the total amount of pixels, between `0` and `1`. Default is
|
||||||
|
* configurable with `TestConfig.expect`. Unset by default.
|
||||||
|
*/
|
||||||
|
maxDiffPixelRatio?: number;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An acceptable amount of pixels that could be different. Default is configurable with `TestConfig.expect`. Unset by
|
||||||
|
* default.
|
||||||
|
*/
|
||||||
|
maxDiffPixels?: number;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An acceptable perceived color difference in the [YIQ color space](https://en.wikipedia.org/wiki/YIQ) between the
|
||||||
|
* same pixel in compared images, between zero (strict) and one (lax), default is configurable with
|
||||||
|
* `TestConfig.expect`. Defaults to `0.2`.
|
||||||
|
*/
|
||||||
|
threshold?: number;
|
||||||
|
}): void;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* **NOTE** To compare screenshots, use
|
||||||
|
* [pageAssertions.toHaveScreenshot([options])](https://playwright.dev/docs/api/class-pageassertions#page-assertions-to-have-screenshot-2)
|
||||||
|
* instead.
|
||||||
|
*
|
||||||
|
* Ensures that passed value, either a [string] or a [Buffer], matches the expected snapshot stored in the test
|
||||||
|
* snapshots directory.
|
||||||
|
*
|
||||||
|
* **Usage**
|
||||||
|
*
|
||||||
|
* ```js
|
||||||
|
* // Basic usage and the file name is derived from the test name.
|
||||||
|
* expect(await page.screenshot()).toMatchSnapshot();
|
||||||
|
*
|
||||||
|
* // Pass options to customize the snapshot comparison and have a generated name.
|
||||||
|
* expect(await page.screenshot()).toMatchSnapshot({
|
||||||
|
* maxDiffPixels: 27, // allow no more than 27 different pixels.
|
||||||
|
* });
|
||||||
|
*
|
||||||
|
* // Configure image matching threshold and snapshot name.
|
||||||
|
* expect(await page.screenshot()).toMatchSnapshot({
|
||||||
|
* name: 'landing-page.png',
|
||||||
|
* threshold: 0.3,
|
||||||
* });
|
* });
|
||||||
* ```
|
* ```
|
||||||
*
|
*
|
||||||
|
* Learn more about [visual comparisons](https://playwright.dev/docs/test-snapshots).
|
||||||
|
*
|
||||||
* Note that matching snapshots only work with Playwright test runner.
|
* Note that matching snapshots only work with Playwright test runner.
|
||||||
* @param options
|
* @param options
|
||||||
*/
|
*/
|
||||||
toMatchSnapshot(options?: {
|
toMatchSnapshot(options?: {
|
||||||
|
/**
|
||||||
|
* An acceptable ratio of pixels that are different to the total amount of pixels, between `0` and `1`. Default is
|
||||||
|
* configurable with `TestConfig.expect`. Unset by default.
|
||||||
|
*/
|
||||||
|
maxDiffPixelRatio?: number;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An acceptable amount of pixels that could be different. Default is configurable with `TestConfig.expect`. Unset by
|
||||||
|
* default.
|
||||||
|
*/
|
||||||
|
maxDiffPixels?: number;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Snapshot name. If not passed, the test name and ordinals are used when called multiple times.
|
* Snapshot name. If not passed, the test name and ordinals are used when called multiple times.
|
||||||
*/
|
*/
|
||||||
name?: string|Array<string>;
|
name?: string|Array<string>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An acceptable perceived color difference in the [YIQ color space](https://en.wikipedia.org/wiki/YIQ) between the
|
||||||
|
* same pixel in compared images, between zero (strict) and one (lax), default is configurable with
|
||||||
|
* `TestConfig.expect`. Defaults to `0.2`.
|
||||||
|
*/
|
||||||
|
threshold?: number;
|
||||||
}): void;
|
}): void;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -6439,19 +6473,19 @@ interface TestProject {
|
||||||
*/
|
*/
|
||||||
toHaveScreenshot?: {
|
toHaveScreenshot?: {
|
||||||
/**
|
/**
|
||||||
* An acceptable perceived color difference between the same pixel in compared images, ranging from `0` (strict) and
|
* an acceptable perceived color difference between the same pixel in compared images, ranging from `0` (strict) and
|
||||||
* `1` (lax). `"pixelmatch"` comparator computes color difference in
|
* `1` (lax). `"pixelmatch"` comparator computes color difference in
|
||||||
* [YIQ color space](https://en.wikipedia.org/wiki/YIQ) and defaults `threshold` value to `0.2`.
|
* [YIQ color space](https://en.wikipedia.org/wiki/YIQ) and defaults `threshold` value to `0.2`.
|
||||||
*/
|
*/
|
||||||
threshold?: number;
|
threshold?: number;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An acceptable amount of pixels that could be different, unset by default.
|
* an acceptable amount of pixels that could be different, unset by default.
|
||||||
*/
|
*/
|
||||||
maxDiffPixels?: number;
|
maxDiffPixels?: number;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An acceptable ratio of pixels that are different to the total amount of pixels, between `0` and `1` , unset by
|
* an acceptable ratio of pixels that are different to the total amount of pixels, between `0` and `1` , unset by
|
||||||
* default.
|
* default.
|
||||||
*/
|
*/
|
||||||
maxDiffPixelRatio?: number;
|
maxDiffPixelRatio?: number;
|
||||||
|
|
@ -6477,25 +6511,25 @@ interface TestProject {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Configuration for the
|
* Configuration for the
|
||||||
* [snapshotAssertions.toMatchSnapshot(name)](https://playwright.dev/docs/api/class-snapshotassertions#snapshot-assertions-to-match-snapshot-1)
|
* [snapshotAssertions.toMatchSnapshot(name[, options])](https://playwright.dev/docs/api/class-snapshotassertions#snapshot-assertions-to-match-snapshot-1)
|
||||||
* method.
|
* method.
|
||||||
*/
|
*/
|
||||||
toMatchSnapshot?: {
|
toMatchSnapshot?: {
|
||||||
/**
|
/**
|
||||||
* **Deprecated.** An acceptable perceived color difference between the same pixel in compared images, ranging from
|
* an acceptable perceived color difference between the same pixel in compared images, ranging from `0` (strict) and
|
||||||
* `0` (strict) and `1` (lax). `"pixelmatch"` comparator computes color difference in
|
* `1` (lax). `"pixelmatch"` comparator computes color difference in
|
||||||
* [YIQ color space](https://en.wikipedia.org/wiki/YIQ) and defaults `threshold` value to `0.2`.
|
* [YIQ color space](https://en.wikipedia.org/wiki/YIQ) and defaults `threshold` value to `0.2`.
|
||||||
*/
|
*/
|
||||||
threshold?: number;
|
threshold?: number;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* **Deprecated.** An acceptable amount of pixels that could be different, unset by default.
|
* an acceptable amount of pixels that could be different, unset by default.
|
||||||
*/
|
*/
|
||||||
maxDiffPixels?: number;
|
maxDiffPixels?: number;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* **Deprecated.** An acceptable ratio of pixels that are different to the total amount of pixels, between `0` and `1`
|
* an acceptable ratio of pixels that are different to the total amount of pixels, between `0` and `1` , unset by
|
||||||
* , unset by default.
|
* default.
|
||||||
*/
|
*/
|
||||||
maxDiffPixelRatio?: number;
|
maxDiffPixelRatio?: number;
|
||||||
};
|
};
|
||||||
|
|
@ -6605,7 +6639,7 @@ interface TestProject {
|
||||||
* This option configures a template controlling location of snapshots generated by
|
* This option configures a template controlling location of snapshots generated by
|
||||||
* [pageAssertions.toHaveScreenshot(name[, options])](https://playwright.dev/docs/api/class-pageassertions#page-assertions-to-have-screenshot-1)
|
* [pageAssertions.toHaveScreenshot(name[, options])](https://playwright.dev/docs/api/class-pageassertions#page-assertions-to-have-screenshot-1)
|
||||||
* and
|
* and
|
||||||
* [snapshotAssertions.toMatchSnapshot(name)](https://playwright.dev/docs/api/class-snapshotassertions#snapshot-assertions-to-match-snapshot-1).
|
* [snapshotAssertions.toMatchSnapshot(name[, options])](https://playwright.dev/docs/api/class-snapshotassertions#snapshot-assertions-to-match-snapshot-1).
|
||||||
*
|
*
|
||||||
* **Usage**
|
* **Usage**
|
||||||
*
|
*
|
||||||
|
|
|
||||||
2
packages/playwright/types/testReporter.d.ts
vendored
2
packages/playwright/types/testReporter.d.ts
vendored
|
|
@ -411,7 +411,7 @@ export interface Reporter {
|
||||||
/**
|
/**
|
||||||
* Called after all tests have been run, or testing has been interrupted. Note that this method may return a [Promise]
|
* Called after all tests have been run, or testing has been interrupted. Note that this method may return a [Promise]
|
||||||
* and Playwright Test will await it.
|
* and Playwright Test will await it.
|
||||||
* @param result Result of the full test run.
|
* @param result Result of the full test run, `status` can be one of:
|
||||||
* - `'passed'` - Everything went as expected.
|
* - `'passed'` - Everything went as expected.
|
||||||
* - `'failed'` - Any test has failed.
|
* - `'failed'` - Any test has failed.
|
||||||
* - `'timedout'` - The
|
* - `'timedout'` - The
|
||||||
|
|
|
||||||
|
|
@ -180,8 +180,6 @@ export type SerializedValue = {
|
||||||
d?: string,
|
d?: string,
|
||||||
u?: string,
|
u?: string,
|
||||||
bi?: string,
|
bi?: string,
|
||||||
m?: SerializedValue,
|
|
||||||
se?: SerializedValue,
|
|
||||||
r?: {
|
r?: {
|
||||||
p: string,
|
p: string,
|
||||||
f: string,
|
f: string,
|
||||||
|
|
|
||||||
|
|
@ -82,10 +82,6 @@ SerializedValue:
|
||||||
u: string?
|
u: string?
|
||||||
# String representation of BigInt.
|
# String representation of BigInt.
|
||||||
bi: string?
|
bi: string?
|
||||||
# JS representation of Map: [[key1, value1], [key2, value2], ...].
|
|
||||||
m: SerializedValue?
|
|
||||||
# JS representation of Set: [item1, item2, ...].
|
|
||||||
se: SerializedValue?
|
|
||||||
# Regular expression pattern and flags.
|
# Regular expression pattern and flags.
|
||||||
r:
|
r:
|
||||||
type: object?
|
type: object?
|
||||||
|
|
|
||||||
|
|
@ -34,9 +34,8 @@ export type ContextEntry = {
|
||||||
pages: PageEntry[];
|
pages: PageEntry[];
|
||||||
resources: ResourceSnapshot[];
|
resources: ResourceSnapshot[];
|
||||||
actions: trace.ActionTraceEvent[];
|
actions: trace.ActionTraceEvent[];
|
||||||
events: trace.EventTraceEvent[];
|
events: (trace.EventTraceEvent | trace.ConsoleMessageTraceEvent)[];
|
||||||
stdio: trace.StdioTraceEvent[];
|
stdio: trace.StdioTraceEvent[];
|
||||||
initializers: { [key: string]: trace.ConsoleMessageTraceEvent['initializer'] };
|
|
||||||
hasSource: boolean;
|
hasSource: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -65,7 +64,6 @@ export function createEmptyContext(): ContextEntry {
|
||||||
actions: [],
|
actions: [],
|
||||||
events: [],
|
events: [],
|
||||||
stdio: [],
|
stdio: [],
|
||||||
initializers: {},
|
|
||||||
hasSource: false
|
hasSource: false
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,7 @@
|
||||||
|
|
||||||
import type * as trace from '@trace/trace';
|
import type * as trace from '@trace/trace';
|
||||||
import type * as traceV3 from './versions/traceV3';
|
import type * as traceV3 from './versions/traceV3';
|
||||||
|
import type * as traceV4 from './versions/traceV4';
|
||||||
import { parseClientSideCallMetadata } from '../../../packages/playwright-core/src/utils/isomorphic/traceUtils';
|
import { parseClientSideCallMetadata } from '../../../packages/playwright-core/src/utils/isomorphic/traceUtils';
|
||||||
import type { ContextEntry, PageEntry } from './entries';
|
import type { ContextEntry, PageEntry } from './entries';
|
||||||
import { createEmptyContext } from './entries';
|
import { createEmptyContext } from './entries';
|
||||||
|
|
@ -38,6 +39,8 @@ export class TraceModel {
|
||||||
private _backend!: TraceModelBackend;
|
private _backend!: TraceModelBackend;
|
||||||
private _attachments = new Map<string, trace.AfterActionTraceEventAttachment>();
|
private _attachments = new Map<string, trace.AfterActionTraceEventAttachment>();
|
||||||
private _resourceToContentType = new Map<string, string>();
|
private _resourceToContentType = new Map<string, string>();
|
||||||
|
private _jsHandles = new Map<string, { preview: string }>();
|
||||||
|
private _consoleObjects = new Map<string, { type: string, text: string, location: { url: string, lineNumber: number, columnNumber: number }, args?: { preview: string, value: string }[] }>();
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
}
|
}
|
||||||
|
|
@ -112,6 +115,8 @@ export class TraceModel {
|
||||||
}
|
}
|
||||||
|
|
||||||
this._snapshotStorage!.finalize();
|
this._snapshotStorage!.finalize();
|
||||||
|
this._jsHandles.clear();
|
||||||
|
this._consoleObjects.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
async hasEntry(filename: string): Promise<boolean> {
|
async hasEntry(filename: string): Promise<boolean> {
|
||||||
|
|
@ -207,8 +212,8 @@ export class TraceModel {
|
||||||
contextEntry!.stdio.push(event);
|
contextEntry!.stdio.push(event);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 'object': {
|
case 'console': {
|
||||||
contextEntry!.initializers[event.guid] = event.initializer;
|
contextEntry!.events.push(event);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 'resource-snapshot':
|
case 'resource-snapshot':
|
||||||
|
|
@ -233,12 +238,15 @@ export class TraceModel {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private _modernize(event: any): trace.TraceEvent {
|
private _modernize(event: any): trace.TraceEvent | null {
|
||||||
if (this._version === undefined)
|
if (this._version === undefined)
|
||||||
return event;
|
return event;
|
||||||
const lastVersion: trace.VERSION = 4;
|
const lastVersion: trace.VERSION = 5;
|
||||||
for (let version = this._version; version < lastVersion; ++version)
|
for (let version = this._version; version < lastVersion; ++version) {
|
||||||
event = (this as any)[`_modernize_${version}_to_${version + 1}`].call(this, event);
|
event = (this as any)[`_modernize_${version}_to_${version + 1}`].call(this, event);
|
||||||
|
if (!event)
|
||||||
|
return null;
|
||||||
|
}
|
||||||
return event;
|
return event;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -284,7 +292,7 @@ export class TraceModel {
|
||||||
return event;
|
return event;
|
||||||
}
|
}
|
||||||
|
|
||||||
_modernize_3_to_4(event: traceV3.TraceEvent): trace.TraceEvent | null {
|
_modernize_3_to_4(event: traceV3.TraceEvent): traceV4.TraceEvent | null {
|
||||||
if (event.type !== 'action' && event.type !== 'event') {
|
if (event.type !== 'action' && event.type !== 'event') {
|
||||||
return event as traceV3.ContextCreatedTraceEvent |
|
return event as traceV3.ContextCreatedTraceEvent |
|
||||||
traceV3.ScreencastFrameTraceEvent |
|
traceV3.ScreencastFrameTraceEvent |
|
||||||
|
|
@ -335,6 +343,47 @@ export class TraceModel {
|
||||||
pageId: metadata.pageId,
|
pageId: metadata.pageId,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_modernize_4_to_5(event: traceV4.TraceEvent): trace.TraceEvent | null {
|
||||||
|
if (event.type === 'event' && event.method === '__create__' && event.class === 'JSHandle')
|
||||||
|
this._jsHandles.set(event.params.guid, event.params.initializer);
|
||||||
|
if (event.type === 'object') {
|
||||||
|
// We do not expect any other 'object' events.
|
||||||
|
if (event.class !== 'ConsoleMessage')
|
||||||
|
return null;
|
||||||
|
// Older traces might have `args` inherited from the protocol initializer - guid of JSHandle,
|
||||||
|
// but might also have modern `args` with preview and value.
|
||||||
|
const args: { preview: string, value: string }[] = (event.initializer as any).args?.map((arg: any) => {
|
||||||
|
if (arg.guid) {
|
||||||
|
const handle = this._jsHandles.get(arg.guid);
|
||||||
|
return { preview: handle?.preview || '', value: '' };
|
||||||
|
}
|
||||||
|
return { preview: arg.preview || '', value: arg.value || '' };
|
||||||
|
});
|
||||||
|
this._consoleObjects.set(event.guid, {
|
||||||
|
type: event.initializer.type,
|
||||||
|
text: event.initializer.text,
|
||||||
|
location: event.initializer.location,
|
||||||
|
args,
|
||||||
|
});
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (event.type === 'event' && event.method === 'console') {
|
||||||
|
const consoleMessage = this._consoleObjects.get(event.params.message?.guid || '');
|
||||||
|
if (!consoleMessage)
|
||||||
|
return null;
|
||||||
|
return {
|
||||||
|
type: 'console',
|
||||||
|
time: event.time,
|
||||||
|
pageId: event.pageId,
|
||||||
|
messageType: consoleMessage.type,
|
||||||
|
text: consoleMessage.text,
|
||||||
|
args: consoleMessage.args,
|
||||||
|
location: consoleMessage.location,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return event;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function stripEncodingFromContentType(contentType: string) {
|
function stripEncodingFromContentType(contentType: string) {
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@
|
||||||
import type * as channels from '@protocol/channels';
|
import type * as channels from '@protocol/channels';
|
||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
import './consoleTab.css';
|
import './consoleTab.css';
|
||||||
import * as modelUtil from './modelUtil';
|
import type * as modelUtil from './modelUtil';
|
||||||
import { ListView } from '@web/components/listView';
|
import { ListView } from '@web/components/listView';
|
||||||
import type { Boundaries } from '../geometry';
|
import type { Boundaries } from '../geometry';
|
||||||
import { msToString } from '@web/uiUtils';
|
import { msToString } from '@web/uiUtils';
|
||||||
|
|
@ -51,29 +51,23 @@ export function useConsoleTabModel(model: modelUtil.MultiTraceModel | undefined,
|
||||||
return { entries: [] };
|
return { entries: [] };
|
||||||
const entries: ConsoleEntry[] = [];
|
const entries: ConsoleEntry[] = [];
|
||||||
for (const event of model.events) {
|
for (const event of model.events) {
|
||||||
if (event.method !== 'console' && event.method !== 'pageError')
|
if (event.type === 'console') {
|
||||||
continue;
|
const body = event.args && event.args.length ? format(event.args) : formatAnsi(event.text);
|
||||||
if (event.method === 'console') {
|
const url = event.location.url;
|
||||||
const { guid } = event.params.message;
|
|
||||||
const browserMessage = modelUtil.context(event).initializers[guid];
|
|
||||||
if (browserMessage) {
|
|
||||||
const body = browserMessage.args && browserMessage.args.length ? format(browserMessage.args) : formatAnsi(browserMessage.text);
|
|
||||||
const url = browserMessage.location.url;
|
|
||||||
const filename = url ? url.substring(url.lastIndexOf('/') + 1) : '<anonymous>';
|
const filename = url ? url.substring(url.lastIndexOf('/') + 1) : '<anonymous>';
|
||||||
const location = `${filename}:${browserMessage.location.lineNumber}`;
|
const location = `${filename}:${event.location.lineNumber}`;
|
||||||
|
|
||||||
entries.push({
|
entries.push({
|
||||||
browserMessage: {
|
browserMessage: {
|
||||||
body,
|
body,
|
||||||
location,
|
location,
|
||||||
},
|
},
|
||||||
isError: modelUtil.context(event).initializers[guid]?.type === 'error',
|
isError: event.messageType === 'error',
|
||||||
isWarning: modelUtil.context(event).initializers[guid]?.type === 'warning',
|
isWarning: event.messageType === 'warning',
|
||||||
timestamp: event.time,
|
timestamp: event.time,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
if (event.type === 'event' && event.method === 'pageError') {
|
||||||
if (event.method === 'pageError') {
|
|
||||||
entries.push({
|
entries.push({
|
||||||
browserError: event.params.error,
|
browserError: event.params.error,
|
||||||
isError: true,
|
isError: true,
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@
|
||||||
import type { Language } from '@isomorphic/locatorGenerators';
|
import type { Language } from '@isomorphic/locatorGenerators';
|
||||||
import type { ResourceSnapshot } from '@trace/snapshot';
|
import type { ResourceSnapshot } from '@trace/snapshot';
|
||||||
import type * as trace from '@trace/trace';
|
import type * as trace from '@trace/trace';
|
||||||
import type { ActionTraceEvent, EventTraceEvent } from '@trace/trace';
|
import type { ActionTraceEvent } from '@trace/trace';
|
||||||
import type { ContextEntry, PageEntry } from '../entries';
|
import type { ContextEntry, PageEntry } from '../entries';
|
||||||
|
|
||||||
const contextSymbol = Symbol('context');
|
const contextSymbol = Symbol('context');
|
||||||
|
|
@ -58,7 +58,7 @@ export class MultiTraceModel {
|
||||||
readonly options: trace.BrowserContextEventOptions;
|
readonly options: trace.BrowserContextEventOptions;
|
||||||
readonly pages: PageEntry[];
|
readonly pages: PageEntry[];
|
||||||
readonly actions: ActionTraceEventInContext[];
|
readonly actions: ActionTraceEventInContext[];
|
||||||
readonly events: trace.EventTraceEvent[];
|
readonly events: (trace.EventTraceEvent | trace.ConsoleMessageTraceEvent)[];
|
||||||
readonly stdio: trace.StdioTraceEvent[];
|
readonly stdio: trace.StdioTraceEvent[];
|
||||||
readonly hasSource: boolean;
|
readonly hasSource: boolean;
|
||||||
readonly sdkLanguage: Language | undefined;
|
readonly sdkLanguage: Language | undefined;
|
||||||
|
|
@ -83,7 +83,7 @@ export class MultiTraceModel {
|
||||||
this.endTime = contexts.map(c => c.endTime).reduce((prev, cur) => Math.max(prev, cur), Number.MIN_VALUE);
|
this.endTime = contexts.map(c => c.endTime).reduce((prev, cur) => Math.max(prev, cur), Number.MIN_VALUE);
|
||||||
this.pages = ([] as PageEntry[]).concat(...contexts.map(c => c.pages));
|
this.pages = ([] as PageEntry[]).concat(...contexts.map(c => c.pages));
|
||||||
this.actions = mergeActions(contexts);
|
this.actions = mergeActions(contexts);
|
||||||
this.events = ([] as EventTraceEvent[]).concat(...contexts.map(c => c.events));
|
this.events = ([] as (trace.EventTraceEvent | trace.ConsoleMessageTraceEvent)[]).concat(...contexts.map(c => c.events));
|
||||||
this.stdio = ([] as trace.StdioTraceEvent[]).concat(...contexts.map(c => c.stdio));
|
this.stdio = ([] as trace.StdioTraceEvent[]).concat(...contexts.map(c => c.stdio));
|
||||||
this.hasSource = contexts.some(c => c.hasSource);
|
this.hasSource = contexts.some(c => c.hasSource);
|
||||||
this.resources = [...contexts.map(c => c.resources)].flat();
|
this.resources = [...contexts.map(c => c.resources)].flat();
|
||||||
|
|
@ -203,7 +203,7 @@ export function idForAction(action: ActionTraceEvent) {
|
||||||
return `${action.pageId || 'none'}:${action.callId}`;
|
return `${action.pageId || 'none'}:${action.callId}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function context(action: ActionTraceEvent | EventTraceEvent): ContextEntry {
|
export function context(action: ActionTraceEvent | trace.EventTraceEvent): ContextEntry {
|
||||||
return (action as any)[contextSymbol];
|
return (action as any)[contextSymbol];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -218,24 +218,22 @@ export function prevInList(action: ActionTraceEvent): ActionTraceEvent {
|
||||||
export function stats(action: ActionTraceEvent): { errors: number, warnings: number } {
|
export function stats(action: ActionTraceEvent): { errors: number, warnings: number } {
|
||||||
let errors = 0;
|
let errors = 0;
|
||||||
let warnings = 0;
|
let warnings = 0;
|
||||||
const c = context(action);
|
|
||||||
for (const event of eventsForAction(action)) {
|
for (const event of eventsForAction(action)) {
|
||||||
if (event.method === 'console') {
|
if (event.type === 'console') {
|
||||||
const { guid } = event.params.message;
|
const type = event.messageType;
|
||||||
const type = c.initializers[guid]?.type;
|
|
||||||
if (type === 'warning')
|
if (type === 'warning')
|
||||||
++warnings;
|
++warnings;
|
||||||
else if (type === 'error')
|
else if (type === 'error')
|
||||||
++errors;
|
++errors;
|
||||||
}
|
}
|
||||||
if (event.method === 'pageError')
|
if (event.type === 'event' && event.method === 'pageError')
|
||||||
++errors;
|
++errors;
|
||||||
}
|
}
|
||||||
return { errors, warnings };
|
return { errors, warnings };
|
||||||
}
|
}
|
||||||
|
|
||||||
export function eventsForAction(action: ActionTraceEvent): EventTraceEvent[] {
|
export function eventsForAction(action: ActionTraceEvent): (trace.EventTraceEvent | trace.ConsoleMessageTraceEvent)[] {
|
||||||
let result: EventTraceEvent[] = (action as any)[eventsSymbol];
|
let result: (trace.EventTraceEvent | trace.ConsoleMessageTraceEvent)[] = (action as any)[eventsSymbol];
|
||||||
if (result)
|
if (result)
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -40,5 +40,5 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.network-request-details .cm-wrapper {
|
.network-request-details .cm-wrapper {
|
||||||
height: 300px;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -123,6 +123,7 @@
|
||||||
|
|
||||||
.filter-list {
|
.filter-list {
|
||||||
padding: 0 10px 10px 10px;
|
padding: 0 10px 10px 10px;
|
||||||
|
user-select: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.filter-title,
|
.filter-title,
|
||||||
|
|
|
||||||
|
|
@ -190,11 +190,22 @@ export const UIModeView: React.FC<{}> = ({
|
||||||
}, [closeInstallDialog]);
|
}, [closeInstallDialog]);
|
||||||
|
|
||||||
return <div className='vbox ui-mode'>
|
return <div className='vbox ui-mode'>
|
||||||
|
{!hasBrowsers && <dialog ref={dialogRef}>
|
||||||
|
<div className='title'><span className='codicon codicon-lightbulb'></span>Install browsers</div>
|
||||||
|
<div className='body'>
|
||||||
|
Playwright did not find installed browsers.
|
||||||
|
<br></br>
|
||||||
|
Would you like to run `playwright install`?
|
||||||
|
<br></br>
|
||||||
|
<button className='button' onClick={installBrowsers}>Install</button>
|
||||||
|
<button className='button secondary' onClick={closeInstallDialog}>Dismiss</button>
|
||||||
|
</div>
|
||||||
|
</dialog>}
|
||||||
{isDisconnected && <div className='drop-target'>
|
{isDisconnected && <div className='drop-target'>
|
||||||
<div className='title'>UI Mode disconnected</div>
|
<div className='title'>UI Mode disconnected</div>
|
||||||
<div><a href='#' onClick={() => window.location.reload()}>Reload the page</a> to reconnect</div>
|
<div><a href='#' onClick={() => window.location.reload()}>Reload the page</a> to reconnect</div>
|
||||||
</div>}
|
</div>}
|
||||||
<SplitView sidebarSize={250} minSidebarSize={125} orientation='horizontal' sidebarIsFirst={true}>
|
<SplitView sidebarSize={250} minSidebarSize={150} orientation='horizontal' sidebarIsFirst={true} settingName='testListSidebar'>
|
||||||
<div className='vbox'>
|
<div className='vbox'>
|
||||||
<div className={'vbox' + (isShowingOutput ? '' : ' hidden')}>
|
<div className={'vbox' + (isShowingOutput ? '' : ' hidden')}>
|
||||||
<Toolbar>
|
<Toolbar>
|
||||||
|
|
@ -216,19 +227,7 @@ export const UIModeView: React.FC<{}> = ({
|
||||||
<ToolbarButton icon='color-mode' title='Toggle color mode' onClick={() => toggleTheme()} />
|
<ToolbarButton icon='color-mode' title='Toggle color mode' onClick={() => toggleTheme()} />
|
||||||
<ToolbarButton icon='refresh' title='Reload' onClick={() => reloadTests()} disabled={isRunningTest || isLoading}></ToolbarButton>
|
<ToolbarButton icon='refresh' title='Reload' onClick={() => reloadTests()} disabled={isRunningTest || isLoading}></ToolbarButton>
|
||||||
<ToolbarButton icon='terminal' title='Toggle output' toggled={isShowingOutput} onClick={() => { setIsShowingOutput(!isShowingOutput); }} />
|
<ToolbarButton icon='terminal' title='Toggle output' toggled={isShowingOutput} onClick={() => { setIsShowingOutput(!isShowingOutput); }} />
|
||||||
{!hasBrowsers && <ToolbarButton icon='lightbulb-autofix' style={{ color: 'var(--vscode-list-warningForeground)' }} title='Playwright browsers are missing' toggled={isShowingOutput} onClick={openInstallDialog}>
|
{!hasBrowsers && <ToolbarButton icon='lightbulb-autofix' style={{ color: 'var(--vscode-list-warningForeground)' }} title='Playwright browsers are missing' onClick={openInstallDialog} />}
|
||||||
<dialog ref={dialogRef}>
|
|
||||||
<div className='title'><span className='codicon codicon-lightbulb'></span>Install browsers</div>
|
|
||||||
<div className='body'>
|
|
||||||
Playwright did not find installed browsers.
|
|
||||||
<br></br>
|
|
||||||
Would you like to run `playwright install`?
|
|
||||||
<br></br>
|
|
||||||
<button className='button' onClick={installBrowsers}>Yes</button>
|
|
||||||
<button className='button secondary' onClick={closeInstallDialog}>No</button>
|
|
||||||
</div>
|
|
||||||
</dialog>
|
|
||||||
</ToolbarButton>}
|
|
||||||
</Toolbar>
|
</Toolbar>
|
||||||
<FiltersView
|
<FiltersView
|
||||||
filterText={filterText}
|
filterText={filterText}
|
||||||
|
|
@ -335,7 +334,7 @@ const FiltersView: React.FC<{
|
||||||
if (configFile)
|
if (configFile)
|
||||||
settings.setObject(configFile + ':projects', [...copy.entries()].filter(([_, v]) => v).map(([k]) => k));
|
settings.setObject(configFile + ':projects', [...copy.entries()].filter(([_, v]) => v).map(([k]) => k));
|
||||||
}}/>
|
}}/>
|
||||||
<div>{projectName}</div>
|
<div>{projectName || 'untitled'}</div>
|
||||||
</label>
|
</label>
|
||||||
</div>;
|
</div>;
|
||||||
})}
|
})}
|
||||||
|
|
|
||||||
|
|
@ -193,7 +193,7 @@ export const Workbench: React.FunctionComponent<{
|
||||||
selectedTime={selectedTime}
|
selectedTime={selectedTime}
|
||||||
setSelectedTime={setSelectedTime}
|
setSelectedTime={setSelectedTime}
|
||||||
/>
|
/>
|
||||||
<SplitView sidebarSize={250} orientation='horizontal' sidebarIsFirst={true}>
|
<SplitView sidebarSize={250} orientation='horizontal' sidebarIsFirst={true} settingName='actionListSidebar'>
|
||||||
<SplitView sidebarSize={250} orientation={sidebarLocation === 'bottom' ? 'vertical' : 'horizontal'} settingName='propertiesSidebar'>
|
<SplitView sidebarSize={250} orientation={sidebarLocation === 'bottom' ? 'vertical' : 'horizontal'} settingName='propertiesSidebar'>
|
||||||
<SnapshotTab
|
<SnapshotTab
|
||||||
action={activeAction}
|
action={activeAction}
|
||||||
|
|
|
||||||
225
packages/trace-viewer/src/versions/traceV4.ts
Normal file
225
packages/trace-viewer/src/versions/traceV4.ts
Normal file
|
|
@ -0,0 +1,225 @@
|
||||||
|
/**
|
||||||
|
* Copyright (c) Microsoft Corporation.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import type { Entry as ResourceSnapshot } from '../../../trace/src/har';
|
||||||
|
|
||||||
|
type Language = 'javascript' | 'python' | 'java' | 'csharp' | 'jsonl';
|
||||||
|
type Point = { x: number, y: number };
|
||||||
|
type Size = { width: number, height: number };
|
||||||
|
|
||||||
|
type StackFrame = {
|
||||||
|
file: string,
|
||||||
|
line: number,
|
||||||
|
column: number,
|
||||||
|
function?: string,
|
||||||
|
};
|
||||||
|
|
||||||
|
type SerializedValue = {
|
||||||
|
n?: number,
|
||||||
|
b?: boolean,
|
||||||
|
s?: string,
|
||||||
|
v?: 'null' | 'undefined' | 'NaN' | 'Infinity' | '-Infinity' | '-0',
|
||||||
|
d?: string,
|
||||||
|
u?: string,
|
||||||
|
bi?: string,
|
||||||
|
m?: SerializedValue,
|
||||||
|
se?: SerializedValue,
|
||||||
|
r?: {
|
||||||
|
p: string,
|
||||||
|
f: string,
|
||||||
|
},
|
||||||
|
a?: SerializedValue[],
|
||||||
|
o?: {
|
||||||
|
k: string,
|
||||||
|
v: SerializedValue,
|
||||||
|
}[],
|
||||||
|
h?: number,
|
||||||
|
id?: number,
|
||||||
|
ref?: number,
|
||||||
|
};
|
||||||
|
|
||||||
|
type SerializedError = {
|
||||||
|
error?: {
|
||||||
|
message: string,
|
||||||
|
name: string,
|
||||||
|
stack?: string,
|
||||||
|
},
|
||||||
|
value?: SerializedValue,
|
||||||
|
};
|
||||||
|
|
||||||
|
type NodeSnapshot =
|
||||||
|
// Text node.
|
||||||
|
string |
|
||||||
|
// Subtree reference, "x snapshots ago, node #y". Could point to a text node.
|
||||||
|
// Only nodes that are not references are counted, starting from zero, using post-order traversal.
|
||||||
|
[ [number, number] ] |
|
||||||
|
// Just node name.
|
||||||
|
[ string ] |
|
||||||
|
// Node name, attributes, child nodes.
|
||||||
|
// Unfortunately, we cannot make this type definition recursive, therefore "any".
|
||||||
|
[ string, { [attr: string]: string }, ...any ];
|
||||||
|
|
||||||
|
|
||||||
|
type ResourceOverride = {
|
||||||
|
url: string,
|
||||||
|
sha1?: string,
|
||||||
|
ref?: number
|
||||||
|
};
|
||||||
|
|
||||||
|
type FrameSnapshot = {
|
||||||
|
snapshotName?: string,
|
||||||
|
callId: string,
|
||||||
|
pageId: string,
|
||||||
|
frameId: string,
|
||||||
|
frameUrl: string,
|
||||||
|
timestamp: number,
|
||||||
|
collectionTime: number,
|
||||||
|
doctype?: string,
|
||||||
|
html: NodeSnapshot,
|
||||||
|
resourceOverrides: ResourceOverride[],
|
||||||
|
viewport: { width: number, height: number },
|
||||||
|
isMainFrame: boolean,
|
||||||
|
};
|
||||||
|
|
||||||
|
type BrowserContextEventOptions = {
|
||||||
|
viewport?: Size,
|
||||||
|
deviceScaleFactor?: number,
|
||||||
|
isMobile?: boolean,
|
||||||
|
userAgent?: string,
|
||||||
|
};
|
||||||
|
|
||||||
|
type ContextCreatedTraceEvent = {
|
||||||
|
version: number,
|
||||||
|
type: 'context-options',
|
||||||
|
browserName: string,
|
||||||
|
channel?: string,
|
||||||
|
platform: string,
|
||||||
|
wallTime: number,
|
||||||
|
title?: string,
|
||||||
|
options: BrowserContextEventOptions,
|
||||||
|
sdkLanguage?: Language,
|
||||||
|
testIdAttributeName?: string,
|
||||||
|
};
|
||||||
|
|
||||||
|
type ScreencastFrameTraceEvent = {
|
||||||
|
type: 'screencast-frame',
|
||||||
|
pageId: string,
|
||||||
|
sha1: string,
|
||||||
|
width: number,
|
||||||
|
height: number,
|
||||||
|
timestamp: number,
|
||||||
|
};
|
||||||
|
|
||||||
|
type BeforeActionTraceEvent = {
|
||||||
|
type: 'before',
|
||||||
|
callId: string;
|
||||||
|
startTime: number;
|
||||||
|
apiName: string;
|
||||||
|
class: string;
|
||||||
|
method: string;
|
||||||
|
params: Record<string, any>;
|
||||||
|
wallTime: number;
|
||||||
|
beforeSnapshot?: string;
|
||||||
|
stack?: StackFrame[];
|
||||||
|
pageId?: string;
|
||||||
|
parentId?: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
type InputActionTraceEvent = {
|
||||||
|
type: 'input',
|
||||||
|
callId: string;
|
||||||
|
inputSnapshot?: string;
|
||||||
|
point?: Point;
|
||||||
|
};
|
||||||
|
|
||||||
|
type AfterActionTraceEventAttachment = {
|
||||||
|
name: string;
|
||||||
|
contentType: string;
|
||||||
|
path?: string;
|
||||||
|
sha1?: string;
|
||||||
|
base64?: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
type AfterActionTraceEvent = {
|
||||||
|
type: 'after',
|
||||||
|
callId: string;
|
||||||
|
endTime: number;
|
||||||
|
afterSnapshot?: string;
|
||||||
|
log: string[];
|
||||||
|
error?: SerializedError['error'];
|
||||||
|
attachments?: AfterActionTraceEventAttachment[];
|
||||||
|
result?: any;
|
||||||
|
};
|
||||||
|
|
||||||
|
type EventTraceEvent = {
|
||||||
|
type: 'event',
|
||||||
|
time: number;
|
||||||
|
class: string;
|
||||||
|
method: string;
|
||||||
|
params: any;
|
||||||
|
pageId?: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
type ConsoleMessageTraceEvent = {
|
||||||
|
type: 'object';
|
||||||
|
class: string;
|
||||||
|
initializer: {
|
||||||
|
type: string,
|
||||||
|
text: string,
|
||||||
|
location: {
|
||||||
|
url: string,
|
||||||
|
lineNumber: number,
|
||||||
|
columnNumber: number,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
guid: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
type ResourceSnapshotTraceEvent = {
|
||||||
|
type: 'resource-snapshot',
|
||||||
|
snapshot: ResourceSnapshot,
|
||||||
|
};
|
||||||
|
|
||||||
|
type FrameSnapshotTraceEvent = {
|
||||||
|
type: 'frame-snapshot',
|
||||||
|
snapshot: FrameSnapshot,
|
||||||
|
};
|
||||||
|
|
||||||
|
type ActionTraceEvent = {
|
||||||
|
type: 'action',
|
||||||
|
} & Omit<BeforeActionTraceEvent, 'type'>
|
||||||
|
& Omit<AfterActionTraceEvent, 'type'>
|
||||||
|
& Omit<InputActionTraceEvent, 'type'>;
|
||||||
|
|
||||||
|
type StdioTraceEvent = {
|
||||||
|
type: 'stdout' | 'stderr';
|
||||||
|
timestamp: number;
|
||||||
|
text?: string;
|
||||||
|
base64?: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type TraceEvent =
|
||||||
|
ContextCreatedTraceEvent |
|
||||||
|
ScreencastFrameTraceEvent |
|
||||||
|
ActionTraceEvent |
|
||||||
|
BeforeActionTraceEvent |
|
||||||
|
InputActionTraceEvent |
|
||||||
|
AfterActionTraceEvent |
|
||||||
|
EventTraceEvent |
|
||||||
|
ConsoleMessageTraceEvent |
|
||||||
|
ResourceSnapshotTraceEvent |
|
||||||
|
FrameSnapshotTraceEvent |
|
||||||
|
StdioTraceEvent;
|
||||||
|
|
@ -21,7 +21,7 @@ import type { FrameSnapshot, ResourceSnapshot } from './snapshot';
|
||||||
export type Size = { width: number, height: number };
|
export type Size = { width: number, height: number };
|
||||||
|
|
||||||
// Make sure you add _modernize_N_to_N1(event: any) to traceModel.ts.
|
// Make sure you add _modernize_N_to_N1(event: any) to traceModel.ts.
|
||||||
export type VERSION = 4;
|
export type VERSION = 5;
|
||||||
|
|
||||||
export type BrowserContextEventOptions = {
|
export type BrowserContextEventOptions = {
|
||||||
viewport?: Size,
|
viewport?: Size,
|
||||||
|
|
@ -103,10 +103,10 @@ export type EventTraceEvent = {
|
||||||
};
|
};
|
||||||
|
|
||||||
export type ConsoleMessageTraceEvent = {
|
export type ConsoleMessageTraceEvent = {
|
||||||
type: 'object';
|
type: 'console';
|
||||||
class: string;
|
time: number;
|
||||||
initializer: {
|
pageId?: string;
|
||||||
type: string,
|
messageType: string,
|
||||||
text: string,
|
text: string,
|
||||||
args?: { preview: string, value: any }[],
|
args?: { preview: string, value: any }[],
|
||||||
location: {
|
location: {
|
||||||
|
|
@ -115,8 +115,6 @@ export type ConsoleMessageTraceEvent = {
|
||||||
columnNumber: number,
|
columnNumber: number,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
guid: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type ResourceSnapshotTraceEvent = {
|
export type ResourceSnapshotTraceEvent = {
|
||||||
type: 'resource-snapshot',
|
type: 'resource-snapshot',
|
||||||
|
|
|
||||||
|
|
@ -79,6 +79,7 @@ dialog .title .codicon {
|
||||||
|
|
||||||
dialog .body {
|
dialog .body {
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.button {
|
.button {
|
||||||
|
|
@ -89,6 +90,7 @@ dialog .body {
|
||||||
height: 28px;
|
height: 28px;
|
||||||
min-width: 40px;
|
min-width: 40px;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
user-select: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.button:focus {
|
.button:focus {
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,7 @@
|
||||||
font-weight: var(--vscode-editor-font-weight);
|
font-weight: var(--vscode-editor-font-weight);
|
||||||
font-size: var(--vscode-editor-font-size);
|
font-size: var(--vscode-editor-font-size);
|
||||||
background-color: var(--vscode-inputValidation-errorBackground);
|
background-color: var(--vscode-inputValidation-errorBackground);
|
||||||
white-space: pre;
|
white-space: pre-wrap;
|
||||||
|
word-break: break-word;
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -39,8 +39,8 @@ export const SplitView: React.FC<SplitViewProps> = ({
|
||||||
settingName,
|
settingName,
|
||||||
children
|
children
|
||||||
}) => {
|
}) => {
|
||||||
const [hSize, setHSize] = useSetting<number>(settingName ? settingName + '.' + orientation + ':size' : undefined, Math.max(minSidebarSize, sidebarSize));
|
const [hSize, setHSize] = useSetting<number>(settingName ? settingName + '.' + orientation + ':size' : undefined, Math.max(minSidebarSize, sidebarSize) * window.devicePixelRatio);
|
||||||
const [vSize, setVSize] = useSetting<number>(settingName ? settingName + '.' + orientation + ':size' : undefined, Math.max(minSidebarSize, sidebarSize));
|
const [vSize, setVSize] = useSetting<number>(settingName ? settingName + '.' + orientation + ':size' : undefined, Math.max(minSidebarSize, sidebarSize) * window.devicePixelRatio);
|
||||||
const [resizing, setResizing] = React.useState<{ offset: number, size: number } | null>(null);
|
const [resizing, setResizing] = React.useState<{ offset: number, size: number } | null>(null);
|
||||||
const [measure, ref] = useMeasure<HTMLDivElement>();
|
const [measure, ref] = useMeasure<HTMLDivElement>();
|
||||||
|
|
||||||
|
|
|
||||||
BIN
tests/assets/trace-1.37.zip
Normal file
BIN
tests/assets/trace-1.37.zip
Normal file
Binary file not shown.
|
|
@ -22,7 +22,7 @@ import { parseClientSideCallMetadata } from '../../packages/playwright-core/lib/
|
||||||
import { TraceModel } from '../../packages/trace-viewer/src/traceModel';
|
import { TraceModel } from '../../packages/trace-viewer/src/traceModel';
|
||||||
import type { ActionTreeItem } from '../../packages/trace-viewer/src/ui/modelUtil';
|
import type { ActionTreeItem } from '../../packages/trace-viewer/src/ui/modelUtil';
|
||||||
import { buildActionTree, MultiTraceModel } from '../../packages/trace-viewer/src/ui/modelUtil';
|
import { buildActionTree, MultiTraceModel } from '../../packages/trace-viewer/src/ui/modelUtil';
|
||||||
import type { ActionTraceEvent, EventTraceEvent, TraceEvent } from '@trace/trace';
|
import type { ActionTraceEvent, ConsoleMessageTraceEvent, EventTraceEvent, TraceEvent } from '@trace/trace';
|
||||||
|
|
||||||
export async function attachFrame(page: Page, frameId: string, url: string): Promise<Frame> {
|
export async function attachFrame(page: Page, frameId: string, url: string): Promise<Frame> {
|
||||||
const handle = await page.evaluateHandle(async ({ frameId, url }) => {
|
const handle = await page.evaluateHandle(async ({ frameId, url }) => {
|
||||||
|
|
@ -158,7 +158,7 @@ export async function parseTraceRaw(file: string): Promise<{ events: any[], reso
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function parseTrace(file: string): Promise<{ resources: Map<string, Buffer>, events: EventTraceEvent[], actions: ActionTraceEvent[], apiNames: string[], traceModel: TraceModel, model: MultiTraceModel, actionTree: string[] }> {
|
export async function parseTrace(file: string): Promise<{ resources: Map<string, Buffer>, events: (EventTraceEvent | ConsoleMessageTraceEvent)[], actions: ActionTraceEvent[], apiNames: string[], traceModel: TraceModel, model: MultiTraceModel, actionTree: string[] }> {
|
||||||
const backend = new TraceBackend(file);
|
const backend = new TraceBackend(file);
|
||||||
const traceModel = new TraceModel();
|
const traceModel = new TraceModel();
|
||||||
await traceModel.load(backend, () => {});
|
await traceModel.load(backend, () => {});
|
||||||
|
|
|
||||||
|
|
@ -226,6 +226,20 @@ it('should include set-cookies', async ({ contextFactory, server }, testInfo) =>
|
||||||
expect(new Date(cookies[2].expires).valueOf()).toBeGreaterThan(Date.now());
|
expect(new Date(cookies[2].expires).valueOf()).toBeGreaterThan(Date.now());
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should skip invalid Expires', async ({ contextFactory, server }, testInfo) => {
|
||||||
|
const { page, getLog } = await pageWithHar(contextFactory, testInfo);
|
||||||
|
server.setRoute('/empty.html', (req, res) => {
|
||||||
|
res.setHeader('Set-Cookie', [
|
||||||
|
'name=value;Expires=Sat Sep 14 01:02:27 CET 2024',
|
||||||
|
]);
|
||||||
|
res.end();
|
||||||
|
});
|
||||||
|
await page.goto(server.EMPTY_PAGE);
|
||||||
|
const log = await getLog();
|
||||||
|
const cookies = log.entries[0].response.cookies;
|
||||||
|
expect(cookies[0]).toEqual({ name: 'name', value: 'value' });
|
||||||
|
});
|
||||||
|
|
||||||
it('should include set-cookies with comma', async ({ contextFactory, server, browserName }, testInfo) => {
|
it('should include set-cookies with comma', async ({ contextFactory, server, browserName }, testInfo) => {
|
||||||
it.fixme(browserName === 'webkit', 'We get "name1=val, ue1, name2=val, ue2" as a header value');
|
it.fixme(browserName === 'webkit', 'We get "name1=val, ue1, name2=val, ue2" as a header value');
|
||||||
const { page, getLog } = await pageWithHar(contextFactory, testInfo);
|
const { page, getLog } = await pageWithHar(contextFactory, testInfo);
|
||||||
|
|
|
||||||
|
|
@ -911,6 +911,18 @@ test('should open trace-1.31', async ({ showTraceViewer }) => {
|
||||||
await expect(snapshot.locator('[__playwright_target__]')).toHaveText(['Submit']);
|
await expect(snapshot.locator('[__playwright_target__]')).toHaveText(['Submit']);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('should open trace-1.37', async ({ showTraceViewer }) => {
|
||||||
|
const traceViewer = await showTraceViewer([path.join(__dirname, '../assets/trace-1.37.zip')]);
|
||||||
|
const snapshot = await traceViewer.snapshotFrame('page.goto');
|
||||||
|
await expect(snapshot.locator('div')).toHaveCSS('background-color', 'rgb(255, 0, 0)');
|
||||||
|
|
||||||
|
await traceViewer.showConsoleTab();
|
||||||
|
await expect(traceViewer.consoleLineMessages).toHaveText(['hello {foo: bar}']);
|
||||||
|
|
||||||
|
await traceViewer.showNetworkTab();
|
||||||
|
await expect(traceViewer.networkRequests).toContainText([/200GET\/index.htmltext\/html/, /200GET\/style.cssx-unknown/]);
|
||||||
|
});
|
||||||
|
|
||||||
test('should prefer later resource request with the same method', async ({ page, server, runAndTrace }) => {
|
test('should prefer later resource request with the same method', async ({ page, server, runAndTrace }) => {
|
||||||
const html = `
|
const html = `
|
||||||
<body>
|
<body>
|
||||||
|
|
|
||||||
|
|
@ -739,7 +739,7 @@ test('should flush console events on tracing stop', async ({ context, page }, te
|
||||||
const tracePath = testInfo.outputPath('trace.zip');
|
const tracePath = testInfo.outputPath('trace.zip');
|
||||||
await context.tracing.stop({ path: tracePath });
|
await context.tracing.stop({ path: tracePath });
|
||||||
const trace = await parseTraceRaw(tracePath);
|
const trace = await parseTraceRaw(tracePath);
|
||||||
const events = trace.events.filter(e => e.method === 'console');
|
const events = trace.events.filter(e => e.type === 'console');
|
||||||
expect(events).toHaveLength(100);
|
expect(events).toHaveLength(100);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -115,6 +115,10 @@ it('should filter by regex with a single quote', async ({ page }) => {
|
||||||
await expect.soft(page.getByRole('button', { name: /let\\'s let\\\'s/i }).locator('span')).toHaveText('hello');
|
await expect.soft(page.getByRole('button', { name: /let\\'s let\\\'s/i }).locator('span')).toHaveText('hello');
|
||||||
await expect.soft(page.locator('button', { hasText: /let\\\'s let\\'s/i }).locator('span')).toHaveText('hello');
|
await expect.soft(page.locator('button', { hasText: /let\\\'s let\\'s/i }).locator('span')).toHaveText('hello');
|
||||||
await expect.soft(page.getByRole('button', { name: /let\\\'s let\\'s/i }).locator('span')).toHaveText('hello');
|
await expect.soft(page.getByRole('button', { name: /let\\\'s let\\'s/i }).locator('span')).toHaveText('hello');
|
||||||
|
|
||||||
|
await page.setContent(`<button>let's hello</button>`);
|
||||||
|
await expect.soft(page.locator('button', { hasText: /let's/iu })).toHaveText(`let's hello`);
|
||||||
|
await expect.soft(page.getByRole('button', { name: /let's/iu })).toHaveText(`let's hello`);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should filter by regex and regexp flags', async ({ page }) => {
|
it('should filter by regex and regexp flags', async ({ page }) => {
|
||||||
|
|
|
||||||
|
|
@ -99,14 +99,9 @@ it('should transfer bigint', async ({ page }) => {
|
||||||
expect(await page.evaluate(a => a, 17n)).toBe(17n);
|
expect(await page.evaluate(a => a, 17n)).toBe(17n);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should transfer maps', async ({ page }) => {
|
it('should transfer maps as empty objects', async ({ page }) => {
|
||||||
expect(await page.evaluate(() => new Map([[1, { test: 42n }]]))).toEqual(new Map([[1, { test: 42n }]]));
|
const result = await page.evaluate(a => a.x.constructor.name + ' ' + JSON.stringify(a.x), { x: new Map([[1, 2]]) });
|
||||||
expect(await page.evaluate(a => a, new Map([[1, { test: 17n }]]))).toEqual(new Map([[1, { test: 17n }]]));
|
expect(result).toBe('Object {}');
|
||||||
});
|
|
||||||
|
|
||||||
it('should transfer sets', async ({ page }) => {
|
|
||||||
expect(await page.evaluate(() => new Set([1, { test: 42n }]))).toEqual(new Set([1, { test: 42n }]));
|
|
||||||
expect(await page.evaluate(a => a, new Set([1, { test: 17n }]))).toEqual(new Set([1, { test: 17n }]));
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should modify global environment', async ({ page }) => {
|
it('should modify global environment', async ({ page }) => {
|
||||||
|
|
|
||||||
|
|
@ -272,11 +272,21 @@ test('should work with custom PlaywrightTest namespace', async ({ runTSC }) => {
|
||||||
}
|
}
|
||||||
`,
|
`,
|
||||||
'a.spec.ts': `
|
'a.spec.ts': `
|
||||||
import { test, expect } from '@playwright/test';
|
import { test, expect, type Page, type APIResponse } from '@playwright/test';
|
||||||
test.expect.extend({
|
test.expect.extend({
|
||||||
toBeWithinRange() { },
|
toBeWithinRange() { },
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const page = {} as Page;
|
||||||
|
const locator = page.locator('');
|
||||||
|
const apiResponse = {} as APIResponse;
|
||||||
|
test.expect(page).toBeEmpty();
|
||||||
|
test.expect(page).not.toBeEmpty();
|
||||||
|
test.expect(locator).toBeEmpty();
|
||||||
|
test.expect(locator).not.toBeEmpty();
|
||||||
|
test.expect(apiResponse).toBeEmpty();
|
||||||
|
test.expect(apiResponse).not.toBeEmpty();
|
||||||
|
|
||||||
test.expect('').toBeEmpty();
|
test.expect('').toBeEmpty();
|
||||||
test.expect('hello').not.toBeEmpty();
|
test.expect('hello').not.toBeEmpty();
|
||||||
test.expect([]).toBeEmpty();
|
test.expect([]).toBeEmpty();
|
||||||
|
|
|
||||||
|
|
@ -96,20 +96,8 @@ test('should compile with different option combinations', async ({ runTSC }) =>
|
||||||
import { test, expect } from '@playwright/test';
|
import { test, expect } from '@playwright/test';
|
||||||
test('is a test', async ({ page }) => {
|
test('is a test', async ({ page }) => {
|
||||||
expect('foo').toMatchSnapshot();
|
expect('foo').toMatchSnapshot();
|
||||||
expect('foo').toMatchSnapshot('foo.txt');
|
|
||||||
expect('foo').toMatchSnapshot(['dir', 'foo.txt']);
|
|
||||||
expect('foo').toMatchSnapshot({ name: 'foo.txt' });
|
|
||||||
|
|
||||||
const buf: Buffer = 1 as any;
|
|
||||||
expect(buf).toMatchSnapshot({ threshold: 0.2 });
|
|
||||||
expect(buf).toMatchSnapshot({ maxDiffPixelRatio: 0.2 });
|
|
||||||
expect(buf).toMatchSnapshot({ maxDiffPixels: 0.2 });
|
|
||||||
|
|
||||||
// @ts-expect-error
|
|
||||||
expect('foo').toMatchSnapshot({ threshold: 0.2 });
|
expect('foo').toMatchSnapshot({ threshold: 0.2 });
|
||||||
// @ts-expect-error
|
|
||||||
expect('foo').toMatchSnapshot({ maxDiffPixelRatio: 0.2 });
|
expect('foo').toMatchSnapshot({ maxDiffPixelRatio: 0.2 });
|
||||||
// @ts-expect-error
|
|
||||||
expect('foo').toMatchSnapshot({ maxDiffPixels: 0.2 });
|
expect('foo').toMatchSnapshot({ maxDiffPixels: 0.2 });
|
||||||
});
|
});
|
||||||
`
|
`
|
||||||
|
|
|
||||||
|
|
@ -196,3 +196,21 @@ test('should report errors with location', async ({ runInlineTest }) => {
|
||||||
column: 9,
|
column: 9,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('should list tests once', async ({ runInlineTest }) => {
|
||||||
|
test.info().annotations.push({ type: 'issue', description: 'https://github.com/microsoft/playwright/issues/27087' });
|
||||||
|
const result = await runInlineTest({
|
||||||
|
'playwright.config.ts': `
|
||||||
|
module.exports = { };
|
||||||
|
`,
|
||||||
|
'a.test.js': `
|
||||||
|
const { test, expect } = require('@playwright/test');
|
||||||
|
test('test 1', ({}) => {});
|
||||||
|
`
|
||||||
|
}, { 'list': true });
|
||||||
|
expect(result.exitCode).toBe(0);
|
||||||
|
expect(result.output).toEqual(`Listing tests:
|
||||||
|
a.test.js:3:7 › test 1
|
||||||
|
Total: 1 test in 1 file
|
||||||
|
`);
|
||||||
|
});
|
||||||
|
|
|
||||||
|
|
@ -578,8 +578,6 @@ class TypesGenerator {
|
||||||
'GenericAssertions.objectContaining',
|
'GenericAssertions.objectContaining',
|
||||||
'GenericAssertions.stringContaining',
|
'GenericAssertions.stringContaining',
|
||||||
'GenericAssertions.stringMatching',
|
'GenericAssertions.stringMatching',
|
||||||
'SnapshotAssertions.toMatchSnapshot#3',
|
|
||||||
'SnapshotAssertions.toMatchSnapshot#4',
|
|
||||||
]),
|
]),
|
||||||
overridesToDocsClassMapping: new Map([
|
overridesToDocsClassMapping: new Map([
|
||||||
['TestType', 'Test'],
|
['TestType', 'Test'],
|
||||||
|
|
|
||||||
30
utils/generate_types/overrides-test.d.ts
vendored
30
utils/generate_types/overrides-test.d.ts
vendored
|
|
@ -329,35 +329,13 @@ type FunctionAssertions = {
|
||||||
toPass(options?: { timeout?: number, intervals?: number[] }): Promise<void>;
|
toPass(options?: { timeout?: number, intervals?: number[] }): Promise<void>;
|
||||||
};
|
};
|
||||||
|
|
||||||
type BufferAssertions = {
|
|
||||||
/**
|
|
||||||
* Ensures that the passed [Buffer] matches the expected snapshot stored in the test snapshots directory.
|
|
||||||
* @deprecated To avoid flakiness, use
|
|
||||||
* [pageAssertions.toHaveScreenshot(name[, options])](https://playwright.dev/docs/api/class-pageassertions#page-assertions-to-have-screenshot-1)
|
|
||||||
* instead.
|
|
||||||
* @param name Snapshot name.
|
|
||||||
* @param options
|
|
||||||
*/
|
|
||||||
toMatchSnapshot(name: string | Array<string>, options?: { maxDiffPixelRatio?: number, maxDiffPixels?: number, threshold?: number }): void;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Ensures that the passed [Buffer] matches the expected snapshot stored in the test snapshots directory.
|
|
||||||
* @deprecated To avoid flakiness, use
|
|
||||||
* [pageAssertions.toHaveScreenshot(name[, options])](https://playwright.dev/docs/api/class-pageassertions#page-assertions-to-have-screenshot-1)
|
|
||||||
* instead.
|
|
||||||
* @param options
|
|
||||||
*/
|
|
||||||
toMatchSnapshot(options?: { maxDiffPixelRatio?: number, maxDiffPixels?: number, name?: string|Array<string>, threshold?: number }): void;
|
|
||||||
};
|
|
||||||
|
|
||||||
type BaseMatchers<R, T> = GenericAssertions<R> & PlaywrightTest.Matchers<R, T> & SnapshotAssertions;
|
type BaseMatchers<R, T> = GenericAssertions<R> & PlaywrightTest.Matchers<R, T> & SnapshotAssertions;
|
||||||
type AllowedGenericMatchers<R> = Pick<GenericAssertions<R>, 'toBe' | 'toBeDefined' | 'toBeFalsy' | 'toBeNull' | 'toBeTruthy' | 'toBeUndefined'>;
|
type AllowedGenericMatchers<R, T> = PlaywrightTest.Matchers<R, T> & Pick<GenericAssertions<R>, 'toBe' | 'toBeDefined' | 'toBeFalsy' | 'toBeNull' | 'toBeTruthy' | 'toBeUndefined'>;
|
||||||
|
|
||||||
type SpecificMatchers<R, T> =
|
type SpecificMatchers<R, T> =
|
||||||
T extends Page ? PageAssertions & AllowedGenericMatchers<R> :
|
T extends Page ? PageAssertions & AllowedGenericMatchers<R, T> :
|
||||||
T extends Locator ? LocatorAssertions & AllowedGenericMatchers<R> :
|
T extends Locator ? LocatorAssertions & AllowedGenericMatchers<R, T> :
|
||||||
T extends APIResponse ? APIResponseAssertions & AllowedGenericMatchers<R> :
|
T extends APIResponse ? APIResponseAssertions & AllowedGenericMatchers<R, T> :
|
||||||
T extends Buffer ? BufferAssertions & GenericAssertions<R> & PlaywrightTest.Matchers<R, T> :
|
|
||||||
BaseMatchers<R, T> & (T extends Function ? FunctionAssertions : {});
|
BaseMatchers<R, T> & (T extends Function ? FunctionAssertions : {});
|
||||||
type AllMatchers<R, T> = PageAssertions & LocatorAssertions & APIResponseAssertions & FunctionAssertions & BaseMatchers<R, T>;
|
type AllMatchers<R, T> = PageAssertions & LocatorAssertions & APIResponseAssertions & FunctionAssertions & BaseMatchers<R, T>;
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue