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.
:::caution Discouraged
The use of ElementHandle is discouraged, use [Locator] objects and web-first assertions instead.
:::
```js
const hrefElement = await page.$('a');
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.
:::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.
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`].
:::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
[`param: expression`]. See [Working with selectors](./selectors.md) for more details. If no
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`].
:::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
as a first argument to [`param: expression`]. See [Working with selectors](./selectors.md) for
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`]:
```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']);
await bodyHandle.dispose();
```
```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"));
bodyHandle.dispose();
```
```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"])
await body_handle.dispose()
```
```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"])
body_handle.dispose()
```
```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" });
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.
:::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
[Working with selectors](./selectors.md) for more details. If no elements match the selector,
returns `null`.
@ -1062,6 +1075,10 @@ returns `null`.
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
[Working with selectors](./selectors.md) for more details. If no elements match the selector,
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
`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
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

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
- 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
[`param: expression`]. If no elements match the selector, the method throws an error. Returns the value of
[`param: expression`].
@ -1081,6 +1086,10 @@ Optional argument to pass to [`param: expression`].
- alias-js: $$eval
- 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
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`]:
```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']);
await bodyHandle.dispose();
```
```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"));
bodyHandle.dispose();
```
```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"])
await body_handle.dispose()
```
```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"])
body_handle.dispose()
```
```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" });
await bodyHandle.DisposeAsync();
```
@ -2422,8 +2431,12 @@ Time to wait between `keydown` and `keyup` in milliseconds. Defaults to 0.
- alias-js: $
- 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
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`].
@ -2437,6 +2450,10 @@ Shortcut for main frame's [`method: Frame.querySelector`].
- alias-js: $$
- 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
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
`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
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

View File

@ -178,7 +178,7 @@ class PlaywrightExample
- `TimeoutError` <[function]> A class of [TimeoutError].
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
[`playwright.errors`](#playwrighterrors).
@ -187,7 +187,7 @@ An example of handling a timeout error:
```js
try {
await page.waitForSelector('.foo');
await page.locator('.foo').waitFor();
} catch (e) {
if (e instanceof playwright.errors.TimeoutError) {
// 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>`);
// 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.
await page.click('tag=div >> text="Click me"');
// 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();
})();
@ -60,11 +60,11 @@ Browser browser = playwright.firefox().launch();
Page page = browser.newPage();
page.setContent("<div><button>Click me</button></div>");
// 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.
page.click("tag=div >> text=\"Click me\"");
// 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();
```
@ -96,7 +96,7 @@ async def run(playwright):
# Combine it with other selector engines.
await page.click('tag=div >> text="Click me"')
# 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)
await browser.close()
@ -130,11 +130,11 @@ def run(playwright):
page.set_content('<div><button>Click me</button></div>')
# Use the selector prefixed with its name.
button = page.query_selector('tag=button')
button = page.locator('tag=button')
# Combine it with other selector engines.
page.click('tag=div >> text="Click me"')
# 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)
browser.close()
@ -160,11 +160,11 @@ await using var browser = await playwright.Chromium.LaunchAsync();
var page = await browser.NewPageAsync();
await page.SetContentAsync("<div><button>Click me</button></div>");
// 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.
await page.ClickAsync("tag=div >> text=\"Click me\"");
// 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

View File

@ -2,7 +2,7 @@
* extends: [Error]
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
const playwright = require('playwright');

View File

@ -131,27 +131,27 @@ Assert.True(checked);
## JS expression
```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');
```
```java
Object content = page.evalOnSelector("nav:first-child", "e => e.textContent");
Object content = page.locator("nav:first-child").textContent();
assertEquals("home", content);
```
```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"
```
```python sync
content = page.eval_on_selector("nav:first-child", "e => e.textContent")
content = page.locator("nav:first-child").text_content()
assert content == "home"
```
```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);
```
@ -264,16 +264,15 @@ const userId = page.evaluate(() => window.localStorage.getItem('userId'));
expect(userId).toBeTruthy();
// Assert value for input element
await page.waitForSelector('#search');
const value = await page.inputValue('#search');
const value = await page.locator('#search').inputValue();
expect(value === 'query').toBeTruthy();
// 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();
// 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();
```
@ -283,16 +282,15 @@ Object userId = page.evaluate("() => window.localStorage.getItem('userId')");
assertNotNull(userId);
// Assert value for input element
page.waitForSelector("#search");
Object value = page.evalOnSelector("#search", "el => el.value");
Object value = page.locator("#search").inputValue();
assertEquals("query", value);
// 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);
// Assert list length
Object length = page.evalOnSelectorAll("li.selected", "items => items.length");
Object length = page.locator("li.selected").count();
assertEquals(3, length);
```
@ -302,16 +300,15 @@ user_id = page.evaluate("() => window.localStorage.getItem('user_id')")
assert user_id
# Assert value for input element
await page.wait_for_selector('#search')
value = await page.eval_on_selector('#search', 'el => el.value')
value = await page.locator('#search').input_value()
assert value == 'query'
# 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 list length
length = await page.eval_on_selector_all('li.selected', '(items) => items.length')
length = await page.locator('li.selected').count()
assert length == 3
```
@ -321,16 +318,15 @@ user_id = page.evaluate("() => window.localStorage.getItem('user_id')")
assert user_id
# Assert value for input element
page.wait_for_selector('#search')
value = page.eval_on_selector('#search', 'el => el.value')
value = page.locator('#search').input_value()
assert value == 'query'
# 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 list length
length = page.eval_on_selector_all('li.selected', '(items) => items.length')
length = page.locator('li.selected').count()
assert length == 3
```
@ -340,26 +336,14 @@ var userId = await page.EvaluateAsync<string>("() => window.localStorage.getItem
Assert.NotNull(userId);
// Assert value for input element
await page.WaitForSelectorAsync("#search");
var value = await page.EvalOnSelectorAsync("#search", "el => el.value");
var value = await page.Locator("#search").InputValueAsync();
Assert.Equals("query", value);
// 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 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);
```
### 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' });
// A single handle.
const button = await page.$('button');
const button = await page.evaluate('window.button');
await page.evaluate(button => button.textContent, button);
// Alternative notation using elementHandle.evaluate.
await button.evaluate((button, from) => button.textContent.substring(from), 5);
// Object with multiple handles.
const button1 = await page.$('.button1');
const button2 = await page.$('.button2');
const button1 = await page.evaluate('window.button1');
const button2 = await page.evaluate('window.button2');
await page.evaluate(
o => o.button1.textContent + o.button2.textContent,
{ button1, button2 });
@ -126,15 +126,15 @@ obj.put("foo", "bar");
page.evaluate("object => object.foo", obj);
// A single handle.
ElementHandle button = page.querySelector("button");
ElementHandle button = page.evaluate("window.button");
page.evaluate("button => button.textContent", button);
// Alternative notation using elementHandle.evaluate.
button.evaluate("(button, from) => button.textContent.substring(from)", 5);
// Object with multiple handles.
ElementHandle button1 = page.querySelector(".button1");
ElementHandle button2 = page.querySelector(".button2");
ElementHandle button1 = page.evaluate("window.button1");
ElementHandle button2 = page.evaluate("window.button2");
Map<String, ElementHandle> arg = new HashMap<>();
arg.put("button1", button1);
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' })
# A single handle.
button = await page.query_selctor('button')
button = await page.evaluate('button')
await page.evaluate('button => button.textContent', button)
# Alternative notation using elementHandle.evaluate.
await button.evaluate('(button, from) => button.textContent.substring(from)', 5)
# Object with multiple handles.
button1 = await page.query_selector('.button1')
button2 = await page.query_selector('.button2')
button1 = await page.query_selector('window.button1')
button2 = await page.query_selector('window.button2')
await page.evaluate("""
o => o.button1.textContent + o.button2.textContent""",
{ 'button1': button1, 'button2': button2 })
@ -218,15 +218,15 @@ page.evaluate('array => array.length', [1, 2, 3])
page.evaluate('object => object.foo', { 'foo': 'bar' })
# A single handle.
button = page.query_selector('button')
button = page.evaluate('window.button')
page.evaluate('button => button.textContent', button)
# Alternative notation using elementHandle.evaluate.
button.evaluate('(button, from) => button.textContent.substring(from)', 5)
# Object with multiple handles.
button1 = page.query_selector('.button1')
button2 = page.query_selector('.button2')
button1 = page.evaluate('window.button1')
button2 = page.evaluate('.button2')
page.evaluate("""o => o.button1.textContent + o.button2.textContent""",
{ '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" });
// A single handle.
var button = await page.QuerySelectorAsync("button");
var button = await page.EvaluateAsync("window.button");
await page.EvaluateAsync<IJSHandle>("button => button.textContent", button);
// Alternative notation using elementHandle.EvaluateAsync.
await button.EvaluateAsync<string>("(button, from) => button.textContent.substring(from)", 5);
// Object with multiple handles.
var button1 = await page.QuerySelectorAsync(".button1");
var button2 = await page.QuerySelectorAsync(".button2");
var button1 = await page.EvaluateAsync("window.button1");
var button2 = await page.EvaluateAsync("window.button2");
await page.EvaluateAsync("o => o.button1.textContent + o.button2.textContent", new { button1, button2 });
// Object destructuring works. Note that property names must match

View File

@ -42,13 +42,14 @@ const createTagNameEngine = () => ({
await selectors.register('tag', createTagNameEngine);
// 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.
await page.click('tag=div >> span >> "Click me"');
// 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
@ -69,13 +70,14 @@ String createTagNameEngine = "{\n" +
playwright.selectors().register("tag", createTagNameEngine);
// 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.
page.click("tag=div >> span >> \"Click me\"");
// 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
@ -97,13 +99,14 @@ tag_selector = """
await playwright.selectors.register("tag", tag_selector)
# 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.
await page.click("tag=div >> span >> "click me"")
# 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
@ -125,11 +128,12 @@ tag_selector = """
playwright.selectors.register("tag", tag_selector)
# 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.
page.click("tag=div >> span >> "click me"")
# 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
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
await frame.fill('#username-input', 'John');
```
@ -70,10 +66,6 @@ Frame frame = page.frame("frame-login");
// Get frame using frame"s URL
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
frame.fill("#username-input", "John");
```
@ -85,10 +77,6 @@ frame = page.frame('frame-login')
# Get frame using frame's URL
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
await frame.fill('#username-input', 'John')
```
@ -100,10 +88,6 @@ frame = page.frame('frame-login')
# Get frame using frame's URL
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
frame.fill('#username-input', 'John')
```
@ -119,7 +103,7 @@ var frame = page.Frame("frame-login");
var frame = page.FrameByUrl("*domain.");
// 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();
// Interact with the frame

View File

@ -48,35 +48,10 @@ var jsHandle = await page.EvaluateHandleAsync("window");
// 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
:::note
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.
:::caution Discouraged
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

View File

@ -95,13 +95,13 @@ await page.GotoAsync("https://example.com", new PageGotoOptions { WaitUntil = Wa
### 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.
```js
// Navigate and wait for element
await page.goto('https://example.com');
await page.waitForSelector('text=Example Domain');
await page.locator('text=Example Domain').waitFor();
// Navigate and click element
// Click will auto-wait for the element
@ -112,7 +112,7 @@ await page.click('text=Example Domain');
```java
// Navigate and wait for element
page.navigate("https://example.com");
page.waitForSelector("text=Example Domain");
page.locator("text=Example Domain").waitFor();
// Navigate and click element
// Click will auto-wait for the element
@ -123,7 +123,7 @@ page.click("text=Example Domain");
```python async
# Navigate and wait for element
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
# Click will auto-wait for the element
@ -134,7 +134,7 @@ await page.click("text=example domain")
```python sync
# Navigate and wait for element
page.goto("https://example.com")
page.wait_for_selector("text=example domain")
page.locator("text=example domain").wait_for()
# Navigate and click element
# Click will auto-wait for the element
@ -145,7 +145,7 @@ page.click("text=example domain")
```csharp
// Navigate and wait for element
await page.GotoAsync("https://example.com");
await page.WaitForSelectorAsync("text=Example Domain");
await page.Locator("text=Example Domain").WaitForAsync();
// Navigate and click element
// Click will auto-wait for the element
@ -239,14 +239,14 @@ await page.WaitForLoadStateAsync(LoadState.NetworkIdle); // This resolves after
### 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.
```js
// Click will auto-wait for the element and trigger navigation
await page.click('text=Login');
// Wait for the element
await page.waitForSelector('#username');
await page.locator('#username').waitFor();
// Click triggers navigation
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
page.click("text=Login");
// Wait for the element
page.waitForSelector("#username");
page.locator("#username").waitFor();
// Click triggers navigation
page.click("text=Login");
@ -270,7 +270,7 @@ page.fill("#username", "John Doe");
# Click will auto-wait for the element and trigger navigation
await page.click("text=Login")
# Wait for the element
await page.wait_for_selector("#username")
await page.locator("#username").wait_for()
# Click triggers navigation
await page.click("text=Login")
@ -282,7 +282,7 @@ await page.fill("#username", "John Doe")
# Click triggers navigation
page.click("text=Login")
# Click will auto-wait for the element
page.wait_for_selector("#username", "John Doe")
page.locator("#username").wait_for()
# Click triggers navigation
page.click("text=Login")
@ -294,7 +294,7 @@ page.fill("#username", "John Doe")
// Click will auto-wait for the element and trigger navigation
await page.ClickAsync("text=Login");
// Wait for the element
await page.WaitForSelectorAsync("#username");
await page.Locator("#username").WaitForAsync();
// Click triggers navigation
await page.ClickAsync("text=Login");
@ -450,7 +450,6 @@ popup.WaitForLoadStateAsync(LoadState.Load);
### API reference
- [`method: Page.click`]
- [`method: Page.waitForLoadState`]
- [`method: Page.waitForSelector`]
- [`method: Page.waitForNavigation`]
- [`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.
```js
const elementHandle = await page.$('.header');
await elementHandle.screenshot({ path: 'screenshot.png' });
await page.locator('.header').screenshot({ path: 'screenshot.png' });
```
```java
ElementHandle elementHandle = page.querySelector(".header");
elementHandle.screenshot(new ElementHandle.ScreenshotOptions().setPath(Paths.get("screenshot.png")));
page.locator(".header").screenshot(new ElementHandle.ScreenshotOptions().setPath(Paths.get("screenshot.png")));
```
```python async
element_handle = await page.query_selector(".header")
await element_handle.screenshot(path="screenshot.png")
await page.locator(".header").screenshot(path="screenshot.png")
```
```python sync
element_handle = page.query_selector(".header")
element_handle.screenshot(path="screenshot.png")
page.locator(".header").screenshot(path="screenshot.png")
```
```csharp
var elementHandle = await page.QuerySelectorAsync(".header")
await elementHandle.ScreenshotAsync(new ElementHandleScreenshotOptions { Path = "screenshot.png" });
await page.Locator(".header").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)");
```
`: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
// 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
// Wait until all three buttons are visible
page.waitForSelector(":nth-match(:text('Buy'), 3)");
page.locator(":nth-match(:text('Buy'), 3)").waitFor();
```
```python async
# 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
# 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
// 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

View File

@ -109,7 +109,7 @@ export interface Page {
* [page.evaluate(pageFunction[, arg])](https://playwright.dev/docs/api/class-page#page-evaluate):
*
* ```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']);
* await bodyHandle.dispose();
* ```
@ -156,7 +156,7 @@ export interface Page {
* [page.evaluate(pageFunction[, arg])](https://playwright.dev/docs/api/class-page#page-evaluate):
*
* ```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']);
* await bodyHandle.dispose();
* ```
@ -250,9 +250,11 @@ export interface Page {
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
* 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
* [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>;
/**
* > 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
* 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
* [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>;
/**
* > 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
* return value resolves to `[]`.
*
@ -281,6 +287,8 @@ export interface Page {
*/
$$<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
* return value resolves to `[]`.
*
@ -290,6 +298,11 @@ export interface Page {
$$(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
* `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>;
/**
* > 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
* `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>;
/**
* > 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
* `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>;
/**
* > 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
* `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>;
/**
* > 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.
*
@ -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>;
/**
* > 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.
*
@ -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>;
/**
* > 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.
*
@ -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>;
/**
* > 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.
*
@ -548,6 +592,9 @@ export interface Page {
* Returns when element specified by selector satisfies `state` option. Returns `null` if waiting for `hidden` or
* `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
* 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.
@ -577,6 +624,9 @@ export interface Page {
* Returns when element specified by selector satisfies `state` option. Returns `null` if waiting for `hidden` or
* `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
* 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.
@ -606,6 +656,9 @@ export interface Page {
* Returns when element specified by selector satisfies `state` option. Returns `null` if waiting for `hidden` or
* `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
* 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.
@ -635,6 +688,9 @@ export interface Page {
* Returns when element specified by selector satisfies `state` option. Returns `null` if waiting for `hidden` or
* `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
* 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.
@ -3871,7 +3927,7 @@ export interface Frame {
* [frame.evaluate(pageFunction[, arg])](https://playwright.dev/docs/api/class-frame#frame-evaluate):
*
* ```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']);
* await bodyHandle.dispose();
* ```
@ -3912,7 +3968,7 @@ export interface Frame {
* [frame.evaluate(pageFunction[, arg])](https://playwright.dev/docs/api/class-frame#frame-evaluate):
*
* ```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']);
* await bodyHandle.dispose();
* ```
@ -4006,6 +4062,8 @@ export interface Frame {
/**
* 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
* [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.
@ -4015,6 +4073,8 @@ export interface Frame {
/**
* 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
* [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.
@ -4025,6 +4085,8 @@ export interface Frame {
/**
* 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
* [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.
@ -4033,6 +4095,8 @@ export interface Frame {
/**
* 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
* [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.
@ -4042,6 +4106,11 @@ export interface Frame {
/**
* 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
* `pageFunction`. See [Working with selectors](https://playwright.dev/docs/selectors) for more details. If no elements match the selector, the
* method throws an error.
@ -4067,6 +4136,11 @@ export interface Frame {
/**
* 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
* `pageFunction`. See [Working with selectors](https://playwright.dev/docs/selectors) for more details. If no elements match the selector, the
* method throws an error.
@ -4092,6 +4166,11 @@ export interface Frame {
/**
* 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
* `pageFunction`. See [Working with selectors](https://playwright.dev/docs/selectors) for more details. If no elements match the selector, the
* method throws an error.
@ -4117,6 +4196,11 @@ export interface Frame {
/**
* 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
* `pageFunction`. See [Working with selectors](https://playwright.dev/docs/selectors) for more details. If no elements match the selector, the
* method throws an error.
@ -4143,6 +4227,10 @@ export interface Frame {
/**
* 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
* 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`.
*
* > 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
* 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`.
*
* > 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
* 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`.
*
* > 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
* 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
* `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
* 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.
@ -4323,6 +4426,9 @@ export interface Frame {
* Returns when element specified by selector satisfies `state` option. Returns `null` if waiting for `hidden` or
* `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
* 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.
@ -4352,6 +4458,9 @@ export interface Frame {
* Returns when element specified by selector satisfies `state` option. Returns `null` if waiting for `hidden` or
* `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
* 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.
@ -4381,6 +4490,9 @@ export interface Frame {
* Returns when element specified by selector satisfies `state` option. Returns `null` if waiting for `hidden` or
* `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
* 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.
@ -7057,6 +7169,8 @@ export interface JSHandle<T = any> {
* 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.
*
* > NOTE: The use of ElementHandle is discouraged, use [Locator] objects and web-first assertions instead.
*
* ```js
* const hrefElement = await page.$('a');
* 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)
* 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
* [Locator] captures the logic of how to retrieve an element.
*
@ -10338,7 +10448,7 @@ export namespace errors {
* - extends: [Error]
*
* 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).
*
* ```js
@ -14434,11 +14544,11 @@ export interface Selectors {
* await page.setContent(`<div><button>Click me</button></div>`);
*
* // 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.
* await page.click('tag=div >> text="Click me"');
* // 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();
* })();