Compare commits
23 commits
main
...
release-1.
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
64a18acf81 | ||
|
|
9e7001557e | ||
|
|
b8b1c40cf3 | ||
|
|
6eec55cffd | ||
|
|
cc00c207af | ||
|
|
5f3e3134bf | ||
|
|
0bdca2b913 | ||
|
|
f2916d4ced | ||
|
|
db88d4ba0f | ||
|
|
5d07c48e17 | ||
|
|
25c747d5ef | ||
|
|
ae7a8d2aa7 | ||
|
|
5c0e23d6aa | ||
|
|
0237b7b742 | ||
|
|
e78bd2436c | ||
|
|
d10cc91cf6 | ||
|
|
efa3756c16 | ||
|
|
00895e36d4 | ||
|
|
0cf3ec2e64 | ||
|
|
5c3be309df | ||
|
|
a100191ec9 | ||
|
|
4b871153d0 | ||
|
|
8a9692e2c5 |
|
|
@ -7,7 +7,7 @@ a way to find element(s) on the page at any moment. Locator can be created with
|
|||
[Learn more about locators](../locators.md).
|
||||
|
||||
## async method: Locator.all
|
||||
* since: v1.14
|
||||
* since: v1.29
|
||||
- returns: <[Array]<[Locator]>>
|
||||
|
||||
When locator points to a list of elements, returns array of locators, pointing
|
||||
|
|
|
|||
|
|
@ -114,11 +114,18 @@ If set changes the request method (e.g. GET or POST).
|
|||
|
||||
### option: Route.continue.postData
|
||||
* since: v1.8
|
||||
* langs: js, python, java
|
||||
* langs: js, python
|
||||
- `postData` <[string]|[Buffer]|[Serializable]>
|
||||
|
||||
If set changes the post data of request.
|
||||
|
||||
### option: Route.continue.postData
|
||||
* since: v1.8
|
||||
* langs: java
|
||||
- `postData` <[string]|[Buffer]>
|
||||
|
||||
If set changes the post data of request.
|
||||
|
||||
### option: Route.continue.postData
|
||||
* since: v1.8
|
||||
* langs: csharp
|
||||
|
|
@ -390,11 +397,18 @@ If set changes the request method (e.g. GET or POST).
|
|||
|
||||
### option: Route.fallback.postData
|
||||
* since: v1.23
|
||||
* langs: js, python, java
|
||||
* langs: js, python
|
||||
- `postData` <[string]|[Buffer]|[Serializable]>
|
||||
|
||||
If set changes the post data of request.
|
||||
|
||||
### option: Route.fallback.postData
|
||||
* since: v1.23
|
||||
* langs: java
|
||||
- `postData` <[string]|[Buffer]>
|
||||
|
||||
If set changes the post data of request.
|
||||
|
||||
### option: Route.fallback.postData
|
||||
* since: v1.23
|
||||
* langs: csharp
|
||||
|
|
@ -480,8 +494,21 @@ If set changes the request URL. New URL must have same protocol as original one.
|
|||
|
||||
If set changes the request method (e.g. GET or POST).
|
||||
|
||||
### option: Route.fetch.postData = %%-js-python-csharp-fetch-option-post-data-%%
|
||||
### option: Route.fetch.postData
|
||||
* langs: js, python
|
||||
* since: v1.29
|
||||
- `postData` <[string]|[Buffer]|[Serializable]>
|
||||
|
||||
Allows to set post data of the request. If the data parameter is an object, it will be serialized to json string
|
||||
and `content-type` header will be set to `application/json` if not explicitly set. Otherwise the `content-type` header will be
|
||||
set to `application/octet-stream` if not explicitly set.
|
||||
|
||||
### option: Route.fetch.postData
|
||||
* langs: java
|
||||
* since: v1.29
|
||||
- `postData` <[string]|[Buffer]>
|
||||
|
||||
If set changes the post data of request.
|
||||
|
||||
### option: Route.fetch.postData
|
||||
* since: v1.29
|
||||
|
|
@ -611,28 +638,11 @@ Optional response body as raw bytes.
|
|||
|
||||
### option: Route.fulfill.json
|
||||
* since: v1.29
|
||||
* langs: js, python
|
||||
* langs: js, python, csharp
|
||||
- `json` <[Serializable]>
|
||||
|
||||
JSON response. This method will set the content type to `application/json` if not set.
|
||||
|
||||
### option: Route.fulfill.json
|
||||
* since: v1.29
|
||||
* langs: csharp
|
||||
- `json` <[JsonElement]>
|
||||
|
||||
JSON response. This method will set the content type to `application/json` if not set.
|
||||
|
||||
**Usage**
|
||||
|
||||
```csharp
|
||||
await page.RouteAsync("https://dog.ceo/api/breeds/list/all", async route =>
|
||||
{
|
||||
var json = /* JsonElement with test payload */;
|
||||
await route.FulfillAsync(new () { Json: json });
|
||||
});
|
||||
```
|
||||
|
||||
### option: Route.fulfill.path
|
||||
* since: v1.8
|
||||
- `path` <[path]>
|
||||
|
|
|
|||
|
|
@ -2,8 +2,7 @@
|
|||
* since: v1.8
|
||||
* extends: [Error]
|
||||
|
||||
TimeoutError is emitted whenever certain operations are terminated due to timeout, e.g. [`method:
|
||||
Locator.waitFor`] or [`method: BrowserType.launch`].
|
||||
TimeoutError is emitted whenever certain operations are terminated due to timeout, e.g. [`method: Locator.waitFor`] or [`method: BrowserType.launch`].
|
||||
|
||||
```js
|
||||
const playwright = require('playwright');
|
||||
|
|
|
|||
|
|
@ -389,14 +389,6 @@ Allows to set post data of the request. If the data parameter is an object, it w
|
|||
and `content-type` header will be set to `application/json` if not explicitly set. Otherwise the `content-type` header will be
|
||||
set to `application/octet-stream` if not explicitly set.
|
||||
|
||||
## js-python-csharp-fetch-option-post-data
|
||||
* langs: js, python, csharp
|
||||
- `postData` <[string]|[Buffer]|[Serializable]>
|
||||
|
||||
Allows to set post data of the request. If the data parameter is an object, it will be serialized to json string
|
||||
and `content-type` header will be set to `application/json` if not explicitly set. Otherwise the `content-type` header will be
|
||||
set to `application/octet-stream` if not explicitly set.
|
||||
|
||||
## js-python-csharp-fetch-option-ignorehttpserrors
|
||||
* langs: js, python, csharp
|
||||
- `ignoreHTTPSErrors` <[boolean]>
|
||||
|
|
|
|||
|
|
@ -319,46 +319,9 @@ export default globalSetup;
|
|||
|
||||
By default, Playwright Test runs tests in parallel. If you reuse a single signed-in state for all your tests, this usually leads to the same account being signed in from multiple tests at the same time. If this behavior is undesirable for your application, you can sign in with a different account in each [worker process](./test-parallel.md#worker-processes) created by Playwright Test.
|
||||
|
||||
In this example we [override `storageState` fixture](./test-fixtures.md#overriding-fixtures) and ensure we only sign in once per worker, using [`property: TestInfo.workerIndex`] to differentiate between workers.
|
||||
In this example we [override `storageState` fixture](./test-fixtures.md#overriding-fixtures) and ensure we only sign in once per worker, using [`property: TestInfo.parallelIndex`] to differentiate between workers.
|
||||
|
||||
```js tab=js-js
|
||||
// fixtures.js
|
||||
const { test: base } = require('@playwright/test');
|
||||
|
||||
const users = [
|
||||
{ username: 'user-1', password: 'password-1' },
|
||||
{ username: 'user-2', password: 'password-2' },
|
||||
// ... put your test users here ...
|
||||
];
|
||||
|
||||
exports.test = base.extend({
|
||||
storageState: async ({ browser }, use, testInfo) => {
|
||||
// Override storage state, use worker index to look up logged-in info and generate it lazily.
|
||||
const fileName = path.join(testInfo.project.outputDir, 'storage-' + testInfo.workerIndex);
|
||||
if (!fs.existsSync(fileName)) {
|
||||
// Make sure we are not using any other storage state.
|
||||
const page = await browser.newPage({ storageState: undefined });
|
||||
await page.goto('https://github.com/login');
|
||||
await page.getByLabel('User Name').fill(users[testInfo.workerIndex].username);
|
||||
await page.getByLabel('Password').fill(users[testInfo.workerIndex].password);
|
||||
await page.getByText('Sign in').click();
|
||||
await page.context().storageState({ path: fileName });
|
||||
await page.close();
|
||||
}
|
||||
await use(fileName);
|
||||
},
|
||||
});
|
||||
exports.expect = base.expect;
|
||||
|
||||
// example.spec.js
|
||||
const { test, expect } = require('./fixtures');
|
||||
|
||||
test('test', async ({ page }) => {
|
||||
// page is signed in.
|
||||
});
|
||||
```
|
||||
|
||||
```js tab=js-ts
|
||||
```js
|
||||
// fixtures.ts
|
||||
import { test as baseTest } from '@playwright/test';
|
||||
export { expect } from '@playwright/test';
|
||||
|
|
@ -371,15 +334,15 @@ const users = [
|
|||
|
||||
export const test = baseTest.extend({
|
||||
storageState: async ({ browser }, use, testInfo) => {
|
||||
// Override storage state, use worker index to look up logged-in info and generate it lazily.
|
||||
const fileName = path.join(testInfo.project.outputDir, 'storage-' + testInfo.workerIndex);
|
||||
// Override storage state, use parallel index to look up logged-in info and generate it lazily.
|
||||
const fileName = path.join(testInfo.project.outputDir, 'storage-' + testInfo.parallelIndex);
|
||||
if (!fs.existsSync(fileName)) {
|
||||
// Make sure we are not using any other storage state.
|
||||
const page = await browser.newPage({ storageState: undefined });
|
||||
await page.goto('https://github.com/login');
|
||||
// Create a unique username for each worker.
|
||||
await page.getByLabel('User Name').fill(users[testInfo.workerIndex].username);
|
||||
await page.getByLabel('Password').fill(users[testInfo.workerIndex].password);
|
||||
await page.getByLabel('User Name').fill(users[testInfo.parallelIndex].username);
|
||||
await page.getByLabel('Password').fill(users[testInfo.parallelIndex].password);
|
||||
await page.getByText('Sign in').click();
|
||||
await page.context().storageState({ path: fileName });
|
||||
await page.close();
|
||||
|
|
|
|||
|
|
@ -176,7 +176,7 @@ steps:
|
|||
name: 'Playwright Tests'
|
||||
runs-on: ubuntu-latest
|
||||
container:
|
||||
image: mcr.microsoft.com/playwright:v1.29.0-focal
|
||||
image: mcr.microsoft.com/playwright:v1.29.2-focal
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/setup-node@v3
|
||||
|
|
@ -194,7 +194,7 @@ steps:
|
|||
name: 'Playwright Tests'
|
||||
runs-on: ubuntu-latest
|
||||
container:
|
||||
image: mcr.microsoft.com/playwright:v1.29.0-focal
|
||||
image: mcr.microsoft.com/playwright:v1.29.2-focal
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: Set up Python
|
||||
|
|
@ -218,7 +218,7 @@ steps:
|
|||
name: 'Playwright Tests'
|
||||
runs-on: ubuntu-latest
|
||||
container:
|
||||
image: mcr.microsoft.com/playwright:v1.29.0-focal
|
||||
image: mcr.microsoft.com/playwright:v1.29.2-focal
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/setup-java@v3
|
||||
|
|
@ -239,7 +239,7 @@ steps:
|
|||
name: 'Playwright Tests'
|
||||
runs-on: ubuntu-latest
|
||||
container:
|
||||
image: mcr.microsoft.com/playwright:v1.29.0-focal
|
||||
image: mcr.microsoft.com/playwright:v1.29.2-focal
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: Setup dotnet
|
||||
|
|
@ -264,7 +264,7 @@ steps:
|
|||
name: 'Playwright Tests - ${{ matrix.project }} - Shard ${{ matrix.shardIndex }} of ${{ matrix.shardTotal }}'
|
||||
runs-on: ubuntu-latest
|
||||
container:
|
||||
image: mcr.microsoft.com/playwright:v1.29.0-focal
|
||||
image: mcr.microsoft.com/playwright:v1.29.2-focal
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
|
|
@ -299,7 +299,7 @@ jobs:
|
|||
- deployment: Run_E2E_Tests
|
||||
pool:
|
||||
vmImage: ubuntu-20.04
|
||||
container: mcr.microsoft.com/playwright:v1.29.0-focal
|
||||
container: mcr.microsoft.com/playwright:v1.29.2-focal
|
||||
environment: testing
|
||||
strategy:
|
||||
runOnce:
|
||||
|
|
@ -325,7 +325,7 @@ jobs:
|
|||
- deployment: Run_E2E_Tests
|
||||
pool:
|
||||
vmImage: ubuntu-20.04
|
||||
container: mcr.microsoft.com/playwright:v1.29.0-focal
|
||||
container: mcr.microsoft.com/playwright:v1.29.2-focal
|
||||
environment: testing
|
||||
strategy:
|
||||
runOnce:
|
||||
|
|
@ -369,7 +369,7 @@ Running Playwright on CircleCI is very similar to running on GitHub Actions. In
|
|||
executors:
|
||||
pw-focal-development:
|
||||
docker:
|
||||
- image: mcr.microsoft.com/playwright:v1.29.0-focal
|
||||
- image: mcr.microsoft.com/playwright:v1.29.2-focal
|
||||
environment:
|
||||
NODE_ENV: development # Needed if playwright is in `devDependencies`
|
||||
```
|
||||
|
|
@ -405,7 +405,7 @@ to run tests on Jenkins.
|
|||
|
||||
```groovy
|
||||
pipeline {
|
||||
agent { docker { image 'mcr.microsoft.com/playwright:v1.29.0-focal' } }
|
||||
agent { docker { image 'mcr.microsoft.com/playwright:v1.29.2-focal' } }
|
||||
stages {
|
||||
stage('e2e-tests') {
|
||||
steps {
|
||||
|
|
@ -423,7 +423,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)).
|
||||
|
||||
```yml
|
||||
image: mcr.microsoft.com/playwright:v1.29.0-focal
|
||||
image: mcr.microsoft.com/playwright:v1.29.2-focal
|
||||
```
|
||||
|
||||
### GitLab CI
|
||||
|
|
@ -436,7 +436,7 @@ stages:
|
|||
|
||||
tests:
|
||||
stage: test
|
||||
image: mcr.microsoft.com/playwright:v1.29.0-focal
|
||||
image: mcr.microsoft.com/playwright:v1.29.2-focal
|
||||
script:
|
||||
...
|
||||
```
|
||||
|
|
@ -452,7 +452,7 @@ stages:
|
|||
|
||||
tests:
|
||||
stage: test
|
||||
image: mcr.microsoft.com/playwright:v1.29.0-focal
|
||||
image: mcr.microsoft.com/playwright:v1.29.2-focal
|
||||
parallel: 7
|
||||
script:
|
||||
- npm ci
|
||||
|
|
@ -467,7 +467,7 @@ stages:
|
|||
|
||||
tests:
|
||||
stage: test
|
||||
image: mcr.microsoft.com/playwright:v1.29.0-focal
|
||||
image: mcr.microsoft.com/playwright:v1.29.2-focal
|
||||
parallel:
|
||||
matrix:
|
||||
- PROJECT: ['chromium', 'webkit']
|
||||
|
|
|
|||
|
|
@ -14,19 +14,19 @@ This image is published on [Docker Hub].
|
|||
### Pull the image
|
||||
|
||||
```bash js
|
||||
docker pull mcr.microsoft.com/playwright:v1.29.0-focal
|
||||
docker pull mcr.microsoft.com/playwright:v1.29.2-focal
|
||||
```
|
||||
|
||||
```bash python
|
||||
docker pull mcr.microsoft.com/playwright/python:v1.29.0-focal
|
||||
docker pull mcr.microsoft.com/playwright/python:v1.29.2-focal
|
||||
```
|
||||
|
||||
```bash csharp
|
||||
docker pull mcr.microsoft.com/playwright/dotnet:v1.29.0-focal
|
||||
docker pull mcr.microsoft.com/playwright/dotnet:v1.29.2-focal
|
||||
```
|
||||
|
||||
```bash java
|
||||
docker pull mcr.microsoft.com/playwright/java:v1.29.0-focal
|
||||
docker pull mcr.microsoft.com/playwright/java:v1.29.2-focal
|
||||
```
|
||||
|
||||
### 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.
|
||||
|
||||
```bash js
|
||||
docker run -it --rm --ipc=host mcr.microsoft.com/playwright:v1.29.0-focal /bin/bash
|
||||
docker run -it --rm --ipc=host mcr.microsoft.com/playwright:v1.29.2-focal /bin/bash
|
||||
```
|
||||
|
||||
```bash python
|
||||
docker run -it --rm --ipc=host mcr.microsoft.com/playwright/python:v1.29.0-focal /bin/bash
|
||||
docker run -it --rm --ipc=host mcr.microsoft.com/playwright/python:v1.29.2-focal /bin/bash
|
||||
```
|
||||
|
||||
```bash csharp
|
||||
docker run -it --rm --ipc=host mcr.microsoft.com/playwright/dotnet:v1.29.0-focal /bin/bash
|
||||
docker run -it --rm --ipc=host mcr.microsoft.com/playwright/dotnet:v1.29.2-focal /bin/bash
|
||||
```
|
||||
|
||||
```bash java
|
||||
docker run -it --rm --ipc=host mcr.microsoft.com/playwright/java:v1.29.0-focal /bin/bash
|
||||
docker run -it --rm --ipc=host mcr.microsoft.com/playwright/java:v1.29.2-focal /bin/bash
|
||||
```
|
||||
|
||||
#### Crawling and scraping
|
||||
|
|
@ -58,19 +58,19 @@ docker run -it --rm --ipc=host mcr.microsoft.com/playwright/java:v1.29.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.
|
||||
|
||||
```bash js
|
||||
docker run -it --rm --ipc=host --user pwuser --security-opt seccomp=seccomp_profile.json mcr.microsoft.com/playwright:v1.29.0-focal /bin/bash
|
||||
docker run -it --rm --ipc=host --user pwuser --security-opt seccomp=seccomp_profile.json mcr.microsoft.com/playwright:v1.29.2-focal /bin/bash
|
||||
```
|
||||
|
||||
```bash python
|
||||
docker run -it --rm --ipc=host --user pwuser --security-opt seccomp=seccomp_profile.json mcr.microsoft.com/playwright/python:v1.29.0-focal /bin/bash
|
||||
docker run -it --rm --ipc=host --user pwuser --security-opt seccomp=seccomp_profile.json mcr.microsoft.com/playwright/python:v1.29.2-focal /bin/bash
|
||||
```
|
||||
|
||||
```bash csharp
|
||||
docker run -it --rm --ipc=host --user pwuser --security-opt seccomp=seccomp_profile.json mcr.microsoft.com/playwright/dotnet:v1.29.0-focal /bin/bash
|
||||
docker run -it --rm --ipc=host --user pwuser --security-opt seccomp=seccomp_profile.json mcr.microsoft.com/playwright/dotnet:v1.29.2-focal /bin/bash
|
||||
```
|
||||
|
||||
```bash java
|
||||
docker run -it --rm --ipc=host --user pwuser --security-opt seccomp=seccomp_profile.json mcr.microsoft.com/playwright/java:v1.29.0-focal /bin/bash
|
||||
docker run -it --rm --ipc=host --user pwuser --security-opt seccomp=seccomp_profile.json mcr.microsoft.com/playwright/java:v1.29.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:
|
||||
|
|
|
|||
|
|
@ -815,7 +815,7 @@ Consider the following DOM structure where we want to click on the buy button of
|
|||
<h3>Product 2</h3>
|
||||
<button>Add to cart</button>
|
||||
</li>
|
||||
<ul>
|
||||
</ul>
|
||||
```
|
||||
|
||||
### Filter by text
|
||||
|
|
@ -854,7 +854,7 @@ page.get_by_role("listitem").filter(has_text="Product 2").get_by_role(
|
|||
await page
|
||||
.GetByRole(AriaRole.Listitem)
|
||||
.Filter(new() { HasText = "Product 2" })
|
||||
.GetByRole(AriaRole.Button, new () { Name = "Add to cart" })
|
||||
.GetByRole(AriaRole.Button, new() { Name = "Add to cart" })
|
||||
.ClickAsync();
|
||||
```
|
||||
|
||||
|
|
@ -893,7 +893,7 @@ page.get_by_role("listitem").filter(has_text=re.compile("Product 2")).get_by_rol
|
|||
await page
|
||||
.GetByRole(AriaRole.Listitem)
|
||||
.Filter(new() { HasTextRegex = new Regex("Product 2") })
|
||||
.GetByRole(AriaRole.Button, new () { Name = "Add to cart" })
|
||||
.GetByRole(AriaRole.Button, new() { Name = "Add to cart" })
|
||||
.ClickAsync();
|
||||
```
|
||||
|
||||
|
|
@ -948,11 +948,11 @@ page.get_by_role("listitem").filter(
|
|||
await page
|
||||
.GetByRole(AriaRole.Listitem)
|
||||
.Filter(new() {
|
||||
Has = page.GetByRole(AriaRole.Heading, new () {
|
||||
Has = page.GetByRole(AriaRole.Heading, new() {
|
||||
Name = "Product 2"
|
||||
})
|
||||
})
|
||||
.GetByRole(AriaRole.Button, new () { Name = "Add to cart" })
|
||||
.GetByRole(AriaRole.Button, new() { Name = "Add to cart" })
|
||||
.ClickAsync();
|
||||
```
|
||||
|
||||
|
|
@ -992,7 +992,7 @@ expect(
|
|||
await Expect(page
|
||||
.GetByRole(AriaRole.Listitem)
|
||||
.Filter(new() {
|
||||
Has = page.GetByRole(AriaRole.Heading, new () { Name = "Product 2" })
|
||||
Has = page.GetByRole(AriaRole.Heading, new() { Name = "Product 2" })
|
||||
})
|
||||
.toHaveCountAsync(1);
|
||||
```
|
||||
|
|
|
|||
|
|
@ -4,6 +4,63 @@ title: "Release notes"
|
|||
toc_max_heading_level: 2
|
||||
---
|
||||
|
||||
## Version 1.29
|
||||
|
||||
### New APIs
|
||||
|
||||
- New method [`method: Route.fetch`] and new option `Json` for [`method: Route.fulfill`]:
|
||||
|
||||
```csharp
|
||||
await Page.RouteAsync("**/api/settings", async route => {
|
||||
// Fetch original settings.
|
||||
var response = await route.FetchAsync();
|
||||
|
||||
// Force settings theme to a predefined value.
|
||||
var json = await response.JsonAsync<MyDataType>();
|
||||
json.Theme = "Solarized";
|
||||
|
||||
// Fulfill with modified data.
|
||||
await route.FulfillAsync(new() {
|
||||
Json = json
|
||||
});
|
||||
});
|
||||
```
|
||||
|
||||
- New method [`method: Locator.all`] to iterate over all matching elements:
|
||||
|
||||
```csharp
|
||||
// Check all checkboxes!
|
||||
var checkboxes = Page.GetByRole(AriaRole.Checkbox);
|
||||
foreach (var checkbox in await checkboxes.AllAsync())
|
||||
await checkbox.CheckAsync();
|
||||
```
|
||||
|
||||
- [`method: Locator.selectOption`] matches now by value or label:
|
||||
|
||||
```html
|
||||
<select multiple>
|
||||
<option value="red">Red</div>
|
||||
<option value="green">Green</div>
|
||||
<option value="blue">Blue</div>
|
||||
</select>
|
||||
```
|
||||
|
||||
```csharp
|
||||
await element.SelectOptionAsync("Red");
|
||||
```
|
||||
|
||||
### Browser Versions
|
||||
|
||||
* Chromium 109.0.5414.46
|
||||
* Mozilla Firefox 107.0
|
||||
* WebKit 16.4
|
||||
|
||||
This version was also tested against the following stable channels:
|
||||
|
||||
* Google Chrome 108
|
||||
* Microsoft Edge 108
|
||||
|
||||
|
||||
## Version 1.28
|
||||
|
||||
### Playwright Tools
|
||||
|
|
|
|||
|
|
@ -4,6 +4,44 @@ title: "Release notes"
|
|||
toc_max_heading_level: 2
|
||||
---
|
||||
|
||||
## Version 1.29
|
||||
|
||||
### New APIs
|
||||
|
||||
- New method [`method: Locator.all`] to iterate over all matching elements:
|
||||
|
||||
```java
|
||||
// Check all checkboxes!
|
||||
Locator checkboxes = page.getByRole(AriaRole.CHECKBOX);
|
||||
for (Locator checkbox : checkboxes.all())
|
||||
checkbox.check();
|
||||
```
|
||||
|
||||
- [`method: Locator.selectOption`] matches now by value or label:
|
||||
|
||||
```html
|
||||
<select multiple>
|
||||
<option value="red">Red</div>
|
||||
<option value="green">Green</div>
|
||||
<option value="blue">Blue</div>
|
||||
</select>
|
||||
```
|
||||
|
||||
```java
|
||||
element.selectOption('Red');
|
||||
```
|
||||
|
||||
### Browser Versions
|
||||
|
||||
* Chromium 109.0.5414.46
|
||||
* Mozilla Firefox 107.0
|
||||
* WebKit 16.4
|
||||
|
||||
This version was also tested against the following stable channels:
|
||||
|
||||
* Google Chrome 108
|
||||
* Microsoft Edge 108
|
||||
|
||||
## Version 1.28
|
||||
|
||||
### Playwright Tools
|
||||
|
|
|
|||
|
|
@ -4,6 +4,94 @@ title: "Release notes"
|
|||
toc_max_heading_level: 2
|
||||
---
|
||||
|
||||
## Version 1.29
|
||||
|
||||
### New APIs
|
||||
|
||||
- New method [`method: Route.fetch`] and new option `json` for [`method: Route.fulfill`]:
|
||||
|
||||
```js
|
||||
await page.route('**/api/settings', async route => {
|
||||
// Fetch original settings.
|
||||
const response = await route.fetch();
|
||||
|
||||
// Force settings theme to a predefined value.
|
||||
const json = await response.json();
|
||||
json.theme = 'Solorized';
|
||||
|
||||
// Fulfill with modified data.
|
||||
await route.fulfill({ json });
|
||||
});
|
||||
```
|
||||
|
||||
- New method [`method: Locator.all`] to iterate over all matching elements:
|
||||
|
||||
```js
|
||||
// Check all checkboxes!
|
||||
const checkboxes = page.getByRole('checkbox');
|
||||
for (const checkbox of await checkboxes.all())
|
||||
await checkbox.check();
|
||||
```
|
||||
|
||||
- [`method: Locator.selectOption`] matches now by value or label:
|
||||
|
||||
```html
|
||||
<select multiple>
|
||||
<option value="red">Red</div>
|
||||
<option value="green">Green</div>
|
||||
<option value="blue">Blue</div>
|
||||
</select>
|
||||
```
|
||||
|
||||
```js
|
||||
await element.selectOption('Red');
|
||||
```
|
||||
|
||||
- Retry blocks of code until all assertions pass:
|
||||
|
||||
```js
|
||||
await expect(async () => {
|
||||
const response = await page.request.get('https://api.example.com');
|
||||
await expect(response).toBeOK();
|
||||
}).toPass();
|
||||
```
|
||||
|
||||
Read more in [our documentation](./test-assertions.md#retrying).
|
||||
|
||||
- Automatically capture **full page screenshot** on test failure:
|
||||
```js
|
||||
// playwright.config.ts
|
||||
import type { PlaywrightTestConfig } from '@playwright/test';
|
||||
|
||||
const config: PlaywrightTestConfig = {
|
||||
use: {
|
||||
screenshot: {
|
||||
mode: 'only-on-failure',
|
||||
fullPage: true,
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
export default config;
|
||||
```
|
||||
|
||||
### Miscellaneous
|
||||
|
||||
- Playwright Test now respects [`jsconfig.json`](https://code.visualstudio.com/docs/languages/jsconfig).
|
||||
- New options `args` and `proxy` for [`method: AndroidDevice.launchBrowser`].
|
||||
- Option `postData` in method [`method: Route.continue`] now supports [Serializable] values.
|
||||
|
||||
### Browser Versions
|
||||
|
||||
* Chromium 109.0.5414.46
|
||||
* Mozilla Firefox 107.0
|
||||
* WebKit 16.4
|
||||
|
||||
This version was also tested against the following stable channels:
|
||||
|
||||
* Google Chrome 108
|
||||
* Microsoft Edge 108
|
||||
|
||||
## Version 1.28
|
||||
|
||||
<div className="embed-youtube">
|
||||
|
|
@ -218,7 +306,7 @@ This version was also tested against the following stable channels:
|
|||
|
||||
### Announcements
|
||||
|
||||
* 🎁 We now ship Ubuntu 22.04 Jammy Jellyfish docker image: `mcr.microsoft.com/playwright:v1.29.0-jammy`.
|
||||
* 🎁 We now ship Ubuntu 22.04 Jammy Jellyfish docker image: `mcr.microsoft.com/playwright:v1.29.2-jammy`.
|
||||
* 🪦 This is the last release with macOS 10.15 support (deprecated as of 1.21).
|
||||
* 🪦 This is the last release with Node.js 12 support, we recommend upgrading to Node.js LTS (16).
|
||||
* ⚠️ Ubuntu 18 is now deprecated and will not be supported as of Dec 2022.
|
||||
|
|
@ -468,7 +556,7 @@ Read more about [component testing with Playwright](./test-components).
|
|||
}
|
||||
});
|
||||
```
|
||||
* Playwright now runs on Ubuntu 22 amd64 and Ubuntu 22 arm64. We also publish new docker image `mcr.microsoft.com/playwright:v1.29.0-jammy`.
|
||||
* Playwright now runs on Ubuntu 22 amd64 and Ubuntu 22 arm64. We also publish new docker image `mcr.microsoft.com/playwright:v1.29.2-jammy`.
|
||||
|
||||
### ⚠️ Breaking Changes ⚠️
|
||||
|
||||
|
|
|
|||
|
|
@ -4,6 +4,66 @@ title: "Release notes"
|
|||
toc_max_heading_level: 2
|
||||
---
|
||||
|
||||
## Version 1.29
|
||||
|
||||
### New APIs
|
||||
|
||||
- New method [`method: Route.fetch`] and new option `json` for [`method: Route.fulfill`]:
|
||||
|
||||
```python
|
||||
def handle_route(route: Route):
|
||||
# Fetch original settings.
|
||||
response = route.fetch()
|
||||
|
||||
# Force settings theme to a predefined value.
|
||||
json = response.json()
|
||||
json["theme"] = "Solorized"
|
||||
|
||||
# Fulfill with modified data.
|
||||
route.fulfill(json=json)
|
||||
|
||||
|
||||
page.route("**/api/settings", handle_route)
|
||||
```
|
||||
|
||||
- New method [`method: Locator.all`] to iterate over all matching elements:
|
||||
|
||||
```python
|
||||
# Check all checkboxes!
|
||||
checkboxes = page.get_by_role("checkbox")
|
||||
for checkbox in checkboxes.all():
|
||||
checkbox.check()
|
||||
```
|
||||
|
||||
- [`method: Locator.selectOption`] matches now by value or label:
|
||||
|
||||
```html
|
||||
<select multiple>
|
||||
<option value="red">Red</div>
|
||||
<option value="green">Green</div>
|
||||
<option value="blue">Blue</div>
|
||||
</select>
|
||||
```
|
||||
|
||||
```python
|
||||
element.select_option("Red")
|
||||
```
|
||||
|
||||
### Miscellaneous
|
||||
|
||||
- Option `postData` in method [`method: Route.continue`] now supports [Serializable] values.
|
||||
|
||||
### Browser Versions
|
||||
|
||||
* Chromium 109.0.5414.46
|
||||
* Mozilla Firefox 107.0
|
||||
* WebKit 16.4
|
||||
|
||||
This version was also tested against the following stable channels:
|
||||
|
||||
* Google Chrome 108
|
||||
* Microsoft Edge 108
|
||||
|
||||
## Version 1.28
|
||||
|
||||
### Playwright Tools
|
||||
|
|
@ -122,7 +182,7 @@ This version was also tested against the following stable channels:
|
|||
|
||||
### Announcements
|
||||
|
||||
* 🎁 We now ship Ubuntu 22.04 Jammy Jellyfish docker image: `mcr.microsoft.com/playwright/python:v1.29.0-jammy`.
|
||||
* 🎁 We now ship Ubuntu 22.04 Jammy Jellyfish docker image: `mcr.microsoft.com/playwright/python:v1.29.2-jammy`.
|
||||
* 🪦 This is the last release with macOS 10.15 support (deprecated as of 1.21).
|
||||
* ⚠️ Ubuntu 18 is now deprecated and will not be supported as of Dec 2022.
|
||||
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
||||
```bash
|
||||
docker run --rm --network host -v $(pwd):/work/ -w /work/ -it mcr.microsoft.com/playwright:v1.29.0-focal /bin/bash
|
||||
docker run --rm --network host -v $(pwd):/work/ -w /work/ -it mcr.microsoft.com/playwright:v1.29.2-focal /bin/bash
|
||||
npm install
|
||||
npx playwright test --update-snapshots
|
||||
```
|
||||
|
|
|
|||
75
package-lock.json
generated
75
package-lock.json
generated
|
|
@ -1,12 +1,12 @@
|
|||
{
|
||||
"name": "playwright-internal",
|
||||
"version": "1.29.0-next",
|
||||
"version": "1.29.2",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "playwright-internal",
|
||||
"version": "1.29.0-next",
|
||||
"version": "1.29.2",
|
||||
"license": "Apache-2.0",
|
||||
"workspaces": [
|
||||
"packages/*"
|
||||
|
|
@ -3754,8 +3754,9 @@
|
|||
"optional": true
|
||||
},
|
||||
"node_modules/json5": {
|
||||
"version": "2.2.1",
|
||||
"license": "MIT",
|
||||
"version": "2.2.2",
|
||||
"resolved": "https://registry.npmjs.org/json5/-/json5-2.2.2.tgz",
|
||||
"integrity": "sha512-46Tk9JiOL2z7ytNQWFLpj99RZkVgeHf87yGQKsIkaPz1qSH9UczKH1rO7K3wgRselo0tYMUNfecYpm/p1vC7tQ==",
|
||||
"bin": {
|
||||
"json5": "lib/cli.js"
|
||||
},
|
||||
|
|
@ -5886,11 +5887,11 @@
|
|||
"version": "0.0.0"
|
||||
},
|
||||
"packages/playwright": {
|
||||
"version": "1.29.0-next",
|
||||
"version": "1.29.2",
|
||||
"hasInstallScript": true,
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"playwright-core": "1.29.0-next"
|
||||
"playwright-core": "1.29.2"
|
||||
},
|
||||
"bin": {
|
||||
"playwright": "cli.js"
|
||||
|
|
@ -5900,11 +5901,11 @@
|
|||
}
|
||||
},
|
||||
"packages/playwright-chromium": {
|
||||
"version": "1.29.0-next",
|
||||
"version": "1.29.2",
|
||||
"hasInstallScript": true,
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"playwright-core": "1.29.0-next"
|
||||
"playwright-core": "1.29.2"
|
||||
},
|
||||
"bin": {
|
||||
"playwright": "cli.js"
|
||||
|
|
@ -5914,7 +5915,7 @@
|
|||
}
|
||||
},
|
||||
"packages/playwright-core": {
|
||||
"version": "1.29.0-next",
|
||||
"version": "1.29.2",
|
||||
"license": "Apache-2.0",
|
||||
"bin": {
|
||||
"playwright": "cli.js"
|
||||
|
|
@ -5925,10 +5926,10 @@
|
|||
},
|
||||
"packages/playwright-ct-react": {
|
||||
"name": "@playwright/experimental-ct-react",
|
||||
"version": "1.29.0-next",
|
||||
"version": "1.29.2",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@playwright/test": "1.29.0-next",
|
||||
"@playwright/test": "1.29.2",
|
||||
"@vitejs/plugin-react": "^2.2.0",
|
||||
"vite": "^3.2.1"
|
||||
},
|
||||
|
|
@ -5965,10 +5966,10 @@
|
|||
},
|
||||
"packages/playwright-ct-solid": {
|
||||
"name": "@playwright/experimental-ct-solid",
|
||||
"version": "1.29.0-next",
|
||||
"version": "1.29.2",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@playwright/test": "1.29.0-next",
|
||||
"@playwright/test": "1.29.2",
|
||||
"vite": "^3.2.1",
|
||||
"vite-plugin-solid": "^2.3.10"
|
||||
},
|
||||
|
|
@ -5981,10 +5982,10 @@
|
|||
},
|
||||
"packages/playwright-ct-svelte": {
|
||||
"name": "@playwright/experimental-ct-svelte",
|
||||
"version": "1.29.0-next",
|
||||
"version": "1.29.2",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@playwright/test": "1.29.0-next",
|
||||
"@playwright/test": "1.29.2",
|
||||
"@sveltejs/vite-plugin-svelte": "^1.1.0",
|
||||
"vite": "^3.2.1"
|
||||
},
|
||||
|
|
@ -5997,10 +5998,10 @@
|
|||
},
|
||||
"packages/playwright-ct-vue": {
|
||||
"name": "@playwright/experimental-ct-vue",
|
||||
"version": "1.29.0-next",
|
||||
"version": "1.29.2",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@playwright/test": "1.29.0-next",
|
||||
"@playwright/test": "1.29.2",
|
||||
"@vitejs/plugin-vue": "^3.2.0",
|
||||
"vite": "^3.2.1"
|
||||
},
|
||||
|
|
@ -6046,10 +6047,10 @@
|
|||
},
|
||||
"packages/playwright-ct-vue2": {
|
||||
"name": "@playwright/experimental-ct-vue2",
|
||||
"version": "1.29.0-next",
|
||||
"version": "1.29.2",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@playwright/test": "1.29.0-next",
|
||||
"@playwright/test": "1.29.2",
|
||||
"@vitejs/plugin-vue2": "^2.0.0",
|
||||
"vite": "^3.2.1"
|
||||
},
|
||||
|
|
@ -6061,11 +6062,11 @@
|
|||
}
|
||||
},
|
||||
"packages/playwright-firefox": {
|
||||
"version": "1.29.0-next",
|
||||
"version": "1.29.2",
|
||||
"hasInstallScript": true,
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"playwright-core": "1.29.0-next"
|
||||
"playwright-core": "1.29.2"
|
||||
},
|
||||
"bin": {
|
||||
"playwright": "cli.js"
|
||||
|
|
@ -6076,11 +6077,11 @@
|
|||
},
|
||||
"packages/playwright-test": {
|
||||
"name": "@playwright/test",
|
||||
"version": "1.29.0-next",
|
||||
"version": "1.29.2",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@types/node": "*",
|
||||
"playwright-core": "1.29.0-next"
|
||||
"playwright-core": "1.29.2"
|
||||
},
|
||||
"bin": {
|
||||
"playwright": "cli.js"
|
||||
|
|
@ -6090,11 +6091,11 @@
|
|||
}
|
||||
},
|
||||
"packages/playwright-webkit": {
|
||||
"version": "1.29.0-next",
|
||||
"version": "1.29.2",
|
||||
"hasInstallScript": true,
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"playwright-core": "1.29.0-next"
|
||||
"playwright-core": "1.29.2"
|
||||
},
|
||||
"bin": {
|
||||
"playwright": "cli.js"
|
||||
|
|
@ -6698,7 +6699,7 @@
|
|||
"@playwright/experimental-ct-react": {
|
||||
"version": "file:packages/playwright-ct-react",
|
||||
"requires": {
|
||||
"@playwright/test": "1.29.0-next",
|
||||
"@playwright/test": "1.29.2",
|
||||
"@vitejs/plugin-react": "^2.2.0",
|
||||
"vite": "^3.2.1"
|
||||
},
|
||||
|
|
@ -6725,7 +6726,7 @@
|
|||
"@playwright/experimental-ct-solid": {
|
||||
"version": "file:packages/playwright-ct-solid",
|
||||
"requires": {
|
||||
"@playwright/test": "1.29.0-next",
|
||||
"@playwright/test": "1.29.2",
|
||||
"solid-js": "^1.4.7",
|
||||
"vite": "^3.2.1",
|
||||
"vite-plugin-solid": "^2.3.10"
|
||||
|
|
@ -6734,7 +6735,7 @@
|
|||
"@playwright/experimental-ct-svelte": {
|
||||
"version": "file:packages/playwright-ct-svelte",
|
||||
"requires": {
|
||||
"@playwright/test": "1.29.0-next",
|
||||
"@playwright/test": "1.29.2",
|
||||
"@sveltejs/vite-plugin-svelte": "^1.1.0",
|
||||
"svelte": "^3.49.0",
|
||||
"vite": "^3.2.1"
|
||||
|
|
@ -6743,7 +6744,7 @@
|
|||
"@playwright/experimental-ct-vue": {
|
||||
"version": "file:packages/playwright-ct-vue",
|
||||
"requires": {
|
||||
"@playwright/test": "1.29.0-next",
|
||||
"@playwright/test": "1.29.2",
|
||||
"@vitejs/plugin-vue": "^3.2.0",
|
||||
"vite": "^3.2.1"
|
||||
},
|
||||
|
|
@ -6778,7 +6779,7 @@
|
|||
"@playwright/experimental-ct-vue2": {
|
||||
"version": "file:packages/playwright-ct-vue2",
|
||||
"requires": {
|
||||
"@playwright/test": "1.29.0-next",
|
||||
"@playwright/test": "1.29.2",
|
||||
"@vitejs/plugin-vue2": "^2.0.0",
|
||||
"vite": "^3.2.1",
|
||||
"vue": "^2.7.13"
|
||||
|
|
@ -6788,7 +6789,7 @@
|
|||
"version": "file:packages/playwright-test",
|
||||
"requires": {
|
||||
"@types/node": "*",
|
||||
"playwright-core": "1.29.0-next"
|
||||
"playwright-core": "1.29.2"
|
||||
}
|
||||
},
|
||||
"@rollup/pluginutils": {
|
||||
|
|
@ -8534,7 +8535,9 @@
|
|||
"optional": true
|
||||
},
|
||||
"json5": {
|
||||
"version": "2.2.1"
|
||||
"version": "2.2.2",
|
||||
"resolved": "https://registry.npmjs.org/json5/-/json5-2.2.2.tgz",
|
||||
"integrity": "sha512-46Tk9JiOL2z7ytNQWFLpj99RZkVgeHf87yGQKsIkaPz1qSH9UczKH1rO7K3wgRselo0tYMUNfecYpm/p1vC7tQ=="
|
||||
},
|
||||
"jsonfile": {
|
||||
"version": "4.0.0",
|
||||
|
|
@ -8899,13 +8902,13 @@
|
|||
"playwright": {
|
||||
"version": "file:packages/playwright",
|
||||
"requires": {
|
||||
"playwright-core": "1.29.0-next"
|
||||
"playwright-core": "1.29.2"
|
||||
}
|
||||
},
|
||||
"playwright-chromium": {
|
||||
"version": "file:packages/playwright-chromium",
|
||||
"requires": {
|
||||
"playwright-core": "1.29.0-next"
|
||||
"playwright-core": "1.29.2"
|
||||
}
|
||||
},
|
||||
"playwright-core": {
|
||||
|
|
@ -8914,13 +8917,13 @@
|
|||
"playwright-firefox": {
|
||||
"version": "file:packages/playwright-firefox",
|
||||
"requires": {
|
||||
"playwright-core": "1.29.0-next"
|
||||
"playwright-core": "1.29.2"
|
||||
}
|
||||
},
|
||||
"playwright-webkit": {
|
||||
"version": "file:packages/playwright-webkit",
|
||||
"requires": {
|
||||
"playwright-core": "1.29.0-next"
|
||||
"playwright-core": "1.29.2"
|
||||
}
|
||||
},
|
||||
"postcss": {
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"name": "playwright-internal",
|
||||
"private": true,
|
||||
"version": "1.29.0-next",
|
||||
"version": "1.29.2",
|
||||
"description": "A high-level API to automate web browsers",
|
||||
"repository": "github:Microsoft/playwright",
|
||||
"homepage": "https://playwright.dev",
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "playwright-chromium",
|
||||
"version": "1.29.0-next",
|
||||
"version": "1.29.2",
|
||||
"description": "A high-level API to automate Chromium",
|
||||
"repository": "github:Microsoft/playwright",
|
||||
"homepage": "https://playwright.dev",
|
||||
|
|
@ -28,6 +28,6 @@
|
|||
"install": "node install.js"
|
||||
},
|
||||
"dependencies": {
|
||||
"playwright-core": "1.29.0-next"
|
||||
"playwright-core": "1.29.2"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,13 +3,13 @@
|
|||
"browsers": [
|
||||
{
|
||||
"name": "chromium",
|
||||
"revision": "1040",
|
||||
"revision": "1041",
|
||||
"installByDefault": true,
|
||||
"browserVersion": "109.0.5414.46"
|
||||
},
|
||||
{
|
||||
"name": "chromium-with-symbols",
|
||||
"revision": "1040",
|
||||
"revision": "1041",
|
||||
"installByDefault": false,
|
||||
"browserVersion": "109.0.5414.46"
|
||||
},
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "playwright-core",
|
||||
"version": "1.29.0-next",
|
||||
"version": "1.29.2",
|
||||
"description": "A high-level API to automate web browsers",
|
||||
"repository": "github:Microsoft/playwright",
|
||||
"homepage": "https://playwright.dev",
|
||||
|
|
|
|||
|
|
@ -37,8 +37,9 @@ export class BrowserServerLauncherImpl implements BrowserServerLauncher {
|
|||
|
||||
async launchServer(options: LaunchServerOptions = {}): Promise<BrowserServer> {
|
||||
const playwright = createPlaywright('javascript');
|
||||
const socksProxy = new SocksProxy();
|
||||
playwright.options.socksProxyPort = await socksProxy.listen(0);
|
||||
// TODO: enable socks proxy once ipv6 is supported.
|
||||
const socksProxy = false ? new SocksProxy() : undefined;
|
||||
playwright.options.socksProxyPort = await socksProxy?.listen(0);
|
||||
|
||||
// 1. Pre-launch the browser
|
||||
const metadata = serverSideCallMetadata();
|
||||
|
|
@ -68,7 +69,7 @@ export class BrowserServerLauncherImpl implements BrowserServerLauncher {
|
|||
(browserServer as any)._disconnectForTest = () => server.close();
|
||||
(browserServer as any)._userDataDirForTest = (browser as any)._userDataDirForTest;
|
||||
browser.options.browserProcess.onclose = (exitCode, signal) => {
|
||||
socksProxy.close().catch(() => {});
|
||||
socksProxy?.close().catch(() => {});
|
||||
server.close();
|
||||
browserServer.emit('close', exitCode, signal);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -62,6 +62,7 @@ export class ElectronApplication extends ChannelOwner<channels.ElectronApplicati
|
|||
readonly _context: BrowserContext;
|
||||
private _windows = new Set<Page>();
|
||||
private _timeoutSettings = new TimeoutSettings();
|
||||
private _isClosed = false;
|
||||
|
||||
static from(electronApplication: channels.ElectronApplicationChannel): ElectronApplication {
|
||||
return (electronApplication as any)._object;
|
||||
|
|
@ -73,7 +74,10 @@ export class ElectronApplication extends ChannelOwner<channels.ElectronApplicati
|
|||
for (const page of this._context._pages)
|
||||
this._onPage(page);
|
||||
this._context.on(Events.BrowserContext.Page, page => this._onPage(page));
|
||||
this._channel.on('close', () => this.emit(Events.ElectronApplication.Close));
|
||||
this._channel.on('close', () => {
|
||||
this._isClosed = true;
|
||||
this.emit(Events.ElectronApplication.Close);
|
||||
});
|
||||
}
|
||||
|
||||
process(): childProcess.ChildProcess {
|
||||
|
|
@ -102,6 +106,8 @@ export class ElectronApplication extends ChannelOwner<channels.ElectronApplicati
|
|||
}
|
||||
|
||||
async close() {
|
||||
if (this._isClosed)
|
||||
return;
|
||||
await this._channel.close();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@
|
|||
*/
|
||||
|
||||
const { app } = require('electron');
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const { chromiumSwitches } = require('../chromium/chromiumSwitches');
|
||||
|
||||
|
|
@ -31,27 +32,36 @@ for (const arg of chromiumSwitches) {
|
|||
app.commandLine.appendSwitch(match[1], match[2]);
|
||||
}
|
||||
|
||||
app.getAppPath = () => path.dirname(appPath);
|
||||
// Defer ready event.
|
||||
const originalWhenReady = app.whenReady();
|
||||
const originalEmit = app.emit.bind(app);
|
||||
let readyEventArgs: any[];
|
||||
app.emit = (event: string | symbol, ...args: any[]): boolean => {
|
||||
if (event === 'ready') {
|
||||
readyEventArgs = args;
|
||||
return app.listenerCount('ready') > 0;
|
||||
}
|
||||
return originalEmit(event, ...args);
|
||||
};
|
||||
|
||||
let launchInfoEventPayload: any;
|
||||
app.on('ready', launchInfo => launchInfoEventPayload = launchInfo);
|
||||
app.getAppPath = () => {
|
||||
if (fs.statSync(appPath).isFile())
|
||||
return path.dirname(appPath);
|
||||
return appPath;
|
||||
};
|
||||
|
||||
let isReady = false;
|
||||
let whenReadyCallback: (event: any) => any;
|
||||
const whenReadyPromise = new Promise<void>(f => whenReadyCallback = f);
|
||||
app.isReady = () => isReady;
|
||||
app.whenReady = () => whenReadyPromise;
|
||||
|
||||
require(appPath);
|
||||
|
||||
(globalThis as any).__playwright_run = async () => {
|
||||
// Wait for app to be ready to avoid browser initialization races.
|
||||
await app.whenReady();
|
||||
|
||||
// Override isReady pipeline.
|
||||
let isReady = false;
|
||||
let whenReadyCallback: () => void;
|
||||
const whenReadyPromise = new Promise<void>(f => whenReadyCallback = f);
|
||||
app.isReady = () => isReady;
|
||||
app.whenReady = () => whenReadyPromise;
|
||||
|
||||
require(appPath);
|
||||
|
||||
// Trigger isReady.
|
||||
const event = await originalWhenReady;
|
||||
isReady = true;
|
||||
whenReadyCallback!();
|
||||
app.emit('will-finish-launching');
|
||||
app.emit('ready', launchInfoEventPayload);
|
||||
whenReadyCallback(event);
|
||||
originalEmit('ready', ...readyEventArgs);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -78,8 +78,10 @@ const DOWNLOAD_PATHS = {
|
|||
'<unknown>': undefined,
|
||||
'generic-linux': 'builds/chromium/%s/chromium-linux.zip',
|
||||
'generic-linux-arm64': 'builds/chromium/%s/chromium-linux-arm64.zip',
|
||||
'ubuntu18.04': 'builds/chromium/%s/chromium-linux.zip',
|
||||
'ubuntu20.04': 'builds/chromium/%s/chromium-linux.zip',
|
||||
'ubuntu22.04': 'builds/chromium/%s/chromium-linux.zip',
|
||||
'ubuntu18.04-arm64': 'builds/chromium/%s/chromium-linux-arm64.zip',
|
||||
'ubuntu20.04-arm64': 'builds/chromium/%s/chromium-linux-arm64.zip',
|
||||
'ubuntu22.04-arm64': 'builds/chromium/%s/chromium-linux-arm64.zip',
|
||||
'debian11': 'builds/chromium/%s/chromium-linux.zip',
|
||||
|
|
@ -96,8 +98,10 @@ const DOWNLOAD_PATHS = {
|
|||
'<unknown>': undefined,
|
||||
'generic-linux': 'builds/chromium-tip-of-tree/%s/chromium-tip-of-tree-linux.zip',
|
||||
'generic-linux-arm64': 'builds/chromium-tip-of-tree/%s/chromium-tip-of-tree-linux-arm64.zip',
|
||||
'ubuntu18.04': 'builds/chromium-tip-of-tree/%s/chromium-tip-of-tree-linux.zip',
|
||||
'ubuntu20.04': 'builds/chromium-tip-of-tree/%s/chromium-tip-of-tree-linux.zip',
|
||||
'ubuntu22.04': 'builds/chromium-tip-of-tree/%s/chromium-tip-of-tree-linux.zip',
|
||||
'ubuntu18.04-arm64': 'builds/chromium-tip-of-tree/%s/chromium-tip-of-tree-linux-arm64.zip',
|
||||
'ubuntu20.04-arm64': 'builds/chromium-tip-of-tree/%s/chromium-tip-of-tree-linux-arm64.zip',
|
||||
'ubuntu22.04-arm64': 'builds/chromium-tip-of-tree/%s/chromium-tip-of-tree-linux-arm64.zip',
|
||||
'debian11': 'builds/chromium-tip-of-tree/%s/chromium-tip-of-tree-linux.zip',
|
||||
|
|
@ -114,8 +118,10 @@ const DOWNLOAD_PATHS = {
|
|||
'<unknown>': undefined,
|
||||
'generic-linux': 'builds/chromium/%s/chromium-with-symbols-linux.zip',
|
||||
'generic-linux-arm64': 'builds/chromium/%s/chromium-with-symbols-linux-arm64.zip',
|
||||
'ubuntu18.04': 'builds/chromium/%s/chromium-with-symbols-linux.zip',
|
||||
'ubuntu20.04': 'builds/chromium/%s/chromium-with-symbols-linux.zip',
|
||||
'ubuntu22.04': 'builds/chromium/%s/chromium-with-symbols-linux.zip',
|
||||
'ubuntu18.04-arm64': 'builds/chromium/%s/chromium-with-symbols-linux-arm64.zip',
|
||||
'ubuntu20.04-arm64': 'builds/chromium/%s/chromium-with-symbols-linux-arm64.zip',
|
||||
'ubuntu22.04-arm64': 'builds/chromium/%s/chromium-with-symbols-linux-arm64.zip',
|
||||
'debian11': 'builds/chromium/%s/chromium-with-symbols-linux.zip',
|
||||
|
|
@ -132,8 +138,10 @@ const DOWNLOAD_PATHS = {
|
|||
'<unknown>': undefined,
|
||||
'generic-linux': 'builds/firefox/%s/firefox-ubuntu-20.04.zip',
|
||||
'generic-linux-arm64': 'builds/firefox/%s/firefox-ubuntu-20.04-arm64.zip',
|
||||
'ubuntu18.04': 'builds/firefox/%s/firefox-ubuntu-18.04.zip',
|
||||
'ubuntu20.04': 'builds/firefox/%s/firefox-ubuntu-20.04.zip',
|
||||
'ubuntu22.04': 'builds/firefox/%s/firefox-ubuntu-22.04.zip',
|
||||
'ubuntu18.04-arm64': undefined,
|
||||
'ubuntu20.04-arm64': 'builds/firefox/%s/firefox-ubuntu-20.04-arm64.zip',
|
||||
'ubuntu22.04-arm64': 'builds/firefox/%s/firefox-ubuntu-22.04-arm64.zip',
|
||||
'debian11': 'builds/firefox/%s/firefox-debian-11.zip',
|
||||
|
|
@ -150,8 +158,10 @@ const DOWNLOAD_PATHS = {
|
|||
'<unknown>': undefined,
|
||||
'generic-linux': 'builds/firefox-beta/%s/firefox-beta-ubuntu-20.04.zip',
|
||||
'generic-linux-arm64': undefined,
|
||||
'ubuntu18.04': 'builds/firefox-beta/%s/firefox-beta-ubuntu-18.04.zip',
|
||||
'ubuntu20.04': 'builds/firefox-beta/%s/firefox-beta-ubuntu-20.04.zip',
|
||||
'ubuntu22.04': 'builds/firefox-beta/%s/firefox-beta-ubuntu-22.04.zip',
|
||||
'ubuntu18.04-arm64': undefined,
|
||||
'ubuntu20.04-arm64': undefined,
|
||||
'ubuntu22.04-arm64': 'builds/firefox-beta/%s/firefox-beta-ubuntu-22.04-arm64.zip',
|
||||
'debian11': 'builds/firefox-beta/%s/firefox-beta-debian-11.zip',
|
||||
|
|
@ -168,8 +178,10 @@ const DOWNLOAD_PATHS = {
|
|||
'<unknown>': undefined,
|
||||
'generic-linux': 'builds/webkit/%s/webkit-ubuntu-20.04.zip',
|
||||
'generic-linux-arm64': 'builds/webkit/%s/webkit-ubuntu-20.04-arm64.zip',
|
||||
'ubuntu18.04': 'builds/deprecated-webkit-ubuntu-18.04/%s/deprecated-webkit-ubuntu-18.04.zip',
|
||||
'ubuntu20.04': 'builds/webkit/%s/webkit-ubuntu-20.04.zip',
|
||||
'ubuntu22.04': 'builds/webkit/%s/webkit-ubuntu-22.04.zip',
|
||||
'ubuntu18.04-arm64': undefined,
|
||||
'ubuntu20.04-arm64': 'builds/webkit/%s/webkit-ubuntu-20.04-arm64.zip',
|
||||
'ubuntu22.04-arm64': 'builds/webkit/%s/webkit-ubuntu-22.04-arm64.zip',
|
||||
'debian11': 'builds/webkit/%s/webkit-debian-11.zip',
|
||||
|
|
@ -186,8 +198,10 @@ const DOWNLOAD_PATHS = {
|
|||
'<unknown>': undefined,
|
||||
'generic-linux': 'builds/ffmpeg/%s/ffmpeg-linux.zip',
|
||||
'generic-linux-arm64': 'builds/ffmpeg/%s/ffmpeg-linux-arm64.zip',
|
||||
'ubuntu18.04': 'builds/ffmpeg/%s/ffmpeg-linux.zip',
|
||||
'ubuntu20.04': 'builds/ffmpeg/%s/ffmpeg-linux.zip',
|
||||
'ubuntu22.04': 'builds/ffmpeg/%s/ffmpeg-linux.zip',
|
||||
'ubuntu18.04-arm64': 'builds/ffmpeg/%s/ffmpeg-linux-arm64.zip',
|
||||
'ubuntu20.04-arm64': 'builds/ffmpeg/%s/ffmpeg-linux-arm64.zip',
|
||||
'ubuntu22.04-arm64': 'builds/ffmpeg/%s/ffmpeg-linux-arm64.zip',
|
||||
'debian11': 'builds/ffmpeg/%s/ffmpeg-linux.zip',
|
||||
|
|
@ -640,7 +654,7 @@ export class Registry {
|
|||
|
||||
private async _validateHostRequirements(sdkLanguage: string, browserName: BrowserName, browserDirectory: string, linuxLddDirectories: string[], dlOpenLibraries: string[], windowsExeAndDllDirectories: string[]) {
|
||||
if (getAsBooleanFromENV('PLAYWRIGHT_SKIP_VALIDATE_HOST_REQUIREMENTS')) {
|
||||
process.stdout.write('Skipping host requirements validation logic because `PLAYWRIGHT_SKIP_VALIDATE_HOST_REQUIREMENTS` env variable is set.\n');
|
||||
process.stderr.write('Skipping host requirements validation logic because `PLAYWRIGHT_SKIP_VALIDATE_HOST_REQUIREMENTS` env variable is set.\n');
|
||||
return;
|
||||
}
|
||||
const distributionInfo = await getLinuxDistributionInfo();
|
||||
|
|
|
|||
|
|
@ -19,6 +19,168 @@
|
|||
// ./utils/linux-browser-dependencies/run.sh ubuntu:20.04
|
||||
|
||||
export const deps: any = {
|
||||
'ubuntu18.04': {
|
||||
tools: [
|
||||
'xvfb',
|
||||
'fonts-noto-color-emoji',
|
||||
'ttf-unifont',
|
||||
'libfontconfig',
|
||||
'libfreetype6',
|
||||
'xfonts-cyrillic',
|
||||
'xfonts-scalable',
|
||||
'fonts-liberation',
|
||||
'fonts-ipafont-gothic',
|
||||
'fonts-wqy-zenhei',
|
||||
'fonts-tlwg-loma-otf',
|
||||
'ttf-ubuntu-font-family',
|
||||
],
|
||||
chromium: [
|
||||
'fonts-liberation',
|
||||
'libasound2',
|
||||
'libatk-bridge2.0-0',
|
||||
'libatk1.0-0',
|
||||
'libatspi2.0-0',
|
||||
'libcairo2',
|
||||
'libcups2',
|
||||
'libdbus-1-3',
|
||||
'libdrm2',
|
||||
'libegl1',
|
||||
'libgbm1',
|
||||
'libglib2.0-0',
|
||||
'libgtk-3-0',
|
||||
'libnspr4',
|
||||
'libnss3',
|
||||
'libpango-1.0-0',
|
||||
'libx11-6',
|
||||
'libx11-xcb1',
|
||||
'libxcb1',
|
||||
'libxcomposite1',
|
||||
'libxdamage1',
|
||||
'libxext6',
|
||||
'libxfixes3',
|
||||
'libxrandr2',
|
||||
'libxshmfence1',
|
||||
],
|
||||
firefox: [
|
||||
'ffmpeg',
|
||||
'libatk1.0-0',
|
||||
'libcairo-gobject2',
|
||||
'libcairo2',
|
||||
'libdbus-1-3',
|
||||
'libdbus-glib-1-2',
|
||||
'libfontconfig1',
|
||||
'libfreetype6',
|
||||
'libgdk-pixbuf2.0-0',
|
||||
'libglib2.0-0',
|
||||
'libgtk-3-0',
|
||||
'libpango-1.0-0',
|
||||
'libpangocairo-1.0-0',
|
||||
'libpangoft2-1.0-0',
|
||||
'libx11-6',
|
||||
'libx11-xcb1',
|
||||
'libxcb-shm0',
|
||||
'libxcb1',
|
||||
'libxcomposite1',
|
||||
'libxcursor1',
|
||||
'libxdamage1',
|
||||
'libxext6',
|
||||
'libxfixes3',
|
||||
'libxi6',
|
||||
'libxrender1',
|
||||
'libxt6',
|
||||
'libxtst6',
|
||||
],
|
||||
webkit: [],
|
||||
lib2package: {
|
||||
'libasound.so.2': 'libasound2',
|
||||
'libatk-1.0.so.0': 'libatk1.0-0',
|
||||
'libatk-bridge-2.0.so.0': 'libatk-bridge2.0-0',
|
||||
'libatspi.so.0': 'libatspi2.0-0',
|
||||
'libbrotlidec.so.1': 'libbrotli1',
|
||||
'libcairo-gobject.so.2': 'libcairo-gobject2',
|
||||
'libcairo.so.2': 'libcairo2',
|
||||
'libcups.so.2': 'libcups2',
|
||||
'libdbus-1.so.3': 'libdbus-1-3',
|
||||
'libdbus-glib-1.so.2': 'libdbus-glib-1-2',
|
||||
'libdrm.so.2': 'libdrm2',
|
||||
'libEGL.so.1': 'libegl1',
|
||||
'libenchant.so.1': 'libenchant1c2a',
|
||||
'libepoxy.so.0': 'libepoxy0',
|
||||
'libevent-2.1.so.6': 'libevent-2.1-6',
|
||||
'libevdev.so.2': 'libevdev2',
|
||||
'libfontconfig.so.1': 'libfontconfig1',
|
||||
'libfreetype.so.6': 'libfreetype6',
|
||||
'libgbm.so.1': 'libgbm1',
|
||||
'libgdk_pixbuf-2.0.so.0': 'libgdk-pixbuf2.0-0',
|
||||
'libgdk-3.so.0': 'libgtk-3-0',
|
||||
'libgdk-x11-2.0.so.0': 'libgtk2.0-0',
|
||||
'libgio-2.0.so.0': 'libglib2.0-0',
|
||||
'libGL.so.1': 'libgl1',
|
||||
'libGLESv2.so.2': 'libgles2',
|
||||
'libglib-2.0.so.0': 'libglib2.0-0',
|
||||
'libgmodule-2.0.so.0': 'libglib2.0-0',
|
||||
'libgobject-2.0.so.0': 'libglib2.0-0',
|
||||
'libgstapp-1.0.so.0': 'gstreamer1.0-plugins-base',
|
||||
'libgstaudio-1.0.so.0': 'gstreamer1.0-plugins-base',
|
||||
'libgstbase-1.0.so.0': 'libgstreamer1.0-0',
|
||||
'libgstcodecparsers-1.0.so.0': 'gstreamer1.0-plugins-bad',
|
||||
'libgstfft-1.0.so.0': 'gstreamer1.0-plugins-base',
|
||||
'libgstgl-1.0.so.0': 'libgstreamer-gl1.0-0',
|
||||
'libgstpbutils-1.0.so.0': 'gstreamer1.0-plugins-base',
|
||||
'libgstreamer-1.0.so.0': 'libgstreamer1.0-0',
|
||||
'libgsttag-1.0.so.0': 'gstreamer1.0-plugins-base',
|
||||
'libgstvideo-1.0.so.0': 'gstreamer1.0-plugins-base',
|
||||
'libgthread-2.0.so.0': 'libglib2.0-0',
|
||||
'libgtk-3.so.0': 'libgtk-3-0',
|
||||
'libgtk-x11-2.0.so.0': 'libgtk2.0-0',
|
||||
'libharfbuzz-icu.so.0': 'libharfbuzz-icu0',
|
||||
'libharfbuzz.so.0': 'libharfbuzz0b',
|
||||
'libhyphen.so.0': 'libhyphen0',
|
||||
'libicudata.so.60': 'libicu60',
|
||||
'libicui18n.so.60': 'libicu60',
|
||||
'libicuuc.so.60': 'libicu60',
|
||||
'libjpeg.so.8': 'libjpeg-turbo8',
|
||||
'libnotify.so.4': 'libnotify4',
|
||||
'libnspr4.so': 'libnspr4',
|
||||
'libnss3.so': 'libnss3',
|
||||
'libnssutil3.so': 'libnss3',
|
||||
'libopenjp2.so.7': 'libopenjp2-7',
|
||||
'libopus.so.0': 'libopus0',
|
||||
'libpango-1.0.so.0': 'libpango-1.0-0',
|
||||
'libpangocairo-1.0.so.0': 'libpangocairo-1.0-0',
|
||||
'libpangoft2-1.0.so.0': 'libpangoft2-1.0-0',
|
||||
'libpng16.so.16': 'libpng16-16',
|
||||
'libsecret-1.so.0': 'libsecret-1-0',
|
||||
'libsmime3.so': 'libnss3',
|
||||
'libvpx.so.5': 'libvpx5',
|
||||
'libwayland-client.so.0': 'libwayland-client0',
|
||||
'libwayland-egl.so.1': 'libwayland-egl1',
|
||||
'libwayland-server.so.0': 'libwayland-server0',
|
||||
'libwebp.so.6': 'libwebp6',
|
||||
'libwebpdemux.so.2': 'libwebpdemux2',
|
||||
'libwoff2dec.so.1.0.2': 'libwoff1',
|
||||
'libX11-xcb.so.1': 'libx11-xcb1',
|
||||
'libX11.so.6': 'libx11-6',
|
||||
'libxcb-dri3.so.0': 'libxcb-dri3-0',
|
||||
'libxcb-shm.so.0': 'libxcb-shm0',
|
||||
'libxcb.so.1': 'libxcb1',
|
||||
'libXcomposite.so.1': 'libxcomposite1',
|
||||
'libXcursor.so.1': 'libxcursor1',
|
||||
'libXdamage.so.1': 'libxdamage1',
|
||||
'libXext.so.6': 'libxext6',
|
||||
'libXfixes.so.3': 'libxfixes3',
|
||||
'libXi.so.6': 'libxi6',
|
||||
'libxkbcommon.so.0': 'libxkbcommon0',
|
||||
'libxml2.so.2': 'libxml2',
|
||||
'libXrandr.so.2': 'libxrandr2',
|
||||
'libXrender.so.1': 'libxrender1',
|
||||
'libxslt.so.1': 'libxslt1.1',
|
||||
'libXt.so.6': 'libxt6',
|
||||
'libXtst.so.6': 'libxtst6',
|
||||
'libevent-2.1-6': 'libevent-2.1-6',
|
||||
},
|
||||
},
|
||||
|
||||
'ubuntu20.04': {
|
||||
tools: [
|
||||
'xvfb',
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ export type HostPlatform = 'win64' |
|
|||
'mac10.15' |
|
||||
'mac11' | 'mac11-arm64' |
|
||||
'mac12' | 'mac12-arm64' |
|
||||
'ubuntu18.04' | 'ubuntu18.04-arm64' |
|
||||
'ubuntu20.04' | 'ubuntu20.04-arm64' |
|
||||
'ubuntu22.04' | 'ubuntu22.04-arm64' |
|
||||
'debian11' |
|
||||
|
|
|
|||
312
packages/playwright-core/types/types.d.ts
vendored
312
packages/playwright-core/types/types.d.ts
vendored
|
|
@ -286,7 +286,8 @@ export interface Page {
|
|||
addInitScript<Arg>(script: PageFunction<Arg, any> | { path?: string, content?: string }, arg?: Arg): Promise<void>;
|
||||
|
||||
/**
|
||||
* **NOTE** Use locator-based [`method: Page.locator`] instead. Read more about [locators](https://playwright.dev/docs/locators).
|
||||
* **NOTE** Use locator-based [page.locator(selector[, options])](https://playwright.dev/docs/api/class-page#page-locator)
|
||||
* instead. Read more about [locators](https://playwright.dev/docs/locators).
|
||||
*
|
||||
* The method finds an element matching the specified selector within the page. If no elements match the selector, the
|
||||
* return value resolves to `null`. To wait for an element on the page, use
|
||||
|
|
@ -296,7 +297,8 @@ export interface Page {
|
|||
*/
|
||||
$<K extends keyof HTMLElementTagNameMap>(selector: K, options?: { strict: boolean }): Promise<ElementHandleForTag<K> | null>;
|
||||
/**
|
||||
* **NOTE** Use locator-based [`method: Page.locator`] instead. Read more about [locators](https://playwright.dev/docs/locators).
|
||||
* **NOTE** Use locator-based [page.locator(selector[, options])](https://playwright.dev/docs/api/class-page#page-locator)
|
||||
* instead. Read more about [locators](https://playwright.dev/docs/locators).
|
||||
*
|
||||
* The method finds an element matching the specified selector within the page. If no elements match the selector, the
|
||||
* return value resolves to `null`. To wait for an element on the page, use
|
||||
|
|
@ -307,7 +309,8 @@ export interface Page {
|
|||
$(selector: string, options?: { strict: boolean }): Promise<ElementHandle<SVGElement | HTMLElement> | null>;
|
||||
|
||||
/**
|
||||
* **NOTE** Use locator-based [`method: Page.locator`] instead. Read more about [locators](https://playwright.dev/docs/locators).
|
||||
* **NOTE** Use locator-based [page.locator(selector[, options])](https://playwright.dev/docs/api/class-page#page-locator)
|
||||
* instead. Read more about [locators](https://playwright.dev/docs/locators).
|
||||
*
|
||||
* The method finds all elements matching the specified selector within the page. If no elements match the selector,
|
||||
* the return value resolves to `[]`.
|
||||
|
|
@ -315,7 +318,8 @@ export interface Page {
|
|||
*/
|
||||
$$<K extends keyof HTMLElementTagNameMap>(selector: K): Promise<ElementHandleForTag<K>[]>;
|
||||
/**
|
||||
* **NOTE** Use locator-based [`method: Page.locator`] instead. Read more about [locators](https://playwright.dev/docs/locators).
|
||||
* **NOTE** Use locator-based [page.locator(selector[, options])](https://playwright.dev/docs/api/class-page#page-locator)
|
||||
* instead. Read more about [locators](https://playwright.dev/docs/locators).
|
||||
*
|
||||
* The method finds all elements matching the specified selector within the page. If no elements match the selector,
|
||||
* the return value resolves to `[]`.
|
||||
|
|
@ -325,7 +329,9 @@ export interface Page {
|
|||
|
||||
/**
|
||||
* **NOTE** This method does not wait for the element to pass actionability checks and therefore can lead to the flaky tests.
|
||||
* Use [`method: Locator.evaluate`], other [Locator] helper methods or web-first assertions instead.
|
||||
* Use
|
||||
* [locator.evaluate(pageFunction[, arg, options])](https://playwright.dev/docs/api/class-locator#locator-evaluate),
|
||||
* other [Locator] helper methods or web-first assertions instead.
|
||||
*
|
||||
* The method finds an element matching the specified selector within the page and passes it as a first argument to
|
||||
* `pageFunction`. If no elements match the selector, the method throws an error. Returns the value of `pageFunction`.
|
||||
|
|
@ -352,7 +358,9 @@ export interface Page {
|
|||
$eval<K extends keyof HTMLElementTagNameMap, R, Arg>(selector: K, pageFunction: PageFunctionOn<HTMLElementTagNameMap[K], Arg, R>, arg: Arg): Promise<R>;
|
||||
/**
|
||||
* **NOTE** This method does not wait for the element to pass actionability checks and therefore can lead to the flaky tests.
|
||||
* Use [`method: Locator.evaluate`], other [Locator] helper methods or web-first assertions instead.
|
||||
* Use
|
||||
* [locator.evaluate(pageFunction[, arg, options])](https://playwright.dev/docs/api/class-locator#locator-evaluate),
|
||||
* other [Locator] helper methods or web-first assertions instead.
|
||||
*
|
||||
* The method finds an element matching the specified selector within the page and passes it as a first argument to
|
||||
* `pageFunction`. If no elements match the selector, the method throws an error. Returns the value of `pageFunction`.
|
||||
|
|
@ -379,7 +387,9 @@ export interface Page {
|
|||
$eval<R, Arg, E extends SVGElement | HTMLElement = SVGElement | HTMLElement>(selector: string, pageFunction: PageFunctionOn<E, Arg, R>, arg: Arg): Promise<R>;
|
||||
/**
|
||||
* **NOTE** This method does not wait for the element to pass actionability checks and therefore can lead to the flaky tests.
|
||||
* Use [`method: Locator.evaluate`], other [Locator] helper methods or web-first assertions instead.
|
||||
* Use
|
||||
* [locator.evaluate(pageFunction[, arg, options])](https://playwright.dev/docs/api/class-locator#locator-evaluate),
|
||||
* other [Locator] helper methods or web-first assertions instead.
|
||||
*
|
||||
* The method finds an element matching the specified selector within the page and passes it as a first argument to
|
||||
* `pageFunction`. If no elements match the selector, the method throws an error. Returns the value of `pageFunction`.
|
||||
|
|
@ -406,7 +416,9 @@ export interface Page {
|
|||
$eval<K extends keyof HTMLElementTagNameMap, R>(selector: K, pageFunction: PageFunctionOn<HTMLElementTagNameMap[K], void, R>, arg?: any): Promise<R>;
|
||||
/**
|
||||
* **NOTE** This method does not wait for the element to pass actionability checks and therefore can lead to the flaky tests.
|
||||
* Use [`method: Locator.evaluate`], other [Locator] helper methods or web-first assertions instead.
|
||||
* Use
|
||||
* [locator.evaluate(pageFunction[, arg, options])](https://playwright.dev/docs/api/class-locator#locator-evaluate),
|
||||
* other [Locator] helper methods or web-first assertions instead.
|
||||
*
|
||||
* The method finds an element matching the specified selector within the page and passes it as a first argument to
|
||||
* `pageFunction`. If no elements match the selector, the method throws an error. Returns the value of `pageFunction`.
|
||||
|
|
@ -433,8 +445,9 @@ export interface Page {
|
|||
$eval<R, E extends SVGElement | HTMLElement = SVGElement | HTMLElement>(selector: string, pageFunction: PageFunctionOn<E, void, R>, arg?: any): Promise<R>;
|
||||
|
||||
/**
|
||||
* **NOTE** In most cases, [`method: Locator.evaluateAll`], other [Locator] helper methods and web-first assertions do a better
|
||||
* job.
|
||||
* **NOTE** In most cases,
|
||||
* [locator.evaluateAll(pageFunction[, arg])](https://playwright.dev/docs/api/class-locator#locator-evaluate-all),
|
||||
* other [Locator] helper methods and web-first assertions do a better job.
|
||||
*
|
||||
* The method finds all elements matching the specified selector within the page and passes an array of matched
|
||||
* elements as a first argument to `pageFunction`. Returns the result of `pageFunction` invocation.
|
||||
|
|
@ -455,8 +468,9 @@ export interface Page {
|
|||
*/
|
||||
$$eval<K extends keyof HTMLElementTagNameMap, R, Arg>(selector: K, pageFunction: PageFunctionOn<HTMLElementTagNameMap[K][], Arg, R>, arg: Arg): Promise<R>;
|
||||
/**
|
||||
* **NOTE** In most cases, [`method: Locator.evaluateAll`], other [Locator] helper methods and web-first assertions do a better
|
||||
* job.
|
||||
* **NOTE** In most cases,
|
||||
* [locator.evaluateAll(pageFunction[, arg])](https://playwright.dev/docs/api/class-locator#locator-evaluate-all),
|
||||
* other [Locator] helper methods and web-first assertions do a better job.
|
||||
*
|
||||
* The method finds all elements matching the specified selector within the page and passes an array of matched
|
||||
* elements as a first argument to `pageFunction`. Returns the result of `pageFunction` invocation.
|
||||
|
|
@ -477,8 +491,9 @@ export interface Page {
|
|||
*/
|
||||
$$eval<R, Arg, E extends SVGElement | HTMLElement = SVGElement | HTMLElement>(selector: string, pageFunction: PageFunctionOn<E[], Arg, R>, arg: Arg): Promise<R>;
|
||||
/**
|
||||
* **NOTE** In most cases, [`method: Locator.evaluateAll`], other [Locator] helper methods and web-first assertions do a better
|
||||
* job.
|
||||
* **NOTE** In most cases,
|
||||
* [locator.evaluateAll(pageFunction[, arg])](https://playwright.dev/docs/api/class-locator#locator-evaluate-all),
|
||||
* other [Locator] helper methods and web-first assertions do a better job.
|
||||
*
|
||||
* The method finds all elements matching the specified selector within the page and passes an array of matched
|
||||
* elements as a first argument to `pageFunction`. Returns the result of `pageFunction` invocation.
|
||||
|
|
@ -499,8 +514,9 @@ export interface Page {
|
|||
*/
|
||||
$$eval<K extends keyof HTMLElementTagNameMap, R>(selector: K, pageFunction: PageFunctionOn<HTMLElementTagNameMap[K][], void, R>, arg?: any): Promise<R>;
|
||||
/**
|
||||
* **NOTE** In most cases, [`method: Locator.evaluateAll`], other [Locator] helper methods and web-first assertions do a better
|
||||
* job.
|
||||
* **NOTE** In most cases,
|
||||
* [locator.evaluateAll(pageFunction[, arg])](https://playwright.dev/docs/api/class-locator#locator-evaluate-all),
|
||||
* other [Locator] helper methods and web-first assertions do a better job.
|
||||
*
|
||||
* The method finds all elements matching the specified selector within the page and passes an array of matched
|
||||
* elements as a first argument to `pageFunction`. Returns the result of `pageFunction` invocation.
|
||||
|
|
@ -1797,7 +1813,8 @@ export interface Page {
|
|||
bringToFront(): Promise<void>;
|
||||
|
||||
/**
|
||||
* **NOTE** Use locator-based [`method: Locator.check`] instead. Read more about [locators](https://playwright.dev/docs/locators).
|
||||
* **NOTE** Use locator-based [locator.check([options])](https://playwright.dev/docs/api/class-locator#locator-check) instead.
|
||||
* Read more about [locators](https://playwright.dev/docs/locators).
|
||||
*
|
||||
* This method checks an element matching `selector` by performing the following steps:
|
||||
* 1. Find an element matching `selector`. If there is none, wait until a matching element is attached to the DOM.
|
||||
|
|
@ -1862,7 +1879,8 @@ export interface Page {
|
|||
}): Promise<void>;
|
||||
|
||||
/**
|
||||
* **NOTE** Use locator-based [`method: Locator.click`] instead. Read more about [locators](https://playwright.dev/docs/locators).
|
||||
* **NOTE** Use locator-based [locator.click([options])](https://playwright.dev/docs/api/class-locator#locator-click) instead.
|
||||
* Read more about [locators](https://playwright.dev/docs/locators).
|
||||
*
|
||||
* This method clicks an element matching `selector` by performing the following steps:
|
||||
* 1. Find an element matching `selector`. If there is none, wait until a matching element is attached to the DOM.
|
||||
|
|
@ -1980,7 +1998,8 @@ export interface Page {
|
|||
coverage: Coverage;
|
||||
|
||||
/**
|
||||
* **NOTE** Use locator-based [`method: Locator.dblclick`] instead. Read more about [locators](https://playwright.dev/docs/locators).
|
||||
* **NOTE** Use locator-based [locator.dblclick([options])](https://playwright.dev/docs/api/class-locator#locator-dblclick)
|
||||
* instead. Read more about [locators](https://playwright.dev/docs/locators).
|
||||
*
|
||||
* This method double clicks an element matching `selector` by performing the following steps:
|
||||
* 1. Find an element matching `selector`. If there is none, wait until a matching element is attached to the DOM.
|
||||
|
|
@ -2061,7 +2080,9 @@ export interface Page {
|
|||
}): Promise<void>;
|
||||
|
||||
/**
|
||||
* **NOTE** Use locator-based [`method: Locator.dispatchEvent`] instead. Read more about [locators](https://playwright.dev/docs/locators).
|
||||
* **NOTE** Use locator-based
|
||||
* [locator.dispatchEvent(type[, eventInit, options])](https://playwright.dev/docs/api/class-locator#locator-dispatch-event)
|
||||
* instead. Read more about [locators](https://playwright.dev/docs/locators).
|
||||
*
|
||||
* The snippet below dispatches the `click` event on the element. Regardless of the visibility state of the element,
|
||||
* `click` is dispatched. This is equivalent to calling
|
||||
|
|
@ -2298,7 +2319,8 @@ export interface Page {
|
|||
exposeFunction(name: string, callback: Function): Promise<void>;
|
||||
|
||||
/**
|
||||
* **NOTE** Use locator-based [`method: Locator.fill`] instead. Read more about [locators](https://playwright.dev/docs/locators).
|
||||
* **NOTE** Use locator-based [locator.fill(value[, options])](https://playwright.dev/docs/api/class-locator#locator-fill)
|
||||
* instead. Read more about [locators](https://playwright.dev/docs/locators).
|
||||
*
|
||||
* This method waits for an element matching `selector`, waits for [actionability](https://playwright.dev/docs/actionability) checks,
|
||||
* focuses the element, fills it and triggers an `input` event after filling. Note that you can pass an empty string
|
||||
|
|
@ -2345,7 +2367,8 @@ export interface Page {
|
|||
}): Promise<void>;
|
||||
|
||||
/**
|
||||
* **NOTE** Use locator-based [`method: Locator.focus`] instead. Read more about [locators](https://playwright.dev/docs/locators).
|
||||
* **NOTE** Use locator-based [locator.focus([options])](https://playwright.dev/docs/api/class-locator#locator-focus) instead.
|
||||
* Read more about [locators](https://playwright.dev/docs/locators).
|
||||
*
|
||||
* This method fetches an element with `selector` and focuses it. If there's no element matching `selector`, the
|
||||
* method waits until a matching element appears in the DOM.
|
||||
|
|
@ -2420,7 +2443,9 @@ export interface Page {
|
|||
frames(): Array<Frame>;
|
||||
|
||||
/**
|
||||
* **NOTE** Use locator-based [`method: Locator.getAttribute`] instead. Read more about [locators](https://playwright.dev/docs/locators).
|
||||
* **NOTE** Use locator-based
|
||||
* [locator.getAttribute(name[, options])](https://playwright.dev/docs/api/class-locator#locator-get-attribute)
|
||||
* instead. Read more about [locators](https://playwright.dev/docs/locators).
|
||||
*
|
||||
* Returns element attribute value.
|
||||
* @param selector A selector to search for an element. If there are multiple elements satisfying the selector, the first will be
|
||||
|
|
@ -2779,7 +2804,8 @@ export interface Page {
|
|||
}): Promise<null|Response>;
|
||||
|
||||
/**
|
||||
* **NOTE** Use locator-based [`method: Locator.hover`] instead. Read more about [locators](https://playwright.dev/docs/locators).
|
||||
* **NOTE** Use locator-based [locator.hover([options])](https://playwright.dev/docs/api/class-locator#locator-hover) instead.
|
||||
* Read more about [locators](https://playwright.dev/docs/locators).
|
||||
*
|
||||
* This method hovers over an element matching `selector` by performing the following steps:
|
||||
* 1. Find an element matching `selector`. If there is none, wait until a matching element is attached to the DOM.
|
||||
|
|
@ -2847,7 +2873,8 @@ export interface Page {
|
|||
}): Promise<void>;
|
||||
|
||||
/**
|
||||
* **NOTE** Use locator-based [`method: Locator.innerHTML`] instead. Read more about [locators](https://playwright.dev/docs/locators).
|
||||
* **NOTE** Use locator-based [locator.innerHTML([options])](https://playwright.dev/docs/api/class-locator#locator-inner-html)
|
||||
* instead. Read more about [locators](https://playwright.dev/docs/locators).
|
||||
*
|
||||
* Returns `element.innerHTML`.
|
||||
* @param selector A selector to search for an element. If there are multiple elements satisfying the selector, the first will be
|
||||
|
|
@ -2871,7 +2898,8 @@ export interface Page {
|
|||
}): Promise<string>;
|
||||
|
||||
/**
|
||||
* **NOTE** Use locator-based [`method: Locator.innerText`] instead. Read more about [locators](https://playwright.dev/docs/locators).
|
||||
* **NOTE** Use locator-based [locator.innerText([options])](https://playwright.dev/docs/api/class-locator#locator-inner-text)
|
||||
* instead. Read more about [locators](https://playwright.dev/docs/locators).
|
||||
*
|
||||
* Returns `element.innerText`.
|
||||
* @param selector A selector to search for an element. If there are multiple elements satisfying the selector, the first will be
|
||||
|
|
@ -2895,7 +2923,9 @@ export interface Page {
|
|||
}): Promise<string>;
|
||||
|
||||
/**
|
||||
* **NOTE** Use locator-based [`method: Locator.inputValue`] instead. Read more about [locators](https://playwright.dev/docs/locators).
|
||||
* **NOTE** Use locator-based
|
||||
* [locator.inputValue([options])](https://playwright.dev/docs/api/class-locator#locator-input-value) instead. Read
|
||||
* more about [locators](https://playwright.dev/docs/locators).
|
||||
*
|
||||
* Returns `input.value` for the selected `<input>` or `<textarea>` or `<select>` element.
|
||||
*
|
||||
|
|
@ -2923,7 +2953,8 @@ export interface Page {
|
|||
}): Promise<string>;
|
||||
|
||||
/**
|
||||
* **NOTE** Use locator-based [`method: Locator.isChecked`] instead. Read more about [locators](https://playwright.dev/docs/locators).
|
||||
* **NOTE** Use locator-based [locator.isChecked([options])](https://playwright.dev/docs/api/class-locator#locator-is-checked)
|
||||
* instead. Read more about [locators](https://playwright.dev/docs/locators).
|
||||
*
|
||||
* Returns whether the element is checked. Throws if the element is not a checkbox or radio input.
|
||||
* @param selector A selector to search for an element. If there are multiple elements satisfying the selector, the first will be
|
||||
|
|
@ -2952,7 +2983,9 @@ export interface Page {
|
|||
isClosed(): boolean;
|
||||
|
||||
/**
|
||||
* **NOTE** Use locator-based [`method: Locator.isDisabled`] instead. Read more about [locators](https://playwright.dev/docs/locators).
|
||||
* **NOTE** Use locator-based
|
||||
* [locator.isDisabled([options])](https://playwright.dev/docs/api/class-locator#locator-is-disabled) instead. Read
|
||||
* more about [locators](https://playwright.dev/docs/locators).
|
||||
*
|
||||
* Returns whether the element is disabled, the opposite of [enabled](https://playwright.dev/docs/actionability#enabled).
|
||||
* @param selector A selector to search for an element. If there are multiple elements satisfying the selector, the first will be
|
||||
|
|
@ -2976,7 +3009,9 @@ export interface Page {
|
|||
}): Promise<boolean>;
|
||||
|
||||
/**
|
||||
* **NOTE** Use locator-based [`method: Locator.isEditable`] instead. Read more about [locators](https://playwright.dev/docs/locators).
|
||||
* **NOTE** Use locator-based
|
||||
* [locator.isEditable([options])](https://playwright.dev/docs/api/class-locator#locator-is-editable) instead. Read
|
||||
* more about [locators](https://playwright.dev/docs/locators).
|
||||
*
|
||||
* Returns whether the element is [editable](https://playwright.dev/docs/actionability#editable).
|
||||
* @param selector A selector to search for an element. If there are multiple elements satisfying the selector, the first will be
|
||||
|
|
@ -3000,7 +3035,8 @@ export interface Page {
|
|||
}): Promise<boolean>;
|
||||
|
||||
/**
|
||||
* **NOTE** Use locator-based [`method: Locator.isEnabled`] instead. Read more about [locators](https://playwright.dev/docs/locators).
|
||||
* **NOTE** Use locator-based [locator.isEnabled([options])](https://playwright.dev/docs/api/class-locator#locator-is-enabled)
|
||||
* instead. Read more about [locators](https://playwright.dev/docs/locators).
|
||||
*
|
||||
* Returns whether the element is [enabled](https://playwright.dev/docs/actionability#enabled).
|
||||
* @param selector A selector to search for an element. If there are multiple elements satisfying the selector, the first will be
|
||||
|
|
@ -3024,7 +3060,8 @@ export interface Page {
|
|||
}): Promise<boolean>;
|
||||
|
||||
/**
|
||||
* **NOTE** Use locator-based [`method: Locator.isHidden`] instead. Read more about [locators](https://playwright.dev/docs/locators).
|
||||
* **NOTE** Use locator-based [locator.isHidden([options])](https://playwright.dev/docs/api/class-locator#locator-is-hidden)
|
||||
* instead. Read more about [locators](https://playwright.dev/docs/locators).
|
||||
*
|
||||
* Returns whether the element is hidden, the opposite of [visible](https://playwright.dev/docs/actionability#visible). `selector` that
|
||||
* does not match any elements is considered hidden.
|
||||
|
|
@ -3040,14 +3077,16 @@ export interface Page {
|
|||
strict?: boolean;
|
||||
|
||||
/**
|
||||
* @deprecated This option is ignored. [`method: Page.isHidden`] does not wait for the element to become hidden and returns
|
||||
* immediately.
|
||||
* @deprecated This option is ignored.
|
||||
* [page.isHidden(selector[, options])](https://playwright.dev/docs/api/class-page#page-is-hidden) does not wait for
|
||||
* the element to become hidden and returns immediately.
|
||||
*/
|
||||
timeout?: number;
|
||||
}): Promise<boolean>;
|
||||
|
||||
/**
|
||||
* **NOTE** Use locator-based [`method: Locator.isVisible`] instead. Read more about [locators](https://playwright.dev/docs/locators).
|
||||
* **NOTE** Use locator-based [locator.isVisible([options])](https://playwright.dev/docs/api/class-locator#locator-is-visible)
|
||||
* instead. Read more about [locators](https://playwright.dev/docs/locators).
|
||||
*
|
||||
* Returns whether the element is [visible](https://playwright.dev/docs/actionability#visible). `selector` that does not match any elements
|
||||
* is considered not visible.
|
||||
|
|
@ -3063,8 +3102,9 @@ export interface Page {
|
|||
strict?: boolean;
|
||||
|
||||
/**
|
||||
* @deprecated This option is ignored. [`method: Page.isVisible`] does not wait for the element to become visible and returns
|
||||
* immediately.
|
||||
* @deprecated This option is ignored.
|
||||
* [page.isVisible(selector[, options])](https://playwright.dev/docs/api/class-page#page-is-visible) does not wait for
|
||||
* the element to become visible and returns immediately.
|
||||
*/
|
||||
timeout?: number;
|
||||
}): Promise<boolean>;
|
||||
|
|
@ -3269,7 +3309,8 @@ export interface Page {
|
|||
}): Promise<Buffer>;
|
||||
|
||||
/**
|
||||
* **NOTE** Use locator-based [`method: Locator.press`] instead. Read more about [locators](https://playwright.dev/docs/locators).
|
||||
* **NOTE** Use locator-based [locator.press(key[, options])](https://playwright.dev/docs/api/class-locator#locator-press)
|
||||
* instead. Read more about [locators](https://playwright.dev/docs/locators).
|
||||
*
|
||||
* Focuses the element, and then uses
|
||||
* [keyboard.down(key)](https://playwright.dev/docs/api/class-keyboard#keyboard-down) and
|
||||
|
|
@ -3486,7 +3527,9 @@ export interface Page {
|
|||
screenshot(options?: PageScreenshotOptions): Promise<Buffer>;
|
||||
|
||||
/**
|
||||
* **NOTE** Use locator-based [`method: Locator.selectOption`] instead. Read more about [locators](https://playwright.dev/docs/locators).
|
||||
* **NOTE** Use locator-based
|
||||
* [locator.selectOption(values[, options])](https://playwright.dev/docs/api/class-locator#locator-select-option)
|
||||
* instead. Read more about [locators](https://playwright.dev/docs/locators).
|
||||
*
|
||||
* This method waits for an element matching `selector`, waits for [actionability](https://playwright.dev/docs/actionability) checks, waits
|
||||
* until all specified options are present in the `<select>` element and selects these options.
|
||||
|
|
@ -3580,7 +3623,9 @@ export interface Page {
|
|||
}): Promise<Array<string>>;
|
||||
|
||||
/**
|
||||
* **NOTE** Use locator-based [`method: Locator.setChecked`] instead. Read more about [locators](https://playwright.dev/docs/locators).
|
||||
* **NOTE** Use locator-based
|
||||
* [locator.setChecked(checked[, options])](https://playwright.dev/docs/api/class-locator#locator-set-checked)
|
||||
* instead. Read more about [locators](https://playwright.dev/docs/locators).
|
||||
*
|
||||
* This method checks or unchecks an element matching `selector` by performing the following steps:
|
||||
* 1. Find an element matching `selector`. If there is none, wait until a matching element is attached to the DOM.
|
||||
|
|
@ -3715,7 +3760,9 @@ export interface Page {
|
|||
setExtraHTTPHeaders(headers: { [key: string]: string; }): Promise<void>;
|
||||
|
||||
/**
|
||||
* **NOTE** Use locator-based [`method: Locator.setInputFiles`] instead. Read more about [locators](https://playwright.dev/docs/locators).
|
||||
* **NOTE** Use locator-based
|
||||
* [locator.setInputFiles(files[, options])](https://playwright.dev/docs/api/class-locator#locator-set-input-files)
|
||||
* instead. Read more about [locators](https://playwright.dev/docs/locators).
|
||||
*
|
||||
* Sets the value of the file input to these file paths or files. If some of the `filePaths` are relative paths, then
|
||||
* they are resolved relative to the current working directory. For empty array, clears the selected files.
|
||||
|
|
@ -3821,7 +3868,8 @@ export interface Page {
|
|||
}): Promise<void>;
|
||||
|
||||
/**
|
||||
* **NOTE** Use locator-based [`method: Locator.tap`] instead. Read more about [locators](https://playwright.dev/docs/locators).
|
||||
* **NOTE** Use locator-based [locator.tap([options])](https://playwright.dev/docs/api/class-locator#locator-tap) instead. Read
|
||||
* more about [locators](https://playwright.dev/docs/locators).
|
||||
*
|
||||
* This method taps an element matching `selector` by performing the following steps:
|
||||
* 1. Find an element matching `selector`. If there is none, wait until a matching element is attached to the DOM.
|
||||
|
|
@ -3892,7 +3940,9 @@ export interface Page {
|
|||
}): Promise<void>;
|
||||
|
||||
/**
|
||||
* **NOTE** Use locator-based [`method: Locator.textContent`] instead. Read more about [locators](https://playwright.dev/docs/locators).
|
||||
* **NOTE** Use locator-based
|
||||
* [locator.textContent([options])](https://playwright.dev/docs/api/class-locator#locator-text-content) instead. Read
|
||||
* more about [locators](https://playwright.dev/docs/locators).
|
||||
*
|
||||
* Returns `element.textContent`.
|
||||
* @param selector A selector to search for an element. If there are multiple elements satisfying the selector, the first will be
|
||||
|
|
@ -3923,7 +3973,8 @@ export interface Page {
|
|||
touchscreen: Touchscreen;
|
||||
|
||||
/**
|
||||
* **NOTE** Use locator-based [`method: Locator.type`] instead. Read more about [locators](https://playwright.dev/docs/locators).
|
||||
* **NOTE** Use locator-based [locator.type(text[, options])](https://playwright.dev/docs/api/class-locator#locator-type)
|
||||
* instead. Read more about [locators](https://playwright.dev/docs/locators).
|
||||
*
|
||||
* Sends a `keydown`, `keypress`/`input`, and `keyup` event for each character in the text. `page.type` can be used to
|
||||
* send fine-grained keyboard events. To fill values in form fields, use
|
||||
|
|
@ -3973,7 +4024,8 @@ export interface Page {
|
|||
}): Promise<void>;
|
||||
|
||||
/**
|
||||
* **NOTE** Use locator-based [`method: Locator.uncheck`] instead. Read more about [locators](https://playwright.dev/docs/locators).
|
||||
* **NOTE** Use locator-based [locator.uncheck([options])](https://playwright.dev/docs/api/class-locator#locator-uncheck)
|
||||
* instead. Read more about [locators](https://playwright.dev/docs/locators).
|
||||
*
|
||||
* This method unchecks an element matching `selector` by performing the following steps:
|
||||
* 1. Find an element matching `selector`. If there is none, wait until a matching element is attached to the DOM.
|
||||
|
|
@ -4692,7 +4744,8 @@ export interface Frame {
|
|||
evaluateHandle<R>(pageFunction: PageFunction<void, R>, arg?: any): Promise<SmartHandle<R>>;
|
||||
|
||||
/**
|
||||
* **NOTE** Use locator-based [`method: Frame.locator`] instead. Read more about [locators](https://playwright.dev/docs/locators).
|
||||
* **NOTE** Use locator-based [frame.locator(selector[, options])](https://playwright.dev/docs/api/class-frame#frame-locator)
|
||||
* instead. Read more about [locators](https://playwright.dev/docs/locators).
|
||||
*
|
||||
* Returns the ElementHandle pointing to the frame element.
|
||||
*
|
||||
|
|
@ -4705,7 +4758,8 @@ export interface Frame {
|
|||
*/
|
||||
$<K extends keyof HTMLElementTagNameMap>(selector: K, options?: { strict: boolean }): Promise<ElementHandleForTag<K> | null>;
|
||||
/**
|
||||
* **NOTE** Use locator-based [`method: Frame.locator`] instead. Read more about [locators](https://playwright.dev/docs/locators).
|
||||
* **NOTE** Use locator-based [frame.locator(selector[, options])](https://playwright.dev/docs/api/class-frame#frame-locator)
|
||||
* instead. Read more about [locators](https://playwright.dev/docs/locators).
|
||||
*
|
||||
* Returns the ElementHandle pointing to the frame element.
|
||||
*
|
||||
|
|
@ -4719,7 +4773,8 @@ export interface Frame {
|
|||
$(selector: string, options?: { strict: boolean }): Promise<ElementHandle<SVGElement | HTMLElement> | null>;
|
||||
|
||||
/**
|
||||
* **NOTE** Use locator-based [`method: Frame.locator`] instead. Read more about [locators](https://playwright.dev/docs/locators).
|
||||
* **NOTE** Use locator-based [frame.locator(selector[, options])](https://playwright.dev/docs/api/class-frame#frame-locator)
|
||||
* instead. Read more about [locators](https://playwright.dev/docs/locators).
|
||||
*
|
||||
* Returns the ElementHandles pointing to the frame elements.
|
||||
*
|
||||
|
|
@ -4731,7 +4786,8 @@ export interface Frame {
|
|||
*/
|
||||
$$<K extends keyof HTMLElementTagNameMap>(selector: K): Promise<ElementHandleForTag<K>[]>;
|
||||
/**
|
||||
* **NOTE** Use locator-based [`method: Frame.locator`] instead. Read more about [locators](https://playwright.dev/docs/locators).
|
||||
* **NOTE** Use locator-based [frame.locator(selector[, options])](https://playwright.dev/docs/api/class-frame#frame-locator)
|
||||
* instead. Read more about [locators](https://playwright.dev/docs/locators).
|
||||
*
|
||||
* Returns the ElementHandles pointing to the frame elements.
|
||||
*
|
||||
|
|
@ -4745,7 +4801,9 @@ export interface Frame {
|
|||
|
||||
/**
|
||||
* **NOTE** This method does not wait for the element to pass the actionability checks and therefore can lead to the flaky
|
||||
* tests. Use [`method: Locator.evaluate`], other [Locator] helper methods or web-first assertions instead.
|
||||
* tests. Use
|
||||
* [locator.evaluate(pageFunction[, arg, options])](https://playwright.dev/docs/api/class-locator#locator-evaluate),
|
||||
* other [Locator] helper methods or web-first assertions instead.
|
||||
*
|
||||
* Returns the return value of `pageFunction`.
|
||||
*
|
||||
|
|
@ -4772,7 +4830,9 @@ export interface Frame {
|
|||
$eval<K extends keyof HTMLElementTagNameMap, R, Arg>(selector: K, pageFunction: PageFunctionOn<HTMLElementTagNameMap[K], Arg, R>, arg: Arg): Promise<R>;
|
||||
/**
|
||||
* **NOTE** This method does not wait for the element to pass the actionability checks and therefore can lead to the flaky
|
||||
* tests. Use [`method: Locator.evaluate`], other [Locator] helper methods or web-first assertions instead.
|
||||
* tests. Use
|
||||
* [locator.evaluate(pageFunction[, arg, options])](https://playwright.dev/docs/api/class-locator#locator-evaluate),
|
||||
* other [Locator] helper methods or web-first assertions instead.
|
||||
*
|
||||
* Returns the return value of `pageFunction`.
|
||||
*
|
||||
|
|
@ -4799,7 +4859,9 @@ export interface Frame {
|
|||
$eval<R, Arg, E extends SVGElement | HTMLElement = SVGElement | HTMLElement>(selector: string, pageFunction: PageFunctionOn<E, Arg, R>, arg: Arg): Promise<R>;
|
||||
/**
|
||||
* **NOTE** This method does not wait for the element to pass the actionability checks and therefore can lead to the flaky
|
||||
* tests. Use [`method: Locator.evaluate`], other [Locator] helper methods or web-first assertions instead.
|
||||
* tests. Use
|
||||
* [locator.evaluate(pageFunction[, arg, options])](https://playwright.dev/docs/api/class-locator#locator-evaluate),
|
||||
* other [Locator] helper methods or web-first assertions instead.
|
||||
*
|
||||
* Returns the return value of `pageFunction`.
|
||||
*
|
||||
|
|
@ -4826,7 +4888,9 @@ export interface Frame {
|
|||
$eval<K extends keyof HTMLElementTagNameMap, R>(selector: K, pageFunction: PageFunctionOn<HTMLElementTagNameMap[K], void, R>, arg?: any): Promise<R>;
|
||||
/**
|
||||
* **NOTE** This method does not wait for the element to pass the actionability checks and therefore can lead to the flaky
|
||||
* tests. Use [`method: Locator.evaluate`], other [Locator] helper methods or web-first assertions instead.
|
||||
* tests. Use
|
||||
* [locator.evaluate(pageFunction[, arg, options])](https://playwright.dev/docs/api/class-locator#locator-evaluate),
|
||||
* other [Locator] helper methods or web-first assertions instead.
|
||||
*
|
||||
* Returns the return value of `pageFunction`.
|
||||
*
|
||||
|
|
@ -4853,8 +4917,9 @@ export interface Frame {
|
|||
$eval<R, E extends SVGElement | HTMLElement = SVGElement | HTMLElement>(selector: string, pageFunction: PageFunctionOn<E, void, R>, arg?: any): Promise<R>;
|
||||
|
||||
/**
|
||||
* **NOTE** In most cases, [`method: Locator.evaluateAll`], other [Locator] helper methods and web-first assertions do a better
|
||||
* job.
|
||||
* **NOTE** In most cases,
|
||||
* [locator.evaluateAll(pageFunction[, arg])](https://playwright.dev/docs/api/class-locator#locator-evaluate-all),
|
||||
* other [Locator] helper methods and web-first assertions do a better job.
|
||||
*
|
||||
* Returns the return value of `pageFunction`.
|
||||
*
|
||||
|
|
@ -4877,8 +4942,9 @@ export interface Frame {
|
|||
*/
|
||||
$$eval<K extends keyof HTMLElementTagNameMap, R, Arg>(selector: K, pageFunction: PageFunctionOn<HTMLElementTagNameMap[K][], Arg, R>, arg: Arg): Promise<R>;
|
||||
/**
|
||||
* **NOTE** In most cases, [`method: Locator.evaluateAll`], other [Locator] helper methods and web-first assertions do a better
|
||||
* job.
|
||||
* **NOTE** In most cases,
|
||||
* [locator.evaluateAll(pageFunction[, arg])](https://playwright.dev/docs/api/class-locator#locator-evaluate-all),
|
||||
* other [Locator] helper methods and web-first assertions do a better job.
|
||||
*
|
||||
* Returns the return value of `pageFunction`.
|
||||
*
|
||||
|
|
@ -4901,8 +4967,9 @@ export interface Frame {
|
|||
*/
|
||||
$$eval<R, Arg, E extends SVGElement | HTMLElement = SVGElement | HTMLElement>(selector: string, pageFunction: PageFunctionOn<E[], Arg, R>, arg: Arg): Promise<R>;
|
||||
/**
|
||||
* **NOTE** In most cases, [`method: Locator.evaluateAll`], other [Locator] helper methods and web-first assertions do a better
|
||||
* job.
|
||||
* **NOTE** In most cases,
|
||||
* [locator.evaluateAll(pageFunction[, arg])](https://playwright.dev/docs/api/class-locator#locator-evaluate-all),
|
||||
* other [Locator] helper methods and web-first assertions do a better job.
|
||||
*
|
||||
* Returns the return value of `pageFunction`.
|
||||
*
|
||||
|
|
@ -4925,8 +4992,9 @@ export interface Frame {
|
|||
*/
|
||||
$$eval<K extends keyof HTMLElementTagNameMap, R>(selector: K, pageFunction: PageFunctionOn<HTMLElementTagNameMap[K][], void, R>, arg?: any): Promise<R>;
|
||||
/**
|
||||
* **NOTE** In most cases, [`method: Locator.evaluateAll`], other [Locator] helper methods and web-first assertions do a better
|
||||
* job.
|
||||
* **NOTE** In most cases,
|
||||
* [locator.evaluateAll(pageFunction[, arg])](https://playwright.dev/docs/api/class-locator#locator-evaluate-all),
|
||||
* other [Locator] helper methods and web-first assertions do a better job.
|
||||
*
|
||||
* Returns the return value of `pageFunction`.
|
||||
*
|
||||
|
|
@ -5210,7 +5278,8 @@ export interface Frame {
|
|||
}): Promise<ElementHandle>;
|
||||
|
||||
/**
|
||||
* **NOTE** Use locator-based [`method: Locator.check`] instead. Read more about [locators](https://playwright.dev/docs/locators).
|
||||
* **NOTE** Use locator-based [locator.check([options])](https://playwright.dev/docs/api/class-locator#locator-check) instead.
|
||||
* Read more about [locators](https://playwright.dev/docs/locators).
|
||||
*
|
||||
* This method checks an element matching `selector` by performing the following steps:
|
||||
* 1. Find an element matching `selector`. If there is none, wait until a matching element is attached to the DOM.
|
||||
|
|
@ -5277,7 +5346,8 @@ export interface Frame {
|
|||
childFrames(): Array<Frame>;
|
||||
|
||||
/**
|
||||
* **NOTE** Use locator-based [`method: Locator.click`] instead. Read more about [locators](https://playwright.dev/docs/locators).
|
||||
* **NOTE** Use locator-based [locator.click([options])](https://playwright.dev/docs/api/class-locator#locator-click) instead.
|
||||
* Read more about [locators](https://playwright.dev/docs/locators).
|
||||
*
|
||||
* This method clicks an element matching `selector` by performing the following steps:
|
||||
* 1. Find an element matching `selector`. If there is none, wait until a matching element is attached to the DOM.
|
||||
|
|
@ -5365,7 +5435,8 @@ export interface Frame {
|
|||
content(): Promise<string>;
|
||||
|
||||
/**
|
||||
* **NOTE** Use locator-based [`method: Locator.dblclick`] instead. Read more about [locators](https://playwright.dev/docs/locators).
|
||||
* **NOTE** Use locator-based [locator.dblclick([options])](https://playwright.dev/docs/api/class-locator#locator-dblclick)
|
||||
* instead. Read more about [locators](https://playwright.dev/docs/locators).
|
||||
*
|
||||
* This method double clicks an element matching `selector` by performing the following steps:
|
||||
* 1. Find an element matching `selector`. If there is none, wait until a matching element is attached to the DOM.
|
||||
|
|
@ -5446,7 +5517,9 @@ export interface Frame {
|
|||
}): Promise<void>;
|
||||
|
||||
/**
|
||||
* **NOTE** Use locator-based [`method: Locator.dispatchEvent`] instead. Read more about [locators](https://playwright.dev/docs/locators).
|
||||
* **NOTE** Use locator-based
|
||||
* [locator.dispatchEvent(type[, eventInit, options])](https://playwright.dev/docs/api/class-locator#locator-dispatch-event)
|
||||
* instead. Read more about [locators](https://playwright.dev/docs/locators).
|
||||
*
|
||||
* The snippet below dispatches the `click` event on the element. Regardless of the visibility state of the element,
|
||||
* `click` is dispatched. This is equivalent to calling
|
||||
|
|
@ -5562,7 +5635,8 @@ export interface Frame {
|
|||
}): Promise<void>;
|
||||
|
||||
/**
|
||||
* **NOTE** Use locator-based [`method: Locator.fill`] instead. Read more about [locators](https://playwright.dev/docs/locators).
|
||||
* **NOTE** Use locator-based [locator.fill(value[, options])](https://playwright.dev/docs/api/class-locator#locator-fill)
|
||||
* instead. Read more about [locators](https://playwright.dev/docs/locators).
|
||||
*
|
||||
* This method waits for an element matching `selector`, waits for [actionability](https://playwright.dev/docs/actionability) checks,
|
||||
* focuses the element, fills it and triggers an `input` event after filling. Note that you can pass an empty string
|
||||
|
|
@ -5609,7 +5683,8 @@ export interface Frame {
|
|||
}): Promise<void>;
|
||||
|
||||
/**
|
||||
* **NOTE** Use locator-based [`method: Locator.focus`] instead. Read more about [locators](https://playwright.dev/docs/locators).
|
||||
* **NOTE** Use locator-based [locator.focus([options])](https://playwright.dev/docs/api/class-locator#locator-focus) instead.
|
||||
* Read more about [locators](https://playwright.dev/docs/locators).
|
||||
*
|
||||
* This method fetches an element with `selector` and focuses it. If there's no element matching `selector`, the
|
||||
* method waits until a matching element appears in the DOM.
|
||||
|
|
@ -5672,7 +5747,9 @@ export interface Frame {
|
|||
frameLocator(selector: string): FrameLocator;
|
||||
|
||||
/**
|
||||
* **NOTE** Use locator-based [`method: Locator.getAttribute`] instead. Read more about [locators](https://playwright.dev/docs/locators).
|
||||
* **NOTE** Use locator-based
|
||||
* [locator.getAttribute(name[, options])](https://playwright.dev/docs/api/class-locator#locator-get-attribute)
|
||||
* instead. Read more about [locators](https://playwright.dev/docs/locators).
|
||||
*
|
||||
* Returns element attribute value.
|
||||
* @param selector A selector to search for an element. If there are multiple elements satisfying the selector, the first will be
|
||||
|
|
@ -5969,7 +6046,8 @@ export interface Frame {
|
|||
}): Promise<null|Response>;
|
||||
|
||||
/**
|
||||
* **NOTE** Use locator-based [`method: Locator.hover`] instead. Read more about [locators](https://playwright.dev/docs/locators).
|
||||
* **NOTE** Use locator-based [locator.hover([options])](https://playwright.dev/docs/api/class-locator#locator-hover) instead.
|
||||
* Read more about [locators](https://playwright.dev/docs/locators).
|
||||
*
|
||||
* This method hovers over an element matching `selector` by performing the following steps:
|
||||
* 1. Find an element matching `selector`. If there is none, wait until a matching element is attached to the DOM.
|
||||
|
|
@ -6037,7 +6115,8 @@ export interface Frame {
|
|||
}): Promise<void>;
|
||||
|
||||
/**
|
||||
* **NOTE** Use locator-based [`method: Locator.innerHTML`] instead. Read more about [locators](https://playwright.dev/docs/locators).
|
||||
* **NOTE** Use locator-based [locator.innerHTML([options])](https://playwright.dev/docs/api/class-locator#locator-inner-html)
|
||||
* instead. Read more about [locators](https://playwright.dev/docs/locators).
|
||||
*
|
||||
* Returns `element.innerHTML`.
|
||||
* @param selector A selector to search for an element. If there are multiple elements satisfying the selector, the first will be
|
||||
|
|
@ -6061,7 +6140,8 @@ export interface Frame {
|
|||
}): Promise<string>;
|
||||
|
||||
/**
|
||||
* **NOTE** Use locator-based [`method: Locator.innerText`] instead. Read more about [locators](https://playwright.dev/docs/locators).
|
||||
* **NOTE** Use locator-based [locator.innerText([options])](https://playwright.dev/docs/api/class-locator#locator-inner-text)
|
||||
* instead. Read more about [locators](https://playwright.dev/docs/locators).
|
||||
*
|
||||
* Returns `element.innerText`.
|
||||
* @param selector A selector to search for an element. If there are multiple elements satisfying the selector, the first will be
|
||||
|
|
@ -6085,7 +6165,9 @@ export interface Frame {
|
|||
}): Promise<string>;
|
||||
|
||||
/**
|
||||
* **NOTE** Use locator-based [`method: Locator.inputValue`] instead. Read more about [locators](https://playwright.dev/docs/locators).
|
||||
* **NOTE** Use locator-based
|
||||
* [locator.inputValue([options])](https://playwright.dev/docs/api/class-locator#locator-input-value) instead. Read
|
||||
* more about [locators](https://playwright.dev/docs/locators).
|
||||
*
|
||||
* Returns `input.value` for the selected `<input>` or `<textarea>` or `<select>` element.
|
||||
*
|
||||
|
|
@ -6113,7 +6195,8 @@ export interface Frame {
|
|||
}): Promise<string>;
|
||||
|
||||
/**
|
||||
* **NOTE** Use locator-based [`method: Locator.isChecked`] instead. Read more about [locators](https://playwright.dev/docs/locators).
|
||||
* **NOTE** Use locator-based [locator.isChecked([options])](https://playwright.dev/docs/api/class-locator#locator-is-checked)
|
||||
* instead. Read more about [locators](https://playwright.dev/docs/locators).
|
||||
*
|
||||
* Returns whether the element is checked. Throws if the element is not a checkbox or radio input.
|
||||
* @param selector A selector to search for an element. If there are multiple elements satisfying the selector, the first will be
|
||||
|
|
@ -6142,7 +6225,9 @@ export interface Frame {
|
|||
isDetached(): boolean;
|
||||
|
||||
/**
|
||||
* **NOTE** Use locator-based [`method: Locator.isDisabled`] instead. Read more about [locators](https://playwright.dev/docs/locators).
|
||||
* **NOTE** Use locator-based
|
||||
* [locator.isDisabled([options])](https://playwright.dev/docs/api/class-locator#locator-is-disabled) instead. Read
|
||||
* more about [locators](https://playwright.dev/docs/locators).
|
||||
*
|
||||
* Returns whether the element is disabled, the opposite of [enabled](https://playwright.dev/docs/actionability#enabled).
|
||||
* @param selector A selector to search for an element. If there are multiple elements satisfying the selector, the first will be
|
||||
|
|
@ -6166,7 +6251,9 @@ export interface Frame {
|
|||
}): Promise<boolean>;
|
||||
|
||||
/**
|
||||
* **NOTE** Use locator-based [`method: Locator.isEditable`] instead. Read more about [locators](https://playwright.dev/docs/locators).
|
||||
* **NOTE** Use locator-based
|
||||
* [locator.isEditable([options])](https://playwright.dev/docs/api/class-locator#locator-is-editable) instead. Read
|
||||
* more about [locators](https://playwright.dev/docs/locators).
|
||||
*
|
||||
* Returns whether the element is [editable](https://playwright.dev/docs/actionability#editable).
|
||||
* @param selector A selector to search for an element. If there are multiple elements satisfying the selector, the first will be
|
||||
|
|
@ -6212,7 +6299,8 @@ export interface Frame {
|
|||
}): Promise<boolean>;
|
||||
|
||||
/**
|
||||
* **NOTE** Use locator-based [`method: Locator.isHidden`] instead. Read more about [locators](https://playwright.dev/docs/locators).
|
||||
* **NOTE** Use locator-based [locator.isHidden([options])](https://playwright.dev/docs/api/class-locator#locator-is-hidden)
|
||||
* instead. Read more about [locators](https://playwright.dev/docs/locators).
|
||||
*
|
||||
* Returns whether the element is hidden, the opposite of [visible](https://playwright.dev/docs/actionability#visible). `selector` that
|
||||
* does not match any elements is considered hidden.
|
||||
|
|
@ -6228,14 +6316,16 @@ export interface Frame {
|
|||
strict?: boolean;
|
||||
|
||||
/**
|
||||
* @deprecated This option is ignored. [`method: Frame.isHidden`] does not wait for the element to become hidden and returns
|
||||
* immediately.
|
||||
* @deprecated This option is ignored.
|
||||
* [frame.isHidden(selector[, options])](https://playwright.dev/docs/api/class-frame#frame-is-hidden) does not wait
|
||||
* for the element to become hidden and returns immediately.
|
||||
*/
|
||||
timeout?: number;
|
||||
}): Promise<boolean>;
|
||||
|
||||
/**
|
||||
* **NOTE** Use locator-based [`method: Locator.isVisible`] instead. Read more about [locators](https://playwright.dev/docs/locators).
|
||||
* **NOTE** Use locator-based [locator.isVisible([options])](https://playwright.dev/docs/api/class-locator#locator-is-visible)
|
||||
* instead. Read more about [locators](https://playwright.dev/docs/locators).
|
||||
*
|
||||
* Returns whether the element is [visible](https://playwright.dev/docs/actionability#visible). `selector` that does not match any elements
|
||||
* is considered not visible.
|
||||
|
|
@ -6251,8 +6341,9 @@ export interface Frame {
|
|||
strict?: boolean;
|
||||
|
||||
/**
|
||||
* @deprecated This option is ignored. [`method: Frame.isVisible`] does not wait for the element to become visible and returns
|
||||
* immediately.
|
||||
* @deprecated This option is ignored.
|
||||
* [frame.isVisible(selector[, options])](https://playwright.dev/docs/api/class-frame#frame-is-visible) does not wait
|
||||
* for the element to become visible and returns immediately.
|
||||
*/
|
||||
timeout?: number;
|
||||
}): Promise<boolean>;
|
||||
|
|
@ -6306,7 +6397,8 @@ export interface Frame {
|
|||
parentFrame(): null|Frame;
|
||||
|
||||
/**
|
||||
* **NOTE** Use locator-based [`method: Locator.press`] instead. Read more about [locators](https://playwright.dev/docs/locators).
|
||||
* **NOTE** Use locator-based [locator.press(key[, options])](https://playwright.dev/docs/api/class-locator#locator-press)
|
||||
* instead. Read more about [locators](https://playwright.dev/docs/locators).
|
||||
*
|
||||
* `key` can specify the intended
|
||||
* [keyboardEvent.key](https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/key) value or a single character
|
||||
|
|
@ -6360,7 +6452,9 @@ export interface Frame {
|
|||
}): Promise<void>;
|
||||
|
||||
/**
|
||||
* **NOTE** Use locator-based [`method: Locator.selectOption`] instead. Read more about [locators](https://playwright.dev/docs/locators).
|
||||
* **NOTE** Use locator-based
|
||||
* [locator.selectOption(values[, options])](https://playwright.dev/docs/api/class-locator#locator-select-option)
|
||||
* instead. Read more about [locators](https://playwright.dev/docs/locators).
|
||||
*
|
||||
* This method waits for an element matching `selector`, waits for [actionability](https://playwright.dev/docs/actionability) checks, waits
|
||||
* until all specified options are present in the `<select>` element and selects these options.
|
||||
|
|
@ -6452,7 +6546,9 @@ export interface Frame {
|
|||
}): Promise<Array<string>>;
|
||||
|
||||
/**
|
||||
* **NOTE** Use locator-based [`method: Locator.setChecked`] instead. Read more about [locators](https://playwright.dev/docs/locators).
|
||||
* **NOTE** Use locator-based
|
||||
* [locator.setChecked(checked[, options])](https://playwright.dev/docs/api/class-locator#locator-set-checked)
|
||||
* instead. Read more about [locators](https://playwright.dev/docs/locators).
|
||||
*
|
||||
* This method checks or unchecks an element matching `selector` by performing the following steps:
|
||||
* 1. Find an element matching `selector`. If there is none, wait until a matching element is attached to the DOM.
|
||||
|
|
@ -6545,7 +6641,9 @@ export interface Frame {
|
|||
}): Promise<void>;
|
||||
|
||||
/**
|
||||
* **NOTE** Use locator-based [`method: Locator.setInputFiles`] instead. Read more about [locators](https://playwright.dev/docs/locators).
|
||||
* **NOTE** Use locator-based
|
||||
* [locator.setInputFiles(files[, options])](https://playwright.dev/docs/api/class-locator#locator-set-input-files)
|
||||
* instead. Read more about [locators](https://playwright.dev/docs/locators).
|
||||
*
|
||||
* Sets the value of the file input to these file paths or files. If some of the `filePaths` are relative paths, then
|
||||
* they are resolved relative to the current working directory. For empty array, clears the selected files.
|
||||
|
|
@ -6613,7 +6711,8 @@ export interface Frame {
|
|||
}): Promise<void>;
|
||||
|
||||
/**
|
||||
* **NOTE** Use locator-based [`method: Locator.tap`] instead. Read more about [locators](https://playwright.dev/docs/locators).
|
||||
* **NOTE** Use locator-based [locator.tap([options])](https://playwright.dev/docs/api/class-locator#locator-tap) instead. Read
|
||||
* more about [locators](https://playwright.dev/docs/locators).
|
||||
*
|
||||
* This method taps an element matching `selector` by performing the following steps:
|
||||
* 1. Find an element matching `selector`. If there is none, wait until a matching element is attached to the DOM.
|
||||
|
|
@ -6683,7 +6782,9 @@ export interface Frame {
|
|||
}): Promise<void>;
|
||||
|
||||
/**
|
||||
* **NOTE** Use locator-based [`method: Locator.textContent`] instead. Read more about [locators](https://playwright.dev/docs/locators).
|
||||
* **NOTE** Use locator-based
|
||||
* [locator.textContent([options])](https://playwright.dev/docs/api/class-locator#locator-text-content) instead. Read
|
||||
* more about [locators](https://playwright.dev/docs/locators).
|
||||
*
|
||||
* Returns `element.textContent`.
|
||||
* @param selector A selector to search for an element. If there are multiple elements satisfying the selector, the first will be
|
||||
|
|
@ -6712,7 +6813,8 @@ export interface Frame {
|
|||
title(): Promise<string>;
|
||||
|
||||
/**
|
||||
* **NOTE** Use locator-based [`method: Locator.type`] instead. Read more about [locators](https://playwright.dev/docs/locators).
|
||||
* **NOTE** Use locator-based [locator.type(text[, options])](https://playwright.dev/docs/api/class-locator#locator-type)
|
||||
* instead. Read more about [locators](https://playwright.dev/docs/locators).
|
||||
*
|
||||
* Sends a `keydown`, `keypress`/`input`, and `keyup` event for each character in the text. `frame.type` can be used
|
||||
* to send fine-grained keyboard events. To fill values in form fields, use
|
||||
|
|
@ -6762,7 +6864,8 @@ export interface Frame {
|
|||
}): Promise<void>;
|
||||
|
||||
/**
|
||||
* **NOTE** Use locator-based [`method: Locator.uncheck`] instead. Read more about [locators](https://playwright.dev/docs/locators).
|
||||
* **NOTE** Use locator-based [locator.uncheck([options])](https://playwright.dev/docs/api/class-locator#locator-uncheck)
|
||||
* instead. Read more about [locators](https://playwright.dev/docs/locators).
|
||||
*
|
||||
* This method checks an element matching `selector` by performing the following steps:
|
||||
* 1. Find an element matching `selector`. If there is none, wait until a matching element is attached to the DOM.
|
||||
|
|
@ -10798,8 +10901,9 @@ export interface Locator {
|
|||
*/
|
||||
isHidden(options?: {
|
||||
/**
|
||||
* @deprecated This option is ignored. [`method: Locator.isHidden`] does not wait for the element to become hidden and returns
|
||||
* immediately.
|
||||
* @deprecated This option is ignored.
|
||||
* [locator.isHidden([options])](https://playwright.dev/docs/api/class-locator#locator-is-hidden) does not wait for
|
||||
* the element to become hidden and returns immediately.
|
||||
*/
|
||||
timeout?: number;
|
||||
}): Promise<boolean>;
|
||||
|
|
@ -10810,8 +10914,9 @@ export interface Locator {
|
|||
*/
|
||||
isVisible(options?: {
|
||||
/**
|
||||
* @deprecated This option is ignored. [`method: Locator.isVisible`] does not wait for the element to become visible and returns
|
||||
* immediately.
|
||||
* @deprecated This option is ignored.
|
||||
* [locator.isVisible([options])](https://playwright.dev/docs/api/class-locator#locator-is-visible) does not wait for
|
||||
* the element to become visible and returns immediately.
|
||||
*/
|
||||
timeout?: number;
|
||||
}): Promise<boolean>;
|
||||
|
|
@ -11874,7 +11979,7 @@ export interface BrowserType<Unused = {}> {
|
|||
userAgent?: string;
|
||||
|
||||
/**
|
||||
* @deprecated Use [`option: recordVideo`] instead.
|
||||
* @deprecated Use `recordVideo` instead.
|
||||
*/
|
||||
videoSize?: {
|
||||
/**
|
||||
|
|
@ -11889,7 +11994,7 @@ export interface BrowserType<Unused = {}> {
|
|||
};
|
||||
|
||||
/**
|
||||
* @deprecated Use [`option: recordVideo`] instead.
|
||||
* @deprecated Use `recordVideo` instead.
|
||||
*/
|
||||
videosPath?: string;
|
||||
|
||||
|
|
@ -12133,8 +12238,9 @@ export namespace errors {
|
|||
/**
|
||||
* - extends: [Error]
|
||||
*
|
||||
* TimeoutError is emitted whenever certain operations are terminated due to timeout, e.g. [`method: Locator.waitFor`]
|
||||
* or [browserType.launch([options])](https://playwright.dev/docs/api/class-browsertype#browser-type-launch).
|
||||
* TimeoutError is emitted whenever certain operations are terminated due to timeout, e.g.
|
||||
* [locator.waitFor([options])](https://playwright.dev/docs/api/class-locator#locator-wait-for) or
|
||||
* [browserType.launch([options])](https://playwright.dev/docs/api/class-browsertype#browser-type-launch).
|
||||
*
|
||||
* ```js
|
||||
* const playwright = require('playwright');
|
||||
|
|
@ -13236,7 +13342,7 @@ export interface AndroidDevice {
|
|||
userAgent?: string;
|
||||
|
||||
/**
|
||||
* @deprecated Use [`option: recordVideo`] instead.
|
||||
* @deprecated Use `recordVideo` instead.
|
||||
*/
|
||||
videoSize?: {
|
||||
/**
|
||||
|
|
@ -13251,7 +13357,7 @@ export interface AndroidDevice {
|
|||
};
|
||||
|
||||
/**
|
||||
* @deprecated Use [`option: recordVideo`] instead.
|
||||
* @deprecated Use `recordVideo` instead.
|
||||
*/
|
||||
videosPath?: string;
|
||||
|
||||
|
|
@ -15138,7 +15244,7 @@ export interface Browser extends EventEmitter {
|
|||
userAgent?: string;
|
||||
|
||||
/**
|
||||
* @deprecated Use [`option: recordVideo`] instead.
|
||||
* @deprecated Use `recordVideo` instead.
|
||||
*/
|
||||
videoSize?: {
|
||||
/**
|
||||
|
|
@ -15153,7 +15259,7 @@ export interface Browser extends EventEmitter {
|
|||
};
|
||||
|
||||
/**
|
||||
* @deprecated Use [`option: recordVideo`] instead.
|
||||
* @deprecated Use `recordVideo` instead.
|
||||
*/
|
||||
videosPath?: string;
|
||||
|
||||
|
|
@ -18087,7 +18193,7 @@ export interface BrowserContextOptions {
|
|||
userAgent?: string;
|
||||
|
||||
/**
|
||||
* @deprecated Use [`option: recordVideo`] instead.
|
||||
* @deprecated Use `recordVideo` instead.
|
||||
*/
|
||||
videoSize?: {
|
||||
/**
|
||||
|
|
@ -18102,7 +18208,7 @@ export interface BrowserContextOptions {
|
|||
};
|
||||
|
||||
/**
|
||||
* @deprecated Use [`option: recordVideo`] instead.
|
||||
* @deprecated Use `recordVideo` instead.
|
||||
*/
|
||||
videosPath?: string;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@playwright/experimental-ct-react",
|
||||
"version": "1.29.0-next",
|
||||
"version": "1.29.2",
|
||||
"description": "Playwright Component Testing for React",
|
||||
"repository": "github:Microsoft/playwright",
|
||||
"homepage": "https://playwright.dev",
|
||||
|
|
@ -27,7 +27,7 @@
|
|||
},
|
||||
"dependencies": {
|
||||
"@vitejs/plugin-react": "^2.2.0",
|
||||
"@playwright/test": "1.29.0-next",
|
||||
"@playwright/test": "1.29.2",
|
||||
"vite": "^3.2.1"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@playwright/experimental-ct-solid",
|
||||
"version": "1.29.0-next",
|
||||
"version": "1.29.2",
|
||||
"description": "Playwright Component Testing for Solid",
|
||||
"repository": "github:Microsoft/playwright",
|
||||
"homepage": "https://playwright.dev",
|
||||
|
|
@ -28,7 +28,7 @@
|
|||
"dependencies": {
|
||||
"vite": "^3.2.1",
|
||||
"vite-plugin-solid": "^2.3.10",
|
||||
"@playwright/test": "1.29.0-next"
|
||||
"@playwright/test": "1.29.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"solid-js": "^1.4.7"
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@playwright/experimental-ct-svelte",
|
||||
"version": "1.29.0-next",
|
||||
"version": "1.29.2",
|
||||
"description": "Playwright Component Testing for Svelte",
|
||||
"repository": "github:Microsoft/playwright",
|
||||
"homepage": "https://playwright.dev",
|
||||
|
|
@ -26,7 +26,7 @@
|
|||
}
|
||||
},
|
||||
"dependencies": {
|
||||
"@playwright/test": "1.29.0-next",
|
||||
"@playwright/test": "1.29.2",
|
||||
"@sveltejs/vite-plugin-svelte": "^1.1.0",
|
||||
"vite": "^3.2.1"
|
||||
},
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@playwright/experimental-ct-vue",
|
||||
"version": "1.29.0-next",
|
||||
"version": "1.29.2",
|
||||
"description": "Playwright Component Testing for Vue",
|
||||
"repository": "github:Microsoft/playwright",
|
||||
"homepage": "https://playwright.dev",
|
||||
|
|
@ -27,7 +27,7 @@
|
|||
},
|
||||
"dependencies": {
|
||||
"@vitejs/plugin-vue": "^3.2.0",
|
||||
"@playwright/test": "1.29.0-next",
|
||||
"@playwright/test": "1.29.2",
|
||||
"vite": "^3.2.1"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@playwright/experimental-ct-vue2",
|
||||
"version": "1.29.0-next",
|
||||
"version": "1.29.2",
|
||||
"description": "Playwright Component Testing for Vue2",
|
||||
"repository": "github:Microsoft/playwright",
|
||||
"homepage": "https://playwright.dev",
|
||||
|
|
@ -26,7 +26,7 @@
|
|||
}
|
||||
},
|
||||
"dependencies": {
|
||||
"@playwright/test": "1.29.0-next",
|
||||
"@playwright/test": "1.29.2",
|
||||
"@vitejs/plugin-vue2": "^2.0.0",
|
||||
"vite": "^3.2.1"
|
||||
},
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "playwright-firefox",
|
||||
"version": "1.29.0-next",
|
||||
"version": "1.29.2",
|
||||
"description": "A high-level API to automate Firefox",
|
||||
"repository": "github:Microsoft/playwright",
|
||||
"homepage": "https://playwright.dev",
|
||||
|
|
@ -28,6 +28,6 @@
|
|||
"install": "node install.js"
|
||||
},
|
||||
"dependencies": {
|
||||
"playwright-core": "1.29.0-next"
|
||||
"playwright-core": "1.29.2"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@playwright/test",
|
||||
"version": "1.29.0-next",
|
||||
"version": "1.29.2",
|
||||
"description": "A high-level API to automate web browsers",
|
||||
"repository": "github:Microsoft/playwright",
|
||||
"homepage": "https://playwright.dev",
|
||||
|
|
@ -34,6 +34,6 @@
|
|||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@types/node": "*",
|
||||
"playwright-core": "1.29.0-next"
|
||||
"playwright-core": "1.29.2"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ import type { APIRequestContext, BrowserContext, BrowserContextOptions, LaunchOp
|
|||
import * as playwrightLibrary from 'playwright-core';
|
||||
import { createGuid, debugMode } from 'playwright-core/lib/utils';
|
||||
import { removeFolders } from 'playwright-core/lib/utils/fileUtils';
|
||||
import type { Fixtures, PlaywrightTestArgs, PlaywrightTestOptions, PlaywrightWorkerArgs, PlaywrightWorkerOptions, TestInfo, TestType, TraceMode, VideoMode } from '../types/test';
|
||||
import type { Fixtures, PlaywrightTestArgs, PlaywrightTestOptions, PlaywrightWorkerArgs, PlaywrightWorkerOptions, ScreenshotMode, TestInfo, TestType, TraceMode, VideoMode } from '../types/test';
|
||||
import { store as _baseStore } from './store';
|
||||
import type { TestInfoImpl } from './testInfo';
|
||||
import { rootTestType, _setProjectSetup } from './testType';
|
||||
|
|
@ -246,8 +246,8 @@ const playwrightFixtures: Fixtures<TestFixtures, WorkerFixtures> = ({
|
|||
if (debugMode())
|
||||
testInfo.setTimeout(0);
|
||||
|
||||
const screenshotOptions = typeof screenshot !== 'string' ? { fullPage: screenshot.fullPage, omitBackground: screenshot.omitBackground } : undefined;
|
||||
const screenshotMode = typeof screenshot === 'string' ? screenshot : screenshot.mode;
|
||||
const screenshotMode = normalizeScreenshotMode(screenshot);
|
||||
const screenshotOptions = typeof screenshot === 'string' ? undefined : screenshot;
|
||||
const traceMode = normalizeTraceMode(trace);
|
||||
const defaultTraceOptions = { screenshots: true, snapshots: true, sources: true };
|
||||
const traceOptions = typeof trace === 'string' ? defaultTraceOptions : { ...defaultTraceOptions, ...trace, mode: undefined };
|
||||
|
|
@ -620,6 +620,12 @@ export function shouldCaptureTrace(traceMode: TraceMode, testInfo: TestInfo) {
|
|||
return traceMode === 'on' || traceMode === 'retain-on-failure' || (traceMode === 'on-first-retry' && testInfo.retry === 1);
|
||||
}
|
||||
|
||||
function normalizeScreenshotMode(screenshot: PlaywrightWorkerOptions['screenshot'] | undefined): ScreenshotMode {
|
||||
if (!screenshot)
|
||||
return 'off';
|
||||
return typeof screenshot === 'string' ? screenshot : screenshot.mode;
|
||||
}
|
||||
|
||||
const kTracingStarted = Symbol('kTracingStarted');
|
||||
|
||||
export const test = _baseTest.extend<TestFixtures, WorkerFixtures>(playwrightFixtures);
|
||||
|
|
|
|||
|
|
@ -358,5 +358,5 @@ export async function toPass(
|
|||
`- ${timeoutMessage}`,
|
||||
].join('\n') : timeoutMessage;
|
||||
|
||||
return { message, pass: false };
|
||||
return { message, pass: isNot ? true : false };
|
||||
}
|
||||
|
|
|
|||
|
|
@ -472,7 +472,7 @@ export class Runner {
|
|||
return { status: 'passed' };
|
||||
|
||||
// Remove output directores.
|
||||
if (!this._removeOutputDirs(options))
|
||||
if (!await this._removeOutputDirs(options))
|
||||
return { status: 'failed' };
|
||||
|
||||
// Run Global setup.
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "playwright-webkit",
|
||||
"version": "1.29.0-next",
|
||||
"version": "1.29.2",
|
||||
"description": "A high-level API to automate WebKit",
|
||||
"repository": "github:Microsoft/playwright",
|
||||
"homepage": "https://playwright.dev",
|
||||
|
|
@ -28,6 +28,6 @@
|
|||
"install": "node install.js"
|
||||
},
|
||||
"dependencies": {
|
||||
"playwright-core": "1.29.0-next"
|
||||
"playwright-core": "1.29.2"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "playwright",
|
||||
"version": "1.29.0-next",
|
||||
"version": "1.29.2",
|
||||
"description": "A high-level API to automate web browsers",
|
||||
"repository": "github:Microsoft/playwright",
|
||||
"homepage": "https://playwright.dev",
|
||||
|
|
@ -28,6 +28,6 @@
|
|||
"install": "node install.js"
|
||||
},
|
||||
"dependencies": {
|
||||
"playwright-core": "1.29.0-next"
|
||||
"playwright-core": "1.29.2"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
2
tests/electron/electron-app-pre-ready-app.js
Normal file
2
tests/electron/electron-app-pre-ready-app.js
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
const { protocol } = require('electron');
|
||||
protocol.registerSchemesAsPrivileged([]);
|
||||
|
|
@ -19,10 +19,8 @@ import path from 'path';
|
|||
import fs from 'fs';
|
||||
import { electronTest as test, expect } from './electronTest';
|
||||
|
||||
test('should fire close event', async ({ playwright }) => {
|
||||
const electronApp = await playwright._electron.launch({
|
||||
args: [path.join(__dirname, 'electron-app.js')],
|
||||
});
|
||||
test('should fire close event', async ({ launchElectronApp }) => {
|
||||
const electronApp = await launchElectronApp('electron-app.js');
|
||||
const events = [];
|
||||
electronApp.on('close', () => events.push('application'));
|
||||
electronApp.context().on('close', () => events.push('context'));
|
||||
|
|
@ -33,22 +31,16 @@ test('should fire close event', async ({ playwright }) => {
|
|||
expect(events.join('|')).toBe('context|application');
|
||||
});
|
||||
|
||||
test('should dispatch ready event', async ({ playwright }) => {
|
||||
const electronApp = await playwright._electron.launch({
|
||||
args: [path.join(__dirname, 'electron-app-ready-event.js')],
|
||||
});
|
||||
try {
|
||||
const events = await electronApp.evaluate(() => globalThis.__playwrightLog);
|
||||
expect(events).toEqual([
|
||||
'isReady == false',
|
||||
'will-finish-launching fired',
|
||||
'ready fired',
|
||||
'whenReady resolved',
|
||||
'isReady == true',
|
||||
]);
|
||||
} finally {
|
||||
await electronApp.close();
|
||||
}
|
||||
test('should dispatch ready event', async ({ launchElectronApp }) => {
|
||||
const electronApp = await launchElectronApp('electron-app-ready-event.js');
|
||||
const events = await electronApp.evaluate(() => globalThis.__playwrightLog);
|
||||
expect(events).toEqual([
|
||||
'isReady == false',
|
||||
'will-finish-launching fired',
|
||||
'ready fired',
|
||||
'whenReady resolved',
|
||||
'isReady == true',
|
||||
]);
|
||||
});
|
||||
|
||||
test('should script application', async ({ electronApp }) => {
|
||||
|
|
@ -114,28 +106,19 @@ test('should have a clipboard instance', async ({ electronApp }) => {
|
|||
expect(clipboardContentRead).toEqual(clipboardContentToWrite);
|
||||
});
|
||||
|
||||
test('should test app that opens window fast', async ({ playwright }) => {
|
||||
const electronApp = await playwright._electron.launch({
|
||||
args: [path.join(__dirname, 'electron-window-app.js')],
|
||||
});
|
||||
await electronApp.close();
|
||||
test('should test app that opens window fast', async ({ launchElectronApp }) => {
|
||||
await launchElectronApp('electron-window-app.js');
|
||||
});
|
||||
|
||||
test('should return browser window', async ({ playwright }) => {
|
||||
const electronApp = await playwright._electron.launch({
|
||||
args: [path.join(__dirname, 'electron-window-app.js')],
|
||||
});
|
||||
test('should return browser window', async ({ launchElectronApp }) => {
|
||||
const electronApp = await launchElectronApp('electron-window-app.js');
|
||||
const page = await electronApp.firstWindow();
|
||||
const bwHandle = await electronApp.browserWindow(page);
|
||||
expect(await bwHandle.evaluate((bw: BrowserWindow) => bw.title)).toBe('Electron');
|
||||
await electronApp.close();
|
||||
});
|
||||
|
||||
test('should bypass csp', async ({ playwright, server }) => {
|
||||
const app = await playwright._electron.launch({
|
||||
args: [require('path').join(__dirname, 'electron-app.js')],
|
||||
bypassCSP: true,
|
||||
});
|
||||
test('should bypass csp', async ({ launchElectronApp, server }) => {
|
||||
const app = await launchElectronApp('electron-app.js', { bypassCSP: true });
|
||||
await app.evaluate(electron => {
|
||||
const window = new electron.BrowserWindow({
|
||||
width: 800,
|
||||
|
|
@ -147,13 +130,10 @@ test('should bypass csp', async ({ playwright, server }) => {
|
|||
await page.goto(server.PREFIX + '/csp.html');
|
||||
await page.addScriptTag({ content: 'window["__injected"] = 42;' });
|
||||
expect(await page.evaluate('window["__injected"]')).toBe(42);
|
||||
await app.close();
|
||||
});
|
||||
|
||||
test('should create page for browser view', async ({ playwright }) => {
|
||||
const app = await playwright._electron.launch({
|
||||
args: [path.join(__dirname, 'electron-window-app.js')],
|
||||
});
|
||||
test('should create page for browser view', async ({ launchElectronApp }) => {
|
||||
const app = await launchElectronApp('electron-window-app.js');
|
||||
await app.firstWindow();
|
||||
await app.evaluate(async electron => {
|
||||
const window = electron.BrowserWindow.getAllWindows()[0];
|
||||
|
|
@ -163,13 +143,10 @@ test('should create page for browser view', async ({ playwright }) => {
|
|||
view.setBounds({ x: 0, y: 0, width: 256, height: 256 });
|
||||
});
|
||||
await expect.poll(() => app.windows().length).toBe(2);
|
||||
await app.close();
|
||||
});
|
||||
|
||||
test('should return same browser window for browser view pages', async ({ playwright }) => {
|
||||
const app = await playwright._electron.launch({
|
||||
args: [path.join(__dirname, 'electron-window-app.js')],
|
||||
});
|
||||
test('should return same browser window for browser view pages', async ({ launchElectronApp }) => {
|
||||
const app = await launchElectronApp('electron-window-app.js');
|
||||
await app.firstWindow();
|
||||
await app.evaluate(async electron => {
|
||||
const window = electron.BrowserWindow.getAllWindows()[0];
|
||||
|
|
@ -187,12 +164,10 @@ test('should return same browser window for browser view pages', async ({ playwr
|
|||
})
|
||||
);
|
||||
expect(firstWindowId).toEqual(secondWindowId);
|
||||
await app.close();
|
||||
});
|
||||
|
||||
test('should record video', async ({ playwright }, testInfo) => {
|
||||
const app = await playwright._electron.launch({
|
||||
args: [path.join(__dirname, 'electron-window-app.js')],
|
||||
test('should record video', async ({ launchElectronApp }, testInfo) => {
|
||||
const app = await launchElectronApp('electron-window-app.js', {
|
||||
recordVideo: { dir: testInfo.outputPath('video') }
|
||||
});
|
||||
const page = await app.firstWindow();
|
||||
|
|
@ -203,25 +178,31 @@ test('should record video', async ({ playwright }, testInfo) => {
|
|||
expect(fs.statSync(videoPath).size).toBeGreaterThan(0);
|
||||
});
|
||||
|
||||
test('should be able to get the first window when with a delayed navigation', async ({ playwright }) => {
|
||||
test('should be able to get the first window when with a delayed navigation', async ({ launchElectronApp }) => {
|
||||
test.info().annotations.push({ type: 'issue', description: 'https://github.com/microsoft/playwright/issues/17765' });
|
||||
|
||||
const app = await playwright._electron.launch({
|
||||
args: [path.join(__dirname, 'electron-window-app-delayed-loadURL.js')],
|
||||
});
|
||||
const app = await launchElectronApp('electron-window-app-delayed-loadURL.js');
|
||||
const page = await app.firstWindow();
|
||||
await expect(page).toHaveURL('data:text/html,<h1>Foobar</h1>');
|
||||
await expect(page.locator('h1')).toHaveText('Foobar');
|
||||
await app.close();
|
||||
});
|
||||
|
||||
test('should detach debugger on app-initiated exit', async ({ playwright }) => {
|
||||
const electronApp = await playwright._electron.launch({
|
||||
args: [path.join(__dirname, 'electron-app.js')],
|
||||
});
|
||||
test('should detach debugger on app-initiated exit', async ({ launchElectronApp }) => {
|
||||
const electronApp = await launchElectronApp('electron-app.js');
|
||||
const closePromise = new Promise(f => electronApp.process().on('close', f));
|
||||
await electronApp.evaluate(({ app }) => {
|
||||
app.quit();
|
||||
});
|
||||
await closePromise;
|
||||
});
|
||||
|
||||
test('should run pre-ready apis', async ({ launchElectronApp }) => {
|
||||
await launchElectronApp('electron-pre-ready-app.js');
|
||||
});
|
||||
|
||||
test('should resolve app path for folder apps', async ({ launchElectronApp }) => {
|
||||
const electronApp = await launchElectronApp('.');
|
||||
const appPath = await electronApp.evaluate(async ({ app }) => app.getAppPath());
|
||||
expect(appPath).toBe(path.resolve(__dirname));
|
||||
await electronApp.close();
|
||||
});
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@ import { assert } from 'playwright-core/lib/utils';
|
|||
|
||||
type ElectronTestFixtures = PageTestFixtures & {
|
||||
electronApp: ElectronApplication;
|
||||
launchElectronApp: (appFile: string, options?: any) => Promise<ElectronApplication>;
|
||||
newWindow: () => Promise<Page>;
|
||||
};
|
||||
|
||||
|
|
@ -40,14 +41,21 @@ export const electronTest = baseTest.extend<TraceViewerFixtures>(traceViewerFixt
|
|||
isElectron: [true, { scope: 'worker' }],
|
||||
isWebView2: [false, { scope: 'worker' }],
|
||||
|
||||
electronApp: async ({ playwright }, run) => {
|
||||
launchElectronApp: async ({ playwright }, use) => {
|
||||
// This env prevents 'Electron Security Policy' console message.
|
||||
process.env['ELECTRON_DISABLE_SECURITY_WARNINGS'] = 'true';
|
||||
const electronApp = await playwright._electron.launch({
|
||||
args: [path.join(__dirname, 'electron-app.js')],
|
||||
const apps: ElectronApplication[] = [];
|
||||
await use(async (appFile: string, options?: any[]) => {
|
||||
const app = await playwright._electron.launch({ ...options, args: [path.join(__dirname, appFile)] });
|
||||
apps.push(app);
|
||||
return app;
|
||||
});
|
||||
await run(electronApp);
|
||||
await electronApp.close();
|
||||
for (const app of apps)
|
||||
await app.close();
|
||||
},
|
||||
|
||||
electronApp: async ({ launchElectronApp }, use) => {
|
||||
await use(await launchElectronApp('electron-app.js'));
|
||||
},
|
||||
|
||||
newWindow: async ({ electronApp }, run) => {
|
||||
|
|
|
|||
1
tests/electron/index.js
Normal file
1
tests/electron/index.js
Normal file
|
|
@ -0,0 +1 @@
|
|||
require('electron');
|
||||
|
|
@ -30,6 +30,7 @@ import type { Browser, ConnectOptions } from 'playwright-core';
|
|||
type ExtraFixtures = {
|
||||
connect: (wsEndpoint: string, options?: ConnectOptions, redirectPortForTest?: number) => Promise<Browser>,
|
||||
dummyServerPort: number,
|
||||
ipV6ServerUrl: string,
|
||||
};
|
||||
const test = playwrightTest.extend<ExtraFixtures>({
|
||||
connect: async ({ browserType }, use) => {
|
||||
|
|
@ -54,6 +55,16 @@ const test = playwrightTest.extend<ExtraFixtures>({
|
|||
await use((server.address() as net.AddressInfo).port);
|
||||
await new Promise<Error>(resolve => server.close(resolve));
|
||||
},
|
||||
|
||||
ipV6ServerUrl: async ({}, use) => {
|
||||
const server = http.createServer((req: http.IncomingMessage, res: http.ServerResponse) => {
|
||||
res.end('<html><body>from-ipv6-server</body></html>');
|
||||
});
|
||||
await new Promise<void>(resolve => server.listen(0, '::1', resolve));
|
||||
const address = server.address() as net.AddressInfo;
|
||||
await use('http://[::1]:' + address.port);
|
||||
await new Promise<Error>(resolve => server.close(resolve));
|
||||
},
|
||||
});
|
||||
|
||||
test.slow(true, 'All connect tests are slow');
|
||||
|
|
@ -126,6 +137,16 @@ for (const kind of ['launchServer', 'run-server'] as const) {
|
|||
}
|
||||
});
|
||||
|
||||
test('should be able to visit ipv6', async ({ connect, startRemoteServer, ipV6ServerUrl }) => {
|
||||
test.fixme(kind === 'run-server', 'socks proxy does not support ipv6 yet');
|
||||
const remoteServer = await startRemoteServer(kind);
|
||||
const browser = await connect(remoteServer.wsEndpoint());
|
||||
const page = await browser.newPage();
|
||||
await page.goto(ipV6ServerUrl);
|
||||
expect(await page.content()).toContain('from-ipv6-server');
|
||||
await browser.close();
|
||||
});
|
||||
|
||||
test('should be able to connect two browsers at the same time', async ({ connect, startRemoteServer }) => {
|
||||
const remoteServer = await startRemoteServer(kind);
|
||||
|
||||
|
|
@ -679,6 +700,7 @@ for (const kind of ['launchServer', 'run-server'] as const) {
|
|||
test.describe('socks proxy', () => {
|
||||
test.fixme(({ platform, browserName }) => browserName === 'webkit' && platform === 'win32');
|
||||
test.skip(({ mode }) => mode !== 'default');
|
||||
test.skip(kind === 'launchServer', 'not supported yet');
|
||||
|
||||
test('should forward non-forwarded requests', async ({ server, startRemoteServer, connect }) => {
|
||||
let reachedOriginalTarget = false;
|
||||
|
|
|
|||
|
|
@ -167,3 +167,16 @@ test('should work with soft', async ({ runInlineTest }) => {
|
|||
expect(result.exitCode).toBe(1);
|
||||
expect(result.failed).toBe(1);
|
||||
});
|
||||
|
||||
test('should not accept TimeoutError', async ({ runInlineTest }) => {
|
||||
const result = await runInlineTest({
|
||||
'a.spec.ts': `
|
||||
const { test } = pwt;
|
||||
test('should fail', async () => {
|
||||
await test.expect(() => {}).not.toPass({ timeout: 1 });
|
||||
});
|
||||
`
|
||||
});
|
||||
expect(result.exitCode).toBe(1);
|
||||
expect(result.failed).toBe(1);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -600,3 +600,86 @@ test('should pass fixture defaults to tests', async ({ runInlineTest }) => {
|
|||
expect(result.exitCode).toBe(0);
|
||||
expect(result.passed).toBe(1);
|
||||
});
|
||||
|
||||
test('should not throw with many fixtures set to undefined', async ({ runInlineTest }, testInfo) => {
|
||||
const result = await runInlineTest({
|
||||
'playwright.config.ts': `
|
||||
module.exports = { use: {
|
||||
headless: undefined,
|
||||
channel: undefined,
|
||||
launchOptions: undefined,
|
||||
connectOptions: undefined,
|
||||
screenshot: undefined,
|
||||
video: undefined,
|
||||
trace: undefined,
|
||||
acceptDownloads: undefined,
|
||||
bypassCSP: undefined,
|
||||
colorScheme: undefined,
|
||||
deviceScaleFactor: undefined,
|
||||
extraHTTPHeaders: undefined,
|
||||
geolocation: undefined,
|
||||
hasTouch: undefined,
|
||||
httpCredentials: undefined,
|
||||
ignoreHTTPSErrors: undefined,
|
||||
isMobile: undefined,
|
||||
javaScriptEnabled: undefined,
|
||||
locale: undefined,
|
||||
offline: undefined,
|
||||
permissions: undefined,
|
||||
proxy: undefined,
|
||||
storageState: undefined,
|
||||
timezoneId: undefined,
|
||||
userAgent: undefined,
|
||||
viewport: undefined,
|
||||
actionTimeout: undefined,
|
||||
testIdAttribute: undefined,
|
||||
navigationTimeout: undefined,
|
||||
baseURL: undefined,
|
||||
serviceWorkers: undefined,
|
||||
contextOptions: undefined,
|
||||
} };
|
||||
`,
|
||||
'a.spec.ts': `
|
||||
const { test } = pwt;
|
||||
test.use({
|
||||
headless: undefined,
|
||||
channel: undefined,
|
||||
launchOptions: undefined,
|
||||
connectOptions: undefined,
|
||||
screenshot: undefined,
|
||||
video: undefined,
|
||||
trace: undefined,
|
||||
acceptDownloads: undefined,
|
||||
bypassCSP: undefined,
|
||||
colorScheme: undefined,
|
||||
deviceScaleFactor: undefined,
|
||||
extraHTTPHeaders: undefined,
|
||||
geolocation: undefined,
|
||||
hasTouch: undefined,
|
||||
httpCredentials: undefined,
|
||||
ignoreHTTPSErrors: undefined,
|
||||
isMobile: undefined,
|
||||
javaScriptEnabled: undefined,
|
||||
locale: undefined,
|
||||
offline: undefined,
|
||||
permissions: undefined,
|
||||
proxy: undefined,
|
||||
storageState: undefined,
|
||||
timezoneId: undefined,
|
||||
userAgent: undefined,
|
||||
viewport: undefined,
|
||||
actionTimeout: undefined,
|
||||
testIdAttribute: undefined,
|
||||
navigationTimeout: undefined,
|
||||
baseURL: undefined,
|
||||
serviceWorkers: undefined,
|
||||
contextOptions: undefined,
|
||||
});
|
||||
test('passes', async ({ page }) => {
|
||||
});
|
||||
`,
|
||||
}, { workers: 1 });
|
||||
|
||||
expect(result.exitCode).toBe(0);
|
||||
expect(result.passed).toBe(1);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -178,6 +178,10 @@ class Documentation {
|
|||
* @param {Class|Member=} classOrMember
|
||||
*/
|
||||
renderLinksInNodes(nodes, classOrMember) {
|
||||
if (classOrMember instanceof Member) {
|
||||
classOrMember.discouraged = classOrMember.discouraged ? this.renderLinksInText(classOrMember.discouraged, classOrMember) : undefined;
|
||||
classOrMember.deprecated = classOrMember.deprecated ? this.renderLinksInText(classOrMember.deprecated, classOrMember) : undefined
|
||||
}
|
||||
md.visitAll(nodes, node => {
|
||||
if (!node.text)
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -117,7 +117,7 @@ function _wrapAndEscape(node, maxColumns = 0) {
|
|||
};
|
||||
|
||||
|
||||
let text = node.text;
|
||||
let text = (node.text || '').replace(/↵/g, ' ');
|
||||
text = text.replace(/\[([^\]]*)\]\((.*?)\)/g, (match, linkName, linkUrl) => {
|
||||
const isInternal = !linkUrl.startsWith('http://') && !linkUrl.startsWith('https://');
|
||||
if (isInternal)
|
||||
|
|
|
|||
|
|
@ -25,7 +25,6 @@ const fs = require('fs');
|
|||
const { parseApi } = require('./api_parser');
|
||||
const { Type } = require('./documentation');
|
||||
const { EOL } = require('os');
|
||||
const { execSync } = require('child_process');
|
||||
|
||||
const maxDocumentationColumnWidth = 80;
|
||||
Error.stackTraceLimit = 100;
|
||||
|
|
@ -91,10 +90,10 @@ classNameMap.set('Readable', 'Stream');
|
|||
*
|
||||
* @param {string} kind
|
||||
* @param {string} name
|
||||
* @param {Documentation.MarkdownNode[]} spec
|
||||
* @param {Documentation.MarkdownNode[]|null} spec
|
||||
* @param {string[]} body
|
||||
* @param {string} folder
|
||||
* @param {string} extendsName
|
||||
* @param {string|null} extendsName
|
||||
*/
|
||||
function writeFile(kind, name, spec, body, folder, extendsName = null) {
|
||||
const out = [];
|
||||
|
|
@ -144,10 +143,19 @@ function renderClass(clazz) {
|
|||
renderMember(member, clazz, {}, body);
|
||||
}
|
||||
|
||||
/** @type {Documentation.MarkdownNode[]} */
|
||||
const spec = [];
|
||||
if (clazz.deprecated)
|
||||
spec.push({ type: 'text', text: '**DEPRECATED** ' + clazz.deprecated });
|
||||
if (clazz.discouraged)
|
||||
spec.push({ type: 'text', text: clazz.discouraged });
|
||||
if (clazz.spec)
|
||||
spec.push(...clazz.spec);
|
||||
|
||||
writeFile(
|
||||
'public partial interface',
|
||||
name,
|
||||
clazz.spec,
|
||||
spec,
|
||||
body,
|
||||
apiDir,
|
||||
clazz.extends ? `I${toTitleCase(clazz.extends)}` : null);
|
||||
|
|
@ -278,7 +286,22 @@ function renderConstructors(name, type, out) {
|
|||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {Documentation.Member} member
|
||||
* @param {string[]} out
|
||||
*/
|
||||
function renderMemberDoc(member, out) {
|
||||
/** @type {Documentation.MarkdownNode[]} */
|
||||
const nodes = [];
|
||||
if (member.deprecated)
|
||||
nodes.push({ type: 'text', text: '**DEPRECATED** ' + member.deprecated });
|
||||
if (member.discouraged)
|
||||
nodes.push({ type: 'text', text: member.discouraged });
|
||||
if (member.spec)
|
||||
nodes.push(...member.spec);
|
||||
out.push(...XmlDoc.renderXmlDoc(nodes, maxDocumentationColumnWidth));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Documentation.Member} member
|
||||
* @param {Documentation.Class|Documentation.Type} parent
|
||||
* @param {{nojson?: boolean, trimRunAndPrefix?: boolean}} options
|
||||
|
|
@ -296,8 +319,7 @@ function renderMember(member, parent, options, out) {
|
|||
if (!member.type)
|
||||
throw new Error(`No Event Type for ${name} in ${parent.name}`);
|
||||
out.push('');
|
||||
if (member.spec)
|
||||
out.push(...XmlDoc.renderXmlDoc(member.spec, maxDocumentationColumnWidth));
|
||||
renderMemberDoc(member, out);
|
||||
if (member.deprecated)
|
||||
out.push(`[System.Obsolete]`);
|
||||
out.push(`event EventHandler<${type}> ${name};`);
|
||||
|
|
@ -314,8 +336,7 @@ function renderMember(member, parent, options, out) {
|
|||
const { name, jsonName } = overload;
|
||||
let { type } = overload;
|
||||
out.push('');
|
||||
if (member.spec)
|
||||
out.push(...XmlDoc.renderXmlDoc(member.spec, maxDocumentationColumnWidth));
|
||||
renderMemberDoc(member, out);
|
||||
if (!member.clazz)
|
||||
out.push(`${member.required ? '[Required]\n' : ''}[JsonPropertyName("${jsonName}")]`);
|
||||
if (member.deprecated)
|
||||
|
|
@ -623,7 +644,7 @@ function renderMethod(member, parent, name, options, out) {
|
|||
|
||||
if (!explodedArgs.length) {
|
||||
if (!options.nodocs) {
|
||||
out.push(...XmlDoc.renderXmlDoc(member.spec, maxDocumentationColumnWidth));
|
||||
renderMemberDoc(member, out);
|
||||
paramDocs.forEach((value, i) => printArgDoc(i, value, out));
|
||||
}
|
||||
if (member.deprecated)
|
||||
|
|
@ -633,7 +654,7 @@ function renderMethod(member, parent, name, options, out) {
|
|||
let containsOptionalExplodedArgs = false;
|
||||
explodedArgs.forEach((explodedArg, argIndex) => {
|
||||
if (!options.nodocs)
|
||||
out.push(...XmlDoc.renderXmlDoc(member.spec, maxDocumentationColumnWidth));
|
||||
renderMemberDoc(member, out);
|
||||
const overloadedArgs = [];
|
||||
for (let i = 0; i < args.length; i++) {
|
||||
const arg = args[i];
|
||||
|
|
@ -662,7 +683,7 @@ function renderMethod(member, parent, name, options, out) {
|
|||
if (containsOptionalExplodedArgs) {
|
||||
const filteredArgs = args.filter(x => x !== 'OPTIONAL_EXPLODED_ARG');
|
||||
if (!options.nodocs)
|
||||
out.push(...XmlDoc.renderXmlDoc(member.spec, maxDocumentationColumnWidth));
|
||||
renderMemberDoc(member, out);
|
||||
filteredArgs.forEach(arg => {
|
||||
if (arg === 'EXPLODED_ARG')
|
||||
throw new Error(`Unsupported required union arg combined an optional union inside ${member.name}`);
|
||||
|
|
|
|||
Loading…
Reference in a new issue