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
|
||||
|
||||
[](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)
|
||||
|
||||
|
|
@ -8,7 +8,7 @@ Playwright is a framework for Web Testing and Automation. It allows testing [Chr
|
|||
|
||||
| | 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: |
|
||||
| Firefox <!-- GEN:firefox-version -->117.0<!-- GEN:stop --> | :white_check_mark: | :white_check_mark: | :white_check_mark: |
|
||||
|
||||
|
|
|
|||
|
|
@ -2,75 +2,24 @@
|
|||
* since: v1.20
|
||||
* langs: js
|
||||
|
||||
:::tip
|
||||
For visual regression testing, use [`method: PageAssertions.toHaveScreenshot#1`] and [`method: LocatorAssertions.toHaveScreenshot#1`] instead.
|
||||
:::
|
||||
|
||||
Playwright provides methods for comparing text values with expected values stored in snapshot files.
|
||||
Playwright provides methods for comparing page and element screenshots with
|
||||
expected values stored in files.
|
||||
|
||||
```js
|
||||
expect(text).toMatchSnapshot('snapshot.txt');
|
||||
expect(screenshot).toMatchSnapshot('landing-page.png');
|
||||
```
|
||||
|
||||
## method: SnapshotAssertions.toMatchSnapshot#1
|
||||
* since: v1.22
|
||||
|
||||
Ensures that the passed [string] matches the expected snapshot stored in the test snapshots directory.
|
||||
|
||||
**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
|
||||
:::caution
|
||||
To compare screenshots, use [`method: PageAssertions.toHaveScreenshot#1`] 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.
|
||||
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
|
||||
// Basic usage.
|
||||
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.
|
||||
|
||||
### param: SnapshotAssertions.toMatchSnapshot#3.name
|
||||
### param: SnapshotAssertions.toMatchSnapshot#1.name
|
||||
* since: v1.22
|
||||
- `name` <[string]|[Array]<[string]>>
|
||||
|
||||
Snapshot name.
|
||||
|
||||
### option: SnapshotAssertions.toMatchSnapshot#3.maxDiffPixels = %%-assertions-max-diff-pixels-%%
|
||||
### option: SnapshotAssertions.toMatchSnapshot#1.maxDiffPixels = %%-assertions-max-diff-pixels-%%
|
||||
* 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
|
||||
|
||||
### option: SnapshotAssertions.toMatchSnapshot#3.threshold = %%-assertions-threshold-%%
|
||||
### option: SnapshotAssertions.toMatchSnapshot#1.threshold = %%-assertions-threshold-%%
|
||||
* since: v1.22
|
||||
|
||||
## method: SnapshotAssertions.toMatchSnapshot#4
|
||||
* deprecated: To avoid flakiness, use [`method: PageAssertions.toHaveScreenshot#1`] instead.
|
||||
## method: SnapshotAssertions.toMatchSnapshot#2
|
||||
* 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**
|
||||
|
||||
|
|
@ -135,18 +87,17 @@ Learn more about [visual comparisons](../test-snapshots.md).
|
|||
|
||||
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
|
||||
|
||||
### option: SnapshotAssertions.toMatchSnapshot#4.maxDiffPixelRatio = %%-assertions-max-diff-pixel-ratio-%%
|
||||
### option: SnapshotAssertions.toMatchSnapshot#2.maxDiffPixelRatio = %%-assertions-max-diff-pixel-ratio-%%
|
||||
* since: v1.22
|
||||
|
||||
### option: SnapshotAssertions.toMatchSnapshot#4.name
|
||||
### 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.
|
||||
|
||||
### option: SnapshotAssertions.toMatchSnapshot#4.threshold = %%-assertions-threshold-%%
|
||||
### option: SnapshotAssertions.toMatchSnapshot#2.threshold = %%-assertions-threshold-%%
|
||||
* since: v1.22
|
||||
|
||||
|
|
|
|||
|
|
@ -4,6 +4,39 @@ title: "Release notes"
|
|||
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
|
||||
|
||||
### 📚 Debian 12 Bookworm Support
|
||||
|
|
|
|||
|
|
@ -4,6 +4,39 @@ title: "Release notes"
|
|||
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
|
||||
|
||||
### New APIs
|
||||
|
|
|
|||
|
|
@ -6,6 +6,81 @@ toc_max_heading_level: 2
|
|||
|
||||
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
|
||||
|
||||
<LiteYouTube
|
||||
|
|
|
|||
|
|
@ -4,6 +4,39 @@ title: "Release notes"
|
|||
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
|
||||
|
||||
### Highlights
|
||||
|
|
|
|||
|
|
@ -41,18 +41,18 @@ export default defineConfig({
|
|||
- type: ?<[Object]>
|
||||
- `timeout` ?<[int]> Default timeout for async expect matchers in milliseconds, defaults to 5000ms.
|
||||
- `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`.
|
||||
- `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.
|
||||
- `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.
|
||||
- `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"`.
|
||||
- `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"`.
|
||||
- `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`.
|
||||
- `maxDiffPixels` ?<[int]> **Deprecated.** 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.
|
||||
- `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.
|
||||
- `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**
|
||||
|
||||
|
|
@ -62,7 +62,7 @@ import { defineConfig } from '@playwright/test';
|
|||
export default defineConfig({
|
||||
expect: {
|
||||
timeout: 10000,
|
||||
toHaveScreenshot: {
|
||||
toMatchSnapshot: {
|
||||
maxDiffPixels: 10,
|
||||
},
|
||||
},
|
||||
|
|
@ -196,7 +196,7 @@ export default defineConfig({
|
|||
* since: v1.26
|
||||
- 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**
|
||||
|
||||
|
|
@ -296,7 +296,7 @@ test('example test', async ({}, testInfo) => {
|
|||
* discouraged: Use [`property: TestConfig.snapshotPathTemplate`] to configure snapshot paths.
|
||||
- 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**
|
||||
|
||||
|
|
|
|||
|
|
@ -397,7 +397,7 @@ Use of [`property: TestInfo.snapshotSuffix`] is discouraged. Please use [`proper
|
|||
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
|
||||
* since: v1.10
|
||||
|
|
|
|||
|
|
@ -91,16 +91,16 @@ export default defineConfig({
|
|||
- type: ?<[Object]>
|
||||
- `timeout` ?<[int]> Default timeout for async expect matchers in milliseconds, defaults to 5000ms.
|
||||
- `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`.
|
||||
- `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.
|
||||
- `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.
|
||||
- `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"`.
|
||||
- `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"`.
|
||||
- `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`.
|
||||
- `maxDiffPixels` ?<[int]> **Deprecated.** 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.
|
||||
- `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.
|
||||
- `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.
|
||||
|
||||
|
|
|
|||
|
|
@ -82,7 +82,6 @@ Prefer [auto-retrying](#auto-retrying-assertions) assertions whenever possible.
|
|||
| [`method: GenericAssertions.toHaveProperty`] | Object has a property |
|
||||
| [`method: GenericAssertions.toMatch`] | String matches a regular expression |
|
||||
| [`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.toThrow`] | Function throws an error |
|
||||
| [`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.
|
||||
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 |
|
||||
| :- | :- |
|
||||
| `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. |
|
||||
| `expect.toHaveScreenshot` | Configuration for [`method: PageAssertions.toHaveScreenshot#1`] and [`method: LocatorAssertions.toHaveScreenshot#1`] methods. |
|
||||
| [`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. |
|
||||
| [`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
|
||||
|
|
|
|||
|
|
@ -112,11 +112,11 @@ Called after all tests have been run, or testing has been interrupted. Note that
|
|||
### param: Reporter.onEnd.result
|
||||
* since: v1.10
|
||||
- `result` <[Object]>
|
||||
- `status` <[FullStatus]<"passed"|"failed"|"timedout"|"interrupted">>
|
||||
- `startTime` <[Date]>
|
||||
- `duration` <[int]>
|
||||
- `status` <[FullStatus]<"passed"|"failed"|"timedout"|"interrupted">> Test run status.
|
||||
- `startTime` <[Date]> Test run start wall time.
|
||||
- `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.
|
||||
* `'failed'` - Any test has failed.
|
||||
* `'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.
|
||||
```
|
||||
|
||||
That's because there was no reference screenshot 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.
|
||||
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.
|
||||
|
||||
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
|
||||
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
|
||||
```
|
||||
|
||||
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:
|
||||
```js
|
||||
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`.
|
||||
|
||||
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.
|
||||
|
||||
|
|
@ -48,6 +54,9 @@ Sometimes you need to update the reference screenshot, for example when the page
|
|||
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:
|
||||
|
||||
```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
|
||||
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
|
||||
Here we compare text content against the reference.
|
||||
|
||||
```js title="example.spec.ts"
|
||||
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": "",
|
||||
"license": "ISC",
|
||||
"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",
|
||||
"version": "1.38.0-next",
|
||||
"version": "1.38.1",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "playwright-internal",
|
||||
"version": "1.38.0-next",
|
||||
"version": "1.38.1",
|
||||
"license": "Apache-2.0",
|
||||
"workspaces": [
|
||||
"packages/*"
|
||||
|
|
@ -6290,10 +6290,10 @@
|
|||
}
|
||||
},
|
||||
"packages/playwright": {
|
||||
"version": "1.38.0-next",
|
||||
"version": "1.38.1",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"playwright-core": "1.38.0-next"
|
||||
"playwright-core": "1.38.1"
|
||||
},
|
||||
"bin": {
|
||||
"playwright": "cli.js"
|
||||
|
|
@ -6307,11 +6307,11 @@
|
|||
},
|
||||
"packages/playwright-browser-chromium": {
|
||||
"name": "@playwright/browser-chromium",
|
||||
"version": "1.38.0-next",
|
||||
"version": "1.38.1",
|
||||
"hasInstallScript": true,
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"playwright-core": "1.38.0-next"
|
||||
"playwright-core": "1.38.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=16"
|
||||
|
|
@ -6319,11 +6319,11 @@
|
|||
},
|
||||
"packages/playwright-browser-firefox": {
|
||||
"name": "@playwright/browser-firefox",
|
||||
"version": "1.38.0-next",
|
||||
"version": "1.38.1",
|
||||
"hasInstallScript": true,
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"playwright-core": "1.38.0-next"
|
||||
"playwright-core": "1.38.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=16"
|
||||
|
|
@ -6331,22 +6331,22 @@
|
|||
},
|
||||
"packages/playwright-browser-webkit": {
|
||||
"name": "@playwright/browser-webkit",
|
||||
"version": "1.38.0-next",
|
||||
"version": "1.38.1",
|
||||
"hasInstallScript": true,
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"playwright-core": "1.38.0-next"
|
||||
"playwright-core": "1.38.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=16"
|
||||
}
|
||||
},
|
||||
"packages/playwright-chromium": {
|
||||
"version": "1.38.0-next",
|
||||
"version": "1.38.1",
|
||||
"hasInstallScript": true,
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"playwright-core": "1.38.0-next"
|
||||
"playwright-core": "1.38.1"
|
||||
},
|
||||
"bin": {
|
||||
"playwright": "cli.js"
|
||||
|
|
@ -6356,7 +6356,7 @@
|
|||
}
|
||||
},
|
||||
"packages/playwright-core": {
|
||||
"version": "1.38.0-next",
|
||||
"version": "1.38.1",
|
||||
"license": "Apache-2.0",
|
||||
"bin": {
|
||||
"playwright-core": "cli.js"
|
||||
|
|
@ -6367,11 +6367,11 @@
|
|||
},
|
||||
"packages/playwright-ct-core": {
|
||||
"name": "@playwright/experimental-ct-core",
|
||||
"version": "1.38.0-next",
|
||||
"version": "1.38.1",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"playwright": "1.38.0-next",
|
||||
"playwright-core": "1.38.0-next",
|
||||
"playwright": "1.38.1",
|
||||
"playwright-core": "1.38.1",
|
||||
"vite": "^4.3.9"
|
||||
},
|
||||
"bin": {
|
||||
|
|
@ -6383,10 +6383,10 @@
|
|||
},
|
||||
"packages/playwright-ct-react": {
|
||||
"name": "@playwright/experimental-ct-react",
|
||||
"version": "1.38.0-next",
|
||||
"version": "1.38.1",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@playwright/experimental-ct-core": "1.38.0-next",
|
||||
"@playwright/experimental-ct-core": "1.38.1",
|
||||
"@vitejs/plugin-react": "^4.0.0"
|
||||
},
|
||||
"bin": {
|
||||
|
|
@ -6415,10 +6415,10 @@
|
|||
},
|
||||
"packages/playwright-ct-react17": {
|
||||
"name": "@playwright/experimental-ct-react17",
|
||||
"version": "1.38.0-next",
|
||||
"version": "1.38.1",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@playwright/experimental-ct-core": "1.38.0-next",
|
||||
"@playwright/experimental-ct-core": "1.38.1",
|
||||
"@vitejs/plugin-react": "^4.0.0"
|
||||
},
|
||||
"bin": {
|
||||
|
|
@ -6447,10 +6447,10 @@
|
|||
},
|
||||
"packages/playwright-ct-solid": {
|
||||
"name": "@playwright/experimental-ct-solid",
|
||||
"version": "1.38.0-next",
|
||||
"version": "1.38.1",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@playwright/experimental-ct-core": "1.38.0-next",
|
||||
"@playwright/experimental-ct-core": "1.38.1",
|
||||
"vite-plugin-solid": "^2.7.0"
|
||||
},
|
||||
"bin": {
|
||||
|
|
@ -6465,10 +6465,10 @@
|
|||
},
|
||||
"packages/playwright-ct-svelte": {
|
||||
"name": "@playwright/experimental-ct-svelte",
|
||||
"version": "1.38.0-next",
|
||||
"version": "1.38.1",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@playwright/experimental-ct-core": "1.38.0-next",
|
||||
"@playwright/experimental-ct-core": "1.38.1",
|
||||
"@sveltejs/vite-plugin-svelte": "^2.1.1"
|
||||
},
|
||||
"bin": {
|
||||
|
|
@ -6483,10 +6483,10 @@
|
|||
},
|
||||
"packages/playwright-ct-vue": {
|
||||
"name": "@playwright/experimental-ct-vue",
|
||||
"version": "1.38.0-next",
|
||||
"version": "1.38.1",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@playwright/experimental-ct-core": "1.38.0-next",
|
||||
"@playwright/experimental-ct-core": "1.38.1",
|
||||
"@vitejs/plugin-vue": "^4.2.1"
|
||||
},
|
||||
"bin": {
|
||||
|
|
@ -6534,10 +6534,10 @@
|
|||
},
|
||||
"packages/playwright-ct-vue2": {
|
||||
"name": "@playwright/experimental-ct-vue2",
|
||||
"version": "1.38.0-next",
|
||||
"version": "1.38.1",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@playwright/experimental-ct-core": "1.38.0-next",
|
||||
"@playwright/experimental-ct-core": "1.38.1",
|
||||
"@vitejs/plugin-vue2": "^2.2.0"
|
||||
},
|
||||
"bin": {
|
||||
|
|
@ -6551,11 +6551,11 @@
|
|||
}
|
||||
},
|
||||
"packages/playwright-firefox": {
|
||||
"version": "1.38.0-next",
|
||||
"version": "1.38.1",
|
||||
"hasInstallScript": true,
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"playwright-core": "1.38.0-next"
|
||||
"playwright-core": "1.38.1"
|
||||
},
|
||||
"bin": {
|
||||
"playwright": "cli.js"
|
||||
|
|
@ -6589,10 +6589,10 @@
|
|||
},
|
||||
"packages/playwright-test": {
|
||||
"name": "@playwright/test",
|
||||
"version": "1.38.0-next",
|
||||
"version": "1.38.1",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"playwright": "1.38.0-next"
|
||||
"playwright": "1.38.1"
|
||||
},
|
||||
"bin": {
|
||||
"playwright": "cli.js"
|
||||
|
|
@ -6602,11 +6602,11 @@
|
|||
}
|
||||
},
|
||||
"packages/playwright-webkit": {
|
||||
"version": "1.38.0-next",
|
||||
"version": "1.38.1",
|
||||
"hasInstallScript": true,
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"playwright-core": "1.38.0-next"
|
||||
"playwright-core": "1.38.1"
|
||||
},
|
||||
"bin": {
|
||||
"playwright": "cli.js"
|
||||
|
|
@ -7451,33 +7451,33 @@
|
|||
"@playwright/browser-chromium": {
|
||||
"version": "file:packages/playwright-browser-chromium",
|
||||
"requires": {
|
||||
"playwright-core": "1.38.0-next"
|
||||
"playwright-core": "1.38.1"
|
||||
}
|
||||
},
|
||||
"@playwright/browser-firefox": {
|
||||
"version": "file:packages/playwright-browser-firefox",
|
||||
"requires": {
|
||||
"playwright-core": "1.38.0-next"
|
||||
"playwright-core": "1.38.1"
|
||||
}
|
||||
},
|
||||
"@playwright/browser-webkit": {
|
||||
"version": "file:packages/playwright-browser-webkit",
|
||||
"requires": {
|
||||
"playwright-core": "1.38.0-next"
|
||||
"playwright-core": "1.38.1"
|
||||
}
|
||||
},
|
||||
"@playwright/experimental-ct-core": {
|
||||
"version": "file:packages/playwright-ct-core",
|
||||
"requires": {
|
||||
"playwright": "1.38.0-next",
|
||||
"playwright-core": "1.38.0-next",
|
||||
"playwright": "1.38.1",
|
||||
"playwright-core": "1.38.1",
|
||||
"vite": "^4.3.9"
|
||||
}
|
||||
},
|
||||
"@playwright/experimental-ct-react": {
|
||||
"version": "file:packages/playwright-ct-react",
|
||||
"requires": {
|
||||
"@playwright/experimental-ct-core": "1.38.0-next",
|
||||
"@playwright/experimental-ct-core": "1.38.1",
|
||||
"@vitejs/plugin-react": "^4.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
|
|
@ -7497,7 +7497,7 @@
|
|||
"@playwright/experimental-ct-react17": {
|
||||
"version": "file:packages/playwright-ct-react17",
|
||||
"requires": {
|
||||
"@playwright/experimental-ct-core": "1.38.0-next",
|
||||
"@playwright/experimental-ct-core": "1.38.1",
|
||||
"@vitejs/plugin-react": "^4.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
|
|
@ -7517,7 +7517,7 @@
|
|||
"@playwright/experimental-ct-solid": {
|
||||
"version": "file:packages/playwright-ct-solid",
|
||||
"requires": {
|
||||
"@playwright/experimental-ct-core": "1.38.0-next",
|
||||
"@playwright/experimental-ct-core": "1.38.1",
|
||||
"solid-js": "^1.7.0",
|
||||
"vite-plugin-solid": "^2.7.0"
|
||||
}
|
||||
|
|
@ -7525,7 +7525,7 @@
|
|||
"@playwright/experimental-ct-svelte": {
|
||||
"version": "file:packages/playwright-ct-svelte",
|
||||
"requires": {
|
||||
"@playwright/experimental-ct-core": "1.38.0-next",
|
||||
"@playwright/experimental-ct-core": "1.38.1",
|
||||
"@sveltejs/vite-plugin-svelte": "^2.1.1",
|
||||
"svelte": "^3.55.1"
|
||||
}
|
||||
|
|
@ -7533,7 +7533,7 @@
|
|||
"@playwright/experimental-ct-vue": {
|
||||
"version": "file:packages/playwright-ct-vue",
|
||||
"requires": {
|
||||
"@playwright/experimental-ct-core": "1.38.0-next",
|
||||
"@playwright/experimental-ct-core": "1.38.1",
|
||||
"@vitejs/plugin-vue": "^4.2.1"
|
||||
},
|
||||
"dependencies": {
|
||||
|
|
@ -7567,7 +7567,7 @@
|
|||
"@playwright/experimental-ct-vue2": {
|
||||
"version": "file:packages/playwright-ct-vue2",
|
||||
"requires": {
|
||||
"@playwright/experimental-ct-core": "1.38.0-next",
|
||||
"@playwright/experimental-ct-core": "1.38.1",
|
||||
"@vitejs/plugin-vue2": "^2.2.0",
|
||||
"vue": "^2.7.14"
|
||||
}
|
||||
|
|
@ -7575,7 +7575,7 @@
|
|||
"@playwright/test": {
|
||||
"version": "file:packages/playwright-test",
|
||||
"requires": {
|
||||
"playwright": "1.38.0-next"
|
||||
"playwright": "1.38.1"
|
||||
}
|
||||
},
|
||||
"@sindresorhus/is": {
|
||||
|
|
@ -9885,13 +9885,13 @@
|
|||
"version": "file:packages/playwright",
|
||||
"requires": {
|
||||
"fsevents": "2.3.2",
|
||||
"playwright-core": "1.38.0-next"
|
||||
"playwright-core": "1.38.1"
|
||||
}
|
||||
},
|
||||
"playwright-chromium": {
|
||||
"version": "file:packages/playwright-chromium",
|
||||
"requires": {
|
||||
"playwright-core": "1.38.0-next"
|
||||
"playwright-core": "1.38.1"
|
||||
}
|
||||
},
|
||||
"playwright-core": {
|
||||
|
|
@ -9900,13 +9900,13 @@
|
|||
"playwright-firefox": {
|
||||
"version": "file:packages/playwright-firefox",
|
||||
"requires": {
|
||||
"playwright-core": "1.38.0-next"
|
||||
"playwright-core": "1.38.1"
|
||||
}
|
||||
},
|
||||
"playwright-webkit": {
|
||||
"version": "file:packages/playwright-webkit",
|
||||
"requires": {
|
||||
"playwright-core": "1.38.0-next"
|
||||
"playwright-core": "1.38.1"
|
||||
}
|
||||
},
|
||||
"postcss": {
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"name": "playwright-internal",
|
||||
"private": true,
|
||||
"version": "1.38.0-next",
|
||||
"version": "1.38.1",
|
||||
"description": "A high-level API to automate web browsers",
|
||||
"repository": "github:Microsoft/playwright",
|
||||
"homepage": "https://playwright.dev",
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@playwright/browser-chromium",
|
||||
"version": "1.38.0-next",
|
||||
"version": "1.38.1",
|
||||
"description": "Playwright package that automatically installs Chromium",
|
||||
"repository": "github:Microsoft/playwright",
|
||||
"homepage": "https://playwright.dev",
|
||||
|
|
@ -24,6 +24,6 @@
|
|||
"install": "node install.js"
|
||||
},
|
||||
"dependencies": {
|
||||
"playwright-core": "1.38.0-next"
|
||||
"playwright-core": "1.38.1"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@playwright/browser-firefox",
|
||||
"version": "1.38.0-next",
|
||||
"version": "1.38.1",
|
||||
"description": "Playwright package that automatically installs Firefox",
|
||||
"repository": "github:Microsoft/playwright",
|
||||
"homepage": "https://playwright.dev",
|
||||
|
|
@ -24,6 +24,6 @@
|
|||
"install": "node install.js"
|
||||
},
|
||||
"dependencies": {
|
||||
"playwright-core": "1.38.0-next"
|
||||
"playwright-core": "1.38.1"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@playwright/browser-webkit",
|
||||
"version": "1.38.0-next",
|
||||
"version": "1.38.1",
|
||||
"description": "Playwright package that automatically installs WebKit",
|
||||
"repository": "github:Microsoft/playwright",
|
||||
"homepage": "https://playwright.dev",
|
||||
|
|
@ -24,6 +24,6 @@
|
|||
"install": "node install.js"
|
||||
},
|
||||
"dependencies": {
|
||||
"playwright-core": "1.38.0-next"
|
||||
"playwright-core": "1.38.1"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "playwright-chromium",
|
||||
"version": "1.38.0-next",
|
||||
"version": "1.38.1",
|
||||
"description": "A high-level API to automate Chromium",
|
||||
"repository": "github:Microsoft/playwright",
|
||||
"homepage": "https://playwright.dev",
|
||||
|
|
@ -27,6 +27,6 @@
|
|||
"install": "node install.js"
|
||||
},
|
||||
"dependencies": {
|
||||
"playwright-core": "1.38.0-next"
|
||||
"playwright-core": "1.38.1"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,15 +3,15 @@
|
|||
"browsers": [
|
||||
{
|
||||
"name": "chromium",
|
||||
"revision": "1079",
|
||||
"revision": "1080",
|
||||
"installByDefault": true,
|
||||
"browserVersion": "117.0.5938.48"
|
||||
"browserVersion": "117.0.5938.62"
|
||||
},
|
||||
{
|
||||
"name": "chromium-with-symbols",
|
||||
"revision": "1079",
|
||||
"revision": "1080",
|
||||
"installByDefault": false,
|
||||
"browserVersion": "117.0.5938.48"
|
||||
"browserVersion": "117.0.5938.62"
|
||||
},
|
||||
{
|
||||
"name": "chromium-tip-of-tree",
|
||||
|
|
@ -39,7 +39,7 @@
|
|||
},
|
||||
{
|
||||
"name": "webkit",
|
||||
"revision": "1907",
|
||||
"revision": "1908",
|
||||
"installByDefault": true,
|
||||
"revisionOverrides": {
|
||||
"mac10.14": "1446",
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "playwright-core",
|
||||
"version": "1.38.0-next",
|
||||
"version": "1.38.1",
|
||||
"description": "A high-level API to automate web browsers",
|
||||
"repository": "github:Microsoft/playwright",
|
||||
"homepage": "https://playwright.dev",
|
||||
|
|
|
|||
|
|
@ -75,10 +75,6 @@ function innerParseSerializedValue(value: SerializedValue, handles: any[] | unde
|
|||
return BigInt(value.bi);
|
||||
if (value.r !== undefined)
|
||||
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) {
|
||||
const result: any[] = [];
|
||||
|
|
@ -149,10 +145,6 @@ function innerSerializeValue(value: any, handleSerializer: (value: any) => Handl
|
|||
}
|
||||
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))
|
||||
return { d: value.toJSON() };
|
||||
if (isURL(value))
|
||||
|
|
@ -183,14 +175,6 @@ function innerSerializeValue(value: any, handleSerializer: (value: any) => Handl
|
|||
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 {
|
||||
return obj instanceof RegExp || Object.prototype.toString.call(obj) === '[object RegExp]';
|
||||
}
|
||||
|
|
|
|||
|
|
@ -58,8 +58,6 @@ scheme.SerializedValue = tObject({
|
|||
d: tOptional(tString),
|
||||
u: tOptional(tString),
|
||||
bi: tOptional(tString),
|
||||
m: tOptional(tType('SerializedValue')),
|
||||
se: tOptional(tType('SerializedValue')),
|
||||
r: tOptional(tObject({
|
||||
p: tString,
|
||||
f: tString,
|
||||
|
|
|
|||
|
|
@ -110,7 +110,7 @@
|
|||
"defaultBrowserType": "webkit"
|
||||
},
|
||||
"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": {
|
||||
"width": 360,
|
||||
"height": 640
|
||||
|
|
@ -121,7 +121,7 @@
|
|||
"defaultBrowserType": "chromium"
|
||||
},
|
||||
"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": {
|
||||
"width": 640,
|
||||
"height": 360
|
||||
|
|
@ -132,7 +132,7 @@
|
|||
"defaultBrowserType": "chromium"
|
||||
},
|
||||
"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": {
|
||||
"width": 360,
|
||||
"height": 740
|
||||
|
|
@ -143,7 +143,7 @@
|
|||
"defaultBrowserType": "chromium"
|
||||
},
|
||||
"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": {
|
||||
"width": 740,
|
||||
"height": 360
|
||||
|
|
@ -154,7 +154,7 @@
|
|||
"defaultBrowserType": "chromium"
|
||||
},
|
||||
"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": {
|
||||
"width": 320,
|
||||
"height": 658
|
||||
|
|
@ -165,7 +165,7 @@
|
|||
"defaultBrowserType": "chromium"
|
||||
},
|
||||
"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": {
|
||||
"width": 658,
|
||||
"height": 320
|
||||
|
|
@ -176,7 +176,7 @@
|
|||
"defaultBrowserType": "chromium"
|
||||
},
|
||||
"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": {
|
||||
"width": 712,
|
||||
"height": 1138
|
||||
|
|
@ -187,7 +187,7 @@
|
|||
"defaultBrowserType": "chromium"
|
||||
},
|
||||
"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": {
|
||||
"width": 1138,
|
||||
"height": 712
|
||||
|
|
@ -978,7 +978,7 @@
|
|||
"defaultBrowserType": "webkit"
|
||||
},
|
||||
"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": {
|
||||
"width": 384,
|
||||
"height": 640
|
||||
|
|
@ -989,7 +989,7 @@
|
|||
"defaultBrowserType": "chromium"
|
||||
},
|
||||
"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": {
|
||||
"width": 640,
|
||||
"height": 384
|
||||
|
|
@ -1000,7 +1000,7 @@
|
|||
"defaultBrowserType": "chromium"
|
||||
},
|
||||
"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": {
|
||||
"width": 640,
|
||||
"height": 360
|
||||
|
|
@ -1011,7 +1011,7 @@
|
|||
"defaultBrowserType": "chromium"
|
||||
},
|
||||
"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": {
|
||||
"width": 360,
|
||||
"height": 640
|
||||
|
|
@ -1022,7 +1022,7 @@
|
|||
"defaultBrowserType": "chromium"
|
||||
},
|
||||
"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": {
|
||||
"width": 360,
|
||||
"height": 640
|
||||
|
|
@ -1033,7 +1033,7 @@
|
|||
"defaultBrowserType": "chromium"
|
||||
},
|
||||
"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": {
|
||||
"width": 640,
|
||||
"height": 360
|
||||
|
|
@ -1044,7 +1044,7 @@
|
|||
"defaultBrowserType": "chromium"
|
||||
},
|
||||
"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": {
|
||||
"width": 800,
|
||||
"height": 1280
|
||||
|
|
@ -1055,7 +1055,7 @@
|
|||
"defaultBrowserType": "chromium"
|
||||
},
|
||||
"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": {
|
||||
"width": 1280,
|
||||
"height": 800
|
||||
|
|
@ -1066,7 +1066,7 @@
|
|||
"defaultBrowserType": "chromium"
|
||||
},
|
||||
"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": {
|
||||
"width": 384,
|
||||
"height": 640
|
||||
|
|
@ -1077,7 +1077,7 @@
|
|||
"defaultBrowserType": "chromium"
|
||||
},
|
||||
"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": {
|
||||
"width": 640,
|
||||
"height": 384
|
||||
|
|
@ -1088,7 +1088,7 @@
|
|||
"defaultBrowserType": "chromium"
|
||||
},
|
||||
"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": {
|
||||
"width": 360,
|
||||
"height": 640
|
||||
|
|
@ -1099,7 +1099,7 @@
|
|||
"defaultBrowserType": "chromium"
|
||||
},
|
||||
"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": {
|
||||
"width": 640,
|
||||
"height": 360
|
||||
|
|
@ -1110,7 +1110,7 @@
|
|||
"defaultBrowserType": "chromium"
|
||||
},
|
||||
"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": {
|
||||
"width": 412,
|
||||
"height": 732
|
||||
|
|
@ -1121,7 +1121,7 @@
|
|||
"defaultBrowserType": "chromium"
|
||||
},
|
||||
"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": {
|
||||
"width": 732,
|
||||
"height": 412
|
||||
|
|
@ -1132,7 +1132,7 @@
|
|||
"defaultBrowserType": "chromium"
|
||||
},
|
||||
"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": {
|
||||
"width": 412,
|
||||
"height": 732
|
||||
|
|
@ -1143,7 +1143,7 @@
|
|||
"defaultBrowserType": "chromium"
|
||||
},
|
||||
"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": {
|
||||
"width": 732,
|
||||
"height": 412
|
||||
|
|
@ -1154,7 +1154,7 @@
|
|||
"defaultBrowserType": "chromium"
|
||||
},
|
||||
"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": {
|
||||
"width": 412,
|
||||
"height": 732
|
||||
|
|
@ -1165,7 +1165,7 @@
|
|||
"defaultBrowserType": "chromium"
|
||||
},
|
||||
"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": {
|
||||
"width": 732,
|
||||
"height": 412
|
||||
|
|
@ -1176,7 +1176,7 @@
|
|||
"defaultBrowserType": "chromium"
|
||||
},
|
||||
"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": {
|
||||
"width": 600,
|
||||
"height": 960
|
||||
|
|
@ -1187,7 +1187,7 @@
|
|||
"defaultBrowserType": "chromium"
|
||||
},
|
||||
"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": {
|
||||
"width": 960,
|
||||
"height": 600
|
||||
|
|
@ -1242,7 +1242,7 @@
|
|||
"defaultBrowserType": "webkit"
|
||||
},
|
||||
"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": {
|
||||
"width": 411,
|
||||
"height": 731
|
||||
|
|
@ -1253,7 +1253,7 @@
|
|||
"defaultBrowserType": "chromium"
|
||||
},
|
||||
"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": {
|
||||
"width": 731,
|
||||
"height": 411
|
||||
|
|
@ -1264,7 +1264,7 @@
|
|||
"defaultBrowserType": "chromium"
|
||||
},
|
||||
"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": {
|
||||
"width": 411,
|
||||
"height": 823
|
||||
|
|
@ -1275,7 +1275,7 @@
|
|||
"defaultBrowserType": "chromium"
|
||||
},
|
||||
"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": {
|
||||
"width": 823,
|
||||
"height": 411
|
||||
|
|
@ -1286,7 +1286,7 @@
|
|||
"defaultBrowserType": "chromium"
|
||||
},
|
||||
"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": {
|
||||
"width": 393,
|
||||
"height": 786
|
||||
|
|
@ -1297,7 +1297,7 @@
|
|||
"defaultBrowserType": "chromium"
|
||||
},
|
||||
"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": {
|
||||
"width": 786,
|
||||
"height": 393
|
||||
|
|
@ -1308,7 +1308,7 @@
|
|||
"defaultBrowserType": "chromium"
|
||||
},
|
||||
"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": {
|
||||
"width": 353,
|
||||
"height": 745
|
||||
|
|
@ -1319,7 +1319,7 @@
|
|||
"defaultBrowserType": "chromium"
|
||||
},
|
||||
"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": {
|
||||
"width": 745,
|
||||
"height": 353
|
||||
|
|
@ -1330,7 +1330,7 @@
|
|||
"defaultBrowserType": "chromium"
|
||||
},
|
||||
"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": {
|
||||
"width": 412,
|
||||
"height": 892
|
||||
|
|
@ -1345,7 +1345,7 @@
|
|||
"defaultBrowserType": "chromium"
|
||||
},
|
||||
"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": {
|
||||
"height": 892,
|
||||
"width": 412
|
||||
|
|
@ -1360,7 +1360,7 @@
|
|||
"defaultBrowserType": "chromium"
|
||||
},
|
||||
"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": {
|
||||
"width": 393,
|
||||
"height": 851
|
||||
|
|
@ -1375,7 +1375,7 @@
|
|||
"defaultBrowserType": "chromium"
|
||||
},
|
||||
"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": {
|
||||
"width": 851,
|
||||
"height": 393
|
||||
|
|
@ -1390,7 +1390,7 @@
|
|||
"defaultBrowserType": "chromium"
|
||||
},
|
||||
"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": {
|
||||
"width": 360,
|
||||
"height": 640
|
||||
|
|
@ -1401,7 +1401,7 @@
|
|||
"defaultBrowserType": "chromium"
|
||||
},
|
||||
"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": {
|
||||
"width": 640,
|
||||
"height": 360
|
||||
|
|
@ -1412,7 +1412,7 @@
|
|||
"defaultBrowserType": "chromium"
|
||||
},
|
||||
"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": {
|
||||
"width": 1792,
|
||||
"height": 1120
|
||||
|
|
@ -1427,7 +1427,7 @@
|
|||
"defaultBrowserType": "chromium"
|
||||
},
|
||||
"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": {
|
||||
"width": 1792,
|
||||
"height": 1120
|
||||
|
|
@ -1472,7 +1472,7 @@
|
|||
"defaultBrowserType": "webkit"
|
||||
},
|
||||
"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": {
|
||||
"width": 1920,
|
||||
"height": 1080
|
||||
|
|
@ -1487,7 +1487,7 @@
|
|||
"defaultBrowserType": "chromium"
|
||||
},
|
||||
"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": {
|
||||
"width": 1920,
|
||||
"height": 1080
|
||||
|
|
|
|||
|
|
@ -223,7 +223,7 @@ export class HarTracer {
|
|||
harEntry.response.cookies = this._options.omitCookies ? [] : event.cookies.map(c => {
|
||||
return {
|
||||
...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')
|
||||
cookie.domain = value;
|
||||
if (name === 'Expires')
|
||||
cookie.expires = new Date(value).toISOString();
|
||||
cookie.expires = safeDateToISOString(value);
|
||||
if (name === 'HttpOnly')
|
||||
cookie.httpOnly = true;
|
||||
if (name === 'Max-Age')
|
||||
cookie.expires = new Date(Date.now() + (+value) * 1000).toISOString();
|
||||
cookie.expires = safeDateToISOString(Date.now() + (+value) * 1000);
|
||||
if (name === 'Path')
|
||||
cookie.path = value;
|
||||
if (name === 'SameSite')
|
||||
|
|
@ -673,4 +673,11 @@ function parseCookie(c: string): har.Cookie {
|
|||
return cookie;
|
||||
}
|
||||
|
||||
function safeDateToISOString(value: string | number) {
|
||||
try {
|
||||
return new Date(value).toISOString();
|
||||
} catch (e) {
|
||||
}
|
||||
}
|
||||
|
||||
const startedDateSymbol = Symbol('startedDate');
|
||||
|
|
@ -20,8 +20,6 @@ export type SerializedValue =
|
|||
{ d: string } |
|
||||
{ u: string } |
|
||||
{ bi: string } |
|
||||
{ m: SerializedValue } |
|
||||
{ se: SerializedValue } |
|
||||
{ r: { p: string, f: string} } |
|
||||
{ a: SerializedValue[], id: number } |
|
||||
{ o: { k: string, v: SerializedValue }[], id: number } |
|
||||
|
|
@ -37,14 +35,6 @@ type VisitorInfo = {
|
|||
|
||||
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 {
|
||||
try {
|
||||
return obj instanceof RegExp || Object.prototype.toString.call(obj) === '[object RegExp]';
|
||||
|
|
@ -104,10 +94,6 @@ export function source() {
|
|||
return new URL(value.u);
|
||||
if ('bi' in value)
|
||||
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)
|
||||
return new RegExp(value.r.p, value.r.f);
|
||||
if ('a' in value) {
|
||||
|
|
@ -177,11 +163,6 @@ export function source() {
|
|||
if (typeof value === 'bigint')
|
||||
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)) {
|
||||
const error = value;
|
||||
if (error.stack?.startsWith(error.name + ': ' + error.message)) {
|
||||
|
|
|
|||
|
|
@ -464,6 +464,7 @@ export const deps: any = {
|
|||
'libxtst6'
|
||||
],
|
||||
webkit: [
|
||||
'libsoup-3.0-0',
|
||||
'libenchant-2-2',
|
||||
'gstreamer1.0-libav',
|
||||
'gstreamer1.0-plugins-bad',
|
||||
|
|
@ -521,6 +522,7 @@ export const deps: any = {
|
|||
'libevent-2.1-7',
|
||||
],
|
||||
lib2package: {
|
||||
'libsoup-3.0.so.0': 'libsoup-3.0-0',
|
||||
'libasound.so.2': 'libasound2',
|
||||
'libatk-1.0.so.0': 'libatk1.0-0',
|
||||
'libatk-bridge-2.0.so.0': 'libatk-bridge2.0-0',
|
||||
|
|
@ -885,6 +887,7 @@ export const deps: any = {
|
|||
'libxtst6'
|
||||
],
|
||||
webkit: [
|
||||
'libsoup-3.0-0',
|
||||
'gstreamer1.0-libav',
|
||||
'gstreamer1.0-plugins-bad',
|
||||
'gstreamer1.0-plugins-base',
|
||||
|
|
@ -941,6 +944,7 @@ export const deps: any = {
|
|||
'libevent-2.1-7',
|
||||
],
|
||||
lib2package: {
|
||||
'libsoup-3.0.so.0': 'libsoup-3.0-0',
|
||||
'libasound.so.2': 'libasound2',
|
||||
'libatk-1.0.so.0': 'libatk1.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 type { ConsoleMessage } from '../../console';
|
||||
|
||||
const version: trace.VERSION = 4;
|
||||
const version: trace.VERSION = 5;
|
||||
|
||||
export type TracerOptions = {
|
||||
name?: string;
|
||||
|
|
@ -384,7 +384,9 @@ export class Tracing extends SdkObject implements InstrumentationListener, Snaps
|
|||
onEvent(sdkObject: SdkObject, event: trace.EventTraceEvent) {
|
||||
if (!sdkObject.attribution.context)
|
||||
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.
|
||||
return;
|
||||
}
|
||||
|
|
@ -427,24 +429,12 @@ export class Tracing extends SdkObject implements InstrumentationListener, Snaps
|
|||
}
|
||||
|
||||
private _onConsoleMessage(message: ConsoleMessage) {
|
||||
const object: trace.ConsoleMessageTraceEvent = {
|
||||
type: 'object',
|
||||
class: 'ConsoleMessage',
|
||||
guid: message.guid,
|
||||
initializer: {
|
||||
type: message.type(),
|
||||
text: message.text(),
|
||||
args: message.args().map(a => ({ preview: a.toString(), value: a.rawValue() })),
|
||||
location: message.location(),
|
||||
},
|
||||
};
|
||||
this._appendTraceEvent(object);
|
||||
|
||||
const event: trace.EventTraceEvent = {
|
||||
type: 'event',
|
||||
class: 'BrowserContext',
|
||||
method: 'console',
|
||||
params: { message: { guid: message.guid } },
|
||||
const event: trace.ConsoleMessageTraceEvent = {
|
||||
type: 'console',
|
||||
messageType: message.type(),
|
||||
text: message.text(),
|
||||
args: message.args().map(a => ({ preview: a.toString(), value: a.rawValue() })),
|
||||
location: message.location(),
|
||||
time: monotonicTime(),
|
||||
pageId: message.page().guid,
|
||||
};
|
||||
|
|
@ -476,7 +466,7 @@ export class Tracing extends SdkObject implements InstrumentationListener, Snaps
|
|||
private _appendTraceEvent(event: trace.TraceEvent) {
|
||||
const visited = visitTraceEvent(event, this._state!.traceSha1s);
|
||||
// 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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -74,6 +74,12 @@ export function normalizeEscapedRegexQuotes(source: 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.
|
||||
return String(re).replace(/(^|[^\\])(\\\\)*(["'`])/g, '$1$2\\$3').replace(/>>/g, '\\>\\>');
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@playwright/experimental-ct-core",
|
||||
"version": "1.38.0-next",
|
||||
"version": "1.38.1",
|
||||
"description": "Playwright Component Testing Helpers",
|
||||
"repository": "github:Microsoft/playwright",
|
||||
"homepage": "https://playwright.dev",
|
||||
|
|
@ -24,9 +24,9 @@
|
|||
}
|
||||
},
|
||||
"dependencies": {
|
||||
"playwright-core": "1.38.0-next",
|
||||
"playwright-core": "1.38.1",
|
||||
"vite": "^4.3.9",
|
||||
"playwright": "1.38.0-next"
|
||||
"playwright": "1.38.1"
|
||||
},
|
||||
"bin": {
|
||||
"playwright": "./cli.js"
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@playwright/experimental-ct-react",
|
||||
"version": "1.38.0-next",
|
||||
"version": "1.38.1",
|
||||
"description": "Playwright Component Testing for React",
|
||||
"repository": "github:Microsoft/playwright",
|
||||
"homepage": "https://playwright.dev",
|
||||
|
|
@ -26,7 +26,7 @@
|
|||
}
|
||||
},
|
||||
"dependencies": {
|
||||
"@playwright/experimental-ct-core": "1.38.0-next",
|
||||
"@playwright/experimental-ct-core": "1.38.1",
|
||||
"@vitejs/plugin-react": "^4.0.0"
|
||||
},
|
||||
"bin": {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@playwright/experimental-ct-react17",
|
||||
"version": "1.38.0-next",
|
||||
"version": "1.38.1",
|
||||
"description": "Playwright Component Testing for React",
|
||||
"repository": "github:Microsoft/playwright",
|
||||
"homepage": "https://playwright.dev",
|
||||
|
|
@ -26,7 +26,7 @@
|
|||
}
|
||||
},
|
||||
"dependencies": {
|
||||
"@playwright/experimental-ct-core": "1.38.0-next",
|
||||
"@playwright/experimental-ct-core": "1.38.1",
|
||||
"@vitejs/plugin-react": "^4.0.0"
|
||||
},
|
||||
"bin": {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@playwright/experimental-ct-solid",
|
||||
"version": "1.38.0-next",
|
||||
"version": "1.38.1",
|
||||
"description": "Playwright Component Testing for Solid",
|
||||
"repository": "github:Microsoft/playwright",
|
||||
"homepage": "https://playwright.dev",
|
||||
|
|
@ -26,7 +26,7 @@
|
|||
}
|
||||
},
|
||||
"dependencies": {
|
||||
"@playwright/experimental-ct-core": "1.38.0-next",
|
||||
"@playwright/experimental-ct-core": "1.38.1",
|
||||
"vite-plugin-solid": "^2.7.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@playwright/experimental-ct-svelte",
|
||||
"version": "1.38.0-next",
|
||||
"version": "1.38.1",
|
||||
"description": "Playwright Component Testing for Svelte",
|
||||
"repository": "github:Microsoft/playwright",
|
||||
"homepage": "https://playwright.dev",
|
||||
|
|
@ -26,7 +26,7 @@
|
|||
}
|
||||
},
|
||||
"dependencies": {
|
||||
"@playwright/experimental-ct-core": "1.38.0-next",
|
||||
"@playwright/experimental-ct-core": "1.38.1",
|
||||
"@sveltejs/vite-plugin-svelte": "^2.1.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@playwright/experimental-ct-vue",
|
||||
"version": "1.38.0-next",
|
||||
"version": "1.38.1",
|
||||
"description": "Playwright Component Testing for Vue",
|
||||
"repository": "github:Microsoft/playwright",
|
||||
"homepage": "https://playwright.dev",
|
||||
|
|
@ -26,7 +26,7 @@
|
|||
}
|
||||
},
|
||||
"dependencies": {
|
||||
"@playwright/experimental-ct-core": "1.38.0-next",
|
||||
"@playwright/experimental-ct-core": "1.38.1",
|
||||
"@vitejs/plugin-vue": "^4.2.1"
|
||||
},
|
||||
"bin": {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@playwright/experimental-ct-vue2",
|
||||
"version": "1.38.0-next",
|
||||
"version": "1.38.1",
|
||||
"description": "Playwright Component Testing for Vue2",
|
||||
"repository": "github:Microsoft/playwright",
|
||||
"homepage": "https://playwright.dev",
|
||||
|
|
@ -26,7 +26,7 @@
|
|||
}
|
||||
},
|
||||
"dependencies": {
|
||||
"@playwright/experimental-ct-core": "1.38.0-next",
|
||||
"@playwright/experimental-ct-core": "1.38.1",
|
||||
"@vitejs/plugin-vue2": "^2.2.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "playwright-firefox",
|
||||
"version": "1.38.0-next",
|
||||
"version": "1.38.1",
|
||||
"description": "A high-level API to automate Firefox",
|
||||
"repository": "github:Microsoft/playwright",
|
||||
"homepage": "https://playwright.dev",
|
||||
|
|
@ -27,6 +27,6 @@
|
|||
"install": "node install.js"
|
||||
},
|
||||
"dependencies": {
|
||||
"playwright-core": "1.38.0-next"
|
||||
"playwright-core": "1.38.1"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@playwright/test",
|
||||
"version": "1.38.0-next",
|
||||
"version": "1.38.1",
|
||||
"description": "A high-level API to automate web browsers",
|
||||
"repository": "github:Microsoft/playwright",
|
||||
"homepage": "https://playwright.dev",
|
||||
|
|
@ -25,9 +25,8 @@
|
|||
"bin": {
|
||||
"playwright": "./cli.js"
|
||||
},
|
||||
"scripts": {
|
||||
},
|
||||
"scripts": {},
|
||||
"dependencies": {
|
||||
"playwright": "1.38.0-next"
|
||||
"playwright": "1.38.1"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "playwright-webkit",
|
||||
"version": "1.38.0-next",
|
||||
"version": "1.38.1",
|
||||
"description": "A high-level API to automate WebKit",
|
||||
"repository": "github:Microsoft/playwright",
|
||||
"homepage": "https://playwright.dev",
|
||||
|
|
@ -27,6 +27,6 @@
|
|||
"install": "node install.js"
|
||||
},
|
||||
"dependencies": {
|
||||
"playwright-core": "1.38.0-next"
|
||||
"playwright-core": "1.38.1"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "playwright",
|
||||
"version": "1.38.0-next",
|
||||
"version": "1.38.1",
|
||||
"description": "A high-level API to automate web browsers",
|
||||
"repository": "github:Microsoft/playwright",
|
||||
"homepage": "https://playwright.dev",
|
||||
|
|
@ -51,7 +51,7 @@
|
|||
},
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"playwright-core": "1.38.0-next"
|
||||
"playwright-core": "1.38.1"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"fsevents": "2.3.2"
|
||||
|
|
|
|||
|
|
@ -104,4 +104,8 @@ class ListModeReporter extends EmptyReporter {
|
|||
// eslint-disable-next-line no-console
|
||||
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
|
||||
* [test configuration](https://playwright.dev/docs/test-configuration#expect-options).
|
||||
* Configuration for the `expect` assertion library. Learn more about [various timeouts](https://playwright.dev/docs/test-timeouts).
|
||||
*
|
||||
* **Usage**
|
||||
*
|
||||
|
|
@ -607,7 +606,7 @@ interface TestConfig {
|
|||
* export default defineConfig({
|
||||
* expect: {
|
||||
* timeout: 10000,
|
||||
* toHaveScreenshot: {
|
||||
* toMatchSnapshot: {
|
||||
* maxDiffPixels: 10,
|
||||
* },
|
||||
* },
|
||||
|
|
@ -628,19 +627,19 @@ interface TestConfig {
|
|||
*/
|
||||
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
|
||||
* [YIQ color space](https://en.wikipedia.org/wiki/YIQ) and defaults `threshold` value to `0.2`.
|
||||
*/
|
||||
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;
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
maxDiffPixelRatio?: number;
|
||||
|
|
@ -666,25 +665,25 @@ interface TestConfig {
|
|||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
toMatchSnapshot?: {
|
||||
/**
|
||||
* **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
|
||||
* 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?: 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;
|
||||
|
||||
/**
|
||||
* **Deprecated.** An acceptable ratio of pixels that are different to the total amount of pixels, between `0` and `1`
|
||||
* , unset by default.
|
||||
* an acceptable ratio of pixels that are different to the total amount of pixels, between `0` and `1` , unset by
|
||||
* default.
|
||||
*/
|
||||
maxDiffPixelRatio?: number;
|
||||
};
|
||||
|
|
@ -834,10 +833,8 @@ interface TestConfig {
|
|||
grepInvert?: RegExp|Array<RegExp>;
|
||||
|
||||
/**
|
||||
* Whether to skip snapshot expectations, such as
|
||||
* [pageAssertions.toHaveScreenshot(name[, options])](https://playwright.dev/docs/api/class-pageassertions#page-assertions-to-have-screenshot-1)
|
||||
* and
|
||||
* [snapshotAssertions.toMatchSnapshot(name)](https://playwright.dev/docs/api/class-snapshotassertions#snapshot-assertions-to-match-snapshot-1).
|
||||
* Whether to skip snapshot expectations, such as `expect(value).toMatchSnapshot()` and `await
|
||||
* expect(page).toHaveScreenshot()`.
|
||||
*
|
||||
* **Usage**
|
||||
*
|
||||
|
|
@ -1106,9 +1103,8 @@ interface TestConfig {
|
|||
* [testConfig.snapshotPathTemplate](https://playwright.dev/docs/api/class-testconfig#test-config-snapshot-path-template)
|
||||
* to configure snapshot paths.
|
||||
*
|
||||
* The base directory, relative to the config file, for screenshot files created with
|
||||
* [pageAssertions.toHaveScreenshot(name[, options])](https://playwright.dev/docs/api/class-pageassertions#page-assertions-to-have-screenshot-1).
|
||||
* Defaults to [testConfig.testDir](https://playwright.dev/docs/api/class-testconfig#test-config-test-dir).
|
||||
* The base directory, relative to the config file, for snapshot files created with `toMatchSnapshot`. Defaults to
|
||||
* [testConfig.testDir](https://playwright.dev/docs/api/class-testconfig#test-config-test-dir).
|
||||
*
|
||||
* **Usage**
|
||||
*
|
||||
|
|
@ -1137,7 +1133,7 @@ interface TestConfig {
|
|||
* 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)
|
||||
* 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**
|
||||
*
|
||||
|
|
@ -2271,8 +2267,8 @@ export interface TestInfo {
|
|||
*
|
||||
* 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
|
||||
* [pageAssertions.toHaveScreenshot(name[, options])](https://playwright.dev/docs/api/class-pageassertions#page-assertions-to-have-screenshot-1)
|
||||
* will use different snapshots depending on the platform. Learn more about [snapshots](https://playwright.dev/docs/test-snapshots).
|
||||
* `expect(value).toMatchSnapshot(snapshotName)` will use different snapshots depending on the platform. Learn more
|
||||
* about [snapshots](https://playwright.dev/docs/test-snapshots).
|
||||
*/
|
||||
snapshotSuffix: string;
|
||||
|
||||
|
|
@ -5075,35 +5071,13 @@ type FunctionAssertions = {
|
|||
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 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> =
|
||||
T extends Page ? PageAssertions & AllowedGenericMatchers<R> :
|
||||
T extends Locator ? LocatorAssertions & AllowedGenericMatchers<R> :
|
||||
T extends APIResponse ? APIResponseAssertions & AllowedGenericMatchers<R> :
|
||||
T extends Buffer ? BufferAssertions & GenericAssertions<R> & PlaywrightTest.Matchers<R, T> :
|
||||
T extends Page ? PageAssertions & AllowedGenericMatchers<R, T> :
|
||||
T extends Locator ? LocatorAssertions & AllowedGenericMatchers<R, T> :
|
||||
T extends APIResponse ? APIResponseAssertions & AllowedGenericMatchers<R, T> :
|
||||
BaseMatchers<R, T> & (T extends Function ? FunctionAssertions : {});
|
||||
type AllMatchers<R, T> = PageAssertions & LocatorAssertions & APIResponseAssertions & FunctionAssertions & BaseMatchers<R, T>;
|
||||
|
||||
|
|
@ -6247,40 +6221,19 @@ interface PageAssertions {
|
|||
}
|
||||
|
||||
/**
|
||||
* **NOTE** For visual regression testing, use
|
||||
* [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.
|
||||
* Playwright provides methods for comparing page and element screenshots with expected values stored in files.
|
||||
*
|
||||
* ```js
|
||||
* expect(text).toMatchSnapshot('snapshot.txt');
|
||||
* expect(screenshot).toMatchSnapshot('landing-page.png');
|
||||
* ```
|
||||
*
|
||||
*/
|
||||
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
|
||||
* snapshots directory.
|
||||
*
|
||||
|
|
@ -6288,22 +6241,103 @@ interface SnapshotAssertions {
|
|||
*
|
||||
* ```js
|
||||
* // Basic usage.
|
||||
* expect(await page.title()).toMatchSnapshot();
|
||||
* expect(await page.screenshot()).toMatchSnapshot('landing-page.png');
|
||||
*
|
||||
* // Configure the snapshot name.
|
||||
* expect(await page.title()).toMatchSnapshot({
|
||||
* name: 'page-title.txt',
|
||||
* // Pass options to customize the snapshot comparison and have a generated name.
|
||||
* expect(await page.screenshot()).toMatchSnapshot('landing-page.png', {
|
||||
* 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.
|
||||
* @param 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.
|
||||
*/
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
@ -6439,19 +6473,19 @@ interface TestProject {
|
|||
*/
|
||||
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
|
||||
* [YIQ color space](https://en.wikipedia.org/wiki/YIQ) and defaults `threshold` value to `0.2`.
|
||||
*/
|
||||
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;
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
maxDiffPixelRatio?: number;
|
||||
|
|
@ -6477,25 +6511,25 @@ interface TestProject {
|
|||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
toMatchSnapshot?: {
|
||||
/**
|
||||
* **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
|
||||
* 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?: 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;
|
||||
|
||||
/**
|
||||
* **Deprecated.** An acceptable ratio of pixels that are different to the total amount of pixels, between `0` and `1`
|
||||
* , unset by default.
|
||||
* an acceptable ratio of pixels that are different to the total amount of pixels, between `0` and `1` , unset by
|
||||
* default.
|
||||
*/
|
||||
maxDiffPixelRatio?: number;
|
||||
};
|
||||
|
|
@ -6605,7 +6639,7 @@ interface TestProject {
|
|||
* 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)
|
||||
* 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**
|
||||
*
|
||||
|
|
|
|||
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]
|
||||
* 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.
|
||||
* - `'failed'` - Any test has failed.
|
||||
* - `'timedout'` - The
|
||||
|
|
|
|||
|
|
@ -180,8 +180,6 @@ export type SerializedValue = {
|
|||
d?: string,
|
||||
u?: string,
|
||||
bi?: string,
|
||||
m?: SerializedValue,
|
||||
se?: SerializedValue,
|
||||
r?: {
|
||||
p: string,
|
||||
f: string,
|
||||
|
|
|
|||
|
|
@ -82,10 +82,6 @@ SerializedValue:
|
|||
u: string?
|
||||
# String representation of BigInt.
|
||||
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.
|
||||
r:
|
||||
type: object?
|
||||
|
|
|
|||
|
|
@ -34,9 +34,8 @@ export type ContextEntry = {
|
|||
pages: PageEntry[];
|
||||
resources: ResourceSnapshot[];
|
||||
actions: trace.ActionTraceEvent[];
|
||||
events: trace.EventTraceEvent[];
|
||||
events: (trace.EventTraceEvent | trace.ConsoleMessageTraceEvent)[];
|
||||
stdio: trace.StdioTraceEvent[];
|
||||
initializers: { [key: string]: trace.ConsoleMessageTraceEvent['initializer'] };
|
||||
hasSource: boolean;
|
||||
};
|
||||
|
||||
|
|
@ -65,7 +64,6 @@ export function createEmptyContext(): ContextEntry {
|
|||
actions: [],
|
||||
events: [],
|
||||
stdio: [],
|
||||
initializers: {},
|
||||
hasSource: false
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@
|
|||
|
||||
import type * as trace from '@trace/trace';
|
||||
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 type { ContextEntry, PageEntry } from './entries';
|
||||
import { createEmptyContext } from './entries';
|
||||
|
|
@ -38,6 +39,8 @@ export class TraceModel {
|
|||
private _backend!: TraceModelBackend;
|
||||
private _attachments = new Map<string, trace.AfterActionTraceEventAttachment>();
|
||||
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() {
|
||||
}
|
||||
|
|
@ -112,6 +115,8 @@ export class TraceModel {
|
|||
}
|
||||
|
||||
this._snapshotStorage!.finalize();
|
||||
this._jsHandles.clear();
|
||||
this._consoleObjects.clear();
|
||||
}
|
||||
|
||||
async hasEntry(filename: string): Promise<boolean> {
|
||||
|
|
@ -207,8 +212,8 @@ export class TraceModel {
|
|||
contextEntry!.stdio.push(event);
|
||||
break;
|
||||
}
|
||||
case 'object': {
|
||||
contextEntry!.initializers[event.guid] = event.initializer;
|
||||
case 'console': {
|
||||
contextEntry!.events.push(event);
|
||||
break;
|
||||
}
|
||||
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)
|
||||
return event;
|
||||
const lastVersion: trace.VERSION = 4;
|
||||
for (let version = this._version; version < lastVersion; ++version)
|
||||
const lastVersion: trace.VERSION = 5;
|
||||
for (let version = this._version; version < lastVersion; ++version) {
|
||||
event = (this as any)[`_modernize_${version}_to_${version + 1}`].call(this, event);
|
||||
if (!event)
|
||||
return null;
|
||||
}
|
||||
return event;
|
||||
}
|
||||
|
||||
|
|
@ -284,7 +292,7 @@ export class TraceModel {
|
|||
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') {
|
||||
return event as traceV3.ContextCreatedTraceEvent |
|
||||
traceV3.ScreencastFrameTraceEvent |
|
||||
|
|
@ -335,6 +343,47 @@ export class TraceModel {
|
|||
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) {
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@
|
|||
import type * as channels from '@protocol/channels';
|
||||
import * as React from 'react';
|
||||
import './consoleTab.css';
|
||||
import * as modelUtil from './modelUtil';
|
||||
import type * as modelUtil from './modelUtil';
|
||||
import { ListView } from '@web/components/listView';
|
||||
import type { Boundaries } from '../geometry';
|
||||
import { msToString } from '@web/uiUtils';
|
||||
|
|
@ -51,29 +51,23 @@ export function useConsoleTabModel(model: modelUtil.MultiTraceModel | undefined,
|
|||
return { entries: [] };
|
||||
const entries: ConsoleEntry[] = [];
|
||||
for (const event of model.events) {
|
||||
if (event.method !== 'console' && event.method !== 'pageError')
|
||||
continue;
|
||||
if (event.method === 'console') {
|
||||
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 location = `${filename}:${browserMessage.location.lineNumber}`;
|
||||
if (event.type === 'console') {
|
||||
const body = event.args && event.args.length ? format(event.args) : formatAnsi(event.text);
|
||||
const url = event.location.url;
|
||||
const filename = url ? url.substring(url.lastIndexOf('/') + 1) : '<anonymous>';
|
||||
const location = `${filename}:${event.location.lineNumber}`;
|
||||
|
||||
entries.push({
|
||||
browserMessage: {
|
||||
body,
|
||||
location,
|
||||
},
|
||||
isError: modelUtil.context(event).initializers[guid]?.type === 'error',
|
||||
isWarning: modelUtil.context(event).initializers[guid]?.type === 'warning',
|
||||
timestamp: event.time,
|
||||
});
|
||||
}
|
||||
entries.push({
|
||||
browserMessage: {
|
||||
body,
|
||||
location,
|
||||
},
|
||||
isError: event.messageType === 'error',
|
||||
isWarning: event.messageType === 'warning',
|
||||
timestamp: event.time,
|
||||
});
|
||||
}
|
||||
if (event.method === 'pageError') {
|
||||
if (event.type === 'event' && event.method === 'pageError') {
|
||||
entries.push({
|
||||
browserError: event.params.error,
|
||||
isError: true,
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@
|
|||
import type { Language } from '@isomorphic/locatorGenerators';
|
||||
import type { ResourceSnapshot } from '@trace/snapshot';
|
||||
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';
|
||||
|
||||
const contextSymbol = Symbol('context');
|
||||
|
|
@ -58,7 +58,7 @@ export class MultiTraceModel {
|
|||
readonly options: trace.BrowserContextEventOptions;
|
||||
readonly pages: PageEntry[];
|
||||
readonly actions: ActionTraceEventInContext[];
|
||||
readonly events: trace.EventTraceEvent[];
|
||||
readonly events: (trace.EventTraceEvent | trace.ConsoleMessageTraceEvent)[];
|
||||
readonly stdio: trace.StdioTraceEvent[];
|
||||
readonly hasSource: boolean;
|
||||
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.pages = ([] as PageEntry[]).concat(...contexts.map(c => c.pages));
|
||||
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.hasSource = contexts.some(c => c.hasSource);
|
||||
this.resources = [...contexts.map(c => c.resources)].flat();
|
||||
|
|
@ -203,7 +203,7 @@ export function idForAction(action: ActionTraceEvent) {
|
|||
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];
|
||||
}
|
||||
|
||||
|
|
@ -218,24 +218,22 @@ export function prevInList(action: ActionTraceEvent): ActionTraceEvent {
|
|||
export function stats(action: ActionTraceEvent): { errors: number, warnings: number } {
|
||||
let errors = 0;
|
||||
let warnings = 0;
|
||||
const c = context(action);
|
||||
for (const event of eventsForAction(action)) {
|
||||
if (event.method === 'console') {
|
||||
const { guid } = event.params.message;
|
||||
const type = c.initializers[guid]?.type;
|
||||
if (event.type === 'console') {
|
||||
const type = event.messageType;
|
||||
if (type === 'warning')
|
||||
++warnings;
|
||||
else if (type === 'error')
|
||||
++errors;
|
||||
}
|
||||
if (event.method === 'pageError')
|
||||
if (event.type === 'event' && event.method === 'pageError')
|
||||
++errors;
|
||||
}
|
||||
return { errors, warnings };
|
||||
}
|
||||
|
||||
export function eventsForAction(action: ActionTraceEvent): EventTraceEvent[] {
|
||||
let result: EventTraceEvent[] = (action as any)[eventsSymbol];
|
||||
export function eventsForAction(action: ActionTraceEvent): (trace.EventTraceEvent | trace.ConsoleMessageTraceEvent)[] {
|
||||
let result: (trace.EventTraceEvent | trace.ConsoleMessageTraceEvent)[] = (action as any)[eventsSymbol];
|
||||
if (result)
|
||||
return result;
|
||||
|
||||
|
|
|
|||
|
|
@ -40,5 +40,5 @@
|
|||
}
|
||||
|
||||
.network-request-details .cm-wrapper {
|
||||
height: 300px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -123,6 +123,7 @@
|
|||
|
||||
.filter-list {
|
||||
padding: 0 10px 10px 10px;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.filter-title,
|
||||
|
|
|
|||
|
|
@ -190,11 +190,22 @@ export const UIModeView: React.FC<{}> = ({
|
|||
}, [closeInstallDialog]);
|
||||
|
||||
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'>
|
||||
<div className='title'>UI Mode disconnected</div>
|
||||
<div><a href='#' onClick={() => window.location.reload()}>Reload the page</a> to reconnect</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' + (isShowingOutput ? '' : ' hidden')}>
|
||||
<Toolbar>
|
||||
|
|
@ -216,19 +227,7 @@ export const UIModeView: React.FC<{}> = ({
|
|||
<ToolbarButton icon='color-mode' title='Toggle color mode' onClick={() => toggleTheme()} />
|
||||
<ToolbarButton icon='refresh' title='Reload' onClick={() => reloadTests()} disabled={isRunningTest || isLoading}></ToolbarButton>
|
||||
<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}>
|
||||
<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>}
|
||||
{!hasBrowsers && <ToolbarButton icon='lightbulb-autofix' style={{ color: 'var(--vscode-list-warningForeground)' }} title='Playwright browsers are missing' onClick={openInstallDialog} />}
|
||||
</Toolbar>
|
||||
<FiltersView
|
||||
filterText={filterText}
|
||||
|
|
@ -335,7 +334,7 @@ const FiltersView: React.FC<{
|
|||
if (configFile)
|
||||
settings.setObject(configFile + ':projects', [...copy.entries()].filter(([_, v]) => v).map(([k]) => k));
|
||||
}}/>
|
||||
<div>{projectName}</div>
|
||||
<div>{projectName || 'untitled'}</div>
|
||||
</label>
|
||||
</div>;
|
||||
})}
|
||||
|
|
|
|||
|
|
@ -193,7 +193,7 @@ export const Workbench: React.FunctionComponent<{
|
|||
selectedTime={selectedTime}
|
||||
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'>
|
||||
<SnapshotTab
|
||||
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 };
|
||||
|
||||
// Make sure you add _modernize_N_to_N1(event: any) to traceModel.ts.
|
||||
export type VERSION = 4;
|
||||
export type VERSION = 5;
|
||||
|
||||
export type BrowserContextEventOptions = {
|
||||
viewport?: Size,
|
||||
|
|
@ -103,19 +103,17 @@ export type EventTraceEvent = {
|
|||
};
|
||||
|
||||
export type ConsoleMessageTraceEvent = {
|
||||
type: 'object';
|
||||
class: string;
|
||||
initializer: {
|
||||
type: string,
|
||||
text: string,
|
||||
args?: { preview: string, value: any }[],
|
||||
location: {
|
||||
url: string,
|
||||
lineNumber: number,
|
||||
columnNumber: number,
|
||||
},
|
||||
};
|
||||
guid: string;
|
||||
type: 'console';
|
||||
time: number;
|
||||
pageId?: string;
|
||||
messageType: string,
|
||||
text: string,
|
||||
args?: { preview: string, value: any }[],
|
||||
location: {
|
||||
url: string,
|
||||
lineNumber: number,
|
||||
columnNumber: number,
|
||||
},
|
||||
};
|
||||
|
||||
export type ResourceSnapshotTraceEvent = {
|
||||
|
|
|
|||
|
|
@ -79,6 +79,7 @@ dialog .title .codicon {
|
|||
|
||||
dialog .body {
|
||||
padding: 10px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.button {
|
||||
|
|
@ -89,6 +90,7 @@ dialog .body {
|
|||
height: 28px;
|
||||
min-width: 40px;
|
||||
cursor: pointer;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.button:focus {
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@
|
|||
font-weight: var(--vscode-editor-font-weight);
|
||||
font-size: var(--vscode-editor-font-size);
|
||||
background-color: var(--vscode-inputValidation-errorBackground);
|
||||
white-space: pre;
|
||||
white-space: pre-wrap;
|
||||
word-break: break-word;
|
||||
padding: 10px;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -39,8 +39,8 @@ export const SplitView: React.FC<SplitViewProps> = ({
|
|||
settingName,
|
||||
children
|
||||
}) => {
|
||||
const [hSize, setHSize] = 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));
|
||||
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) * window.devicePixelRatio);
|
||||
const [resizing, setResizing] = React.useState<{ offset: number, size: number } | null>(null);
|
||||
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 type { ActionTreeItem } 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> {
|
||||
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 traceModel = new TraceModel();
|
||||
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());
|
||||
});
|
||||
|
||||
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.fixme(browserName === 'webkit', 'We get "name1=val, ue1, name2=val, ue2" as a header value');
|
||||
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']);
|
||||
});
|
||||
|
||||
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 }) => {
|
||||
const html = `
|
||||
<body>
|
||||
|
|
|
|||
|
|
@ -739,7 +739,7 @@ test('should flush console events on tracing stop', async ({ context, page }, te
|
|||
const tracePath = testInfo.outputPath('trace.zip');
|
||||
await context.tracing.stop({ path: 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);
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -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.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 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 }) => {
|
||||
|
|
|
|||
|
|
@ -99,14 +99,9 @@ it('should transfer bigint', async ({ page }) => {
|
|||
expect(await page.evaluate(a => a, 17n)).toBe(17n);
|
||||
});
|
||||
|
||||
it('should transfer maps', async ({ page }) => {
|
||||
expect(await page.evaluate(() => new Map([[1, { test: 42n }]]))).toEqual(new Map([[1, { test: 42n }]]));
|
||||
expect(await page.evaluate(a => a, new Map([[1, { test: 17n }]]))).toEqual(new Map([[1, { test: 17n }]]));
|
||||
});
|
||||
|
||||
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 transfer maps as empty objects', async ({ page }) => {
|
||||
const result = await page.evaluate(a => a.x.constructor.name + ' ' + JSON.stringify(a.x), { x: new Map([[1, 2]]) });
|
||||
expect(result).toBe('Object {}');
|
||||
});
|
||||
|
||||
it('should modify global environment', async ({ page }) => {
|
||||
|
|
|
|||
|
|
@ -272,11 +272,21 @@ test('should work with custom PlaywrightTest namespace', async ({ runTSC }) => {
|
|||
}
|
||||
`,
|
||||
'a.spec.ts': `
|
||||
import { test, expect } from '@playwright/test';
|
||||
import { test, expect, type Page, type APIResponse } from '@playwright/test';
|
||||
test.expect.extend({
|
||||
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('hello').not.toBeEmpty();
|
||||
test.expect([]).toBeEmpty();
|
||||
|
|
|
|||
|
|
@ -96,20 +96,8 @@ test('should compile with different option combinations', async ({ runTSC }) =>
|
|||
import { test, expect } from '@playwright/test';
|
||||
test('is a test', async ({ page }) => {
|
||||
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 });
|
||||
// @ts-expect-error
|
||||
expect('foo').toMatchSnapshot({ maxDiffPixelRatio: 0.2 });
|
||||
// @ts-expect-error
|
||||
expect('foo').toMatchSnapshot({ maxDiffPixels: 0.2 });
|
||||
});
|
||||
`
|
||||
|
|
|
|||
|
|
@ -196,3 +196,21 @@ test('should report errors with location', async ({ runInlineTest }) => {
|
|||
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.stringContaining',
|
||||
'GenericAssertions.stringMatching',
|
||||
'SnapshotAssertions.toMatchSnapshot#3',
|
||||
'SnapshotAssertions.toMatchSnapshot#4',
|
||||
]),
|
||||
overridesToDocsClassMapping: new Map([
|
||||
['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>;
|
||||
};
|
||||
|
||||
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 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> =
|
||||
T extends Page ? PageAssertions & AllowedGenericMatchers<R> :
|
||||
T extends Locator ? LocatorAssertions & AllowedGenericMatchers<R> :
|
||||
T extends APIResponse ? APIResponseAssertions & AllowedGenericMatchers<R> :
|
||||
T extends Buffer ? BufferAssertions & GenericAssertions<R> & PlaywrightTest.Matchers<R, T> :
|
||||
T extends Page ? PageAssertions & AllowedGenericMatchers<R, T> :
|
||||
T extends Locator ? LocatorAssertions & AllowedGenericMatchers<R, T> :
|
||||
T extends APIResponse ? APIResponseAssertions & AllowedGenericMatchers<R, T> :
|
||||
BaseMatchers<R, T> & (T extends Function ? FunctionAssertions : {});
|
||||
type AllMatchers<R, T> = PageAssertions & LocatorAssertions & APIResponseAssertions & FunctionAssertions & BaseMatchers<R, T>;
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue