docs(element-handle): discourage the element handle use (#10220)

This commit is contained in:
Pavel Feldman 2021-11-10 11:30:25 -08:00 committed by GitHub
parent 96d7b21b34
commit 1e38ec5fa4
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
15 changed files with 267 additions and 177 deletions

View file

@ -3,6 +3,10 @@
ElementHandle represents an in-page DOM element. ElementHandles can be created with the [`method: Page.querySelector`] method. ElementHandle represents an in-page DOM element. ElementHandles can be created with the [`method: Page.querySelector`] method.
:::caution Discouraged
The use of ElementHandle is discouraged, use [Locator] objects and web-first assertions instead.
:::
```js ```js
const hrefElement = await page.$('a'); const hrefElement = await page.$('a');
await hrefElement.click(); await hrefElement.click();
@ -33,11 +37,6 @@ ElementHandle prevents DOM element from garbage collection unless the handle is
ElementHandle instances can be used as an argument in [`method: Page.evalOnSelector`] and [`method: Page.evaluate`] methods. ElementHandle instances can be used as an argument in [`method: Page.evalOnSelector`] and [`method: Page.evaluate`] methods.
:::note
In most cases, you would want to use the [Locator] object instead. You should only use [ElementHandle] if you want to retain
a handle to a particular DOM Node that you intend to pass into [`method: Page.evaluate`] as an argument.
:::
The difference between the [Locator] and ElementHandle is that the ElementHandle points to a particular element, while [Locator] captures the logic of how to retrieve an element. The difference between the [Locator] and ElementHandle is that the ElementHandle points to a particular element, while [Locator] captures the logic of how to retrieve an element.
In the example below, handle points to a particular DOM element on page. If that element changes text or is used by React to render an entirely different component, handle is still pointing to that very DOM element. This can lead to unexpected behaviors. In the example below, handle points to a particular DOM element on page. If that element changes text or is used by React to render an entirely different component, handle is still pointing to that very DOM element. This can lead to unexpected behaviors.

View file

@ -383,6 +383,11 @@ Optional event-specific initialization properties.
Returns the return value of [`param: expression`]. Returns the return value of [`param: expression`].
:::caution
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.
:::
The method finds an element matching the specified selector within the frame and passes it as a first argument to The method finds an element matching the specified selector within the frame and passes it as a first argument to
[`param: expression`]. See [Working with selectors](./selectors.md) for more details. If no [`param: expression`]. See [Working with selectors](./selectors.md) for more details. If no
elements match the selector, the method throws an error. elements match the selector, the method throws an error.
@ -439,6 +444,10 @@ Optional argument to pass to [`param: expression`].
Returns the return value of [`param: expression`]. Returns the return value of [`param: expression`].
:::note
In most cases, [`method: Locator.evaluateAll`], other [Locator] helper methods and web-first assertions do a better job.
:::
The method finds all elements matching the specified selector within the frame and passes an array of matched elements The method finds all elements matching the specified selector within the frame and passes an array of matched elements
as a first argument to [`param: expression`]. See [Working with selectors](./selectors.md) for as a first argument to [`param: expression`]. See [Working with selectors](./selectors.md) for
more details. more details.
@ -546,31 +555,31 @@ Console.WriteLine(await frame.EvaluateAsync<int>("1 + 2")); // prints "3"
[ElementHandle] instances can be passed as an argument to the [`method: Frame.evaluate`]: [ElementHandle] instances can be passed as an argument to the [`method: Frame.evaluate`]:
```js ```js
const bodyHandle = await frame.$('body'); const bodyHandle = await frame.evaluate('document.body');
const html = await frame.evaluate(([body, suffix]) => body.innerHTML + suffix, [bodyHandle, 'hello']); const html = await frame.evaluate(([body, suffix]) => body.innerHTML + suffix, [bodyHandle, 'hello']);
await bodyHandle.dispose(); await bodyHandle.dispose();
``` ```
```java ```java
ElementHandle bodyHandle = frame.querySelector("body"); ElementHandle bodyHandle = frame.evaluate("document.body");
String html = (String) frame.evaluate("([body, suffix]) => body.innerHTML + suffix", Arrays.asList(bodyHandle, "hello")); String html = (String) frame.evaluate("([body, suffix]) => body.innerHTML + suffix", Arrays.asList(bodyHandle, "hello"));
bodyHandle.dispose(); bodyHandle.dispose();
``` ```
```python async ```python async
body_handle = await frame.query_selector("body") body_handle = await frame.evaluate("document.body")
html = await frame.evaluate("([body, suffix]) => body.innerHTML + suffix", [body_handle, "hello"]) html = await frame.evaluate("([body, suffix]) => body.innerHTML + suffix", [body_handle, "hello"])
await body_handle.dispose() await body_handle.dispose()
``` ```
```python sync ```python sync
body_handle = frame.query_selector("body") body_handle = frame.evaluate("document.body")
html = frame.evaluate("([body, suffix]) => body.innerHTML + suffix", [body_handle, "hello"]) html = frame.evaluate("([body, suffix]) => body.innerHTML + suffix", [body_handle, "hello"])
body_handle.dispose() body_handle.dispose()
``` ```
```csharp ```csharp
var bodyHandle = await frame.QuerySelectorAsync("body"); var bodyHandle = await frame.EvaluateAsync("document.body");
var html = await frame.EvaluateAsync<string>("([body, suffix]) => body.innerHTML + suffix", new object [] { bodyHandle, "hello" }); var html = await frame.EvaluateAsync<string>("([body, suffix]) => body.innerHTML + suffix", new object [] { bodyHandle, "hello" });
await bodyHandle.DisposeAsync(); await bodyHandle.DisposeAsync();
``` ```
@ -1046,6 +1055,10 @@ Time to wait between `keydown` and `keyup` in milliseconds. Defaults to 0.
Returns the ElementHandle pointing to the frame element. Returns the ElementHandle pointing to the frame element.
:::caution
The use of [ElementHandle] is discouraged, use [Locator] objects and web-first assertions instead.
:::
The method finds an element matching the specified selector within the frame. See The method finds an element matching the specified selector within the frame. See
[Working with selectors](./selectors.md) for more details. If no elements match the selector, [Working with selectors](./selectors.md) for more details. If no elements match the selector,
returns `null`. returns `null`.
@ -1062,6 +1075,10 @@ returns `null`.
Returns the ElementHandles pointing to the frame elements. Returns the ElementHandles pointing to the frame elements.
:::caution
The use of [ElementHandle] is discouraged, use [Locator] objects instead.
:::
The method finds all elements matching the specified selector within the frame. See The method finds all elements matching the specified selector within the frame. See
[Working with selectors](./selectors.md) for more details. If no elements match the selector, [Working with selectors](./selectors.md) for more details. If no elements match the selector,
returns empty array. returns empty array.
@ -1540,6 +1557,11 @@ a navigation.
Returns when element specified by selector satisfies [`option: state`] option. Returns `null` if waiting for `hidden` or Returns when element specified by selector satisfies [`option: state`] option. Returns `null` if waiting for `hidden` or
`detached`. `detached`.
:::note
Playwright automatically waits for element to be ready before performing an action. Using
[Locator] objects and web-first assertions make the code wait-for-selector-free.
:::
Wait for the [`param: selector`] to satisfy [`option: state`] option (either appear/disappear from dom, or become Wait for the [`param: selector`] to satisfy [`option: state`] option (either appear/disappear from dom, or become
visible/hidden). If at the moment of calling the method [`param: selector`] already satisfies the condition, the method visible/hidden). If at the moment of calling the method [`param: selector`] already satisfies the condition, the method
will return immediately. If the selector doesn't satisfy the condition for the [`option: timeout`] milliseconds, the will return immediately. If the selector doesn't satisfy the condition for the [`option: timeout`] milliseconds, the

View file

@ -1023,6 +1023,11 @@ It's not supported in WebKit, see [here](https://bugs.webkit.org/show_bug.cgi?id
- alias-js: $eval - alias-js: $eval
- returns: <[Serializable]> - returns: <[Serializable]>
:::caution
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.
:::
The method finds an element matching the specified selector within the page and passes it as a first argument to The method finds an element matching the specified selector within the page and passes it as a first argument to
[`param: expression`]. If no elements match the selector, the method throws an error. Returns the value of [`param: expression`]. If no elements match the selector, the method throws an error. Returns the value of
[`param: expression`]. [`param: expression`].
@ -1081,6 +1086,10 @@ Optional argument to pass to [`param: expression`].
- alias-js: $$eval - alias-js: $$eval
- returns: <[Serializable]> - returns: <[Serializable]>
:::note
In most cases, [`method: Locator.evaluateAll`], 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 The method finds all elements matching the specified selector within the page and passes an array of matched elements as
a first argument to [`param: expression`]. Returns the result of [`param: expression`] invocation. a first argument to [`param: expression`]. Returns the result of [`param: expression`] invocation.
@ -1190,31 +1199,31 @@ Console.WriteLine(await page.EvaluateAsync<int>("1 + 2")); // prints "3"
[ElementHandle] instances can be passed as an argument to the [`method: Page.evaluate`]: [ElementHandle] instances can be passed as an argument to the [`method: Page.evaluate`]:
```js ```js
const bodyHandle = await page.$('body'); const bodyHandle = await page.evaluate('document.body');
const html = await page.evaluate(([body, suffix]) => body.innerHTML + suffix, [bodyHandle, 'hello']); const html = await page.evaluate(([body, suffix]) => body.innerHTML + suffix, [bodyHandle, 'hello']);
await bodyHandle.dispose(); await bodyHandle.dispose();
``` ```
```java ```java
ElementHandle bodyHandle = page.querySelector("body"); ElementHandle bodyHandle = page.evaluate("document.body");
String html = (String) page.evaluate("([body, suffix]) => body.innerHTML + suffix", Arrays.asList(bodyHandle, "hello")); String html = (String) page.evaluate("([body, suffix]) => body.innerHTML + suffix", Arrays.asList(bodyHandle, "hello"));
bodyHandle.dispose(); bodyHandle.dispose();
``` ```
```python async ```python async
body_handle = await page.query_selector("body") body_handle = await page.evaluate("document.body")
html = await page.evaluate("([body, suffix]) => body.innerHTML + suffix", [body_handle, "hello"]) html = await page.evaluate("([body, suffix]) => body.innerHTML + suffix", [body_handle, "hello"])
await body_handle.dispose() await body_handle.dispose()
``` ```
```python sync ```python sync
body_handle = page.query_selector("body") body_handle = page.evaluate("document.body")
html = page.evaluate("([body, suffix]) => body.innerHTML + suffix", [body_handle, "hello"]) html = page.evaluate("([body, suffix]) => body.innerHTML + suffix", [body_handle, "hello"])
body_handle.dispose() body_handle.dispose()
``` ```
```csharp ```csharp
var bodyHandle = await page.QuerySelectorAsync("body"); var bodyHandle = await page.EvaluateAsync("document.body");
var html = await page.EvaluateAsync<string>("([body, suffix]) => body.innerHTML + suffix", new object [] { bodyHandle, "hello" }); var html = await page.EvaluateAsync<string>("([body, suffix]) => body.innerHTML + suffix", new object [] { bodyHandle, "hello" });
await bodyHandle.DisposeAsync(); await bodyHandle.DisposeAsync();
``` ```
@ -2422,8 +2431,12 @@ Time to wait between `keydown` and `keyup` in milliseconds. Defaults to 0.
- alias-js: $ - alias-js: $
- returns: <[null]|[ElementHandle]> - returns: <[null]|[ElementHandle]>
:::caution
The use of [ElementHandle] is discouraged, use [Locator] objects and web-first assertions instead.
:::
The method finds an element matching the specified selector within the page. If no elements match the selector, the 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 [`method: Page.waitForSelector`]. return value resolves to `null`. To wait for an element on the page, use [`method: Locator.waitFor`].
Shortcut for main frame's [`method: Frame.querySelector`]. Shortcut for main frame's [`method: Frame.querySelector`].
@ -2437,6 +2450,10 @@ Shortcut for main frame's [`method: Frame.querySelector`].
- alias-js: $$ - alias-js: $$
- returns: <[Array]<[ElementHandle]>> - returns: <[Array]<[ElementHandle]>>
:::caution
The use of [ElementHandle] is discouraged, use [Locator] objects and web-first assertions instead.
:::
The method finds all elements matching the specified selector within the page. If no elements match the selector, the The method finds all elements matching the specified selector within the page. If no elements match the selector, the
return value resolves to `[]`. return value resolves to `[]`.
@ -3674,6 +3691,11 @@ changed by using the [`method: BrowserContext.setDefaultTimeout`] or [`method: P
Returns when element specified by selector satisfies [`option: state`] option. Returns `null` if waiting for `hidden` or Returns when element specified by selector satisfies [`option: state`] option. Returns `null` if waiting for `hidden` or
`detached`. `detached`.
:::note
Playwright automatically waits for element to be ready before performing an action. Using
[Locator] objects and web-first assertions make the code wait-for-selector-free.
:::
Wait for the [`param: selector`] to satisfy [`option: state`] option (either appear/disappear from dom, or become Wait for the [`param: selector`] to satisfy [`option: state`] option (either appear/disappear from dom, or become
visible/hidden). If at the moment of calling the method [`param: selector`] already satisfies the condition, the method visible/hidden). If at the moment of calling the method [`param: selector`] already satisfies the condition, the method
will return immediately. If the selector doesn't satisfy the condition for the [`option: timeout`] milliseconds, the will return immediately. If the selector doesn't satisfy the condition for the [`option: timeout`] milliseconds, the

View file

@ -178,7 +178,7 @@ class PlaywrightExample
- `TimeoutError` <[function]> A class of [TimeoutError]. - `TimeoutError` <[function]> A class of [TimeoutError].
Playwright methods might throw errors if they are unable to fulfill a request. For example, Playwright methods might throw errors if they are unable to fulfill a request. For example,
[`method: Page.waitForSelector`] might fail if the selector doesn't match any nodes during the given timeframe. [`method: Locator.waitFor`] might fail if the selector doesn't match any nodes during the given timeframe.
For certain types of errors Playwright uses specific error classes. These classes are available via For certain types of errors Playwright uses specific error classes. These classes are available via
[`playwright.errors`](#playwrighterrors). [`playwright.errors`](#playwrighterrors).
@ -187,7 +187,7 @@ An example of handling a timeout error:
```js ```js
try { try {
await page.waitForSelector('.foo'); await page.locator('.foo').waitFor();
} catch (e) { } catch (e) {
if (e instanceof playwright.errors.TimeoutError) { if (e instanceof playwright.errors.TimeoutError) {
// Do something if this is a timeout. // Do something if this is a timeout.

View file

@ -32,11 +32,11 @@ const { selectors, firefox } = require('playwright'); // Or 'chromium' or 'webk
await page.setContent(`<div><button>Click me</button></div>`); await page.setContent(`<div><button>Click me</button></div>`);
// Use the selector prefixed with its name. // Use the selector prefixed with its name.
const button = await page.$('tag=button'); const button = page.locator('tag=button');
// Combine it with other selector engines. // Combine it with other selector engines.
await page.click('tag=div >> text="Click me"'); await page.click('tag=div >> text="Click me"');
// Can use it in any methods supporting selectors. // Can use it in any methods supporting selectors.
const buttonCount = await page.$$eval('tag=button', buttons => buttons.length); const buttonCount = await page.locator('tag=button').count();
await browser.close(); await browser.close();
})(); })();
@ -60,11 +60,11 @@ Browser browser = playwright.firefox().launch();
Page page = browser.newPage(); Page page = browser.newPage();
page.setContent("<div><button>Click me</button></div>"); page.setContent("<div><button>Click me</button></div>");
// Use the selector prefixed with its name. // Use the selector prefixed with its name.
ElementHandle button = page.querySelector("tag=button"); Locator button = page.locator("tag=button");
// Combine it with other selector engines. // Combine it with other selector engines.
page.click("tag=div >> text=\"Click me\""); page.click("tag=div >> text=\"Click me\"");
// Can use it in any methods supporting selectors. // Can use it in any methods supporting selectors.
int buttonCount = (int) page.evalOnSelectorAll("tag=button", "buttons => buttons.length"); int buttonCount = (int) page.locator("tag=button").count();
browser.close(); browser.close();
``` ```
@ -96,7 +96,7 @@ async def run(playwright):
# Combine it with other selector engines. # Combine it with other selector engines.
await page.click('tag=div >> text="Click me"') await page.click('tag=div >> text="Click me"')
# Can use it in any methods supporting selectors. # Can use it in any methods supporting selectors.
button_count = await page.eval_on_selector_all('tag=button', 'buttons => buttons.length') button_count = await page.locator('tag=button').count()
print(button_count) print(button_count)
await browser.close() await browser.close()
@ -130,11 +130,11 @@ def run(playwright):
page.set_content('<div><button>Click me</button></div>') page.set_content('<div><button>Click me</button></div>')
# Use the selector prefixed with its name. # Use the selector prefixed with its name.
button = page.query_selector('tag=button') button = page.locator('tag=button')
# Combine it with other selector engines. # Combine it with other selector engines.
page.click('tag=div >> text="Click me"') page.click('tag=div >> text="Click me"')
# Can use it in any methods supporting selectors. # Can use it in any methods supporting selectors.
button_count = page.eval_on_selector_all('tag=button', 'buttons => buttons.length') button_count = page.locator('tag=button').count()
print(button_count) print(button_count)
browser.close() browser.close()
@ -160,11 +160,11 @@ await using var browser = await playwright.Chromium.LaunchAsync();
var page = await browser.NewPageAsync(); var page = await browser.NewPageAsync();
await page.SetContentAsync("<div><button>Click me</button></div>"); await page.SetContentAsync("<div><button>Click me</button></div>");
// Use the selector prefixed with its name. // Use the selector prefixed with its name.
var button = await page.QuerySelectorAsync("tag=button"); var button = page.Locator("tag=button");
// Combine it with other selector engines. // Combine it with other selector engines.
await page.ClickAsync("tag=div >> text=\"Click me\""); await page.ClickAsync("tag=div >> text=\"Click me\"");
// Can use it in any methods supporting selectors. // Can use it in any methods supporting selectors.
int buttonCount = await page.EvalOnSelectorAllAsync<int>("tag=button", "buttons => buttons.length"); int buttonCount = await page.Locator("tag=button").CountAsync();
``` ```
### param: Selectors.register.name ### param: Selectors.register.name

View file

@ -2,7 +2,7 @@
* extends: [Error] * extends: [Error]
TimeoutError is emitted whenever certain operations are terminated due to timeout, e.g. [`method: TimeoutError is emitted whenever certain operations are terminated due to timeout, e.g. [`method:
Page.waitForSelector`] or [`method: BrowserType.launch`]. Locator.waitFor`] or [`method: BrowserType.launch`].
```js ```js
const playwright = require('playwright'); const playwright = require('playwright');

View file

@ -131,27 +131,27 @@ Assert.True(checked);
## JS expression ## JS expression
```js ```js
const content = await page.$eval('nav:first-child', e => e.textContent); const content = await page.locator('nav:first-child').textContent();
expect(content).toBe('home'); expect(content).toBe('home');
``` ```
```java ```java
Object content = page.evalOnSelector("nav:first-child", "e => e.textContent"); Object content = page.locator("nav:first-child").textContent();
assertEquals("home", content); assertEquals("home", content);
``` ```
```python async ```python async
content = await page.eval_on_selector("nav:first-child", "e => e.textContent") content = await page.locator("nav:first-child").text_content()
assert content == "home" assert content == "home"
``` ```
```python sync ```python sync
content = page.eval_on_selector("nav:first-child", "e => e.textContent") content = page.locator("nav:first-child").text_content()
assert content == "home" assert content == "home"
``` ```
```csharp ```csharp
var content = await page.EvalOnSelectorAsync("nav:first-child", "e => e.textContent"); var content = await page.locator("nav:first-child").TextContentAsync();
Assert.Equals("home", content); Assert.Equals("home", content);
``` ```
@ -264,16 +264,15 @@ const userId = page.evaluate(() => window.localStorage.getItem('userId'));
expect(userId).toBeTruthy(); expect(userId).toBeTruthy();
// Assert value for input element // Assert value for input element
await page.waitForSelector('#search'); const value = await page.locator('#search').inputValue();
const value = await page.inputValue('#search');
expect(value === 'query').toBeTruthy(); expect(value === 'query').toBeTruthy();
// Assert computed style // Assert computed style
const fontSize = await page.$eval('div', el => window.getComputedStyle(el).fontSize); const fontSize = await page.locator('div').evaluate(el => window.getComputedStyle(el).fontSize);
expect(fontSize === '16px').toBeTruthy(); expect(fontSize === '16px').toBeTruthy();
// Assert list length // Assert list length
const length = await page.$$eval('li.selected', (items) => items.length); const length = await page.locator('li.selected').count();
expect(length === 3).toBeTruthy(); expect(length === 3).toBeTruthy();
``` ```
@ -283,16 +282,15 @@ Object userId = page.evaluate("() => window.localStorage.getItem('userId')");
assertNotNull(userId); assertNotNull(userId);
// Assert value for input element // Assert value for input element
page.waitForSelector("#search"); Object value = page.locator("#search").inputValue();
Object value = page.evalOnSelector("#search", "el => el.value");
assertEquals("query", value); assertEquals("query", value);
// Assert computed style // Assert computed style
Object fontSize = page.evalOnSelector("div", "el => window.getComputedStyle(el).fontSize"); Object fontSize = page.locator("div").evaluate("el => window.getComputedStyle(el).fontSize");
assertEquals("16px", fontSize); assertEquals("16px", fontSize);
// Assert list length // Assert list length
Object length = page.evalOnSelectorAll("li.selected", "items => items.length"); Object length = page.locator("li.selected").count();
assertEquals(3, length); assertEquals(3, length);
``` ```
@ -302,16 +300,15 @@ user_id = page.evaluate("() => window.localStorage.getItem('user_id')")
assert user_id assert user_id
# Assert value for input element # Assert value for input element
await page.wait_for_selector('#search') value = await page.locator('#search').input_value()
value = await page.eval_on_selector('#search', 'el => el.value')
assert value == 'query' assert value == 'query'
# Assert computed style # Assert computed style
font_size = await page.eval_on_selector('div', 'el => window.getComputedStyle(el).fontSize') font_size = await page.locator('div').evaluate('el => window.getComputedStyle(el).fontSize')
assert font_size == '16px' assert font_size == '16px'
# Assert list length # Assert list length
length = await page.eval_on_selector_all('li.selected', '(items) => items.length') length = await page.locator('li.selected').count()
assert length == 3 assert length == 3
``` ```
@ -321,16 +318,15 @@ user_id = page.evaluate("() => window.localStorage.getItem('user_id')")
assert user_id assert user_id
# Assert value for input element # Assert value for input element
page.wait_for_selector('#search') value = page.locator('#search').input_value()
value = page.eval_on_selector('#search', 'el => el.value')
assert value == 'query' assert value == 'query'
# Assert computed style # Assert computed style
font_size = page.eval_on_selector('div', 'el => window.getComputedStyle(el).fontSize') font_size = page.locator('div').evaluate('el => window.getComputedStyle(el).fontSize')
assert font_size == '16px' assert font_size == '16px'
# Assert list length # Assert list length
length = page.eval_on_selector_all('li.selected', '(items) => items.length') length = page.locator('li.selected').count()
assert length == 3 assert length == 3
``` ```
@ -340,26 +336,14 @@ var userId = await page.EvaluateAsync<string>("() => window.localStorage.getItem
Assert.NotNull(userId); Assert.NotNull(userId);
// Assert value for input element // Assert value for input element
await page.WaitForSelectorAsync("#search"); var value = await page.Locator("#search").InputValueAsync();
var value = await page.EvalOnSelectorAsync("#search", "el => el.value");
Assert.Equals("query", value); Assert.Equals("query", value);
// Assert computed style // Assert computed style
var fontSize = await page.EvalOnSelectorAsync<string>("div", "el => window.getComputedStyle(el).fontSize"); var fontSize = await page.Locator("div").EvalOnSelectorAsync<string>("el => window.getComputedStyle(el).fontSize");
Assert.Equals("16px", fontSize); Assert.Equals("16px", fontSize);
// Assert list length // Assert list length
var length = await page.EvalOnSelectorAllAsync<int>("li.selected", "items => items.length"); var length = await page.Locator("li.selected").CountAsync();
Assert.Equals(3, length); Assert.Equals(3, length);
``` ```
### API reference
- [`method: Page.evaluate`]
- [`method: Page.evalOnSelector`]
- [`method: Page.evalOnSelectorAll`]
- [`method: Frame.evaluate`]
- [`method: Frame.evalOnSelector`]
- [`method: Frame.evalOnSelectorAll`]
- [`method: ElementHandle.evalOnSelector`]
- [`method: ElementHandle.evalOnSelectorAll`]
- [EvaluationArgument]

View file

@ -81,15 +81,15 @@ await page.evaluate(array => array.length, [1, 2, 3]);
await page.evaluate(object => object.foo, { foo: 'bar' }); await page.evaluate(object => object.foo, { foo: 'bar' });
// A single handle. // A single handle.
const button = await page.$('button'); const button = await page.evaluate('window.button');
await page.evaluate(button => button.textContent, button); await page.evaluate(button => button.textContent, button);
// Alternative notation using elementHandle.evaluate. // Alternative notation using elementHandle.evaluate.
await button.evaluate((button, from) => button.textContent.substring(from), 5); await button.evaluate((button, from) => button.textContent.substring(from), 5);
// Object with multiple handles. // Object with multiple handles.
const button1 = await page.$('.button1'); const button1 = await page.evaluate('window.button1');
const button2 = await page.$('.button2'); const button2 = await page.evaluate('window.button2');
await page.evaluate( await page.evaluate(
o => o.button1.textContent + o.button2.textContent, o => o.button1.textContent + o.button2.textContent,
{ button1, button2 }); { button1, button2 });
@ -126,15 +126,15 @@ obj.put("foo", "bar");
page.evaluate("object => object.foo", obj); page.evaluate("object => object.foo", obj);
// A single handle. // A single handle.
ElementHandle button = page.querySelector("button"); ElementHandle button = page.evaluate("window.button");
page.evaluate("button => button.textContent", button); page.evaluate("button => button.textContent", button);
// Alternative notation using elementHandle.evaluate. // Alternative notation using elementHandle.evaluate.
button.evaluate("(button, from) => button.textContent.substring(from)", 5); button.evaluate("(button, from) => button.textContent.substring(from)", 5);
// Object with multiple handles. // Object with multiple handles.
ElementHandle button1 = page.querySelector(".button1"); ElementHandle button1 = page.evaluate("window.button1");
ElementHandle button2 = page.querySelector(".button2"); ElementHandle button2 = page.evaluate("window.button2");
Map<String, ElementHandle> arg = new HashMap<>(); Map<String, ElementHandle> arg = new HashMap<>();
arg.put("button1", button1); arg.put("button1", button1);
arg.put("button2", button2); arg.put("button2", button2);
@ -175,15 +175,15 @@ await page.evaluate('array => array.length', [1, 2, 3])
await page.evaluate('object => object.foo', { 'foo': 'bar' }) await page.evaluate('object => object.foo', { 'foo': 'bar' })
# A single handle. # A single handle.
button = await page.query_selctor('button') button = await page.evaluate('button')
await page.evaluate('button => button.textContent', button) await page.evaluate('button => button.textContent', button)
# Alternative notation using elementHandle.evaluate. # Alternative notation using elementHandle.evaluate.
await button.evaluate('(button, from) => button.textContent.substring(from)', 5) await button.evaluate('(button, from) => button.textContent.substring(from)', 5)
# Object with multiple handles. # Object with multiple handles.
button1 = await page.query_selector('.button1') button1 = await page.query_selector('window.button1')
button2 = await page.query_selector('.button2') button2 = await page.query_selector('window.button2')
await page.evaluate(""" await page.evaluate("""
o => o.button1.textContent + o.button2.textContent""", o => o.button1.textContent + o.button2.textContent""",
{ 'button1': button1, 'button2': button2 }) { 'button1': button1, 'button2': button2 })
@ -218,15 +218,15 @@ page.evaluate('array => array.length', [1, 2, 3])
page.evaluate('object => object.foo', { 'foo': 'bar' }) page.evaluate('object => object.foo', { 'foo': 'bar' })
# A single handle. # A single handle.
button = page.query_selector('button') button = page.evaluate('window.button')
page.evaluate('button => button.textContent', button) page.evaluate('button => button.textContent', button)
# Alternative notation using elementHandle.evaluate. # Alternative notation using elementHandle.evaluate.
button.evaluate('(button, from) => button.textContent.substring(from)', 5) button.evaluate('(button, from) => button.textContent.substring(from)', 5)
# Object with multiple handles. # Object with multiple handles.
button1 = page.query_selector('.button1') button1 = page.evaluate('window.button1')
button2 = page.query_selector('.button2') button2 = page.evaluate('.button2')
page.evaluate("""o => o.button1.textContent + o.button2.textContent""", page.evaluate("""o => o.button1.textContent + o.button2.textContent""",
{ 'button1': button1, 'button2': button2 }) { 'button1': button1, 'button2': button2 })
@ -260,15 +260,15 @@ await page.EvaluateAsync<int[]>("array => array.length", new[] { 1, 2, 3 });
await page.EvaluateAsync<object>("object => object.foo", new { foo = "bar" }); await page.EvaluateAsync<object>("object => object.foo", new { foo = "bar" });
// A single handle. // A single handle.
var button = await page.QuerySelectorAsync("button"); var button = await page.EvaluateAsync("window.button");
await page.EvaluateAsync<IJSHandle>("button => button.textContent", button); await page.EvaluateAsync<IJSHandle>("button => button.textContent", button);
// Alternative notation using elementHandle.EvaluateAsync. // Alternative notation using elementHandle.EvaluateAsync.
await button.EvaluateAsync<string>("(button, from) => button.textContent.substring(from)", 5); await button.EvaluateAsync<string>("(button, from) => button.textContent.substring(from)", 5);
// Object with multiple handles. // Object with multiple handles.
var button1 = await page.QuerySelectorAsync(".button1"); var button1 = await page.EvaluateAsync("window.button1");
var button2 = await page.QuerySelectorAsync(".button2"); var button2 = await page.EvaluateAsync("window.button2");
await page.EvaluateAsync("o => o.button1.textContent + o.button2.textContent", new { button1, button2 }); await page.EvaluateAsync("o => o.button1.textContent + o.button2.textContent", new { button1, button2 });
// Object destructuring works. Note that property names must match // Object destructuring works. Note that property names must match

View file

@ -42,13 +42,14 @@ const createTagNameEngine = () => ({
await selectors.register('tag', createTagNameEngine); await selectors.register('tag', createTagNameEngine);
// Now we can use 'tag=' selectors. // Now we can use 'tag=' selectors.
const button = await page.$('tag=button'); const button = page.locator('tag=button');
await button.click();
// We can combine it with other selector engines using `>>` combinator. // We can combine it with other selector engines using `>>` combinator.
await page.click('tag=div >> span >> "Click me"'); await page.click('tag=div >> span >> "Click me"');
// We can use it in any methods supporting selectors. // We can use it in any methods supporting selectors.
const buttonCount = await page.$$eval('tag=button', buttons => buttons.length); const buttonCount = await page.locator('tag=button').count();
``` ```
```java ```java
@ -69,13 +70,14 @@ String createTagNameEngine = "{\n" +
playwright.selectors().register("tag", createTagNameEngine); playwright.selectors().register("tag", createTagNameEngine);
// Now we can use "tag=" selectors. // Now we can use "tag=" selectors.
ElementHandle button = page.querySelector("tag=button"); Locator button = page.locator("tag=button");
button.click();
// We can combine it with other selector engines using ">>" combinator. // We can combine it with other selector engines using ">>" combinator.
page.click("tag=div >> span >> \"Click me\""); page.click("tag=div >> span >> \"Click me\"");
// We can use it in any methods supporting selectors. // We can use it in any methods supporting selectors.
int buttonCount = (int) page.evalOnSelectorAll("tag=button", "buttons => buttons.length"); int buttonCount = (int) page.locator("tag=button").count();
``` ```
```python async ```python async
@ -97,13 +99,14 @@ tag_selector = """
await playwright.selectors.register("tag", tag_selector) await playwright.selectors.register("tag", tag_selector)
# now we can use "tag=" selectors. # now we can use "tag=" selectors.
button = await page.query_selector("tag=button") button = page.locator("tag=button")
await button.click()
# we can combine it with other selector engines using `>>` combinator. # we can combine it with other selector engines using `>>` combinator.
await page.click("tag=div >> span >> "click me"") await page.click("tag=div >> span >> "click me"")
# we can use it in any methods supporting selectors. # we can use it in any methods supporting selectors.
button_count = await page.eval_on_selector_all("tag=button", buttons => buttons.length) button_count = await page.locator("tag=button").count()
``` ```
```python sync ```python sync
@ -125,11 +128,12 @@ tag_selector = """
playwright.selectors.register("tag", tag_selector) playwright.selectors.register("tag", tag_selector)
# now we can use "tag=" selectors. # now we can use "tag=" selectors.
button = page.query_selector("tag=button") button = page.locator("tag=button")
button.click()
# we can combine it with other selector engines using `>>` combinator. # we can combine it with other selector engines using `>>` combinator.
page.click("tag=div >> span >> "click me"") page.click("tag=div >> span >> "click me"")
# we can use it in any methods supporting selectors. # we can use it in any methods supporting selectors.
button_count = page.eval_on_selector_all("tag=button", buttons => buttons.length) button_count = page.locator("tag=button").count()
``` ```

View file

@ -55,10 +55,6 @@ const frame = page.frame('frame-login');
// Get frame using frame's URL // Get frame using frame's URL
const frame = page.frame({ url: /.*domain.*/ }); const frame = page.frame({ url: /.*domain.*/ });
// Get frame using any other selector
const frameElementHandle = await page.$('.frame-class');
const frame = await frameElementHandle.contentFrame();
// Interact with the frame // Interact with the frame
await frame.fill('#username-input', 'John'); await frame.fill('#username-input', 'John');
``` ```
@ -70,10 +66,6 @@ Frame frame = page.frame("frame-login");
// Get frame using frame"s URL // Get frame using frame"s URL
Frame frame = page.frameByUrl(Pattern.compile(".*domain.*")); Frame frame = page.frameByUrl(Pattern.compile(".*domain.*"));
// Get frame using any other selector
ElementHandle frameElementHandle = page.querySelector(".frame-class");
Frame frame = frameElementHandle.contentFrame();
// Interact with the frame // Interact with the frame
frame.fill("#username-input", "John"); frame.fill("#username-input", "John");
``` ```
@ -85,10 +77,6 @@ frame = page.frame('frame-login')
# Get frame using frame's URL # Get frame using frame's URL
frame = page.frame(url=r'.*domain.*') frame = page.frame(url=r'.*domain.*')
# Get frame using any other selector
frame_element_handle = await page.query_selector('.frame-class')
frame = await frame_element_handle.content_frame()
# Interact with the frame # Interact with the frame
await frame.fill('#username-input', 'John') await frame.fill('#username-input', 'John')
``` ```
@ -100,10 +88,6 @@ frame = page.frame('frame-login')
# Get frame using frame's URL # Get frame using frame's URL
frame = page.frame(url=r'.*domain.*') frame = page.frame(url=r'.*domain.*')
# Get frame using any other selector
frame_element_handle = page.query_selector('.frame-class')
frame = frame_element_handle.content_frame()
# Interact with the frame # Interact with the frame
frame.fill('#username-input', 'John') frame.fill('#username-input', 'John')
``` ```
@ -119,7 +103,7 @@ var frame = page.Frame("frame-login");
var frame = page.FrameByUrl("*domain."); var frame = page.FrameByUrl("*domain.");
// Get frame using any other selector // Get frame using any other selector
var frameElementHandle = await page.QuerySelectorAsync(".frame-class"); var frameElementHandle = await page.EvaluateAsync("window.frames[1]");
var frame = await frameElementHandle.ContentFrameAsync(); var frame = await frameElementHandle.ContentFrameAsync();
// Interact with the frame // Interact with the frame

View file

@ -48,35 +48,10 @@ var jsHandle = await page.EvaluateHandleAsync("window");
// Use jsHandle for evaluations. // Use jsHandle for evaluations.
``` ```
```js
const ulElementHandle = await page.waitForSelector('ul');
// Use ulElementHandle for actions and evaluation.
```
```java
ElementHandle ulElementHandle = page.waitForSelector("ul");
// Use ulElementHandle for actions and evaluation.
```
```python async
ul_element_handle = await page.wait_for_selector('ul')
# Use ul_element_handle for actions and evaluation.
```
```python sync
ul_element_handle = page.wait_for_selector('ul')
# Use ul_element_handle for actions and evaluation.
```
```csharp
var ulElementHandle = await page.WaitForSelectorAsync("ul");
// Use ulElementHandle for actions and evaluation.
```
## Element Handles ## Element Handles
:::note :::caution Discouraged
It is recommended to use selector-based actions like [`method: Page.click`] rather than using the [ElementHandle] for input actions, unless your use case specifically requires the use of handles. The use of [ElementHandle] is discouraged, use [Locator] objects and web-first assertions instead.
::: :::
When [ElementHandle] is required, it is recommended to fetch it with the When [ElementHandle] is required, it is recommended to fetch it with the

View file

@ -95,13 +95,13 @@ await page.GotoAsync("https://example.com", new PageGotoOptions { WaitUntil = Wa
### Wait for element ### Wait for element
In lazy-loaded pages, it can be useful to wait until an element is visible with [`method: Page.waitForSelector`]. In lazy-loaded pages, it can be useful to wait until an element is visible with [`method: Locator.waitFor`].
Alternatively, page interactions like [`method: Page.click`] auto-wait for elements. Alternatively, page interactions like [`method: Page.click`] auto-wait for elements.
```js ```js
// Navigate and wait for element // Navigate and wait for element
await page.goto('https://example.com'); await page.goto('https://example.com');
await page.waitForSelector('text=Example Domain'); await page.locator('text=Example Domain').waitFor();
// Navigate and click element // Navigate and click element
// Click will auto-wait for the element // Click will auto-wait for the element
@ -112,7 +112,7 @@ await page.click('text=Example Domain');
```java ```java
// Navigate and wait for element // Navigate and wait for element
page.navigate("https://example.com"); page.navigate("https://example.com");
page.waitForSelector("text=Example Domain"); page.locator("text=Example Domain").waitFor();
// Navigate and click element // Navigate and click element
// Click will auto-wait for the element // Click will auto-wait for the element
@ -123,7 +123,7 @@ page.click("text=Example Domain");
```python async ```python async
# Navigate and wait for element # Navigate and wait for element
await page.goto("https://example.com") await page.goto("https://example.com")
await page.wait_for_selector("text=example domain") await page.locator("text=example domain").wait_for()
# Navigate and click element # Navigate and click element
# Click will auto-wait for the element # Click will auto-wait for the element
@ -134,7 +134,7 @@ await page.click("text=example domain")
```python sync ```python sync
# Navigate and wait for element # Navigate and wait for element
page.goto("https://example.com") page.goto("https://example.com")
page.wait_for_selector("text=example domain") page.locator("text=example domain").wait_for()
# Navigate and click element # Navigate and click element
# Click will auto-wait for the element # Click will auto-wait for the element
@ -145,7 +145,7 @@ page.click("text=example domain")
```csharp ```csharp
// Navigate and wait for element // Navigate and wait for element
await page.GotoAsync("https://example.com"); await page.GotoAsync("https://example.com");
await page.WaitForSelectorAsync("text=Example Domain"); await page.Locator("text=Example Domain").WaitForAsync();
// Navigate and click element // Navigate and click element
// Click will auto-wait for the element // Click will auto-wait for the element
@ -239,14 +239,14 @@ await page.WaitForLoadStateAsync(LoadState.NetworkIdle); // This resolves after
### Wait for element ### Wait for element
In lazy-loaded pages, it can be useful to wait until an element is visible with [`method: Page.waitForSelector`]. In lazy-loaded pages, it can be useful to wait until an element is visible with [`method: Locator.waitFor`].
Alternatively, page interactions like [`method: Page.click`] auto-wait for elements. Alternatively, page interactions like [`method: Page.click`] auto-wait for elements.
```js ```js
// Click will auto-wait for the element and trigger navigation // Click will auto-wait for the element and trigger navigation
await page.click('text=Login'); await page.click('text=Login');
// Wait for the element // Wait for the element
await page.waitForSelector('#username'); await page.locator('#username').waitFor();
// Click triggers navigation // Click triggers navigation
await page.click('text=Login'); await page.click('text=Login');
@ -258,7 +258,7 @@ await page.fill('#username', 'John Doe');
// Click will auto-wait for the element and trigger navigation // Click will auto-wait for the element and trigger navigation
page.click("text=Login"); page.click("text=Login");
// Wait for the element // Wait for the element
page.waitForSelector("#username"); page.locator("#username").waitFor();
// Click triggers navigation // Click triggers navigation
page.click("text=Login"); page.click("text=Login");
@ -270,7 +270,7 @@ page.fill("#username", "John Doe");
# Click will auto-wait for the element and trigger navigation # Click will auto-wait for the element and trigger navigation
await page.click("text=Login") await page.click("text=Login")
# Wait for the element # Wait for the element
await page.wait_for_selector("#username") await page.locator("#username").wait_for()
# Click triggers navigation # Click triggers navigation
await page.click("text=Login") await page.click("text=Login")
@ -282,7 +282,7 @@ await page.fill("#username", "John Doe")
# Click triggers navigation # Click triggers navigation
page.click("text=Login") page.click("text=Login")
# Click will auto-wait for the element # Click will auto-wait for the element
page.wait_for_selector("#username", "John Doe") page.locator("#username").wait_for()
# Click triggers navigation # Click triggers navigation
page.click("text=Login") page.click("text=Login")
@ -294,7 +294,7 @@ page.fill("#username", "John Doe")
// Click will auto-wait for the element and trigger navigation // Click will auto-wait for the element and trigger navigation
await page.ClickAsync("text=Login"); await page.ClickAsync("text=Login");
// Wait for the element // Wait for the element
await page.WaitForSelectorAsync("#username"); await page.Locator("#username").WaitForAsync();
// Click triggers navigation // Click triggers navigation
await page.ClickAsync("text=Login"); await page.ClickAsync("text=Login");
@ -450,7 +450,6 @@ popup.WaitForLoadStateAsync(LoadState.Load);
### API reference ### API reference
- [`method: Page.click`] - [`method: Page.click`]
- [`method: Page.waitForLoadState`] - [`method: Page.waitForLoadState`]
- [`method: Page.waitForSelector`]
- [`method: Page.waitForNavigation`] - [`method: Page.waitForNavigation`]
- [`method: Page.waitForFunction`] - [`method: Page.waitForFunction`]

View file

@ -79,30 +79,21 @@ var bytes = await page.ScreenshotAsync();
Sometimes it is useful to take a screenshot of a single element. Sometimes it is useful to take a screenshot of a single element.
```js ```js
const elementHandle = await page.$('.header'); await page.locator('.header').screenshot({ path: 'screenshot.png' });
await elementHandle.screenshot({ path: 'screenshot.png' });
``` ```
```java ```java
ElementHandle elementHandle = page.querySelector(".header"); page.locator(".header").screenshot(new ElementHandle.ScreenshotOptions().setPath(Paths.get("screenshot.png")));
elementHandle.screenshot(new ElementHandle.ScreenshotOptions().setPath(Paths.get("screenshot.png")));
``` ```
```python async ```python async
element_handle = await page.query_selector(".header") await page.locator(".header").screenshot(path="screenshot.png")
await element_handle.screenshot(path="screenshot.png")
``` ```
```python sync ```python sync
element_handle = page.query_selector(".header") page.locator(".header").screenshot(path="screenshot.png")
element_handle.screenshot(path="screenshot.png")
``` ```
```csharp ```csharp
var elementHandle = await page.QuerySelectorAsync(".header") await page.Locator(".header").ScreenshotAsync(new ElementHandleScreenshotOptions { Path = "screenshot.png" });
await elementHandle.ScreenshotAsync(new ElementHandleScreenshotOptions { Path = "screenshot.png" });
``` ```
### API reference
- [`method: Page.screenshot`]
- [`method: ElementHandle.screenshot`]

View file

@ -877,31 +877,31 @@ page.click(":nth-match(:text('Buy'), 3)"
await page.ClickAsync(":nth-match(:text('Buy'), 3)"); await page.ClickAsync(":nth-match(:text('Buy'), 3)");
``` ```
`:nth-match()` is also useful to wait until a specified number of elements appear, using [`method: Page.waitForSelector`]. `:nth-match()` is also useful to wait until a specified number of elements appear, using [`method: Locator.waitFor`].
```js ```js
// Wait until all three buttons are visible // Wait until all three buttons are visible
await page.waitForSelector(':nth-match(:text("Buy"), 3)'); await page.locator(':nth-match(:text("Buy"), 3)').waitFor();
``` ```
```java ```java
// Wait until all three buttons are visible // Wait until all three buttons are visible
page.waitForSelector(":nth-match(:text('Buy'), 3)"); page.locator(":nth-match(:text('Buy'), 3)").waitFor();
``` ```
```python async ```python async
# Wait until all three buttons are visible # Wait until all three buttons are visible
await page.wait_for_selector(":nth-match(:text('Buy'), 3)") await page.locator(":nth-match(:text('Buy'), 3)").wait_for()
``` ```
```python sync ```python sync
# Wait until all three buttons are visible # Wait until all three buttons are visible
page.wait_for_selector(":nth-match(:text('Buy'), 3)") page.locator(":nth-match(:text('Buy'), 3)").wait_for()
``` ```
```csharp ```csharp
// Wait until all three buttons are visible // Wait until all three buttons are visible
await page.WaitForSelectorAsync(":nth-match(:text('Buy'), 3)"); await page.Locator(":nth-match(:text('Buy'), 3)").WaitForAsync();
``` ```
:::note :::note

View file

@ -109,7 +109,7 @@ export interface Page {
* [page.evaluate(pageFunction[, arg])](https://playwright.dev/docs/api/class-page#page-evaluate): * [page.evaluate(pageFunction[, arg])](https://playwright.dev/docs/api/class-page#page-evaluate):
* *
* ```js * ```js
* const bodyHandle = await page.$('body'); * const bodyHandle = await page.evaluate('document.body');
* const html = await page.evaluate(([body, suffix]) => body.innerHTML + suffix, [bodyHandle, 'hello']); * const html = await page.evaluate(([body, suffix]) => body.innerHTML + suffix, [bodyHandle, 'hello']);
* await bodyHandle.dispose(); * await bodyHandle.dispose();
* ``` * ```
@ -156,7 +156,7 @@ export interface Page {
* [page.evaluate(pageFunction[, arg])](https://playwright.dev/docs/api/class-page#page-evaluate): * [page.evaluate(pageFunction[, arg])](https://playwright.dev/docs/api/class-page#page-evaluate):
* *
* ```js * ```js
* const bodyHandle = await page.$('body'); * const bodyHandle = await page.evaluate('document.body');
* const html = await page.evaluate(([body, suffix]) => body.innerHTML + suffix, [bodyHandle, 'hello']); * const html = await page.evaluate(([body, suffix]) => body.innerHTML + suffix, [bodyHandle, 'hello']);
* await bodyHandle.dispose(); * await bodyHandle.dispose();
* ``` * ```
@ -250,9 +250,11 @@ export interface Page {
evaluateHandle<R>(pageFunction: PageFunction<void, R>, arg?: any): Promise<SmartHandle<R>>; evaluateHandle<R>(pageFunction: PageFunction<void, R>, arg?: any): Promise<SmartHandle<R>>;
/** /**
* > NOTE: The use of [ElementHandle] is discouraged, use [Locator] objects and web-first assertions instead.
*
* The method finds an element matching the specified selector within the page. If no elements match the selector, the * 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 * return value resolves to `null`. To wait for an element on the page, use
* [page.waitForSelector(selector[, options])](https://playwright.dev/docs/api/class-page#page-wait-for-selector). * [locator.waitFor([options])](https://playwright.dev/docs/api/class-locator#locator-wait-for).
* *
* Shortcut for main frame's * Shortcut for main frame's
* [frame.$(selector[, options])](https://playwright.dev/docs/api/class-frame#frame-query-selector). * [frame.$(selector[, options])](https://playwright.dev/docs/api/class-frame#frame-query-selector).
@ -261,9 +263,11 @@ export interface Page {
*/ */
$<K extends keyof HTMLElementTagNameMap>(selector: K, options?: { strict: boolean }): Promise<ElementHandleForTag<K> | null>; $<K extends keyof HTMLElementTagNameMap>(selector: K, options?: { strict: boolean }): Promise<ElementHandleForTag<K> | null>;
/** /**
* > NOTE: The use of [ElementHandle] is discouraged, use [Locator] objects and web-first assertions instead.
*
* The method finds an element matching the specified selector within the page. If no elements match the selector, the * 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 * return value resolves to `null`. To wait for an element on the page, use
* [page.waitForSelector(selector[, options])](https://playwright.dev/docs/api/class-page#page-wait-for-selector). * [locator.waitFor([options])](https://playwright.dev/docs/api/class-locator#locator-wait-for).
* *
* Shortcut for main frame's * Shortcut for main frame's
* [frame.$(selector[, options])](https://playwright.dev/docs/api/class-frame#frame-query-selector). * [frame.$(selector[, options])](https://playwright.dev/docs/api/class-frame#frame-query-selector).
@ -273,6 +277,8 @@ export interface Page {
$(selector: string, options?: { strict: boolean }): Promise<ElementHandle<SVGElement | HTMLElement> | null>; $(selector: string, options?: { strict: boolean }): Promise<ElementHandle<SVGElement | HTMLElement> | null>;
/** /**
* > NOTE: The use of [ElementHandle] is discouraged, use [Locator] objects and web-first assertions instead.
*
* The method finds all elements matching the specified selector within the page. If no elements match the selector, the * The method finds all elements matching the specified selector within the page. If no elements match the selector, the
* return value resolves to `[]`. * return value resolves to `[]`.
* *
@ -281,6 +287,8 @@ export interface Page {
*/ */
$$<K extends keyof HTMLElementTagNameMap>(selector: K): Promise<ElementHandleForTag<K>[]>; $$<K extends keyof HTMLElementTagNameMap>(selector: K): Promise<ElementHandleForTag<K>[]>;
/** /**
* > NOTE: The use of [ElementHandle] is discouraged, use [Locator] objects and web-first assertions instead.
*
* The method finds all elements matching the specified selector within the page. If no elements match the selector, the * The method finds all elements matching the specified selector within the page. If no elements match the selector, the
* return value resolves to `[]`. * return value resolves to `[]`.
* *
@ -290,6 +298,11 @@ export interface Page {
$$(selector: string): Promise<ElementHandle<SVGElement | HTMLElement>[]>; $$(selector: string): Promise<ElementHandle<SVGElement | HTMLElement>[]>;
/** /**
* > NOTE: This method does not wait for the element to pass actionability checks and therefore can lead to the flaky
* 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.
*
* The method finds an element matching the specified selector within the page and passes it as a first argument to * 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`. * `pageFunction`. If no elements match the selector, the method throws an error. Returns the value of `pageFunction`.
* *
@ -316,6 +329,11 @@ export interface Page {
*/ */
$eval<K extends keyof HTMLElementTagNameMap, R, Arg>(selector: K, pageFunction: PageFunctionOn<HTMLElementTagNameMap[K], Arg, R>, arg: Arg): Promise<R>; $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
* [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 * 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`. * `pageFunction`. If no elements match the selector, the method throws an error. Returns the value of `pageFunction`.
* *
@ -342,6 +360,11 @@ export interface Page {
*/ */
$eval<R, Arg, E extends SVGElement | HTMLElement = SVGElement | HTMLElement>(selector: string, pageFunction: PageFunctionOn<E, Arg, R>, arg: Arg): Promise<R>; $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
* [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 * 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`. * `pageFunction`. If no elements match the selector, the method throws an error. Returns the value of `pageFunction`.
* *
@ -368,6 +391,11 @@ export interface Page {
*/ */
$eval<K extends keyof HTMLElementTagNameMap, R>(selector: K, pageFunction: PageFunctionOn<HTMLElementTagNameMap[K], void, R>, arg?: any): Promise<R>; $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
* [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 * 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`. * `pageFunction`. If no elements match the selector, the method throws an error. Returns the value of `pageFunction`.
* *
@ -395,6 +423,10 @@ export interface Page {
$eval<R, E extends SVGElement | HTMLElement = SVGElement | HTMLElement>(selector: string, pageFunction: PageFunctionOn<E, void, R>, arg?: any): Promise<R>; $eval<R, E extends SVGElement | HTMLElement = SVGElement | HTMLElement>(selector: string, pageFunction: PageFunctionOn<E, void, R>, arg?: any): Promise<R>;
/** /**
* > 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 * 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. * a first argument to `pageFunction`. Returns the result of `pageFunction` invocation.
* *
@ -414,6 +446,10 @@ export interface Page {
*/ */
$$eval<K extends keyof HTMLElementTagNameMap, R, Arg>(selector: K, pageFunction: PageFunctionOn<HTMLElementTagNameMap[K][], Arg, R>, arg: Arg): Promise<R>; $$eval<K extends keyof HTMLElementTagNameMap, R, Arg>(selector: K, pageFunction: PageFunctionOn<HTMLElementTagNameMap[K][], Arg, R>, arg: Arg): Promise<R>;
/** /**
* > 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 * 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. * a first argument to `pageFunction`. Returns the result of `pageFunction` invocation.
* *
@ -433,6 +469,10 @@ export interface Page {
*/ */
$$eval<R, Arg, E extends SVGElement | HTMLElement = SVGElement | HTMLElement>(selector: string, pageFunction: PageFunctionOn<E[], Arg, R>, arg: Arg): Promise<R>; $$eval<R, Arg, E extends SVGElement | HTMLElement = SVGElement | HTMLElement>(selector: string, pageFunction: PageFunctionOn<E[], Arg, R>, arg: Arg): Promise<R>;
/** /**
* > 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 * 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. * a first argument to `pageFunction`. Returns the result of `pageFunction` invocation.
* *
@ -452,6 +492,10 @@ export interface Page {
*/ */
$$eval<K extends keyof HTMLElementTagNameMap, R>(selector: K, pageFunction: PageFunctionOn<HTMLElementTagNameMap[K][], void, R>, arg?: any): Promise<R>; $$eval<K extends keyof HTMLElementTagNameMap, R>(selector: K, pageFunction: PageFunctionOn<HTMLElementTagNameMap[K][], void, R>, arg?: any): Promise<R>;
/** /**
* > 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 * 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. * a first argument to `pageFunction`. Returns the result of `pageFunction` invocation.
* *
@ -548,6 +592,9 @@ export interface Page {
* Returns when element specified by selector satisfies `state` option. Returns `null` if waiting for `hidden` or * Returns when element specified by selector satisfies `state` option. Returns `null` if waiting for `hidden` or
* `detached`. * `detached`.
* *
* > NOTE: Playwright automatically waits for element to be ready before performing an action. Using [Locator] objects and
* web-first assertions make the code wait-for-selector-free.
*
* Wait for the `selector` to satisfy `state` option (either appear/disappear from dom, or become visible/hidden). If at * Wait for the `selector` to satisfy `state` option (either appear/disappear from dom, or become visible/hidden). If at
* the moment of calling the method `selector` already satisfies the condition, the method will return immediately. If the * the moment of calling the method `selector` already satisfies the condition, the method will return immediately. If the
* selector doesn't satisfy the condition for the `timeout` milliseconds, the function will throw. * selector doesn't satisfy the condition for the `timeout` milliseconds, the function will throw.
@ -577,6 +624,9 @@ export interface Page {
* Returns when element specified by selector satisfies `state` option. Returns `null` if waiting for `hidden` or * Returns when element specified by selector satisfies `state` option. Returns `null` if waiting for `hidden` or
* `detached`. * `detached`.
* *
* > NOTE: Playwright automatically waits for element to be ready before performing an action. Using [Locator] objects and
* web-first assertions make the code wait-for-selector-free.
*
* Wait for the `selector` to satisfy `state` option (either appear/disappear from dom, or become visible/hidden). If at * Wait for the `selector` to satisfy `state` option (either appear/disappear from dom, or become visible/hidden). If at
* the moment of calling the method `selector` already satisfies the condition, the method will return immediately. If the * the moment of calling the method `selector` already satisfies the condition, the method will return immediately. If the
* selector doesn't satisfy the condition for the `timeout` milliseconds, the function will throw. * selector doesn't satisfy the condition for the `timeout` milliseconds, the function will throw.
@ -606,6 +656,9 @@ export interface Page {
* Returns when element specified by selector satisfies `state` option. Returns `null` if waiting for `hidden` or * Returns when element specified by selector satisfies `state` option. Returns `null` if waiting for `hidden` or
* `detached`. * `detached`.
* *
* > NOTE: Playwright automatically waits for element to be ready before performing an action. Using [Locator] objects and
* web-first assertions make the code wait-for-selector-free.
*
* Wait for the `selector` to satisfy `state` option (either appear/disappear from dom, or become visible/hidden). If at * Wait for the `selector` to satisfy `state` option (either appear/disappear from dom, or become visible/hidden). If at
* the moment of calling the method `selector` already satisfies the condition, the method will return immediately. If the * the moment of calling the method `selector` already satisfies the condition, the method will return immediately. If the
* selector doesn't satisfy the condition for the `timeout` milliseconds, the function will throw. * selector doesn't satisfy the condition for the `timeout` milliseconds, the function will throw.
@ -635,6 +688,9 @@ export interface Page {
* Returns when element specified by selector satisfies `state` option. Returns `null` if waiting for `hidden` or * Returns when element specified by selector satisfies `state` option. Returns `null` if waiting for `hidden` or
* `detached`. * `detached`.
* *
* > NOTE: Playwright automatically waits for element to be ready before performing an action. Using [Locator] objects and
* web-first assertions make the code wait-for-selector-free.
*
* Wait for the `selector` to satisfy `state` option (either appear/disappear from dom, or become visible/hidden). If at * Wait for the `selector` to satisfy `state` option (either appear/disappear from dom, or become visible/hidden). If at
* the moment of calling the method `selector` already satisfies the condition, the method will return immediately. If the * the moment of calling the method `selector` already satisfies the condition, the method will return immediately. If the
* selector doesn't satisfy the condition for the `timeout` milliseconds, the function will throw. * selector doesn't satisfy the condition for the `timeout` milliseconds, the function will throw.
@ -3871,7 +3927,7 @@ export interface Frame {
* [frame.evaluate(pageFunction[, arg])](https://playwright.dev/docs/api/class-frame#frame-evaluate): * [frame.evaluate(pageFunction[, arg])](https://playwright.dev/docs/api/class-frame#frame-evaluate):
* *
* ```js * ```js
* const bodyHandle = await frame.$('body'); * const bodyHandle = await frame.evaluate('document.body');
* const html = await frame.evaluate(([body, suffix]) => body.innerHTML + suffix, [bodyHandle, 'hello']); * const html = await frame.evaluate(([body, suffix]) => body.innerHTML + suffix, [bodyHandle, 'hello']);
* await bodyHandle.dispose(); * await bodyHandle.dispose();
* ``` * ```
@ -3912,7 +3968,7 @@ export interface Frame {
* [frame.evaluate(pageFunction[, arg])](https://playwright.dev/docs/api/class-frame#frame-evaluate): * [frame.evaluate(pageFunction[, arg])](https://playwright.dev/docs/api/class-frame#frame-evaluate):
* *
* ```js * ```js
* const bodyHandle = await frame.$('body'); * const bodyHandle = await frame.evaluate('document.body');
* const html = await frame.evaluate(([body, suffix]) => body.innerHTML + suffix, [bodyHandle, 'hello']); * const html = await frame.evaluate(([body, suffix]) => body.innerHTML + suffix, [bodyHandle, 'hello']);
* await bodyHandle.dispose(); * await bodyHandle.dispose();
* ``` * ```
@ -4006,6 +4062,8 @@ export interface Frame {
/** /**
* Returns the ElementHandle pointing to the frame element. * Returns the ElementHandle pointing to the frame element.
* *
* > NOTE: The use of [ElementHandle] is discouraged, use [Locator] objects and web-first assertions instead.
*
* The method finds an element matching the specified selector within the frame. See * The method finds an element matching the specified selector within the frame. See
* [Working with selectors](https://playwright.dev/docs/selectors) for more details. If no elements match the selector, returns `null`. * [Working with selectors](https://playwright.dev/docs/selectors) for more details. If no elements match the selector, returns `null`.
* @param selector A selector to query for. See [working with selectors](https://playwright.dev/docs/selectors) for more details. * @param selector A selector to query for. See [working with selectors](https://playwright.dev/docs/selectors) for more details.
@ -4015,6 +4073,8 @@ export interface Frame {
/** /**
* Returns the ElementHandle pointing to the frame element. * Returns the ElementHandle pointing to the frame element.
* *
* > NOTE: The use of [ElementHandle] is discouraged, use [Locator] objects and web-first assertions instead.
*
* The method finds an element matching the specified selector within the frame. See * The method finds an element matching the specified selector within the frame. See
* [Working with selectors](https://playwright.dev/docs/selectors) for more details. If no elements match the selector, returns `null`. * [Working with selectors](https://playwright.dev/docs/selectors) for more details. If no elements match the selector, returns `null`.
* @param selector A selector to query for. See [working with selectors](https://playwright.dev/docs/selectors) for more details. * @param selector A selector to query for. See [working with selectors](https://playwright.dev/docs/selectors) for more details.
@ -4025,6 +4085,8 @@ export interface Frame {
/** /**
* Returns the ElementHandles pointing to the frame elements. * Returns the ElementHandles pointing to the frame elements.
* *
* > NOTE: The use of [ElementHandle] is discouraged, use [Locator] objects instead.
*
* The method finds all elements matching the specified selector within the frame. See * The method finds all elements matching the specified selector within the frame. See
* [Working with selectors](https://playwright.dev/docs/selectors) for more details. If no elements match the selector, returns empty array. * [Working with selectors](https://playwright.dev/docs/selectors) for more details. If no elements match the selector, returns empty array.
* @param selector A selector to query for. See [working with selectors](https://playwright.dev/docs/selectors) for more details. * @param selector A selector to query for. See [working with selectors](https://playwright.dev/docs/selectors) for more details.
@ -4033,6 +4095,8 @@ export interface Frame {
/** /**
* Returns the ElementHandles pointing to the frame elements. * Returns the ElementHandles pointing to the frame elements.
* *
* > NOTE: The use of [ElementHandle] is discouraged, use [Locator] objects instead.
*
* The method finds all elements matching the specified selector within the frame. See * The method finds all elements matching the specified selector within the frame. See
* [Working with selectors](https://playwright.dev/docs/selectors) for more details. If no elements match the selector, returns empty array. * [Working with selectors](https://playwright.dev/docs/selectors) for more details. If no elements match the selector, returns empty array.
* @param selector A selector to query for. See [working with selectors](https://playwright.dev/docs/selectors) for more details. * @param selector A selector to query for. See [working with selectors](https://playwright.dev/docs/selectors) for more details.
@ -4042,6 +4106,11 @@ export interface Frame {
/** /**
* Returns the return value of `pageFunction`. * Returns the return value of `pageFunction`.
* *
* > NOTE: This method does not wait for the element to pass actionability checks and therefore can lead to the flaky
* 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.
*
* The method finds an element matching the specified selector within the frame and passes it as a first argument to * The method finds an element matching the specified selector within the frame and passes it as a first argument to
* `pageFunction`. See [Working with selectors](https://playwright.dev/docs/selectors) for more details. If no elements match the selector, the * `pageFunction`. See [Working with selectors](https://playwright.dev/docs/selectors) for more details. If no elements match the selector, the
* method throws an error. * method throws an error.
@ -4067,6 +4136,11 @@ export interface Frame {
/** /**
* Returns the return value of `pageFunction`. * Returns the return value of `pageFunction`.
* *
* > NOTE: This method does not wait for the element to pass actionability checks and therefore can lead to the flaky
* 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.
*
* The method finds an element matching the specified selector within the frame and passes it as a first argument to * The method finds an element matching the specified selector within the frame and passes it as a first argument to
* `pageFunction`. See [Working with selectors](https://playwright.dev/docs/selectors) for more details. If no elements match the selector, the * `pageFunction`. See [Working with selectors](https://playwright.dev/docs/selectors) for more details. If no elements match the selector, the
* method throws an error. * method throws an error.
@ -4092,6 +4166,11 @@ export interface Frame {
/** /**
* Returns the return value of `pageFunction`. * Returns the return value of `pageFunction`.
* *
* > NOTE: This method does not wait for the element to pass actionability checks and therefore can lead to the flaky
* 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.
*
* The method finds an element matching the specified selector within the frame and passes it as a first argument to * The method finds an element matching the specified selector within the frame and passes it as a first argument to
* `pageFunction`. See [Working with selectors](https://playwright.dev/docs/selectors) for more details. If no elements match the selector, the * `pageFunction`. See [Working with selectors](https://playwright.dev/docs/selectors) for more details. If no elements match the selector, the
* method throws an error. * method throws an error.
@ -4117,6 +4196,11 @@ export interface Frame {
/** /**
* Returns the return value of `pageFunction`. * Returns the return value of `pageFunction`.
* *
* > NOTE: This method does not wait for the element to pass actionability checks and therefore can lead to the flaky
* 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.
*
* The method finds an element matching the specified selector within the frame and passes it as a first argument to * The method finds an element matching the specified selector within the frame and passes it as a first argument to
* `pageFunction`. See [Working with selectors](https://playwright.dev/docs/selectors) for more details. If no elements match the selector, the * `pageFunction`. See [Working with selectors](https://playwright.dev/docs/selectors) for more details. If no elements match the selector, the
* method throws an error. * method throws an error.
@ -4143,6 +4227,10 @@ export interface Frame {
/** /**
* Returns the return value of `pageFunction`. * Returns the return value of `pageFunction`.
* *
* > 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 frame and passes an array of matched elements * The method finds all elements matching the specified selector within the frame and passes an array of matched elements
* as a first argument to `pageFunction`. See [Working with selectors](https://playwright.dev/docs/selectors) for more details. * as a first argument to `pageFunction`. See [Working with selectors](https://playwright.dev/docs/selectors) for more details.
* *
@ -4164,6 +4252,10 @@ export interface Frame {
/** /**
* Returns the return value of `pageFunction`. * Returns the return value of `pageFunction`.
* *
* > 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 frame and passes an array of matched elements * The method finds all elements matching the specified selector within the frame and passes an array of matched elements
* as a first argument to `pageFunction`. See [Working with selectors](https://playwright.dev/docs/selectors) for more details. * as a first argument to `pageFunction`. See [Working with selectors](https://playwright.dev/docs/selectors) for more details.
* *
@ -4185,6 +4277,10 @@ export interface Frame {
/** /**
* Returns the return value of `pageFunction`. * Returns the return value of `pageFunction`.
* *
* > 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 frame and passes an array of matched elements * The method finds all elements matching the specified selector within the frame and passes an array of matched elements
* as a first argument to `pageFunction`. See [Working with selectors](https://playwright.dev/docs/selectors) for more details. * as a first argument to `pageFunction`. See [Working with selectors](https://playwright.dev/docs/selectors) for more details.
* *
@ -4206,6 +4302,10 @@ export interface Frame {
/** /**
* Returns the return value of `pageFunction`. * Returns the return value of `pageFunction`.
* *
* > 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 frame and passes an array of matched elements * The method finds all elements matching the specified selector within the frame and passes an array of matched elements
* as a first argument to `pageFunction`. See [Working with selectors](https://playwright.dev/docs/selectors) for more details. * as a first argument to `pageFunction`. See [Working with selectors](https://playwright.dev/docs/selectors) for more details.
* *
@ -4294,6 +4394,9 @@ export interface Frame {
* Returns when element specified by selector satisfies `state` option. Returns `null` if waiting for `hidden` or * Returns when element specified by selector satisfies `state` option. Returns `null` if waiting for `hidden` or
* `detached`. * `detached`.
* *
* > NOTE: Playwright automatically waits for element to be ready before performing an action. Using [Locator] objects and
* web-first assertions make the code wait-for-selector-free.
*
* Wait for the `selector` to satisfy `state` option (either appear/disappear from dom, or become visible/hidden). If at * Wait for the `selector` to satisfy `state` option (either appear/disappear from dom, or become visible/hidden). If at
* the moment of calling the method `selector` already satisfies the condition, the method will return immediately. If the * the moment of calling the method `selector` already satisfies the condition, the method will return immediately. If the
* selector doesn't satisfy the condition for the `timeout` milliseconds, the function will throw. * selector doesn't satisfy the condition for the `timeout` milliseconds, the function will throw.
@ -4323,6 +4426,9 @@ export interface Frame {
* Returns when element specified by selector satisfies `state` option. Returns `null` if waiting for `hidden` or * Returns when element specified by selector satisfies `state` option. Returns `null` if waiting for `hidden` or
* `detached`. * `detached`.
* *
* > NOTE: Playwright automatically waits for element to be ready before performing an action. Using [Locator] objects and
* web-first assertions make the code wait-for-selector-free.
*
* Wait for the `selector` to satisfy `state` option (either appear/disappear from dom, or become visible/hidden). If at * Wait for the `selector` to satisfy `state` option (either appear/disappear from dom, or become visible/hidden). If at
* the moment of calling the method `selector` already satisfies the condition, the method will return immediately. If the * the moment of calling the method `selector` already satisfies the condition, the method will return immediately. If the
* selector doesn't satisfy the condition for the `timeout` milliseconds, the function will throw. * selector doesn't satisfy the condition for the `timeout` milliseconds, the function will throw.
@ -4352,6 +4458,9 @@ export interface Frame {
* Returns when element specified by selector satisfies `state` option. Returns `null` if waiting for `hidden` or * Returns when element specified by selector satisfies `state` option. Returns `null` if waiting for `hidden` or
* `detached`. * `detached`.
* *
* > NOTE: Playwright automatically waits for element to be ready before performing an action. Using [Locator] objects and
* web-first assertions make the code wait-for-selector-free.
*
* Wait for the `selector` to satisfy `state` option (either appear/disappear from dom, or become visible/hidden). If at * Wait for the `selector` to satisfy `state` option (either appear/disappear from dom, or become visible/hidden). If at
* the moment of calling the method `selector` already satisfies the condition, the method will return immediately. If the * the moment of calling the method `selector` already satisfies the condition, the method will return immediately. If the
* selector doesn't satisfy the condition for the `timeout` milliseconds, the function will throw. * selector doesn't satisfy the condition for the `timeout` milliseconds, the function will throw.
@ -4381,6 +4490,9 @@ export interface Frame {
* Returns when element specified by selector satisfies `state` option. Returns `null` if waiting for `hidden` or * Returns when element specified by selector satisfies `state` option. Returns `null` if waiting for `hidden` or
* `detached`. * `detached`.
* *
* > NOTE: Playwright automatically waits for element to be ready before performing an action. Using [Locator] objects and
* web-first assertions make the code wait-for-selector-free.
*
* Wait for the `selector` to satisfy `state` option (either appear/disappear from dom, or become visible/hidden). If at * Wait for the `selector` to satisfy `state` option (either appear/disappear from dom, or become visible/hidden). If at
* the moment of calling the method `selector` already satisfies the condition, the method will return immediately. If the * the moment of calling the method `selector` already satisfies the condition, the method will return immediately. If the
* selector doesn't satisfy the condition for the `timeout` milliseconds, the function will throw. * selector doesn't satisfy the condition for the `timeout` milliseconds, the function will throw.
@ -7057,6 +7169,8 @@ export interface JSHandle<T = any> {
* ElementHandle represents an in-page DOM element. ElementHandles can be created with the * ElementHandle represents an in-page DOM element. ElementHandles can be created with the
* [page.$(selector[, options])](https://playwright.dev/docs/api/class-page#page-query-selector) method. * [page.$(selector[, options])](https://playwright.dev/docs/api/class-page#page-query-selector) method.
* *
* > NOTE: The use of ElementHandle is discouraged, use [Locator] objects and web-first assertions instead.
*
* ```js * ```js
* const hrefElement = await page.$('a'); * const hrefElement = await page.$('a');
* await hrefElement.click(); * await hrefElement.click();
@ -7070,10 +7184,6 @@ export interface JSHandle<T = any> {
* [page.$eval(selector, pageFunction[, arg, options])](https://playwright.dev/docs/api/class-page#page-eval-on-selector) * [page.$eval(selector, pageFunction[, arg, options])](https://playwright.dev/docs/api/class-page#page-eval-on-selector)
* and [page.evaluate(pageFunction[, arg])](https://playwright.dev/docs/api/class-page#page-evaluate) methods. * and [page.evaluate(pageFunction[, arg])](https://playwright.dev/docs/api/class-page#page-evaluate) methods.
* *
* > NOTE: In most cases, you would want to use the [Locator] object instead. You should only use [ElementHandle] if you
* want to retain a handle to a particular DOM Node that you intend to pass into
* [page.evaluate(pageFunction[, arg])](https://playwright.dev/docs/api/class-page#page-evaluate) as an argument.
*
* The difference between the [Locator] and ElementHandle is that the ElementHandle points to a particular element, while * The difference between the [Locator] and ElementHandle is that the ElementHandle points to a particular element, while
* [Locator] captures the logic of how to retrieve an element. * [Locator] captures the logic of how to retrieve an element.
* *
@ -10338,7 +10448,7 @@ export namespace errors {
* - extends: [Error] * - extends: [Error]
* *
* TimeoutError is emitted whenever certain operations are terminated due to timeout, e.g. * TimeoutError is emitted whenever certain operations are terminated due to timeout, e.g.
* [page.waitForSelector(selector[, options])](https://playwright.dev/docs/api/class-page#page-wait-for-selector) or * [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). * [browserType.launch([options])](https://playwright.dev/docs/api/class-browsertype#browser-type-launch).
* *
* ```js * ```js
@ -14434,11 +14544,11 @@ export interface Selectors {
* await page.setContent(`<div><button>Click me</button></div>`); * await page.setContent(`<div><button>Click me</button></div>`);
* *
* // Use the selector prefixed with its name. * // Use the selector prefixed with its name.
* const button = await page.$('tag=button'); * const button = page.locator('tag=button');
* // Combine it with other selector engines. * // Combine it with other selector engines.
* await page.click('tag=div >> text="Click me"'); * await page.click('tag=div >> text="Click me"');
* // Can use it in any methods supporting selectors. * // Can use it in any methods supporting selectors.
* const buttonCount = await page.$$eval('tag=button', buttons => buttons.length); * const buttonCount = await page.locator('tag=button').count();
* *
* await browser.close(); * await browser.close();
* })(); * })();