Compare commits
14 commits
main
...
release-1.
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b9e9f4dfaa | ||
|
|
bb1da5ec1e | ||
|
|
5965143b73 | ||
|
|
38fe4a5102 | ||
|
|
95614581db | ||
|
|
41c6aaf426 | ||
|
|
abd4258080 | ||
|
|
14782d7a6b | ||
|
|
baa6aa9f63 | ||
|
|
de23a1b3d2 | ||
|
|
28d4804a70 | ||
|
|
cce4550cb1 | ||
|
|
263ae4028a | ||
|
|
9177bd1614 |
|
|
@ -1002,38 +1002,54 @@ Property value.
|
||||||
### option: LocatorAssertions.toHaveJSProperty.timeout = %%-csharp-java-python-assertions-timeout-%%
|
### option: LocatorAssertions.toHaveJSProperty.timeout = %%-csharp-java-python-assertions-timeout-%%
|
||||||
|
|
||||||
|
|
||||||
## async method: LocatorAssertions.toHaveScreenshot
|
## async method: LocatorAssertions.toHaveScreenshot#1
|
||||||
* langs: js
|
* langs: js
|
||||||
|
|
||||||
Ensures that [Locator] resolves to a given screenshot. This function will re-take
|
This function will wait until two consecutive locator screenshots
|
||||||
screenshots until it matches with the saved expectation.
|
yield the same result, and then compare the last screenshot with the expectation.
|
||||||
|
|
||||||
If there's no expectation yet, it will wait until two consecutive screenshots
|
```js
|
||||||
yield the same result, and save the last one as an expectation.
|
const locator = page.locator('button');
|
||||||
|
await expect(locator).toHaveScreenshot('image.png');
|
||||||
|
```
|
||||||
|
|
||||||
|
### param: LocatorAssertions.toHaveScreenshot#1.name
|
||||||
|
- `name` <[string]|[Array]<[string]>>
|
||||||
|
|
||||||
|
Snapshot name.
|
||||||
|
|
||||||
|
### option: LocatorAssertions.toHaveScreenshot#1.timeout = %%-js-assertions-timeout-%%
|
||||||
|
### option: LocatorAssertions.toHaveScreenshot#1.animations = %%-screenshot-option-animations-default-disabled-%%
|
||||||
|
|
||||||
|
### option: LocatorAssertions.toHaveScreenshot#1.caret = %%-screenshot-option-caret-%%
|
||||||
|
### option: LocatorAssertions.toHaveScreenshot#1.mask = %%-screenshot-option-mask-%%
|
||||||
|
### option: LocatorAssertions.toHaveScreenshot#1.omitBackground = %%-screenshot-option-omit-background-%%
|
||||||
|
### option: LocatorAssertions.toHaveScreenshot#1.scale = %%-screenshot-option-scale-default-css-%%
|
||||||
|
### option: LocatorAssertions.toHaveScreenshot#1.maxDiffPixels = %%-assertions-max-diff-pixels-%%
|
||||||
|
### option: LocatorAssertions.toHaveScreenshot#1.maxDiffPixelRatio = %%-assertions-max-diff-pixel-ratio-%%
|
||||||
|
### option: LocatorAssertions.toHaveScreenshot#1.threshold = %%-assertions-threshold-%%
|
||||||
|
|
||||||
|
## async method: LocatorAssertions.toHaveScreenshot#2
|
||||||
|
* langs: js
|
||||||
|
|
||||||
|
This function will wait until two consecutive locator screenshots
|
||||||
|
yield the same result, and then compare the last screenshot with the expectation.
|
||||||
|
|
||||||
```js
|
```js
|
||||||
const locator = page.locator('button');
|
const locator = page.locator('button');
|
||||||
await expect(locator).toHaveScreenshot();
|
await expect(locator).toHaveScreenshot();
|
||||||
```
|
```
|
||||||
|
|
||||||
### option: LocatorAssertions.toHaveScreenshot.timeout = %%-js-assertions-timeout-%%
|
### option: LocatorAssertions.toHaveScreenshot#2.timeout = %%-js-assertions-timeout-%%
|
||||||
### option: LocatorAssertions.toHaveScreenshot.timeout = %%-csharp-java-python-assertions-timeout-%%
|
### option: LocatorAssertions.toHaveScreenshot#2.animations = %%-screenshot-option-animations-default-disabled-%%
|
||||||
|
|
||||||
### option: LocatorAssertions.toHaveScreenshot.animations = %%-screenshot-option-animations-%%
|
### option: LocatorAssertions.toHaveScreenshot#2.caret = %%-screenshot-option-caret-%%
|
||||||
|
### option: LocatorAssertions.toHaveScreenshot#2.mask = %%-screenshot-option-mask-%%
|
||||||
### option: LocatorAssertions.toHaveScreenshot.caret = %%-screenshot-option-caret-%%
|
### option: LocatorAssertions.toHaveScreenshot#2.omitBackground = %%-screenshot-option-omit-background-%%
|
||||||
|
### option: LocatorAssertions.toHaveScreenshot#2.scale = %%-screenshot-option-scale-default-css-%%
|
||||||
### option: LocatorAssertions.toHaveScreenshot.mask = %%-screenshot-option-mask-%%
|
### option: LocatorAssertions.toHaveScreenshot#2.maxDiffPixels = %%-assertions-max-diff-pixels-%%
|
||||||
|
### option: LocatorAssertions.toHaveScreenshot#2.maxDiffPixelRatio = %%-assertions-max-diff-pixel-ratio-%%
|
||||||
### option: LocatorAssertions.toHaveScreenshot.omitBackground = %%-screenshot-option-omit-background-%%
|
### option: LocatorAssertions.toHaveScreenshot#2.threshold = %%-assertions-threshold-%%
|
||||||
|
|
||||||
### option: LocatorAssertions.toHaveScreenshot.scale = %%-screenshot-option-scale-%%
|
|
||||||
|
|
||||||
### option: LocatorAssertions.toHaveScreenshot.maxDiffPixels = %%-assertions-max-diff-pixels-%%
|
|
||||||
|
|
||||||
### option: LocatorAssertions.toHaveScreenshot.maxDiffPixelRatio = %%-assertions-max-diff-pixel-ratio-%%
|
|
||||||
|
|
||||||
### option: LocatorAssertions.toHaveScreenshot.threshold = %%-assertions-threshold-%%
|
|
||||||
|
|
||||||
|
|
||||||
## async method: LocatorAssertions.toHaveText
|
## async method: LocatorAssertions.toHaveText
|
||||||
|
|
|
||||||
|
|
@ -114,41 +114,55 @@ Expected substring or RegExp.
|
||||||
### option: PageAssertions.NotToHaveURL.timeout = %%-csharp-java-python-assertions-timeout-%%
|
### option: PageAssertions.NotToHaveURL.timeout = %%-csharp-java-python-assertions-timeout-%%
|
||||||
|
|
||||||
|
|
||||||
## async method: PageAssertions.toHaveScreenshot
|
## async method: PageAssertions.toHaveScreenshot#1
|
||||||
* langs: js
|
* langs: js
|
||||||
|
|
||||||
Ensures that the page resolves to a given screenshot. This function will re-take
|
This function will wait until two consecutive page screenshots
|
||||||
screenshots until it matches with the saved expectation.
|
yield the same result, and then compare the last screenshot with the expectation.
|
||||||
|
|
||||||
If there's no expectation yet, it will wait until two consecutive screenshots
|
```js
|
||||||
yield the same result, and save the last one as an expectation.
|
await expect(page).toHaveScreenshot('image.png');
|
||||||
|
```
|
||||||
|
|
||||||
|
### param: PageAssertions.toHaveScreenshot#1.name
|
||||||
|
- `name` <[string]|[Array]<[string]>>
|
||||||
|
|
||||||
|
Snapshot name.
|
||||||
|
|
||||||
|
### option: PageAssertions.toHaveScreenshot#1.timeout = %%-js-assertions-timeout-%%
|
||||||
|
### option: PageAssertions.toHaveScreenshot#1.animations = %%-screenshot-option-animations-default-disabled-%%
|
||||||
|
### option: PageAssertions.toHaveScreenshot#1.caret = %%-screenshot-option-caret-%%
|
||||||
|
### option: PageAssertions.toHaveScreenshot#1.clip = %%-screenshot-option-clip-%%
|
||||||
|
### option: PageAssertions.toHaveScreenshot#1.fullPage = %%-screenshot-option-full-page-%%
|
||||||
|
### option: PageAssertions.toHaveScreenshot#1.mask = %%-screenshot-option-mask-%%
|
||||||
|
### option: PageAssertions.toHaveScreenshot#1.omitBackground = %%-screenshot-option-omit-background-%%
|
||||||
|
### option: PageAssertions.toHaveScreenshot#1.scale = %%-screenshot-option-scale-default-css-%%
|
||||||
|
### option: PageAssertions.toHaveScreenshot#1.maxDiffPixels = %%-assertions-max-diff-pixels-%%
|
||||||
|
### option: PageAssertions.toHaveScreenshot#1.maxDiffPixelRatio = %%-assertions-max-diff-pixel-ratio-%%
|
||||||
|
### option: PageAssertions.toHaveScreenshot#1.threshold = %%-assertions-threshold-%%
|
||||||
|
|
||||||
|
|
||||||
|
## async method: PageAssertions.toHaveScreenshot#2
|
||||||
|
* langs: js
|
||||||
|
|
||||||
|
This function will wait until two consecutive page screenshots
|
||||||
|
yield the same result, and then compare the last screenshot with the expectation.
|
||||||
|
|
||||||
```js
|
```js
|
||||||
await expect(page).toHaveScreenshot();
|
await expect(page).toHaveScreenshot();
|
||||||
```
|
```
|
||||||
|
|
||||||
### option: PageAssertions.toHaveScreenshot.timeout = %%-js-assertions-timeout-%%
|
### option: PageAssertions.toHaveScreenshot#2.timeout = %%-js-assertions-timeout-%%
|
||||||
### option: PageAssertions.toHaveScreenshot.timeout = %%-csharp-java-python-assertions-timeout-%%
|
### option: PageAssertions.toHaveScreenshot#2.animations = %%-screenshot-option-animations-default-disabled-%%
|
||||||
|
### option: PageAssertions.toHaveScreenshot#2.caret = %%-screenshot-option-caret-%%
|
||||||
### option: PageAssertions.toHaveScreenshot.animations = %%-screenshot-option-animations-%%
|
### option: PageAssertions.toHaveScreenshot#2.clip = %%-screenshot-option-clip-%%
|
||||||
|
### option: PageAssertions.toHaveScreenshot#2.fullPage = %%-screenshot-option-full-page-%%
|
||||||
### option: PageAssertions.toHaveScreenshot.caret = %%-screenshot-option-caret-%%
|
### option: PageAssertions.toHaveScreenshot#2.mask = %%-screenshot-option-mask-%%
|
||||||
|
### option: PageAssertions.toHaveScreenshot#2.omitBackground = %%-screenshot-option-omit-background-%%
|
||||||
### option: PageAssertions.toHaveScreenshot.clip = %%-screenshot-option-clip-%%
|
### option: PageAssertions.toHaveScreenshot#2.scale = %%-screenshot-option-scale-default-css-%%
|
||||||
|
### option: PageAssertions.toHaveScreenshot#2.maxDiffPixels = %%-assertions-max-diff-pixels-%%
|
||||||
### option: PageAssertions.toHaveScreenshot.fullPage = %%-screenshot-option-full-page-%%
|
### option: PageAssertions.toHaveScreenshot#2.maxDiffPixelRatio = %%-assertions-max-diff-pixel-ratio-%%
|
||||||
|
### option: PageAssertions.toHaveScreenshot#2.threshold = %%-assertions-threshold-%%
|
||||||
### option: PageAssertions.toHaveScreenshot.mask = %%-screenshot-option-mask-%%
|
|
||||||
|
|
||||||
### option: PageAssertions.toHaveScreenshot.omitBackground = %%-screenshot-option-omit-background-%%
|
|
||||||
|
|
||||||
### option: PageAssertions.toHaveScreenshot.scale = %%-screenshot-option-scale-%%
|
|
||||||
|
|
||||||
### option: PageAssertions.toHaveScreenshot.maxDiffPixels = %%-assertions-max-diff-pixels-%%
|
|
||||||
|
|
||||||
### option: PageAssertions.toHaveScreenshot.maxDiffPixelRatio = %%-assertions-max-diff-pixel-ratio-%%
|
|
||||||
|
|
||||||
### option: PageAssertions.toHaveScreenshot.threshold = %%-assertions-threshold-%%
|
|
||||||
|
|
||||||
|
|
||||||
## async method: PageAssertions.toHaveTitle
|
## async method: PageAssertions.toHaveTitle
|
||||||
|
|
|
||||||
|
|
@ -910,6 +910,15 @@ When set to `"disabled"`, stops CSS animations, CSS transitions and Web Animatio
|
||||||
|
|
||||||
Defaults to `"allow"` that leaves animations untouched.
|
Defaults to `"allow"` that leaves animations untouched.
|
||||||
|
|
||||||
|
## screenshot-option-animations-default-disabled
|
||||||
|
- `animations` <[ScreenshotAnimations]<"disabled"|"allow">>
|
||||||
|
|
||||||
|
When set to `"disabled"`, stops CSS animations, CSS transitions and Web Animations. Animations get different treatment depending on their duration:
|
||||||
|
* finite animations are fast-forwarded to completion, so they'll fire `transitionend` event.
|
||||||
|
* infinite animations are canceled to initial state, and then played over after the screenshot.
|
||||||
|
|
||||||
|
Defaults to `"disabled"` that disables animations.
|
||||||
|
|
||||||
## screenshot-option-omit-background
|
## screenshot-option-omit-background
|
||||||
- `omitBackground` <[boolean]>
|
- `omitBackground` <[boolean]>
|
||||||
|
|
||||||
|
|
@ -957,7 +966,16 @@ An object which specifies clipping of the resulting image. Should have the follo
|
||||||
## screenshot-option-scale
|
## screenshot-option-scale
|
||||||
- `scale` <[ScreenshotScale]<"css"|"device">>
|
- `scale` <[ScreenshotScale]<"css"|"device">>
|
||||||
|
|
||||||
When set to `"css"`, screenshot will have a single pixel per each css pixel on the page. For high-dpi devices, this will keep screenshots small. Using `"device"` option will produce a single pixel per each device pixel, so screenhots of high-dpi devices will be twice as large or even larger. Defaults to `"device"`.
|
When set to `"css"`, screenshot will have a single pixel per each css pixel on the page. For high-dpi devices, this will keep screenshots small. Using `"device"` option will produce a single pixel per each device pixel, so screenhots of high-dpi devices will be twice as large or even larger.
|
||||||
|
|
||||||
|
Defaults to `"device"`.
|
||||||
|
|
||||||
|
## screenshot-option-scale-default-css
|
||||||
|
- `scale` <[ScreenshotScale]<"css"|"device">>
|
||||||
|
|
||||||
|
When set to `"css"`, screenshot will have a single pixel per each css pixel on the page. For high-dpi devices, this will keep screenshots small. Using `"device"` option will produce a single pixel per each device pixel, so screenhots of high-dpi devices will be twice as large or even larger.
|
||||||
|
|
||||||
|
Defaults to `"css"`.
|
||||||
|
|
||||||
## screenshot-option-caret
|
## screenshot-option-caret
|
||||||
- `caret` <[ScreenshotCaret]<"hide"|"initial">>
|
- `caret` <[ScreenshotCaret]<"hide"|"initial">>
|
||||||
|
|
|
||||||
|
|
@ -143,7 +143,7 @@ Alternatively, you can use [Command line tools](./cli.md#install-system-dependen
|
||||||
pool:
|
pool:
|
||||||
vmImage: 'ubuntu-20.04'
|
vmImage: 'ubuntu-20.04'
|
||||||
|
|
||||||
container: mcr.microsoft.com/playwright:v1.22.0-focal
|
container: mcr.microsoft.com/playwright:v1.22.2-focal
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
...
|
...
|
||||||
|
|
@ -157,7 +157,7 @@ Running Playwright on CircleCI requires the following steps:
|
||||||
|
|
||||||
```yml
|
```yml
|
||||||
docker:
|
docker:
|
||||||
- image: mcr.microsoft.com/playwright:v1.22.0-focal
|
- image: mcr.microsoft.com/playwright:v1.22.2-focal
|
||||||
environment:
|
environment:
|
||||||
NODE_ENV: development # Needed if playwright is in `devDependencies`
|
NODE_ENV: development # Needed if playwright is in `devDependencies`
|
||||||
```
|
```
|
||||||
|
|
@ -179,7 +179,7 @@ to run tests on Jenkins.
|
||||||
|
|
||||||
```groovy
|
```groovy
|
||||||
pipeline {
|
pipeline {
|
||||||
agent { docker { image 'mcr.microsoft.com/playwright:v1.22.0-focal' } }
|
agent { docker { image 'mcr.microsoft.com/playwright:v1.22.2-focal' } }
|
||||||
stages {
|
stages {
|
||||||
stage('e2e-tests') {
|
stage('e2e-tests') {
|
||||||
steps {
|
steps {
|
||||||
|
|
@ -196,7 +196,7 @@ pipeline {
|
||||||
Bitbucket Pipelines can use public [Docker images as build environments](https://confluence.atlassian.com/bitbucket/use-docker-images-as-build-environments-792298897.html). To run Playwright tests on Bitbucket, use our public Docker image ([see Dockerfile](./docker.md)).
|
Bitbucket Pipelines can use public [Docker images as build environments](https://confluence.atlassian.com/bitbucket/use-docker-images-as-build-environments-792298897.html). To run Playwright tests on Bitbucket, use our public Docker image ([see Dockerfile](./docker.md)).
|
||||||
|
|
||||||
```yml
|
```yml
|
||||||
image: mcr.microsoft.com/playwright:v1.22.0-focal
|
image: mcr.microsoft.com/playwright:v1.22.2-focal
|
||||||
```
|
```
|
||||||
|
|
||||||
### GitLab CI
|
### GitLab CI
|
||||||
|
|
@ -209,7 +209,7 @@ stages:
|
||||||
|
|
||||||
tests:
|
tests:
|
||||||
stage: test
|
stage: test
|
||||||
image: mcr.microsoft.com/playwright:v1.22.0-focal
|
image: mcr.microsoft.com/playwright:v1.22.2-focal
|
||||||
script:
|
script:
|
||||||
...
|
...
|
||||||
```
|
```
|
||||||
|
|
|
||||||
|
|
@ -14,19 +14,19 @@ This image is published on [Docker Hub].
|
||||||
### Pull the image
|
### Pull the image
|
||||||
|
|
||||||
```bash js
|
```bash js
|
||||||
docker pull mcr.microsoft.com/playwright:v1.22.0-focal
|
docker pull mcr.microsoft.com/playwright:v1.22.2-focal
|
||||||
```
|
```
|
||||||
|
|
||||||
```bash python
|
```bash python
|
||||||
docker pull mcr.microsoft.com/playwright/python:v1.22.0-focal
|
docker pull mcr.microsoft.com/playwright/python:v1.22.2-focal
|
||||||
```
|
```
|
||||||
|
|
||||||
```bash csharp
|
```bash csharp
|
||||||
docker pull mcr.microsoft.com/playwright/dotnet:v1.22.0-focal
|
docker pull mcr.microsoft.com/playwright/dotnet:v1.22.2-focal
|
||||||
```
|
```
|
||||||
|
|
||||||
```bash java
|
```bash java
|
||||||
docker pull mcr.microsoft.com/playwright/java:v1.22.0-focal
|
docker pull mcr.microsoft.com/playwright/java:v1.22.2-focal
|
||||||
```
|
```
|
||||||
|
|
||||||
### Run the image
|
### Run the image
|
||||||
|
|
@ -38,19 +38,19 @@ By default, the Docker image will use the `root` user to run the browsers. This
|
||||||
On trusted websites, you can avoid creating a separate user and use root for it since you trust the code which will run on the browsers.
|
On trusted websites, you can avoid creating a separate user and use root for it since you trust the code which will run on the browsers.
|
||||||
|
|
||||||
```bash js
|
```bash js
|
||||||
docker run -it --rm --ipc=host mcr.microsoft.com/playwright:v1.22.0-focal /bin/bash
|
docker run -it --rm --ipc=host mcr.microsoft.com/playwright:v1.22.2-focal /bin/bash
|
||||||
```
|
```
|
||||||
|
|
||||||
```bash python
|
```bash python
|
||||||
docker run -it --rm --ipc=host mcr.microsoft.com/playwright/python:v1.22.0-focal /bin/bash
|
docker run -it --rm --ipc=host mcr.microsoft.com/playwright/python:v1.22.2-focal /bin/bash
|
||||||
```
|
```
|
||||||
|
|
||||||
```bash csharp
|
```bash csharp
|
||||||
docker run -it --rm --ipc=host mcr.microsoft.com/playwright/dotnet:v1.22.0-focal /bin/bash
|
docker run -it --rm --ipc=host mcr.microsoft.com/playwright/dotnet:v1.22.2-focal /bin/bash
|
||||||
```
|
```
|
||||||
|
|
||||||
```bash java
|
```bash java
|
||||||
docker run -it --rm --ipc=host mcr.microsoft.com/playwright/java:v1.22.0-focal /bin/bash
|
docker run -it --rm --ipc=host mcr.microsoft.com/playwright/java:v1.22.2-focal /bin/bash
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Crawling and scraping
|
#### Crawling and scraping
|
||||||
|
|
@ -58,19 +58,19 @@ docker run -it --rm --ipc=host mcr.microsoft.com/playwright/java:v1.22.0-focal /
|
||||||
On untrusted websites, it's recommended to use a separate user for launching the browsers in combination with the seccomp profile. Inside the container or if you are using the Docker image as a base image you have to use `adduser` for it.
|
On untrusted websites, it's recommended to use a separate user for launching the browsers in combination with the seccomp profile. Inside the container or if you are using the Docker image as a base image you have to use `adduser` for it.
|
||||||
|
|
||||||
```bash js
|
```bash js
|
||||||
docker run -it --rm --ipc=host --user pwuser --security-opt seccomp=seccomp_profile.json mcr.microsoft.com/playwright:v1.22.0-focal /bin/bash
|
docker run -it --rm --ipc=host --user pwuser --security-opt seccomp=seccomp_profile.json mcr.microsoft.com/playwright:v1.22.2-focal /bin/bash
|
||||||
```
|
```
|
||||||
|
|
||||||
```bash python
|
```bash python
|
||||||
docker run -it --rm --ipc=host --user pwuser --security-opt seccomp=seccomp_profile.json mcr.microsoft.com/playwright/python:v1.22.0-focal /bin/bash
|
docker run -it --rm --ipc=host --user pwuser --security-opt seccomp=seccomp_profile.json mcr.microsoft.com/playwright/python:v1.22.2-focal /bin/bash
|
||||||
```
|
```
|
||||||
|
|
||||||
```bash csharp
|
```bash csharp
|
||||||
docker run -it --rm --ipc=host --user pwuser --security-opt seccomp=seccomp_profile.json mcr.microsoft.com/playwright/dotnet:v1.22.0-focal /bin/bash
|
docker run -it --rm --ipc=host --user pwuser --security-opt seccomp=seccomp_profile.json mcr.microsoft.com/playwright/dotnet:v1.22.2-focal /bin/bash
|
||||||
```
|
```
|
||||||
|
|
||||||
```bash java
|
```bash java
|
||||||
docker run -it --rm --ipc=host --user pwuser --security-opt seccomp=seccomp_profile.json mcr.microsoft.com/playwright/java:v1.22.0-focal /bin/bash
|
docker run -it --rm --ipc=host --user pwuser --security-opt seccomp=seccomp_profile.json mcr.microsoft.com/playwright/java:v1.22.2-focal /bin/bash
|
||||||
```
|
```
|
||||||
|
|
||||||
[`seccomp_profile.json`](https://github.com/microsoft/playwright/blob/main/utils/docker/seccomp_profile.json) is needed to run Chromium with sandbox. This is a [default Docker seccomp profile](https://github.com/docker/engine/blob/d0d99b04cf6e00ed3fc27e81fc3d94e7eda70af3/profiles/seccomp/default.json) with extra user namespace cloning permissions:
|
[`seccomp_profile.json`](https://github.com/microsoft/playwright/blob/main/utils/docker/seccomp_profile.json) is needed to run Chromium with sandbox. This is a [default Docker seccomp profile](https://github.com/docker/engine/blob/d0d99b04cf6e00ed3fc27e81fc3d94e7eda70af3/profiles/seccomp/default.json) with extra user namespace cloning permissions:
|
||||||
|
|
|
||||||
|
|
@ -59,7 +59,7 @@ title: "Release notes"
|
||||||
await submitButton.click();
|
await submitButton.click();
|
||||||
```
|
```
|
||||||
|
|
||||||
- New web-first assertions [`method: PageAssertions.toHaveScreenshot`] and [`method: LocatorAssertions.toHaveScreenshot`] that
|
- New web-first assertions [`method: PageAssertions.toHaveScreenshot#1`] and [`method: LocatorAssertions.toHaveScreenshot#1`] that
|
||||||
wait for screenshot stabilization and enhances test reliability.
|
wait for screenshot stabilization and enhances test reliability.
|
||||||
|
|
||||||
The new assertions has screenshot-specific defaults, such as:
|
The new assertions has screenshot-specific defaults, such as:
|
||||||
|
|
@ -71,7 +71,7 @@ title: "Release notes"
|
||||||
await expect(page).toHaveScreenshot();
|
await expect(page).toHaveScreenshot();
|
||||||
```
|
```
|
||||||
|
|
||||||
The new [`method: PageAssertions.toHaveScreenshot`] saves screenshots at the same
|
The new [`method: PageAssertions.toHaveScreenshot#1`] saves screenshots at the same
|
||||||
location as [`method: ScreenshotAssertions.toMatchSnapshot#1`].
|
location as [`method: ScreenshotAssertions.toMatchSnapshot#1`].
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -36,11 +36,11 @@ export default config;
|
||||||
## property: TestConfig.expect
|
## property: TestConfig.expect
|
||||||
- type: ?<[Object]>
|
- type: ?<[Object]>
|
||||||
- `timeout` ?<[int]> Default timeout for async expect matchers in milliseconds, defaults to 5000ms.
|
- `timeout` ?<[int]> Default timeout for async expect matchers in milliseconds, defaults to 5000ms.
|
||||||
- `toHaveScreenshot` ?<[Object]> Configuration for the [`method: PageAssertions.toHaveScreenshot`] method.
|
- `toHaveScreenshot` ?<[Object]> Configuration for the [`method: PageAssertions.toHaveScreenshot#1`] method.
|
||||||
- `threshold` ?<[float]> 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). Defaults to `0.2`.
|
- `threshold` ?<[float]> 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). Defaults to `0.2`.
|
||||||
- `maxDiffPixels` ?<[int]> an acceptable amount of pixels that could be different, unset by default.
|
- `maxDiffPixels` ?<[int]> an acceptable amount of pixels that could be different, unset by default.
|
||||||
- `maxDiffPixelRatio` ?<[float]> an acceptable ratio of pixels that are different to the total amount of pixels, between `0` and `1` , unset by default.
|
- `maxDiffPixelRatio` ?<[float]> an acceptable ratio of pixels that are different to the total amount of pixels, between `0` and `1` , unset by default.
|
||||||
- `animations` ?<[ScreenshotAnimations]<"allow"|"disable">> See [`option: animations`] in [`method: Page.screenshot`]. Defaults to `"disable"`.
|
- `animations` ?<[ScreenshotAnimations]<"allow"|"disabled">> See [`option: animations`] in [`method: Page.screenshot`]. Defaults to `"disabled"`.
|
||||||
- `caret` ?<[ScreenshotCaret]<"hide"|"initial">> See [`option: caret`] in [`method: Page.screenshot`]. Defaults to `"hide"`.
|
- `caret` ?<[ScreenshotCaret]<"hide"|"initial">> See [`option: caret`] in [`method: Page.screenshot`]. Defaults to `"hide"`.
|
||||||
- `scale` ?<[ScreenshotScale]<"css"|"device">> See [`option: scale`] in [`method: Page.screenshot`]. Defaults to `"css"`.
|
- `scale` ?<[ScreenshotScale]<"css"|"device">> See [`option: scale`] in [`method: Page.screenshot`]. Defaults to `"css"`.
|
||||||
- `toMatchSnapshot` ?<[Object]> Configuration for the [`method: ScreenshotAssertions.toMatchSnapshot#1`] method.
|
- `toMatchSnapshot` ?<[Object]> Configuration for the [`method: ScreenshotAssertions.toMatchSnapshot#1`] method.
|
||||||
|
|
@ -419,7 +419,7 @@ export default config;
|
||||||
* experimental
|
* experimental
|
||||||
- type: ?<[string]>
|
- type: ?<[string]>
|
||||||
|
|
||||||
The base directory, relative to the config file, for screenshot files created with [`method: PageAssertions.toHaveScreenshot`]. Defaults to
|
The base directory, relative to the config file, for screenshot files created with [`method: PageAssertions.toHaveScreenshot#1`]. Defaults to
|
||||||
|
|
||||||
```
|
```
|
||||||
<directory-of-configuration-file>/__screenshots__/<platform name>/<project name>
|
<directory-of-configuration-file>/__screenshots__/<platform name>/<project name>
|
||||||
|
|
|
||||||
|
|
@ -107,11 +107,11 @@ export default config;
|
||||||
## property: TestProject.expect
|
## property: TestProject.expect
|
||||||
- type: ?<[Object]>
|
- type: ?<[Object]>
|
||||||
- `timeout` ?<[int]> Default timeout for async expect matchers in milliseconds, defaults to 5000ms.
|
- `timeout` ?<[int]> Default timeout for async expect matchers in milliseconds, defaults to 5000ms.
|
||||||
- `toHaveScreenshot` ?<[Object]> Configuration for the [`method: PageAssertions.toHaveScreenshot`] method.
|
- `toHaveScreenshot` ?<[Object]> Configuration for the [`method: PageAssertions.toHaveScreenshot#1`] method.
|
||||||
- `threshold` ?<[float]> 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). Defaults to `0.2`.
|
- `threshold` ?<[float]> 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). Defaults to `0.2`.
|
||||||
- `maxDiffPixels` ?<[int]> an acceptable amount of pixels that could be different, unset by default.
|
- `maxDiffPixels` ?<[int]> an acceptable amount of pixels that could be different, unset by default.
|
||||||
- `maxDiffPixelRatio` ?<[float]> an acceptable ratio of pixels that are different to the total amount of pixels, between `0` and `1` , unset by default.
|
- `maxDiffPixelRatio` ?<[float]> an acceptable ratio of pixels that are different to the total amount of pixels, between `0` and `1` , unset by default.
|
||||||
- `animations` ?<[ScreenshotAnimations]<"allow"|"disable">> See [`option: animations`] in [`method: Page.screenshot`]. Defaults to `"disable"`.
|
- `animations` ?<[ScreenshotAnimations]<"allow"|"disabled">> See [`option: animations`] in [`method: Page.screenshot`]. Defaults to `"disabled"`.
|
||||||
- `caret` ?<[ScreenshotCaret]<"hide"|"initial">> See [`option: caret`] in [`method: Page.screenshot`]. Defaults to `"hide"`.
|
- `caret` ?<[ScreenshotCaret]<"hide"|"initial">> See [`option: caret`] in [`method: Page.screenshot`]. Defaults to `"hide"`.
|
||||||
- `scale` ?<[ScreenshotScale]<"css"|"device">> See [`option: scale`] in [`method: Page.screenshot`]. Defaults to `"css"`.
|
- `scale` ?<[ScreenshotScale]<"css"|"device">> See [`option: scale`] in [`method: Page.screenshot`]. Defaults to `"css"`.
|
||||||
- `toMatchSnapshot` ?<[Object]> Configuration for the [`method: ScreenshotAssertions.toMatchSnapshot#1`] method.
|
- `toMatchSnapshot` ?<[Object]> Configuration for the [`method: ScreenshotAssertions.toMatchSnapshot#1`] method.
|
||||||
|
|
|
||||||
|
|
@ -56,7 +56,7 @@ The snapshot name `example-test-1-chromium-darwin.png` consists of a few parts:
|
||||||
If you are not on the same operating system as your CI system, you can use Docker to generate/update the screenshots:
|
If you are not on the same operating system as your CI system, you can use Docker to generate/update the screenshots:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
docker run --rm --network host -v $(pwd):/work/ -w /work/ -it mcr.microsoft.com/playwright:v1.22.0-focal /bin/bash
|
docker run --rm --network host -v $(pwd):/work/ -w /work/ -it mcr.microsoft.com/playwright:v1.22.2-focal /bin/bash
|
||||||
npm install
|
npm install
|
||||||
npx playwright test --update-snapshots
|
npx playwright test --update-snapshots
|
||||||
```
|
```
|
||||||
|
|
|
||||||
60
package-lock.json
generated
60
package-lock.json
generated
|
|
@ -1,12 +1,12 @@
|
||||||
{
|
{
|
||||||
"name": "playwright-internal",
|
"name": "playwright-internal",
|
||||||
"version": "1.22.0-next",
|
"version": "1.22.2",
|
||||||
"lockfileVersion": 2,
|
"lockfileVersion": 2,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "playwright-internal",
|
"name": "playwright-internal",
|
||||||
"version": "1.22.0-next",
|
"version": "1.22.2",
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"workspaces": [
|
"workspaces": [
|
||||||
"packages/*"
|
"packages/*"
|
||||||
|
|
@ -981,8 +981,7 @@
|
||||||
"node_modules/@types/node": {
|
"node_modules/@types/node": {
|
||||||
"version": "14.17.15",
|
"version": "14.17.15",
|
||||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-14.17.15.tgz",
|
"resolved": "https://registry.npmjs.org/@types/node/-/node-14.17.15.tgz",
|
||||||
"integrity": "sha512-D1sdW0EcSCmNdLKBGMYb38YsHUS6JcM7yQ6sLQ9KuZ35ck7LYCKE7kYFHOO59ayFOY3zobWVZxf4KXhYHcHYFA==",
|
"integrity": "sha512-D1sdW0EcSCmNdLKBGMYb38YsHUS6JcM7yQ6sLQ9KuZ35ck7LYCKE7kYFHOO59ayFOY3zobWVZxf4KXhYHcHYFA=="
|
||||||
"dev": true
|
|
||||||
},
|
},
|
||||||
"node_modules/@types/normalize-package-data": {
|
"node_modules/@types/normalize-package-data": {
|
||||||
"version": "2.4.1",
|
"version": "2.4.1",
|
||||||
|
|
@ -5668,11 +5667,11 @@
|
||||||
"version": "0.0.0"
|
"version": "0.0.0"
|
||||||
},
|
},
|
||||||
"packages/playwright": {
|
"packages/playwright": {
|
||||||
"version": "1.22.0-next",
|
"version": "1.22.2",
|
||||||
"hasInstallScript": true,
|
"hasInstallScript": true,
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"playwright-core": "1.22.0-next"
|
"playwright-core": "1.22.2"
|
||||||
},
|
},
|
||||||
"bin": {
|
"bin": {
|
||||||
"playwright": "cli.js"
|
"playwright": "cli.js"
|
||||||
|
|
@ -5682,11 +5681,11 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"packages/playwright-chromium": {
|
"packages/playwright-chromium": {
|
||||||
"version": "1.22.0-next",
|
"version": "1.22.2",
|
||||||
"hasInstallScript": true,
|
"hasInstallScript": true,
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"playwright-core": "1.22.0-next"
|
"playwright-core": "1.22.2"
|
||||||
},
|
},
|
||||||
"bin": {
|
"bin": {
|
||||||
"playwright": "cli.js"
|
"playwright": "cli.js"
|
||||||
|
|
@ -5696,7 +5695,7 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"packages/playwright-core": {
|
"packages/playwright-core": {
|
||||||
"version": "1.22.0-next",
|
"version": "1.22.2",
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"bin": {
|
"bin": {
|
||||||
"playwright": "cli.js"
|
"playwright": "cli.js"
|
||||||
|
|
@ -5707,10 +5706,10 @@
|
||||||
},
|
},
|
||||||
"packages/playwright-ct-react": {
|
"packages/playwright-ct-react": {
|
||||||
"name": "@playwright/experimental-ct-react",
|
"name": "@playwright/experimental-ct-react",
|
||||||
"version": "1.22.0-next",
|
"version": "1.22.2",
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@playwright/test": "1.22.0-next",
|
"@playwright/test": "1.22.2",
|
||||||
"@vitejs/plugin-react": "^1.0.7",
|
"@vitejs/plugin-react": "^1.0.7",
|
||||||
"vite": "^2.9.5"
|
"vite": "^2.9.5"
|
||||||
},
|
},
|
||||||
|
|
@ -5720,10 +5719,10 @@
|
||||||
},
|
},
|
||||||
"packages/playwright-ct-svelte": {
|
"packages/playwright-ct-svelte": {
|
||||||
"name": "@playwright/experimental-ct-svelte",
|
"name": "@playwright/experimental-ct-svelte",
|
||||||
"version": "1.22.0-next",
|
"version": "1.22.2",
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@playwright/test": "1.22.0-next",
|
"@playwright/test": "1.22.2",
|
||||||
"@sveltejs/vite-plugin-svelte": "^1.0.0-next.30",
|
"@sveltejs/vite-plugin-svelte": "^1.0.0-next.30",
|
||||||
"vite": "^2.9.5"
|
"vite": "^2.9.5"
|
||||||
},
|
},
|
||||||
|
|
@ -5733,10 +5732,10 @@
|
||||||
},
|
},
|
||||||
"packages/playwright-ct-vue": {
|
"packages/playwright-ct-vue": {
|
||||||
"name": "@playwright/experimental-ct-vue",
|
"name": "@playwright/experimental-ct-vue",
|
||||||
"version": "1.22.0-next",
|
"version": "1.22.2",
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@playwright/test": "1.22.0-next",
|
"@playwright/test": "1.22.2",
|
||||||
"@vitejs/plugin-vue": "^2.3.1",
|
"@vitejs/plugin-vue": "^2.3.1",
|
||||||
"vite": "^2.9.5"
|
"vite": "^2.9.5"
|
||||||
},
|
},
|
||||||
|
|
@ -5745,11 +5744,11 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"packages/playwright-firefox": {
|
"packages/playwright-firefox": {
|
||||||
"version": "1.22.0-next",
|
"version": "1.22.2",
|
||||||
"hasInstallScript": true,
|
"hasInstallScript": true,
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"playwright-core": "1.22.0-next"
|
"playwright-core": "1.22.2"
|
||||||
},
|
},
|
||||||
"bin": {
|
"bin": {
|
||||||
"playwright": "cli.js"
|
"playwright": "cli.js"
|
||||||
|
|
@ -5760,10 +5759,10 @@
|
||||||
},
|
},
|
||||||
"packages/playwright-test": {
|
"packages/playwright-test": {
|
||||||
"name": "@playwright/test",
|
"name": "@playwright/test",
|
||||||
"version": "1.22.0-next",
|
"version": "1.22.2",
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"playwright-core": "1.22.0-next"
|
"playwright-core": "1.22.2"
|
||||||
},
|
},
|
||||||
"bin": {
|
"bin": {
|
||||||
"playwright": "cli.js"
|
"playwright": "cli.js"
|
||||||
|
|
@ -5773,11 +5772,11 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"packages/playwright-webkit": {
|
"packages/playwright-webkit": {
|
||||||
"version": "1.22.0-next",
|
"version": "1.22.2",
|
||||||
"hasInstallScript": true,
|
"hasInstallScript": true,
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"playwright-core": "1.22.0-next"
|
"playwright-core": "1.22.2"
|
||||||
},
|
},
|
||||||
"bin": {
|
"bin": {
|
||||||
"playwright": "cli.js"
|
"playwright": "cli.js"
|
||||||
|
|
@ -6385,7 +6384,7 @@
|
||||||
"@playwright/experimental-ct-react": {
|
"@playwright/experimental-ct-react": {
|
||||||
"version": "file:packages/playwright-ct-react",
|
"version": "file:packages/playwright-ct-react",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@playwright/test": "1.22.0-next",
|
"@playwright/test": "1.22.2",
|
||||||
"@vitejs/plugin-react": "^1.0.7",
|
"@vitejs/plugin-react": "^1.0.7",
|
||||||
"vite": "^2.9.5"
|
"vite": "^2.9.5"
|
||||||
}
|
}
|
||||||
|
|
@ -6393,7 +6392,7 @@
|
||||||
"@playwright/experimental-ct-svelte": {
|
"@playwright/experimental-ct-svelte": {
|
||||||
"version": "file:packages/playwright-ct-svelte",
|
"version": "file:packages/playwright-ct-svelte",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@playwright/test": "1.22.0-next",
|
"@playwright/test": "1.22.2",
|
||||||
"@sveltejs/vite-plugin-svelte": "^1.0.0-next.30",
|
"@sveltejs/vite-plugin-svelte": "^1.0.0-next.30",
|
||||||
"vite": "^2.9.5"
|
"vite": "^2.9.5"
|
||||||
}
|
}
|
||||||
|
|
@ -6401,7 +6400,7 @@
|
||||||
"@playwright/experimental-ct-vue": {
|
"@playwright/experimental-ct-vue": {
|
||||||
"version": "file:packages/playwright-ct-vue",
|
"version": "file:packages/playwright-ct-vue",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@playwright/test": "1.22.0-next",
|
"@playwright/test": "1.22.2",
|
||||||
"@vitejs/plugin-vue": "^2.3.1",
|
"@vitejs/plugin-vue": "^2.3.1",
|
||||||
"vite": "^2.9.5"
|
"vite": "^2.9.5"
|
||||||
}
|
}
|
||||||
|
|
@ -6409,7 +6408,7 @@
|
||||||
"@playwright/test": {
|
"@playwright/test": {
|
||||||
"version": "file:packages/playwright-test",
|
"version": "file:packages/playwright-test",
|
||||||
"requires": {
|
"requires": {
|
||||||
"playwright-core": "1.22.0-next"
|
"playwright-core": "1.22.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@rollup/pluginutils": {
|
"@rollup/pluginutils": {
|
||||||
|
|
@ -6466,8 +6465,7 @@
|
||||||
"@types/node": {
|
"@types/node": {
|
||||||
"version": "14.17.15",
|
"version": "14.17.15",
|
||||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-14.17.15.tgz",
|
"resolved": "https://registry.npmjs.org/@types/node/-/node-14.17.15.tgz",
|
||||||
"integrity": "sha512-D1sdW0EcSCmNdLKBGMYb38YsHUS6JcM7yQ6sLQ9KuZ35ck7LYCKE7kYFHOO59ayFOY3zobWVZxf4KXhYHcHYFA==",
|
"integrity": "sha512-D1sdW0EcSCmNdLKBGMYb38YsHUS6JcM7yQ6sLQ9KuZ35ck7LYCKE7kYFHOO59ayFOY3zobWVZxf4KXhYHcHYFA=="
|
||||||
"dev": true
|
|
||||||
},
|
},
|
||||||
"@types/normalize-package-data": {
|
"@types/normalize-package-data": {
|
||||||
"version": "2.4.1",
|
"version": "2.4.1",
|
||||||
|
|
@ -8968,13 +8966,13 @@
|
||||||
"playwright": {
|
"playwright": {
|
||||||
"version": "file:packages/playwright",
|
"version": "file:packages/playwright",
|
||||||
"requires": {
|
"requires": {
|
||||||
"playwright-core": "1.22.0-next"
|
"playwright-core": "1.22.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"playwright-chromium": {
|
"playwright-chromium": {
|
||||||
"version": "file:packages/playwright-chromium",
|
"version": "file:packages/playwright-chromium",
|
||||||
"requires": {
|
"requires": {
|
||||||
"playwright-core": "1.22.0-next"
|
"playwright-core": "1.22.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"playwright-core": {
|
"playwright-core": {
|
||||||
|
|
@ -8983,13 +8981,13 @@
|
||||||
"playwright-firefox": {
|
"playwright-firefox": {
|
||||||
"version": "file:packages/playwright-firefox",
|
"version": "file:packages/playwright-firefox",
|
||||||
"requires": {
|
"requires": {
|
||||||
"playwright-core": "1.22.0-next"
|
"playwright-core": "1.22.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"playwright-webkit": {
|
"playwright-webkit": {
|
||||||
"version": "file:packages/playwright-webkit",
|
"version": "file:packages/playwright-webkit",
|
||||||
"requires": {
|
"requires": {
|
||||||
"playwright-core": "1.22.0-next"
|
"playwright-core": "1.22.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"postcss": {
|
"postcss": {
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
{
|
{
|
||||||
"name": "playwright-internal",
|
"name": "playwright-internal",
|
||||||
"private": true,
|
"private": true,
|
||||||
"version": "1.22.0-next",
|
"version": "1.22.2",
|
||||||
"description": "A high-level API to automate web browsers",
|
"description": "A high-level API to automate web browsers",
|
||||||
"repository": "github:Microsoft/playwright",
|
"repository": "github:Microsoft/playwright",
|
||||||
"homepage": "https://playwright.dev",
|
"homepage": "https://playwright.dev",
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "playwright-chromium",
|
"name": "playwright-chromium",
|
||||||
"version": "1.22.0-next",
|
"version": "1.22.2",
|
||||||
"description": "A high-level API to automate Chromium",
|
"description": "A high-level API to automate Chromium",
|
||||||
"repository": "github:Microsoft/playwright",
|
"repository": "github:Microsoft/playwright",
|
||||||
"homepage": "https://playwright.dev",
|
"homepage": "https://playwright.dev",
|
||||||
|
|
@ -13,6 +13,7 @@
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"exports": {
|
"exports": {
|
||||||
".": {
|
".": {
|
||||||
|
"types": "./index.d.ts",
|
||||||
"import": "./index.mjs",
|
"import": "./index.mjs",
|
||||||
"require": "./index.js"
|
"require": "./index.js"
|
||||||
},
|
},
|
||||||
|
|
@ -26,6 +27,6 @@
|
||||||
"install": "node install.js"
|
"install": "node install.js"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"playwright-core": "1.22.0-next"
|
"playwright-core": "1.22.2"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "playwright-core",
|
"name": "playwright-core",
|
||||||
"version": "1.22.0-next",
|
"version": "1.22.2",
|
||||||
"description": "A high-level API to automate web browsers",
|
"description": "A high-level API to automate web browsers",
|
||||||
"repository": "github:Microsoft/playwright",
|
"repository": "github:Microsoft/playwright",
|
||||||
"homepage": "https://playwright.dev",
|
"homepage": "https://playwright.dev",
|
||||||
|
|
@ -13,6 +13,7 @@
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"exports": {
|
"exports": {
|
||||||
".": {
|
".": {
|
||||||
|
"types": "./index.d.ts",
|
||||||
"import": "./index.mjs",
|
"import": "./index.mjs",
|
||||||
"require": "./index.js"
|
"require": "./index.js"
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -674,7 +674,7 @@ export class InjectedScript {
|
||||||
|
|
||||||
const activeElement = (node.getRootNode() as (Document | ShadowRoot)).activeElement;
|
const activeElement = (node.getRootNode() as (Document | ShadowRoot)).activeElement;
|
||||||
const wasFocused = activeElement === node && node.ownerDocument && node.ownerDocument.hasFocus();
|
const wasFocused = activeElement === node && node.ownerDocument && node.ownerDocument.hasFocus();
|
||||||
if (!wasFocused && activeElement && (activeElement as HTMLElement | SVGElement).blur) {
|
if ((node as HTMLElement).isContentEditable && !wasFocused && activeElement && (activeElement as HTMLElement | SVGElement).blur) {
|
||||||
// Workaround the Firefox bug where focusing the element does not switch current
|
// Workaround the Firefox bug where focusing the element does not switch current
|
||||||
// contenteditable to the new element. However, blurring the previous one helps.
|
// contenteditable to the new element. However, blurring the previous one helps.
|
||||||
(activeElement as HTMLElement | SVGElement).blur();
|
(activeElement as HTMLElement | SVGElement).blur();
|
||||||
|
|
|
||||||
12
packages/playwright-core/types/types.d.ts
vendored
12
packages/playwright-core/types/types.d.ts
vendored
|
|
@ -8202,7 +8202,9 @@ export interface ElementHandle<T=Node> extends JSHandle<T> {
|
||||||
/**
|
/**
|
||||||
* When set to `"css"`, screenshot will have a single pixel per each css pixel on the page. For high-dpi devices, this will
|
* When set to `"css"`, screenshot will have a single pixel per each css pixel on the page. For high-dpi devices, this will
|
||||||
* keep screenshots small. Using `"device"` option will produce a single pixel per each device pixel, so screenhots of
|
* keep screenshots small. Using `"device"` option will produce a single pixel per each device pixel, so screenhots of
|
||||||
* high-dpi devices will be twice as large or even larger. Defaults to `"device"`.
|
* high-dpi devices will be twice as large or even larger.
|
||||||
|
*
|
||||||
|
* Defaults to `"device"`.
|
||||||
*/
|
*/
|
||||||
scale?: "css"|"device";
|
scale?: "css"|"device";
|
||||||
|
|
||||||
|
|
@ -15844,7 +15846,9 @@ export interface LocatorScreenshotOptions {
|
||||||
/**
|
/**
|
||||||
* When set to `"css"`, screenshot will have a single pixel per each css pixel on the page. For high-dpi devices, this will
|
* When set to `"css"`, screenshot will have a single pixel per each css pixel on the page. For high-dpi devices, this will
|
||||||
* keep screenshots small. Using `"device"` option will produce a single pixel per each device pixel, so screenhots of
|
* keep screenshots small. Using `"device"` option will produce a single pixel per each device pixel, so screenhots of
|
||||||
* high-dpi devices will be twice as large or even larger. Defaults to `"device"`.
|
* high-dpi devices will be twice as large or even larger.
|
||||||
|
*
|
||||||
|
* Defaults to `"device"`.
|
||||||
*/
|
*/
|
||||||
scale?: "css"|"device";
|
scale?: "css"|"device";
|
||||||
|
|
||||||
|
|
@ -16027,7 +16031,9 @@ export interface PageScreenshotOptions {
|
||||||
/**
|
/**
|
||||||
* When set to `"css"`, screenshot will have a single pixel per each css pixel on the page. For high-dpi devices, this will
|
* When set to `"css"`, screenshot will have a single pixel per each css pixel on the page. For high-dpi devices, this will
|
||||||
* keep screenshots small. Using `"device"` option will produce a single pixel per each device pixel, so screenhots of
|
* keep screenshots small. Using `"device"` option will produce a single pixel per each device pixel, so screenhots of
|
||||||
* high-dpi devices will be twice as large or even larger. Defaults to `"device"`.
|
* high-dpi devices will be twice as large or even larger.
|
||||||
|
*
|
||||||
|
* Defaults to `"device"`.
|
||||||
*/
|
*/
|
||||||
scale?: "css"|"device";
|
scale?: "css"|"device";
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "@playwright/experimental-ct-react",
|
"name": "@playwright/experimental-ct-react",
|
||||||
"version": "1.22.0-next",
|
"version": "1.22.2",
|
||||||
"description": "Playwright Component Testing for React",
|
"description": "Playwright Component Testing for React",
|
||||||
"repository": "github:Microsoft/playwright",
|
"repository": "github:Microsoft/playwright",
|
||||||
"homepage": "https://playwright.dev",
|
"homepage": "https://playwright.dev",
|
||||||
|
|
@ -12,12 +12,18 @@
|
||||||
},
|
},
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"exports": {
|
"exports": {
|
||||||
"./register": "./register.mjs",
|
".": {
|
||||||
".": "./index.js"
|
"types": "./index.d.ts",
|
||||||
|
"default": "./index.js"
|
||||||
|
},
|
||||||
|
"./register": {
|
||||||
|
"types": "./register.d.ts",
|
||||||
|
"default": "./register.mjs"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@vitejs/plugin-react": "^1.0.7",
|
"@vitejs/plugin-react": "^1.0.7",
|
||||||
"@playwright/test": "1.22.0-next",
|
"@playwright/test": "1.22.2",
|
||||||
"vite": "^2.9.5"
|
"vite": "^2.9.5"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "@playwright/experimental-ct-svelte",
|
"name": "@playwright/experimental-ct-svelte",
|
||||||
"version": "1.22.0-next",
|
"version": "1.22.2",
|
||||||
"description": "Playwright Component Testing for Svelte",
|
"description": "Playwright Component Testing for Svelte",
|
||||||
"repository": "github:Microsoft/playwright",
|
"repository": "github:Microsoft/playwright",
|
||||||
"homepage": "https://playwright.dev",
|
"homepage": "https://playwright.dev",
|
||||||
|
|
@ -12,12 +12,18 @@
|
||||||
},
|
},
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"exports": {
|
"exports": {
|
||||||
"./register": "./register.mjs",
|
".": {
|
||||||
".": "./index.js"
|
"types": "./index.d.ts",
|
||||||
|
"default": "./index.js"
|
||||||
|
},
|
||||||
|
"./register": {
|
||||||
|
"types": "./register.d.ts",
|
||||||
|
"default": "./register.mjs"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@sveltejs/vite-plugin-svelte": "^1.0.0-next.30",
|
"@sveltejs/vite-plugin-svelte": "^1.0.0-next.30",
|
||||||
"@playwright/test": "1.22.0-next",
|
"@playwright/test": "1.22.2",
|
||||||
"vite": "^2.9.5"
|
"vite": "^2.9.5"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "@playwright/experimental-ct-vue",
|
"name": "@playwright/experimental-ct-vue",
|
||||||
"version": "1.22.0-next",
|
"version": "1.22.2",
|
||||||
"description": "Playwright Component Testing for Vue",
|
"description": "Playwright Component Testing for Vue",
|
||||||
"repository": "github:Microsoft/playwright",
|
"repository": "github:Microsoft/playwright",
|
||||||
"homepage": "https://playwright.dev",
|
"homepage": "https://playwright.dev",
|
||||||
|
|
@ -12,12 +12,18 @@
|
||||||
},
|
},
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"exports": {
|
"exports": {
|
||||||
"./register": "./register.mjs",
|
".": {
|
||||||
".": "./index.js"
|
"types": "./index.d.ts",
|
||||||
|
"default": "./index.js"
|
||||||
|
},
|
||||||
|
"./register": {
|
||||||
|
"types": "./register.d.ts",
|
||||||
|
"default": "./register.mjs"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@vitejs/plugin-vue": "^2.3.1",
|
"@vitejs/plugin-vue": "^2.3.1",
|
||||||
"@playwright/test": "1.22.0-next",
|
"@playwright/test": "1.22.2",
|
||||||
"vite": "^2.9.5"
|
"vite": "^2.9.5"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "playwright-firefox",
|
"name": "playwright-firefox",
|
||||||
"version": "1.22.0-next",
|
"version": "1.22.2",
|
||||||
"description": "A high-level API to automate Firefox",
|
"description": "A high-level API to automate Firefox",
|
||||||
"repository": "github:Microsoft/playwright",
|
"repository": "github:Microsoft/playwright",
|
||||||
"homepage": "https://playwright.dev",
|
"homepage": "https://playwright.dev",
|
||||||
|
|
@ -13,6 +13,7 @@
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"exports": {
|
"exports": {
|
||||||
".": {
|
".": {
|
||||||
|
"types": "./index.d.ts",
|
||||||
"import": "./index.mjs",
|
"import": "./index.mjs",
|
||||||
"require": "./index.js"
|
"require": "./index.js"
|
||||||
},
|
},
|
||||||
|
|
@ -26,6 +27,6 @@
|
||||||
"install": "node install.js"
|
"install": "node install.js"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"playwright-core": "1.22.0-next"
|
"playwright-core": "1.22.2"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "@playwright/test",
|
"name": "@playwright/test",
|
||||||
"version": "1.22.0-next",
|
"version": "1.22.2",
|
||||||
"description": "A high-level API to automate web browsers",
|
"description": "A high-level API to automate web browsers",
|
||||||
"repository": "github:Microsoft/playwright",
|
"repository": "github:Microsoft/playwright",
|
||||||
"homepage": "https://playwright.dev",
|
"homepage": "https://playwright.dev",
|
||||||
|
|
@ -10,6 +10,7 @@
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
"exports": {
|
"exports": {
|
||||||
".": {
|
".": {
|
||||||
|
"types": "./index.d.ts",
|
||||||
"import": "./index.mjs",
|
"import": "./index.mjs",
|
||||||
"require": "./index.js"
|
"require": "./index.js"
|
||||||
},
|
},
|
||||||
|
|
@ -31,6 +32,7 @@
|
||||||
},
|
},
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"playwright-core": "1.22.0-next"
|
"@types/node": "*",
|
||||||
|
"playwright-core": "1.22.2"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -14,35 +14,47 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import type { Fixtures, Locator, Page, PlaywrightTestArgs, PlaywrightTestOptions, PlaywrightWorkerArgs } from './types';
|
import type { Fixtures, Locator, Page, BrowserContextOptions, PlaywrightTestArgs, PlaywrightTestOptions, PlaywrightWorkerArgs } from './types';
|
||||||
|
|
||||||
let boundCallbacksForMount: Function[] = [];
|
let boundCallbacksForMount: Function[] = [];
|
||||||
|
|
||||||
export const fixtures: Fixtures<PlaywrightTestArgs & PlaywrightTestOptions & { mount: (component: any, options: any) => Promise<Locator> }, PlaywrightWorkerArgs & { _workerPage: Page }> = {
|
export const fixtures: Fixtures<PlaywrightTestArgs & PlaywrightTestOptions & { mount: (component: any, options: any) => Promise<Locator> }, PlaywrightWorkerArgs & { _ctPage: { page: Page | undefined, hash: string } }> = {
|
||||||
_workerPage: [async ({ browser }, use) => {
|
_ctPage: [{ page: undefined, hash: '' }, { scope: 'worker' }],
|
||||||
|
|
||||||
|
context: async ({ page }, use) => {
|
||||||
|
await use(page.context());
|
||||||
|
},
|
||||||
|
|
||||||
|
page: async ({ _ctPage, browser, viewport, playwright }, use) => {
|
||||||
|
const defaultContextOptions = (playwright.chromium as any)._defaultContextOptions as BrowserContextOptions;
|
||||||
|
const hash = contextHash(defaultContextOptions);
|
||||||
|
|
||||||
|
if (!_ctPage.page || _ctPage.hash !== hash) {
|
||||||
|
if (_ctPage.page)
|
||||||
|
await _ctPage.page.close();
|
||||||
const page = await (browser as any)._wrapApiCall(async () => {
|
const page = await (browser as any)._wrapApiCall(async () => {
|
||||||
const page = await browser.newPage();
|
const page = await browser.newPage();
|
||||||
await page.addInitScript('navigator.serviceWorker.register = () => {}');
|
await page.addInitScript('navigator.serviceWorker.register = () => {}');
|
||||||
await page.exposeFunction('__pw_dispatch', (ordinal: number, args: any[]) => {
|
await page.exposeFunction('__pw_dispatch', (ordinal: number, args: any[]) => {
|
||||||
boundCallbacksForMount[ordinal](...args);
|
boundCallbacksForMount[ordinal](...args);
|
||||||
});
|
});
|
||||||
|
await page.goto(process.env.PLAYWRIGHT_VITE_COMPONENTS_BASE_URL!);
|
||||||
return page;
|
return page;
|
||||||
});
|
}, true);
|
||||||
|
_ctPage.page = page;
|
||||||
|
_ctPage.hash = hash;
|
||||||
await use(page);
|
await use(page);
|
||||||
}, { scope: 'worker' }],
|
} else {
|
||||||
|
const page = _ctPage.page;
|
||||||
context: async ({ page }, use) => {
|
await (page as any)._wrapApiCall(async () => {
|
||||||
await use(page.context());
|
|
||||||
},
|
|
||||||
|
|
||||||
page: async ({ _workerPage, viewport }, use) => {
|
|
||||||
const page = _workerPage;
|
|
||||||
await page.goto('about:blank');
|
|
||||||
await (page as any)._resetForReuse();
|
await (page as any)._resetForReuse();
|
||||||
await (page.context() as any)._resetForReuse();
|
await (page.context() as any)._resetForReuse();
|
||||||
|
await page.goto('about:blank');
|
||||||
await page.setViewportSize(viewport || { width: 1280, height: 800 });
|
await page.setViewportSize(viewport || { width: 1280, height: 800 });
|
||||||
await page.goto(process.env.PLAYWRIGHT_VITE_COMPONENTS_BASE_URL!);
|
await page.goto(process.env.PLAYWRIGHT_VITE_COMPONENTS_BASE_URL!);
|
||||||
await use(_workerPage);
|
}, true);
|
||||||
|
await use(page);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
mount: async ({ page }, use) => {
|
mount: async ({ page }, use) => {
|
||||||
|
|
@ -100,3 +112,28 @@ function wrapFunctions(object: any, page: Page, callbacks: Function[]) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function contextHash(context: BrowserContextOptions): string {
|
||||||
|
const hash = {
|
||||||
|
acceptDownloads: context.acceptDownloads,
|
||||||
|
bypassCSP: context.bypassCSP,
|
||||||
|
colorScheme: context.colorScheme,
|
||||||
|
extraHTTPHeaders: context.extraHTTPHeaders,
|
||||||
|
forcedColors: context.forcedColors,
|
||||||
|
geolocation: context.geolocation,
|
||||||
|
hasTouch: context.hasTouch,
|
||||||
|
httpCredentials: context.httpCredentials,
|
||||||
|
ignoreHTTPSErrors: context.ignoreHTTPSErrors,
|
||||||
|
isMobile: context.isMobile,
|
||||||
|
javaScriptEnabled: context.javaScriptEnabled,
|
||||||
|
locale: context.locale,
|
||||||
|
offline: context.offline,
|
||||||
|
permissions: context.permissions,
|
||||||
|
proxy: context.proxy,
|
||||||
|
storageState: context.storageState,
|
||||||
|
timezoneId: context.timezoneId,
|
||||||
|
userAgent: context.userAgent,
|
||||||
|
deviceScaleFactor: context.deviceScaleFactor,
|
||||||
|
};
|
||||||
|
return JSON.stringify(hash);
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,7 @@ import type { FullConfig } from '../types';
|
||||||
import { assert } from 'playwright-core/lib/utils';
|
import { assert } from 'playwright-core/lib/utils';
|
||||||
|
|
||||||
let previewServer: PreviewServer;
|
let previewServer: PreviewServer;
|
||||||
const VERSION = 1;
|
const VERSION = 2;
|
||||||
|
|
||||||
type CtConfig = {
|
type CtConfig = {
|
||||||
ctPort?: number;
|
ctPort?: number;
|
||||||
|
|
@ -56,10 +56,12 @@ export function createPlugin(
|
||||||
const outDir = viteConfig?.build?.outDir || (use.ctCacheDir ? path.resolve(rootDir, use.ctCacheDir) : path.resolve(templateDir, '.cache'));
|
const outDir = viteConfig?.build?.outDir || (use.ctCacheDir ? path.resolve(rootDir, use.ctCacheDir) : path.resolve(templateDir, '.cache'));
|
||||||
|
|
||||||
const buildInfoFile = path.join(outDir, 'metainfo.json');
|
const buildInfoFile = path.join(outDir, 'metainfo.json');
|
||||||
|
let buildExists = false;
|
||||||
let buildInfo: BuildInfo;
|
let buildInfo: BuildInfo;
|
||||||
try {
|
try {
|
||||||
buildInfo = JSON.parse(await fs.promises.readFile(buildInfoFile, 'utf-8')) as BuildInfo;
|
buildInfo = JSON.parse(await fs.promises.readFile(buildInfoFile, 'utf-8')) as BuildInfo;
|
||||||
assert(buildInfo.version === VERSION);
|
assert(buildInfo.version === VERSION);
|
||||||
|
buildExists = true;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
buildInfo = {
|
buildInfo = {
|
||||||
version: VERSION,
|
version: VERSION,
|
||||||
|
|
@ -75,7 +77,7 @@ export function createPlugin(
|
||||||
// 2. Check if the set of required components has changed.
|
// 2. Check if the set of required components has changed.
|
||||||
const hasNewComponents = await checkNewComponents(buildInfo, componentRegistry);
|
const hasNewComponents = await checkNewComponents(buildInfo, componentRegistry);
|
||||||
// 3. Check component sources.
|
// 3. Check component sources.
|
||||||
const sourcesDirty = hasNewComponents || await checkSources(buildInfo);
|
const sourcesDirty = !buildExists || hasNewComponents || await checkSources(buildInfo);
|
||||||
|
|
||||||
viteConfig.root = rootDir;
|
viteConfig.root = rootDir;
|
||||||
viteConfig.preview = { port };
|
viteConfig.preview = { port };
|
||||||
|
|
|
||||||
226
packages/playwright-test/types/test.d.ts
vendored
226
packages/playwright-test/types/test.d.ts
vendored
|
|
@ -486,7 +486,7 @@ interface TestConfig {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Configuration for the
|
* Configuration for the
|
||||||
* [pageAssertions.toHaveScreenshot([options])](https://playwright.dev/docs/api/class-pageassertions#page-assertions-to-have-screenshot)
|
* [pageAssertions.toHaveScreenshot(name[, options])](https://playwright.dev/docs/api/class-pageassertions#page-assertions-to-have-screenshot-1)
|
||||||
* method.
|
* method.
|
||||||
*/
|
*/
|
||||||
toHaveScreenshot?: {
|
toHaveScreenshot?: {
|
||||||
|
|
@ -508,9 +508,9 @@ interface TestConfig {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* See `animations` in [page.screenshot([options])](https://playwright.dev/docs/api/class-page#page-screenshot). Defaults
|
* See `animations` in [page.screenshot([options])](https://playwright.dev/docs/api/class-page#page-screenshot). Defaults
|
||||||
* to `"disable"`.
|
* to `"disabled"`.
|
||||||
*/
|
*/
|
||||||
animations?: "allow"|"disable";
|
animations?: "allow"|"disabled";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* See `caret` in [page.screenshot([options])](https://playwright.dev/docs/api/class-page#page-screenshot). Defaults to
|
* See `caret` in [page.screenshot([options])](https://playwright.dev/docs/api/class-page#page-screenshot). Defaults to
|
||||||
|
|
@ -3328,27 +3328,25 @@ interface LocatorAssertions {
|
||||||
}): Promise<void>;
|
}): Promise<void>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Ensures that [Locator] resolves to a given screenshot. This function will re-take screenshots until it matches with the
|
* This function will wait until two consecutive locator screenshots yield the same result, and then compare the last
|
||||||
* saved expectation.
|
* screenshot with the expectation.
|
||||||
*
|
|
||||||
* If there's no expectation yet, it will wait until two consecutive screenshots yield the same result, and save the last
|
|
||||||
* one as an expectation.
|
|
||||||
*
|
*
|
||||||
* ```js
|
* ```js
|
||||||
* const locator = page.locator('button');
|
* const locator = page.locator('button');
|
||||||
* await expect(locator).toHaveScreenshot();
|
* await expect(locator).toHaveScreenshot('image.png');
|
||||||
* ```
|
* ```
|
||||||
*
|
*
|
||||||
|
* @param name Snapshot name.
|
||||||
* @param options
|
* @param options
|
||||||
*/
|
*/
|
||||||
toHaveScreenshot(options?: {
|
toHaveScreenshot(name: string|Array<string>, options?: {
|
||||||
/**
|
/**
|
||||||
* When set to `"disabled"`, stops CSS animations, CSS transitions and Web Animations. Animations get different treatment
|
* When set to `"disabled"`, stops CSS animations, CSS transitions and Web Animations. Animations get different treatment
|
||||||
* depending on their duration:
|
* depending on their duration:
|
||||||
* - finite animations are fast-forwarded to completion, so they'll fire `transitionend` event.
|
* - finite animations are fast-forwarded to completion, so they'll fire `transitionend` event.
|
||||||
* - infinite animations are canceled to initial state, and then played over after the screenshot.
|
* - infinite animations are canceled to initial state, and then played over after the screenshot.
|
||||||
*
|
*
|
||||||
* Defaults to `"allow"` that leaves animations untouched.
|
* Defaults to `"disabled"` that disables animations.
|
||||||
*/
|
*/
|
||||||
animations?: "disabled"|"allow";
|
animations?: "disabled"|"allow";
|
||||||
|
|
||||||
|
|
@ -3385,7 +3383,83 @@ interface LocatorAssertions {
|
||||||
/**
|
/**
|
||||||
* When set to `"css"`, screenshot will have a single pixel per each css pixel on the page. For high-dpi devices, this will
|
* When set to `"css"`, screenshot will have a single pixel per each css pixel on the page. For high-dpi devices, this will
|
||||||
* keep screenshots small. Using `"device"` option will produce a single pixel per each device pixel, so screenhots of
|
* keep screenshots small. Using `"device"` option will produce a single pixel per each device pixel, so screenhots of
|
||||||
* high-dpi devices will be twice as large or even larger. Defaults to `"device"`.
|
* high-dpi devices will be twice as large or even larger.
|
||||||
|
*
|
||||||
|
* Defaults to `"css"`.
|
||||||
|
*/
|
||||||
|
scale?: "css"|"device";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Time to retry the assertion for. Defaults to `timeout` in `TestConfig.expect`.
|
||||||
|
*/
|
||||||
|
timeout?: number;
|
||||||
|
}): Promise<void>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function will wait until two consecutive locator screenshots yield the same result, and then compare the last
|
||||||
|
* screenshot with the expectation.
|
||||||
|
*
|
||||||
|
* ```js
|
||||||
|
* const locator = page.locator('button');
|
||||||
|
* await expect(locator).toHaveScreenshot();
|
||||||
|
* ```
|
||||||
|
*
|
||||||
|
* @param options
|
||||||
|
*/
|
||||||
|
toHaveScreenshot(options?: {
|
||||||
|
/**
|
||||||
|
* When set to `"disabled"`, stops CSS animations, CSS transitions and Web Animations. Animations get different treatment
|
||||||
|
* depending on their duration:
|
||||||
|
* - finite animations are fast-forwarded to completion, so they'll fire `transitionend` event.
|
||||||
|
* - infinite animations are canceled to initial state, and then played over after the screenshot.
|
||||||
|
*
|
||||||
|
* Defaults to `"disabled"` that disables animations.
|
||||||
|
*/
|
||||||
|
animations?: "disabled"|"allow";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* When set to `"hide"`, screenshot will hide text caret. When set to `"initial"`, text caret behavior will not be changed.
|
||||||
|
* Defaults to `"hide"`.
|
||||||
|
*/
|
||||||
|
caret?: "hide"|"initial";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Specify locators that should be masked when the screenshot is taken. Masked elements will be overlayed with a pink box
|
||||||
|
* `#FF00FF` that completely covers its bounding box.
|
||||||
|
*/
|
||||||
|
mask?: Array<Locator>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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`. Default is
|
||||||
|
* configurable with `TestConfig.expect`. Unset by default.
|
||||||
|
*/
|
||||||
|
maxDiffPixels?: number;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Hides default white background and allows capturing screenshots with transparency. Not applicable to `jpeg` images.
|
||||||
|
* Defaults to `false`.
|
||||||
|
*/
|
||||||
|
omitBackground?: boolean;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* When set to `"css"`, screenshot will have a single pixel per each css pixel on the page. For high-dpi devices, this will
|
||||||
|
* keep screenshots small. Using `"device"` option will produce a single pixel per each device pixel, so screenhots of
|
||||||
|
* high-dpi devices will be twice as large or even larger.
|
||||||
|
*
|
||||||
|
* Defaults to `"css"`.
|
||||||
*/
|
*/
|
||||||
scale?: "css"|"device";
|
scale?: "css"|"device";
|
||||||
|
|
||||||
|
|
@ -3482,26 +3556,24 @@ interface PageAssertions {
|
||||||
not: PageAssertions;
|
not: PageAssertions;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Ensures that the page resolves to a given screenshot. This function will re-take screenshots until it matches with the
|
* This function will wait until two consecutive page screenshots yield the same result, and then compare the last
|
||||||
* saved expectation.
|
* screenshot with the expectation.
|
||||||
*
|
|
||||||
* If there's no expectation yet, it will wait until two consecutive screenshots yield the same result, and save the last
|
|
||||||
* one as an expectation.
|
|
||||||
*
|
*
|
||||||
* ```js
|
* ```js
|
||||||
* await expect(page).toHaveScreenshot();
|
* await expect(page).toHaveScreenshot('image.png');
|
||||||
* ```
|
* ```
|
||||||
*
|
*
|
||||||
|
* @param name Snapshot name.
|
||||||
* @param options
|
* @param options
|
||||||
*/
|
*/
|
||||||
toHaveScreenshot(options?: {
|
toHaveScreenshot(name: string|Array<string>, options?: {
|
||||||
/**
|
/**
|
||||||
* When set to `"disabled"`, stops CSS animations, CSS transitions and Web Animations. Animations get different treatment
|
* When set to `"disabled"`, stops CSS animations, CSS transitions and Web Animations. Animations get different treatment
|
||||||
* depending on their duration:
|
* depending on their duration:
|
||||||
* - finite animations are fast-forwarded to completion, so they'll fire `transitionend` event.
|
* - finite animations are fast-forwarded to completion, so they'll fire `transitionend` event.
|
||||||
* - infinite animations are canceled to initial state, and then played over after the screenshot.
|
* - infinite animations are canceled to initial state, and then played over after the screenshot.
|
||||||
*
|
*
|
||||||
* Defaults to `"allow"` that leaves animations untouched.
|
* Defaults to `"disabled"` that disables animations.
|
||||||
*/
|
*/
|
||||||
animations?: "disabled"|"allow";
|
animations?: "disabled"|"allow";
|
||||||
|
|
||||||
|
|
@ -3569,7 +3641,113 @@ interface PageAssertions {
|
||||||
/**
|
/**
|
||||||
* When set to `"css"`, screenshot will have a single pixel per each css pixel on the page. For high-dpi devices, this will
|
* When set to `"css"`, screenshot will have a single pixel per each css pixel on the page. For high-dpi devices, this will
|
||||||
* keep screenshots small. Using `"device"` option will produce a single pixel per each device pixel, so screenhots of
|
* keep screenshots small. Using `"device"` option will produce a single pixel per each device pixel, so screenhots of
|
||||||
* high-dpi devices will be twice as large or even larger. Defaults to `"device"`.
|
* high-dpi devices will be twice as large or even larger.
|
||||||
|
*
|
||||||
|
* Defaults to `"css"`.
|
||||||
|
*/
|
||||||
|
scale?: "css"|"device";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Time to retry the assertion for. Defaults to `timeout` in `TestConfig.expect`.
|
||||||
|
*/
|
||||||
|
timeout?: number;
|
||||||
|
}): Promise<void>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function will wait until two consecutive page screenshots yield the same result, and then compare the last
|
||||||
|
* screenshot with the expectation.
|
||||||
|
*
|
||||||
|
* ```js
|
||||||
|
* await expect(page).toHaveScreenshot();
|
||||||
|
* ```
|
||||||
|
*
|
||||||
|
* @param options
|
||||||
|
*/
|
||||||
|
toHaveScreenshot(options?: {
|
||||||
|
/**
|
||||||
|
* When set to `"disabled"`, stops CSS animations, CSS transitions and Web Animations. Animations get different treatment
|
||||||
|
* depending on their duration:
|
||||||
|
* - finite animations are fast-forwarded to completion, so they'll fire `transitionend` event.
|
||||||
|
* - infinite animations are canceled to initial state, and then played over after the screenshot.
|
||||||
|
*
|
||||||
|
* Defaults to `"disabled"` that disables animations.
|
||||||
|
*/
|
||||||
|
animations?: "disabled"|"allow";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* When set to `"hide"`, screenshot will hide text caret. When set to `"initial"`, text caret behavior will not be changed.
|
||||||
|
* Defaults to `"hide"`.
|
||||||
|
*/
|
||||||
|
caret?: "hide"|"initial";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An object which specifies clipping of the resulting image. Should have the following fields:
|
||||||
|
*/
|
||||||
|
clip?: {
|
||||||
|
/**
|
||||||
|
* x-coordinate of top-left corner of clip area
|
||||||
|
*/
|
||||||
|
x: number;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* y-coordinate of top-left corner of clip area
|
||||||
|
*/
|
||||||
|
y: number;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* width of clipping area
|
||||||
|
*/
|
||||||
|
width: number;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* height of clipping area
|
||||||
|
*/
|
||||||
|
height: number;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* When true, takes a screenshot of the full scrollable page, instead of the currently visible viewport. Defaults to
|
||||||
|
* `false`.
|
||||||
|
*/
|
||||||
|
fullPage?: boolean;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Specify locators that should be masked when the screenshot is taken. Masked elements will be overlayed with a pink box
|
||||||
|
* `#FF00FF` that completely covers its bounding box.
|
||||||
|
*/
|
||||||
|
mask?: Array<Locator>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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`. Default is
|
||||||
|
* configurable with `TestConfig.expect`. Unset by default.
|
||||||
|
*/
|
||||||
|
maxDiffPixels?: number;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Hides default white background and allows capturing screenshots with transparency. Not applicable to `jpeg` images.
|
||||||
|
* Defaults to `false`.
|
||||||
|
*/
|
||||||
|
omitBackground?: boolean;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* When set to `"css"`, screenshot will have a single pixel per each css pixel on the page. For high-dpi devices, this will
|
||||||
|
* keep screenshots small. Using `"device"` option will produce a single pixel per each device pixel, so screenhots of
|
||||||
|
* high-dpi devices will be twice as large or even larger.
|
||||||
|
*
|
||||||
|
* Defaults to `"css"`.
|
||||||
*/
|
*/
|
||||||
scale?: "css"|"device";
|
scale?: "css"|"device";
|
||||||
|
|
||||||
|
|
@ -3820,7 +3998,7 @@ interface TestProject {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Configuration for the
|
* Configuration for the
|
||||||
* [pageAssertions.toHaveScreenshot([options])](https://playwright.dev/docs/api/class-pageassertions#page-assertions-to-have-screenshot)
|
* [pageAssertions.toHaveScreenshot(name[, options])](https://playwright.dev/docs/api/class-pageassertions#page-assertions-to-have-screenshot-1)
|
||||||
* method.
|
* method.
|
||||||
*/
|
*/
|
||||||
toHaveScreenshot?: {
|
toHaveScreenshot?: {
|
||||||
|
|
@ -3842,9 +4020,9 @@ interface TestProject {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* See `animations` in [page.screenshot([options])](https://playwright.dev/docs/api/class-page#page-screenshot). Defaults
|
* See `animations` in [page.screenshot([options])](https://playwright.dev/docs/api/class-page#page-screenshot). Defaults
|
||||||
* to `"disable"`.
|
* to `"disabled"`.
|
||||||
*/
|
*/
|
||||||
animations?: "allow"|"disable";
|
animations?: "allow"|"disabled";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* See `caret` in [page.screenshot([options])](https://playwright.dev/docs/api/class-page#page-screenshot). Defaults to
|
* See `caret` in [page.screenshot([options])](https://playwright.dev/docs/api/class-page#page-screenshot). Defaults to
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "playwright-webkit",
|
"name": "playwright-webkit",
|
||||||
"version": "1.22.0-next",
|
"version": "1.22.2",
|
||||||
"description": "A high-level API to automate WebKit",
|
"description": "A high-level API to automate WebKit",
|
||||||
"repository": "github:Microsoft/playwright",
|
"repository": "github:Microsoft/playwright",
|
||||||
"homepage": "https://playwright.dev",
|
"homepage": "https://playwright.dev",
|
||||||
|
|
@ -13,6 +13,7 @@
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"exports": {
|
"exports": {
|
||||||
".": {
|
".": {
|
||||||
|
"types": "./index.d.ts",
|
||||||
"import": "./index.mjs",
|
"import": "./index.mjs",
|
||||||
"require": "./index.js"
|
"require": "./index.js"
|
||||||
},
|
},
|
||||||
|
|
@ -26,6 +27,6 @@
|
||||||
"install": "node install.js"
|
"install": "node install.js"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"playwright-core": "1.22.0-next"
|
"playwright-core": "1.22.2"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "playwright",
|
"name": "playwright",
|
||||||
"version": "1.22.0-next",
|
"version": "1.22.2",
|
||||||
"description": "A high-level API to automate web browsers",
|
"description": "A high-level API to automate web browsers",
|
||||||
"repository": "github:Microsoft/playwright",
|
"repository": "github:Microsoft/playwright",
|
||||||
"homepage": "https://playwright.dev",
|
"homepage": "https://playwright.dev",
|
||||||
|
|
@ -13,6 +13,7 @@
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"exports": {
|
"exports": {
|
||||||
".": {
|
".": {
|
||||||
|
"types": "./index.d.ts",
|
||||||
"import": "./index.mjs",
|
"import": "./index.mjs",
|
||||||
"require": "./index.js"
|
"require": "./index.js"
|
||||||
},
|
},
|
||||||
|
|
@ -26,6 +27,6 @@
|
||||||
"install": "node install.js"
|
"install": "node install.js"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"playwright-core": "1.22.0-next"
|
"playwright-core": "1.22.2"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
240
tests/config/experimental.d.ts
vendored
240
tests/config/experimental.d.ts
vendored
|
|
@ -8204,7 +8204,9 @@ export interface ElementHandle<T=Node> extends JSHandle<T> {
|
||||||
/**
|
/**
|
||||||
* When set to `"css"`, screenshot will have a single pixel per each css pixel on the page. For high-dpi devices, this will
|
* When set to `"css"`, screenshot will have a single pixel per each css pixel on the page. For high-dpi devices, this will
|
||||||
* keep screenshots small. Using `"device"` option will produce a single pixel per each device pixel, so screenhots of
|
* keep screenshots small. Using `"device"` option will produce a single pixel per each device pixel, so screenhots of
|
||||||
* high-dpi devices will be twice as large or even larger. Defaults to `"device"`.
|
* high-dpi devices will be twice as large or even larger.
|
||||||
|
*
|
||||||
|
* Defaults to `"device"`.
|
||||||
*/
|
*/
|
||||||
scale?: "css"|"device";
|
scale?: "css"|"device";
|
||||||
|
|
||||||
|
|
@ -15846,7 +15848,9 @@ export interface LocatorScreenshotOptions {
|
||||||
/**
|
/**
|
||||||
* When set to `"css"`, screenshot will have a single pixel per each css pixel on the page. For high-dpi devices, this will
|
* When set to `"css"`, screenshot will have a single pixel per each css pixel on the page. For high-dpi devices, this will
|
||||||
* keep screenshots small. Using `"device"` option will produce a single pixel per each device pixel, so screenhots of
|
* keep screenshots small. Using `"device"` option will produce a single pixel per each device pixel, so screenhots of
|
||||||
* high-dpi devices will be twice as large or even larger. Defaults to `"device"`.
|
* high-dpi devices will be twice as large or even larger.
|
||||||
|
*
|
||||||
|
* Defaults to `"device"`.
|
||||||
*/
|
*/
|
||||||
scale?: "css"|"device";
|
scale?: "css"|"device";
|
||||||
|
|
||||||
|
|
@ -16029,7 +16033,9 @@ export interface PageScreenshotOptions {
|
||||||
/**
|
/**
|
||||||
* When set to `"css"`, screenshot will have a single pixel per each css pixel on the page. For high-dpi devices, this will
|
* When set to `"css"`, screenshot will have a single pixel per each css pixel on the page. For high-dpi devices, this will
|
||||||
* keep screenshots small. Using `"device"` option will produce a single pixel per each device pixel, so screenhots of
|
* keep screenshots small. Using `"device"` option will produce a single pixel per each device pixel, so screenhots of
|
||||||
* high-dpi devices will be twice as large or even larger. Defaults to `"device"`.
|
* high-dpi devices will be twice as large or even larger.
|
||||||
|
*
|
||||||
|
* Defaults to `"device"`.
|
||||||
*/
|
*/
|
||||||
scale?: "css"|"device";
|
scale?: "css"|"device";
|
||||||
|
|
||||||
|
|
@ -16662,7 +16668,7 @@ interface TestConfig {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Configuration for the
|
* Configuration for the
|
||||||
* [pageAssertions.toHaveScreenshot([options])](https://playwright.dev/docs/api/class-pageassertions#page-assertions-to-have-screenshot)
|
* [pageAssertions.toHaveScreenshot(name[, options])](https://playwright.dev/docs/api/class-pageassertions#page-assertions-to-have-screenshot-1)
|
||||||
* method.
|
* method.
|
||||||
*/
|
*/
|
||||||
toHaveScreenshot?: {
|
toHaveScreenshot?: {
|
||||||
|
|
@ -16684,9 +16690,9 @@ interface TestConfig {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* See `animations` in [page.screenshot([options])](https://playwright.dev/docs/api/class-page#page-screenshot). Defaults
|
* See `animations` in [page.screenshot([options])](https://playwright.dev/docs/api/class-page#page-screenshot). Defaults
|
||||||
* to `"disable"`.
|
* to `"disabled"`.
|
||||||
*/
|
*/
|
||||||
animations?: "allow"|"disable";
|
animations?: "allow"|"disabled";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* See `caret` in [page.screenshot([options])](https://playwright.dev/docs/api/class-page#page-screenshot). Defaults to
|
* See `caret` in [page.screenshot([options])](https://playwright.dev/docs/api/class-page#page-screenshot). Defaults to
|
||||||
|
|
@ -16966,7 +16972,7 @@ interface TestConfig {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The base directory, relative to the config file, for screenshot files created with
|
* The base directory, relative to the config file, for screenshot files created with
|
||||||
* [pageAssertions.toHaveScreenshot([options])](https://playwright.dev/docs/api/class-pageassertions#page-assertions-to-have-screenshot).
|
* [pageAssertions.toHaveScreenshot(name[, options])](https://playwright.dev/docs/api/class-pageassertions#page-assertions-to-have-screenshot-1).
|
||||||
* Defaults to
|
* Defaults to
|
||||||
*
|
*
|
||||||
* ```
|
* ```
|
||||||
|
|
@ -19534,27 +19540,25 @@ interface LocatorAssertions {
|
||||||
}): Promise<void>;
|
}): Promise<void>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Ensures that [Locator] resolves to a given screenshot. This function will re-take screenshots until it matches with the
|
* This function will wait until two consecutive locator screenshots yield the same result, and then compare the last
|
||||||
* saved expectation.
|
* screenshot with the expectation.
|
||||||
*
|
|
||||||
* If there's no expectation yet, it will wait until two consecutive screenshots yield the same result, and save the last
|
|
||||||
* one as an expectation.
|
|
||||||
*
|
*
|
||||||
* ```js
|
* ```js
|
||||||
* const locator = page.locator('button');
|
* const locator = page.locator('button');
|
||||||
* await expect(locator).toHaveScreenshot();
|
* await expect(locator).toHaveScreenshot('image.png');
|
||||||
* ```
|
* ```
|
||||||
*
|
*
|
||||||
|
* @param name Snapshot name.
|
||||||
* @param options
|
* @param options
|
||||||
*/
|
*/
|
||||||
toHaveScreenshot(options?: {
|
toHaveScreenshot(name: string|Array<string>, options?: {
|
||||||
/**
|
/**
|
||||||
* When set to `"disabled"`, stops CSS animations, CSS transitions and Web Animations. Animations get different treatment
|
* When set to `"disabled"`, stops CSS animations, CSS transitions and Web Animations. Animations get different treatment
|
||||||
* depending on their duration:
|
* depending on their duration:
|
||||||
* - finite animations are fast-forwarded to completion, so they'll fire `transitionend` event.
|
* - finite animations are fast-forwarded to completion, so they'll fire `transitionend` event.
|
||||||
* - infinite animations are canceled to initial state, and then played over after the screenshot.
|
* - infinite animations are canceled to initial state, and then played over after the screenshot.
|
||||||
*
|
*
|
||||||
* Defaults to `"allow"` that leaves animations untouched.
|
* Defaults to `"disabled"` that disables animations.
|
||||||
*/
|
*/
|
||||||
animations?: "disabled"|"allow";
|
animations?: "disabled"|"allow";
|
||||||
|
|
||||||
|
|
@ -19591,7 +19595,83 @@ interface LocatorAssertions {
|
||||||
/**
|
/**
|
||||||
* When set to `"css"`, screenshot will have a single pixel per each css pixel on the page. For high-dpi devices, this will
|
* When set to `"css"`, screenshot will have a single pixel per each css pixel on the page. For high-dpi devices, this will
|
||||||
* keep screenshots small. Using `"device"` option will produce a single pixel per each device pixel, so screenhots of
|
* keep screenshots small. Using `"device"` option will produce a single pixel per each device pixel, so screenhots of
|
||||||
* high-dpi devices will be twice as large or even larger. Defaults to `"device"`.
|
* high-dpi devices will be twice as large or even larger.
|
||||||
|
*
|
||||||
|
* Defaults to `"css"`.
|
||||||
|
*/
|
||||||
|
scale?: "css"|"device";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Time to retry the assertion for. Defaults to `timeout` in `TestConfig.expect`.
|
||||||
|
*/
|
||||||
|
timeout?: number;
|
||||||
|
}): Promise<void>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function will wait until two consecutive locator screenshots yield the same result, and then compare the last
|
||||||
|
* screenshot with the expectation.
|
||||||
|
*
|
||||||
|
* ```js
|
||||||
|
* const locator = page.locator('button');
|
||||||
|
* await expect(locator).toHaveScreenshot();
|
||||||
|
* ```
|
||||||
|
*
|
||||||
|
* @param options
|
||||||
|
*/
|
||||||
|
toHaveScreenshot(options?: {
|
||||||
|
/**
|
||||||
|
* When set to `"disabled"`, stops CSS animations, CSS transitions and Web Animations. Animations get different treatment
|
||||||
|
* depending on their duration:
|
||||||
|
* - finite animations are fast-forwarded to completion, so they'll fire `transitionend` event.
|
||||||
|
* - infinite animations are canceled to initial state, and then played over after the screenshot.
|
||||||
|
*
|
||||||
|
* Defaults to `"disabled"` that disables animations.
|
||||||
|
*/
|
||||||
|
animations?: "disabled"|"allow";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* When set to `"hide"`, screenshot will hide text caret. When set to `"initial"`, text caret behavior will not be changed.
|
||||||
|
* Defaults to `"hide"`.
|
||||||
|
*/
|
||||||
|
caret?: "hide"|"initial";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Specify locators that should be masked when the screenshot is taken. Masked elements will be overlayed with a pink box
|
||||||
|
* `#FF00FF` that completely covers its bounding box.
|
||||||
|
*/
|
||||||
|
mask?: Array<Locator>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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`. Default is
|
||||||
|
* configurable with `TestConfig.expect`. Unset by default.
|
||||||
|
*/
|
||||||
|
maxDiffPixels?: number;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Hides default white background and allows capturing screenshots with transparency. Not applicable to `jpeg` images.
|
||||||
|
* Defaults to `false`.
|
||||||
|
*/
|
||||||
|
omitBackground?: boolean;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* When set to `"css"`, screenshot will have a single pixel per each css pixel on the page. For high-dpi devices, this will
|
||||||
|
* keep screenshots small. Using `"device"` option will produce a single pixel per each device pixel, so screenhots of
|
||||||
|
* high-dpi devices will be twice as large or even larger.
|
||||||
|
*
|
||||||
|
* Defaults to `"css"`.
|
||||||
*/
|
*/
|
||||||
scale?: "css"|"device";
|
scale?: "css"|"device";
|
||||||
|
|
||||||
|
|
@ -19688,26 +19768,24 @@ interface PageAssertions {
|
||||||
not: PageAssertions;
|
not: PageAssertions;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Ensures that the page resolves to a given screenshot. This function will re-take screenshots until it matches with the
|
* This function will wait until two consecutive page screenshots yield the same result, and then compare the last
|
||||||
* saved expectation.
|
* screenshot with the expectation.
|
||||||
*
|
|
||||||
* If there's no expectation yet, it will wait until two consecutive screenshots yield the same result, and save the last
|
|
||||||
* one as an expectation.
|
|
||||||
*
|
*
|
||||||
* ```js
|
* ```js
|
||||||
* await expect(page).toHaveScreenshot();
|
* await expect(page).toHaveScreenshot('image.png');
|
||||||
* ```
|
* ```
|
||||||
*
|
*
|
||||||
|
* @param name Snapshot name.
|
||||||
* @param options
|
* @param options
|
||||||
*/
|
*/
|
||||||
toHaveScreenshot(options?: {
|
toHaveScreenshot(name: string|Array<string>, options?: {
|
||||||
/**
|
/**
|
||||||
* When set to `"disabled"`, stops CSS animations, CSS transitions and Web Animations. Animations get different treatment
|
* When set to `"disabled"`, stops CSS animations, CSS transitions and Web Animations. Animations get different treatment
|
||||||
* depending on their duration:
|
* depending on their duration:
|
||||||
* - finite animations are fast-forwarded to completion, so they'll fire `transitionend` event.
|
* - finite animations are fast-forwarded to completion, so they'll fire `transitionend` event.
|
||||||
* - infinite animations are canceled to initial state, and then played over after the screenshot.
|
* - infinite animations are canceled to initial state, and then played over after the screenshot.
|
||||||
*
|
*
|
||||||
* Defaults to `"allow"` that leaves animations untouched.
|
* Defaults to `"disabled"` that disables animations.
|
||||||
*/
|
*/
|
||||||
animations?: "disabled"|"allow";
|
animations?: "disabled"|"allow";
|
||||||
|
|
||||||
|
|
@ -19775,7 +19853,113 @@ interface PageAssertions {
|
||||||
/**
|
/**
|
||||||
* When set to `"css"`, screenshot will have a single pixel per each css pixel on the page. For high-dpi devices, this will
|
* When set to `"css"`, screenshot will have a single pixel per each css pixel on the page. For high-dpi devices, this will
|
||||||
* keep screenshots small. Using `"device"` option will produce a single pixel per each device pixel, so screenhots of
|
* keep screenshots small. Using `"device"` option will produce a single pixel per each device pixel, so screenhots of
|
||||||
* high-dpi devices will be twice as large or even larger. Defaults to `"device"`.
|
* high-dpi devices will be twice as large or even larger.
|
||||||
|
*
|
||||||
|
* Defaults to `"css"`.
|
||||||
|
*/
|
||||||
|
scale?: "css"|"device";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Time to retry the assertion for. Defaults to `timeout` in `TestConfig.expect`.
|
||||||
|
*/
|
||||||
|
timeout?: number;
|
||||||
|
}): Promise<void>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function will wait until two consecutive page screenshots yield the same result, and then compare the last
|
||||||
|
* screenshot with the expectation.
|
||||||
|
*
|
||||||
|
* ```js
|
||||||
|
* await expect(page).toHaveScreenshot();
|
||||||
|
* ```
|
||||||
|
*
|
||||||
|
* @param options
|
||||||
|
*/
|
||||||
|
toHaveScreenshot(options?: {
|
||||||
|
/**
|
||||||
|
* When set to `"disabled"`, stops CSS animations, CSS transitions and Web Animations. Animations get different treatment
|
||||||
|
* depending on their duration:
|
||||||
|
* - finite animations are fast-forwarded to completion, so they'll fire `transitionend` event.
|
||||||
|
* - infinite animations are canceled to initial state, and then played over after the screenshot.
|
||||||
|
*
|
||||||
|
* Defaults to `"disabled"` that disables animations.
|
||||||
|
*/
|
||||||
|
animations?: "disabled"|"allow";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* When set to `"hide"`, screenshot will hide text caret. When set to `"initial"`, text caret behavior will not be changed.
|
||||||
|
* Defaults to `"hide"`.
|
||||||
|
*/
|
||||||
|
caret?: "hide"|"initial";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An object which specifies clipping of the resulting image. Should have the following fields:
|
||||||
|
*/
|
||||||
|
clip?: {
|
||||||
|
/**
|
||||||
|
* x-coordinate of top-left corner of clip area
|
||||||
|
*/
|
||||||
|
x: number;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* y-coordinate of top-left corner of clip area
|
||||||
|
*/
|
||||||
|
y: number;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* width of clipping area
|
||||||
|
*/
|
||||||
|
width: number;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* height of clipping area
|
||||||
|
*/
|
||||||
|
height: number;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* When true, takes a screenshot of the full scrollable page, instead of the currently visible viewport. Defaults to
|
||||||
|
* `false`.
|
||||||
|
*/
|
||||||
|
fullPage?: boolean;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Specify locators that should be masked when the screenshot is taken. Masked elements will be overlayed with a pink box
|
||||||
|
* `#FF00FF` that completely covers its bounding box.
|
||||||
|
*/
|
||||||
|
mask?: Array<Locator>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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`. Default is
|
||||||
|
* configurable with `TestConfig.expect`. Unset by default.
|
||||||
|
*/
|
||||||
|
maxDiffPixels?: number;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Hides default white background and allows capturing screenshots with transparency. Not applicable to `jpeg` images.
|
||||||
|
* Defaults to `false`.
|
||||||
|
*/
|
||||||
|
omitBackground?: boolean;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* When set to `"css"`, screenshot will have a single pixel per each css pixel on the page. For high-dpi devices, this will
|
||||||
|
* keep screenshots small. Using `"device"` option will produce a single pixel per each device pixel, so screenhots of
|
||||||
|
* high-dpi devices will be twice as large or even larger.
|
||||||
|
*
|
||||||
|
* Defaults to `"css"`.
|
||||||
*/
|
*/
|
||||||
scale?: "css"|"device";
|
scale?: "css"|"device";
|
||||||
|
|
||||||
|
|
@ -20026,7 +20210,7 @@ interface TestProject {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Configuration for the
|
* Configuration for the
|
||||||
* [pageAssertions.toHaveScreenshot([options])](https://playwright.dev/docs/api/class-pageassertions#page-assertions-to-have-screenshot)
|
* [pageAssertions.toHaveScreenshot(name[, options])](https://playwright.dev/docs/api/class-pageassertions#page-assertions-to-have-screenshot-1)
|
||||||
* method.
|
* method.
|
||||||
*/
|
*/
|
||||||
toHaveScreenshot?: {
|
toHaveScreenshot?: {
|
||||||
|
|
@ -20048,9 +20232,9 @@ interface TestProject {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* See `animations` in [page.screenshot([options])](https://playwright.dev/docs/api/class-page#page-screenshot). Defaults
|
* See `animations` in [page.screenshot([options])](https://playwright.dev/docs/api/class-page#page-screenshot). Defaults
|
||||||
* to `"disable"`.
|
* to `"disabled"`.
|
||||||
*/
|
*/
|
||||||
animations?: "allow"|"disable";
|
animations?: "allow"|"disabled";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* See `caret` in [page.screenshot([options])](https://playwright.dev/docs/api/class-page#page-screenshot). Defaults to
|
* See `caret` in [page.screenshot([options])](https://playwright.dev/docs/api/class-page#page-screenshot). Defaults to
|
||||||
|
|
|
||||||
|
|
@ -117,3 +117,31 @@ it('clicking checkbox should activate it', async ({ page, browserName, headless,
|
||||||
const nodeName = await page.evaluate(() => document.activeElement.nodeName);
|
const nodeName = await page.evaluate(() => document.activeElement.nodeName);
|
||||||
expect(nodeName).toBe('INPUT');
|
expect(nodeName).toBe('INPUT');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('keeps focus on element when attempting to focus a non-focusable element', async ({ page }) => {
|
||||||
|
it.info().annotations.push({ type: 'issue', description: 'https://github.com/microsoft/playwright/issues/14254' });
|
||||||
|
|
||||||
|
await page.setContent(`
|
||||||
|
<div id="focusable" tabindex="0">focusable</div>
|
||||||
|
<div id="non-focusable">not focusable</div>
|
||||||
|
<script>
|
||||||
|
window.eventLog = [];
|
||||||
|
|
||||||
|
const focusable = document.getElementById("focusable");
|
||||||
|
|
||||||
|
focusable.addEventListener('blur', () => window.eventLog.push('blur focusable'));
|
||||||
|
focusable.addEventListener('focus', () => window.eventLog.push('focus focusable'));
|
||||||
|
|
||||||
|
const nonFocusable = document.getElementById("non-focusable");
|
||||||
|
nonFocusable.addEventListener('blur', () => window.eventLog.push('blur non-focusable'));
|
||||||
|
nonFocusable.addEventListener('focus', () => window.eventLog.push('focus non-focusable'));
|
||||||
|
</script>
|
||||||
|
`);
|
||||||
|
await page.locator('#focusable').click();
|
||||||
|
expect.soft(await page.evaluate(() => document.activeElement?.id)).toBe('focusable');
|
||||||
|
await page.locator('#non-focusable').focus();
|
||||||
|
expect.soft(await page.evaluate(() => document.activeElement?.id)).toBe('focusable');
|
||||||
|
expect.soft(await page.evaluate(() => window['eventLog'])).toEqual([
|
||||||
|
'focus focusable',
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
|
|
||||||
|
|
@ -532,6 +532,98 @@ it('should type repeatedly in contenteditable in shadow dom', async ({ page }) =
|
||||||
expect(await sectionEditor.textContent()).toBe('This is the second box.');
|
expect(await sectionEditor.textContent()).toBe('This is the second box.');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should type repeatedly in contenteditable in shadow dom with nested elements', async ({ page }) => {
|
||||||
|
await page.setContent(`
|
||||||
|
<html>
|
||||||
|
<body>
|
||||||
|
<shadow-element></shadow-element>
|
||||||
|
<script>
|
||||||
|
customElements.define('shadow-element', class extends HTMLElement {
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
this.attachShadow({ mode: 'open' });
|
||||||
|
}
|
||||||
|
|
||||||
|
connectedCallback() {
|
||||||
|
this.shadowRoot.innerHTML = \`
|
||||||
|
<style>
|
||||||
|
.editor { padding: 1rem; margin: 1rem; border: 1px solid #ccc; }
|
||||||
|
</style>
|
||||||
|
<div class=editor contenteditable id=foo><p>hello</p></div>
|
||||||
|
<hr>
|
||||||
|
<section>
|
||||||
|
<div class=editor contenteditable id=bar><p>world</p></div>
|
||||||
|
</section>
|
||||||
|
\`;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
`);
|
||||||
|
|
||||||
|
const editor = page.locator('shadow-element > .editor').first();
|
||||||
|
await editor.type('This is the first box: ');
|
||||||
|
|
||||||
|
const sectionEditor = page.locator('section .editor');
|
||||||
|
await sectionEditor.type('This is the second box: ');
|
||||||
|
|
||||||
|
expect(await editor.textContent()).toBe('This is the first box: hello');
|
||||||
|
expect(await sectionEditor.textContent()).toBe('This is the second box: world');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should type repeatedly in input in shadow dom', async ({ page }) => {
|
||||||
|
await page.setContent(`
|
||||||
|
<html>
|
||||||
|
<body>
|
||||||
|
<shadow-element></shadow-element>
|
||||||
|
<script>
|
||||||
|
customElements.define('shadow-element', class extends HTMLElement {
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
this.attachShadow({ mode: 'open' });
|
||||||
|
}
|
||||||
|
|
||||||
|
connectedCallback() {
|
||||||
|
this.shadowRoot.innerHTML = \`
|
||||||
|
<style>
|
||||||
|
.editor { padding: 1rem; margin: 1rem; border: 1px solid #ccc; }
|
||||||
|
</style>
|
||||||
|
<input class=editor id=foo>
|
||||||
|
<hr>
|
||||||
|
<section>
|
||||||
|
<input class=editor id=bar>
|
||||||
|
</section>
|
||||||
|
\`;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
`);
|
||||||
|
|
||||||
|
const editor = page.locator('shadow-element > .editor').first();
|
||||||
|
await editor.type('This is the first box.');
|
||||||
|
|
||||||
|
const sectionEditor = page.locator('section .editor');
|
||||||
|
await sectionEditor.type('This is the second box.');
|
||||||
|
|
||||||
|
expect(await editor.inputValue()).toBe('This is the first box.');
|
||||||
|
expect(await sectionEditor.inputValue()).toBe('This is the second box.');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('type to non-focusable element should maintain old focus', async ({ page }) => {
|
||||||
|
await page.setContent(`
|
||||||
|
<div id="focusable" tabindex="0">focusable div</div>
|
||||||
|
<div id="non-focusable-and-non-editable">non-editable, non-focusable</div>
|
||||||
|
`);
|
||||||
|
|
||||||
|
await page.locator('#focusable').focus();
|
||||||
|
expect(await page.evaluate(() => document.activeElement?.id)).toBe('focusable');
|
||||||
|
await page.locator('#non-focusable-and-non-editable').type('foo');
|
||||||
|
expect(await page.evaluate(() => document.activeElement?.id)).toBe('focusable');
|
||||||
|
});
|
||||||
|
|
||||||
async function captureLastKeydown(page) {
|
async function captureLastKeydown(page) {
|
||||||
const lastEvent = await page.evaluateHandle(() => {
|
const lastEvent = await page.evaluateHandle(() => {
|
||||||
const lastEvent = {
|
const lastEvent = {
|
||||||
|
|
|
||||||
|
|
@ -74,6 +74,42 @@ test('should disable animations by default', async ({ runInlineTest }, testInfo)
|
||||||
expect(result.exitCode).toBe(0);
|
expect(result.exitCode).toBe(0);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test.describe('expect config animations option', () => {
|
||||||
|
test('disabled', async ({ runInlineTest }, testInfo) => {
|
||||||
|
const cssTransitionURL = pathToFileURL(path.join(__dirname, '../assets/css-transition.html'));
|
||||||
|
const result = await runInlineTest({
|
||||||
|
...playwrightConfig({
|
||||||
|
expect: { toHaveScreenshot: { animations: 'disabled' } },
|
||||||
|
}),
|
||||||
|
'a.spec.js': `
|
||||||
|
pwt.test('is a test', async ({ page }) => {
|
||||||
|
await page.goto('${cssTransitionURL}');
|
||||||
|
await expect(page).toHaveScreenshot({ timeout: 2000 });
|
||||||
|
});
|
||||||
|
`
|
||||||
|
}, { 'update-snapshots': true });
|
||||||
|
expect(result.exitCode).toBe(0);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('allow', async ({ runInlineTest }, testInfo) => {
|
||||||
|
const cssTransitionURL = pathToFileURL(path.join(__dirname, '../assets/css-transition.html'));
|
||||||
|
const result = await runInlineTest({
|
||||||
|
...playwrightConfig({
|
||||||
|
expect: { toHaveScreenshot: { animations: 'allow' } },
|
||||||
|
}),
|
||||||
|
'a.spec.js': `
|
||||||
|
pwt.test('is a test', async ({ page }) => {
|
||||||
|
await page.goto('${cssTransitionURL}');
|
||||||
|
await expect(page).toHaveScreenshot({ timeout: 2000 });
|
||||||
|
});
|
||||||
|
`
|
||||||
|
}, { 'update-snapshots': true });
|
||||||
|
expect(result.exitCode).toBe(1);
|
||||||
|
expect(result.output).toContain('is-a-test-1-diff.png');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
test('should fail with proper error when unsupported argument is given', async ({ runInlineTest }, testInfo) => {
|
test('should fail with proper error when unsupported argument is given', async ({ runInlineTest }, testInfo) => {
|
||||||
const cssTransitionURL = pathToFileURL(path.join(__dirname, '../assets/css-transition.html'));
|
const cssTransitionURL = pathToFileURL(path.join(__dirname, '../assets/css-transition.html'));
|
||||||
const result = await runInlineTest({
|
const result = await runInlineTest({
|
||||||
|
|
@ -403,6 +439,8 @@ test('should compile with different option combinations', async ({ runTSC }) =>
|
||||||
const { test } = pwt;
|
const { test } = pwt;
|
||||||
test('is a test', async ({ page }) => {
|
test('is a test', async ({ page }) => {
|
||||||
await expect(page).toHaveScreenshot();
|
await expect(page).toHaveScreenshot();
|
||||||
|
await expect(page).toHaveScreenshot('img.png');
|
||||||
|
await expect(page).toHaveScreenshot('img.png', { threshold: 0.2, caret: 'initial' });
|
||||||
await expect(page.locator('body')).toHaveScreenshot({ threshold: 0.2 });
|
await expect(page.locator('body')).toHaveScreenshot({ threshold: 0.2 });
|
||||||
await expect(page).toHaveScreenshot({ maxDiffPixelRatio: 0.2 });
|
await expect(page).toHaveScreenshot({ maxDiffPixelRatio: 0.2 });
|
||||||
await expect(page).toHaveScreenshot({
|
await expect(page).toHaveScreenshot({
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue