cherry-pick(#18832): docs: remove images from locators.md
This commit is contained in:
parent
f7087bfe3b
commit
553a211b65
|
|
@ -77,6 +77,7 @@ For example, consider the following DOM structure.
|
||||||
```html
|
```html
|
||||||
<button>Sign in</button>
|
<button>Sign in</button>
|
||||||
```
|
```
|
||||||
|
|
||||||
Locate the element by its role of `button` with name "Sign in".
|
Locate the element by its role of `button` with name "Sign in".
|
||||||
|
|
||||||
```js
|
```js
|
||||||
|
|
@ -186,68 +187,74 @@ The [`method: Page.getByRole`] locator reflects how users and assistive technolo
|
||||||
For example, consider the following DOM structure.
|
For example, consider the following DOM structure.
|
||||||
|
|
||||||
```html
|
```html
|
||||||
<h1>my form<h1>
|
<h3>Sign up</h3>
|
||||||
<form>
|
|
||||||
<label for="newsletter">newsletter</label>
|
|
||||||
<input type="checkbox" checked id="newsletter">
|
|
||||||
<button>Submit</button>
|
|
||||||
<form>
|
<form>
|
||||||
|
<input type="checkbox" id="subscribe" />
|
||||||
|
<label for="subscribe">Subscribe</label>
|
||||||
|
<br>
|
||||||
|
<button>Submit</button>
|
||||||
|
</form>
|
||||||
```
|
```
|
||||||
|
|
||||||
<img width="247" alt="form with newsletter checkbox that is checked and a submit button" src="https://user-images.githubusercontent.com/13063165/201355711-20f1f45d-81b5-42b1-8932-397c935cedd8.png" />
|
|
||||||
|
|
||||||
You can locate each element by it's implicit role:
|
You can locate each element by it's implicit role:
|
||||||
|
|
||||||
```js
|
```js
|
||||||
await expect(page.getByRole('heading', { name: 'my form' }))
|
await expect(page.getByRole('heading', { name: 'Sign up' }))
|
||||||
.toBeVisible()
|
.toBeVisible()
|
||||||
|
|
||||||
await page.getByRole('checkbox', { checked: true, name: "newsletter" })
|
await page.getByRole('checkbox', { name: 'Subscribe' })
|
||||||
.uncheck();
|
.check();
|
||||||
|
|
||||||
await page.getByRole('button', { name: /submit/i })
|
await page.getByRole('button', { name: /submit/i })
|
||||||
.click();
|
.click();
|
||||||
```
|
```
|
||||||
|
|
||||||
```python async
|
```python async
|
||||||
await expect(page.get_by_role("heading", name="my form")).to_be_visible()
|
await expect(page.get_by_role("heading", name="Sign up")).to_be_visible()
|
||||||
|
|
||||||
await page.get_by_role("checkbox", checked=True, name="newsletter").uncheck()
|
await page.get_by_role("checkbox", name="Subscribe").check()
|
||||||
|
|
||||||
await page.get_by_role("button", name=re.compile("submit", re.IGNORECASE)).click()
|
await page.get_by_role("button", name=re.compile("submit", re.IGNORECASE)).click()
|
||||||
```
|
```
|
||||||
|
|
||||||
```python sync
|
```python sync
|
||||||
expect(page.get_by_role("heading", name="my from")).to_be_visible()
|
expect(page.get_by_role("heading", name="Sign up")).to_be_visible()
|
||||||
|
|
||||||
page.get_by_role("checkbox", checked=True, name="newsletter").uncheck()
|
page.get_by_role("checkbox", name="Subscribe").check()
|
||||||
|
|
||||||
page.get_by_role("button", name=re.compile("submit", re.IGNORECASE)).click()
|
page.get_by_role("button", name=re.compile("submit", re.IGNORECASE)).click()
|
||||||
```
|
```
|
||||||
|
|
||||||
```java
|
```java
|
||||||
assertThat(page.getByRole("heading", new Page.GetByRoleOptions().setName("my form")))
|
assertThat(page.getByRole("heading", new Page.GetByRoleOptions().setName("Sign up")))
|
||||||
.isVisible();
|
.isVisible();
|
||||||
|
|
||||||
page.getByRole("checkbox", new Page.GetByRoleOptions().setChecked(true).setName("newsletter"))
|
page.getByRole("checkbox", new Page.GetByRoleOptions().setName("Subscribe"))
|
||||||
.uncheck();
|
.check();
|
||||||
|
|
||||||
page.getByRole("button", new Page.GetByRoleOptions().setName(Pattern.compile("submit", Pattern.CASE_INSENSITIVE)))
|
page.getByRole("button", new Page.GetByRoleOptions().setName(Pattern.compile("submit", Pattern.CASE_INSENSITIVE)))
|
||||||
.click();
|
.click();
|
||||||
```
|
```
|
||||||
|
|
||||||
```csharp
|
```csharp
|
||||||
await Expect(page.GetByRole("heading", new() { NameString = "my form" }))
|
await Expect(page.GetByRole("heading", new() { NameString = "Sign up" }))
|
||||||
.ToBeVisibleAsync();
|
.ToBeVisibleAsync();
|
||||||
|
|
||||||
await page.GetByRole("checkbox", new() { Checked = true, NameString = "newsletter" })
|
await page.GetByRole("checkbox", new() { NameString = "Subscribe" })
|
||||||
.UncheckAsync();
|
.CheckAsync();
|
||||||
|
|
||||||
await page.GetByRole("button", new() { NameRegex = new Regex("submit", RegexOptions.IgnoreCase) })
|
await page.GetByRole("button", new() { NameRegex = new Regex("submit", RegexOptions.IgnoreCase) })
|
||||||
.ClickAsync();
|
.ClickAsync();
|
||||||
```
|
```
|
||||||
|
|
||||||
<img width="239" alt="form with newsletter checkbox unchecked and submit button highlighted" src="https://user-images.githubusercontent.com/13063165/201134851-f707a433-1e10-4b83-b648-c19df2a04de0.png" />
|
```html
|
||||||
|
<form>
|
||||||
|
<input type="checkbox" checked id="subscribe" />
|
||||||
|
<label for="subscribe">Subscribe</label>
|
||||||
|
<br>
|
||||||
|
<button>Submit</button>
|
||||||
|
</form>
|
||||||
|
```
|
||||||
|
|
||||||
Role locators include [buttons, checkboxes, headings, links, lists, tables, and many more](https://www.w3.org/TR/html-aria/#docconformance) and follow W3C specifications for [ARIA role](https://www.w3.org/TR/wai-aria-1.2/#roles), [ARIA attributes](https://www.w3.org/TR/wai-aria-1.2/#aria-attributes) and [accessible name](https://w3c.github.io/accname/#dfn-accessible-name).
|
Role locators include [buttons, checkboxes, headings, links, lists, tables, and many more](https://www.w3.org/TR/html-aria/#docconformance) and follow W3C specifications for [ARIA role](https://www.w3.org/TR/wai-aria-1.2/#roles), [ARIA attributes](https://www.w3.org/TR/wai-aria-1.2/#aria-attributes) and [accessible name](https://w3c.github.io/accname/#dfn-accessible-name).
|
||||||
|
|
||||||
|
|
@ -267,7 +274,6 @@ For example, consider the following DOM structure.
|
||||||
<label for="password">Password</label>
|
<label for="password">Password</label>
|
||||||
<input type="password" id="password">
|
<input type="password" id="password">
|
||||||
```
|
```
|
||||||
<img width="220" alt="password input with label of password" src="https://user-images.githubusercontent.com/13063165/201115785-f996ede8-01ae-4aa6-bd76-a60600efa125.png" />
|
|
||||||
|
|
||||||
You can fill the input after locating it by the label text:
|
You can fill the input after locating it by the label text:
|
||||||
|
|
||||||
|
|
@ -290,7 +296,11 @@ page.get_by_label("Password").fill("secret")
|
||||||
```csharp
|
```csharp
|
||||||
await page.GetByLabel("Password").FillAsync("secret");
|
await page.GetByLabel("Password").FillAsync("secret");
|
||||||
```
|
```
|
||||||
<img width="225" alt="password input with label and password filled in with encryption" src="https://user-images.githubusercontent.com/13063165/201113928-3b383887-433c-4b2c-9516-6c17d87d1eb2.png" />
|
|
||||||
|
```html
|
||||||
|
<label for="password">Password</label>
|
||||||
|
<input type="password" id="password" value="secret" target>
|
||||||
|
```
|
||||||
|
|
||||||
:::tip When to use label locators
|
:::tip When to use label locators
|
||||||
Use this locator when locating form fields.
|
Use this locator when locating form fields.
|
||||||
|
|
@ -302,11 +312,9 @@ Inputs may have a placeholder attribute to hint to the user what value should be
|
||||||
For example, consider the following DOM structure.
|
For example, consider the following DOM structure.
|
||||||
|
|
||||||
```html
|
```html
|
||||||
<input id="email" name="email" type="email" placeholder="name@example.com">
|
<input id="email" name="email" type="email" placeholder="name@example.com">
|
||||||
```
|
```
|
||||||
|
|
||||||
<img width="155" alt="input field filled in with name@example.com" src="https://user-images.githubusercontent.com/13063165/201114537-597b157f-68f3-473e-8802-4c099d1d6e93.png" />
|
|
||||||
|
|
||||||
You can fill the input after locating it by the placeholder text:
|
You can fill the input after locating it by the placeholder text:
|
||||||
|
|
||||||
```js
|
```js
|
||||||
|
|
@ -332,7 +340,9 @@ await page.GetByPlaceholder("name@example.com")
|
||||||
.FillAsync("playwright@microsoft.com");
|
.FillAsync("playwright@microsoft.com");
|
||||||
```
|
```
|
||||||
|
|
||||||
<img width="155" alt="input field filled in with playwright@microsoft.com" src="https://user-images.githubusercontent.com/13063165/201114985-c5bb9709-3680-4137-a3d9-e272056ca79e.png" />
|
```html
|
||||||
|
<input id="email" name="email" type="email" placeholder="name@example.com" value="playwright@microsoft.com">
|
||||||
|
```
|
||||||
|
|
||||||
:::tip When to use placeholder locators
|
:::tip When to use placeholder locators
|
||||||
Use this locator when locating form elements that do not have labels but do have placeholder texts.
|
Use this locator when locating form elements that do not have labels but do have placeholder texts.
|
||||||
|
|
@ -347,7 +357,6 @@ For example, consider the following DOM structure.
|
||||||
```html
|
```html
|
||||||
<span>Welcome, John</span>
|
<span>Welcome, John</span>
|
||||||
```
|
```
|
||||||
<img width="218" alt="Welcome, John" src="https://user-images.githubusercontent.com/13063165/201122791-10ee8cba-871c-4fb6-a925-ce42c8500f04.png" />
|
|
||||||
|
|
||||||
You can locate the element by the text it contains:
|
You can locate the element by the text it contains:
|
||||||
|
|
||||||
|
|
@ -380,7 +389,6 @@ await expect(page.getByText('Welcome, John', { exact: true }))
|
||||||
.toBeVisible();
|
.toBeVisible();
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
```java
|
```java
|
||||||
assertThat(page.getByText("Welcome, John", new Page.GetByTextOptions().setExact(true)))
|
assertThat(page.getByText("Welcome, John", new Page.GetByTextOptions().setExact(true)))
|
||||||
.isVisible();
|
.isVisible();
|
||||||
|
|
@ -437,16 +445,12 @@ You can also [filter by text](#filter-by-text) which can be useful when trying t
|
||||||
|
|
||||||
All images should have an `alt` attribute that describes the image. You can locate an image based on the text alternative using [`method: Page.getByAltText`].
|
All images should have an `alt` attribute that describes the image. You can locate an image based on the text alternative using [`method: Page.getByAltText`].
|
||||||
|
|
||||||
|
|
||||||
For example, consider the following DOM structure.
|
For example, consider the following DOM structure.
|
||||||
|
|
||||||
```html
|
```html
|
||||||
<img alt="playwright logo" src="/playwright-logo.png" />
|
<img alt="playwright logo" src="/playwright-logo.png" />
|
||||||
```
|
```
|
||||||
|
|
||||||
<img width="48" alt="playwright logo" src="https://user-images.githubusercontent.com/13063165/201125864-dad707d2-efbc-4fd8-ab2e-8f41e3b24416.png" />
|
|
||||||
|
|
||||||
|
|
||||||
You can click on the image after locating it by the text alternative:
|
You can click on the image after locating it by the text alternative:
|
||||||
|
|
||||||
```js
|
```js
|
||||||
|
|
@ -472,8 +476,9 @@ await page.GetByAltText("playwright logo")
|
||||||
.ClickAsync();
|
.ClickAsync();
|
||||||
```
|
```
|
||||||
|
|
||||||
<img width="49" alt="playwright logo being clicked" src="https://user-images.githubusercontent.com/13063165/201134010-4b7af9fc-cfaf-42b5-b968-79b2e1921b57.png" />
|
```html
|
||||||
|
<img alt="playwright logo" src="/playwright-logo.png">
|
||||||
|
```
|
||||||
|
|
||||||
:::tip When to use alt locators
|
:::tip When to use alt locators
|
||||||
Use this locator when your element supports alt text such as `img` and `area` elements.
|
Use this locator when your element supports alt text such as `img` and `area` elements.
|
||||||
|
|
@ -488,7 +493,6 @@ For example, consider the following DOM structure.
|
||||||
```html
|
```html
|
||||||
<span title='Issues count'>25 issues</span>
|
<span title='Issues count'>25 issues</span>
|
||||||
```
|
```
|
||||||
<img width="67" alt="25 issues" src="https://user-images.githubusercontent.com/13063165/201129562-2c2cb7f2-4072-4dfe-8286-e7d3a036e965.png" />
|
|
||||||
|
|
||||||
You can check the issues count after locating it by the title text:
|
You can check the issues count after locating it by the title text:
|
||||||
|
|
||||||
|
|
@ -528,7 +532,6 @@ For example, consider the following DOM structure.
|
||||||
```html
|
```html
|
||||||
<button data-testid="directions">Itinéraire</button>
|
<button data-testid="directions">Itinéraire</button>
|
||||||
```
|
```
|
||||||
<img width="74" alt="Screenshot 2022-11-10 at 16 07 47" src="https://user-images.githubusercontent.com/13063165/201131385-5e18c551-625c-4153-9808-e2666b90b152.png" />
|
|
||||||
|
|
||||||
You can locate the element by it's test id:
|
You can locate the element by it's test id:
|
||||||
|
|
||||||
|
|
@ -555,7 +558,9 @@ await page.GetByTestId("directions")
|
||||||
.ClickAsync();
|
.ClickAsync();
|
||||||
```
|
```
|
||||||
|
|
||||||
<img width="72" alt="button with Itinéraire text showing click action" src="https://user-images.githubusercontent.com/13063165/201133588-789926c6-9de3-4866-abd9-8d0a7e3fa95d.png" />
|
```html
|
||||||
|
<button data-testid="directions">Itinéraire</button>
|
||||||
|
```
|
||||||
|
|
||||||
:::tip When to use testid locators
|
:::tip When to use testid locators
|
||||||
You can also use test ids when you choose to use the test id methodology or when you can't locate by [role](#locate-by-role) or [text](#locate-by-text).
|
You can also use test ids when you choose to use the test id methodology or when you can't locate by [role](#locate-by-role) or [text](#locate-by-text).
|
||||||
|
|
@ -735,9 +740,6 @@ Consider the following example with a custom web component:
|
||||||
</x-details>
|
</x-details>
|
||||||
```
|
```
|
||||||
|
|
||||||
<img width="101" alt="Title, shadow-root and details" src="https://user-images.githubusercontent.com/13063165/201364144-fe6ea945-505d-4650-bbe4-056439c311c8.png" />
|
|
||||||
|
|
||||||
|
|
||||||
You can locate in the same way as if the shadow root was not present at all.
|
You can locate in the same way as if the shadow root was not present at all.
|
||||||
|
|
||||||
To click `<div>Details</div>`:
|
To click `<div>Details</div>`:
|
||||||
|
|
@ -758,10 +760,13 @@ page.get_by_text("Details").click()
|
||||||
await page.GetByText("Details").ClickAsync();
|
await page.GetByText("Details").ClickAsync();
|
||||||
```
|
```
|
||||||
|
|
||||||
<img width="100" alt="Title, shadow-root and details with text details highlighted" src="https://user-images.githubusercontent.com/13063165/201364000-42820d75-053f-449e-80bf-8b38470a2a23.png" />
|
```html
|
||||||
|
<x-details role=button aria-expanded=true aria-controls=inner-details>
|
||||||
|
<div>Title</div>
|
||||||
<br /><br />
|
#shadow-root
|
||||||
|
<div id=inner-details>Details</div>
|
||||||
|
</x-details>
|
||||||
|
```
|
||||||
|
|
||||||
To click `<x-details>`:
|
To click `<x-details>`:
|
||||||
|
|
||||||
|
|
@ -781,9 +786,13 @@ page.locator("x-details", has_text="Details" ).click()
|
||||||
await page.Locator("x-details", new() { HasTextString = "Details" }).ClickAsync();
|
await page.Locator("x-details", new() { HasTextString = "Details" }).ClickAsync();
|
||||||
```
|
```
|
||||||
|
|
||||||
<img width="103" alt="Title, shadow-root and details highlighted" src="https://user-images.githubusercontent.com/13063165/201363856-09fd3eec-6e55-45fe-a251-7b39c3ea09d7.png" />
|
```html
|
||||||
|
<x-details role=button aria-expanded=true aria-controls=inner-details>
|
||||||
<br /><br />
|
<div>Title</div>
|
||||||
|
#shadow-root
|
||||||
|
<div id=inner-details>Details</div>
|
||||||
|
</x-details>
|
||||||
|
```
|
||||||
|
|
||||||
To ensure that `<x-details>` contains the text "Details":
|
To ensure that `<x-details>` contains the text "Details":
|
||||||
```js
|
```js
|
||||||
|
|
@ -808,17 +817,14 @@ Consider the following DOM structure where we want to click on the buy button of
|
||||||
```html
|
```html
|
||||||
<div data-testid='product-card'>
|
<div data-testid='product-card'>
|
||||||
<h3>Product 1</h3>
|
<h3>Product 1</h3>
|
||||||
<button>Buy</button>
|
<button>Add to cart</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div data-testid='product-card'>
|
<div data-testid='product-card'>
|
||||||
<h3>Product 2</h3>
|
<h3>Product 2</h3>
|
||||||
<button>Buy</button>
|
<button>Add to cart</button>
|
||||||
</div>
|
</div>
|
||||||
```
|
```
|
||||||
|
|
||||||
<img width="83" alt="2 product cards with text and a button" src="https://user-images.githubusercontent.com/13063165/201182468-348eb733-7cf5-4e5b-94de-604312fe5fc7.png" />
|
|
||||||
|
|
||||||
### Filter by text
|
### Filter by text
|
||||||
|
|
||||||
Locators can be filtered by text with the [`method: Locator.filter`] method. It will search for a particular string somewhere inside the element, possibly in a descendant element, case-insensitively. You can also pass a regular expression.
|
Locators can be filtered by text with the [`method: Locator.filter`] method. It will search for a particular string somewhere inside the element, possibly in a descendant element, case-insensitively. You can also pass a regular expression.
|
||||||
|
|
@ -826,28 +832,28 @@ Locators can be filtered by text with the [`method: Locator.filter`] method. It
|
||||||
```js
|
```js
|
||||||
await page.getByTestId('product-card')
|
await page.getByTestId('product-card')
|
||||||
.filter({ hasText: 'Product 2' })
|
.filter({ hasText: 'Product 2' })
|
||||||
.getByRole('button', { name: 'Buy' })
|
.getByRole('button', { name: 'Add to cart' })
|
||||||
.click();
|
.click();
|
||||||
```
|
```
|
||||||
|
|
||||||
```java
|
```java
|
||||||
page.getByTestId("product-card")
|
page.getByTestId("product-card")
|
||||||
.filter(new Locator.FilterOptions().setHasText("Product 2"))
|
.filter(new Locator.FilterOptions().setHasText("Product 2"))
|
||||||
.getByRole(AriaRole.BUTTON, new Page.GetByRoleOptions().setName("Buy"))
|
.getByRole(AriaRole.BUTTON, new Page.GetByRoleOptions().setName("Add to cart"))
|
||||||
.click();
|
.click();
|
||||||
```
|
```
|
||||||
|
|
||||||
```python async
|
```python async
|
||||||
await page.get_by_test_id("product-card").filter(has_text="Product 2").get_by_role("button", name="Buy").click()
|
await page.get_by_test_id("product-card").filter(has_text="Product 2").get_by_role("button", name="Add to cart").click()
|
||||||
```
|
```
|
||||||
|
|
||||||
```python sync
|
```python sync
|
||||||
page.get_by_test_id("product-card").filter(has_text="Product 2").get_by_role("button", name="Buy").click()
|
page.get_by_test_id("product-card").filter(has_text="Product 2").get_by_role("button", name="Add to cart").click()
|
||||||
```
|
```
|
||||||
```csharp
|
```csharp
|
||||||
await page.GetByTestId("product-card")
|
await page.GetByTestId("product-card")
|
||||||
.Filter(new() { HasTextString = "Product 2" })
|
.Filter(new() { HasTextString = "Product 2" })
|
||||||
.GetByRole(AriaRole.Button, new () { NameString = "Buy" })
|
.GetByRole(AriaRole.Button, new () { NameString = "Add to cart" })
|
||||||
.ClickAsync();
|
.ClickAsync();
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
@ -856,36 +862,45 @@ Use a regular expression:
|
||||||
```js
|
```js
|
||||||
await page.getByTestId('product-card')
|
await page.getByTestId('product-card')
|
||||||
.filter({ hasText: /Product 2/ })
|
.filter({ hasText: /Product 2/ })
|
||||||
.getByRole('button', { name: 'Buy' })
|
.getByRole('button', { name: 'Add to cart' })
|
||||||
.click();
|
.click();
|
||||||
```
|
```
|
||||||
|
|
||||||
```java
|
```java
|
||||||
page.getByTestId("product-card")
|
page.getByTestId("product-card")
|
||||||
.filter(new Locator.FilterOptions().setHasText(Pattern.compile("Product 2")))
|
.filter(new Locator.FilterOptions().setHasText(Pattern.compile("Product 2")))
|
||||||
.getByRole(AriaRole.BUTTON, new Page.GetByRoleOptions().setName("Buy"))
|
.getByRole(AriaRole.BUTTON, new Page.GetByRoleOptions().setName("Add to cart"))
|
||||||
.click();
|
.click();
|
||||||
```
|
```
|
||||||
|
|
||||||
```python async
|
```python async
|
||||||
await page.get_by_test_id("product-card").filter(has_text=re.compile("Product 2")).get_by_role("button", name="Buy").click()
|
await page.get_by_test_id("product-card").filter(has_text=re.compile("Product 2")).get_by_role("button", name="Add to cart").click()
|
||||||
```
|
```
|
||||||
|
|
||||||
```python sync
|
```python sync
|
||||||
page.get_by_test_id("product-card")
|
page.get_by_test_id("product-card")
|
||||||
.filter(has_text=re.compile("Product 2"))
|
.filter(has_text=re.compile("Product 2"))
|
||||||
.get_by_role("button", name="Buy")
|
.get_by_role("button", name="Add to cart")
|
||||||
.click()
|
.click()
|
||||||
```
|
```
|
||||||
|
|
||||||
```csharp
|
```csharp
|
||||||
await page.GetByTestId("product-card")
|
await page.GetByTestId("product-card")
|
||||||
.Filter(new() { HasTextRegex = new Regex("Product 2") })
|
.Filter(new() { HasTextRegex = new Regex("Product 2") })
|
||||||
.GetByRole(AriaRole.Button, new () { NameString = "Buy" })
|
.GetByRole(AriaRole.Button, new () { NameString = "Add to cart" })
|
||||||
.ClickAsync();
|
.ClickAsync();
|
||||||
```
|
```
|
||||||
|
|
||||||
<img width="83" alt="2 product cards with text and a button and the second one being highlighted" src="https://user-images.githubusercontent.com/13063165/201182749-253ff808-cd70-4d42-88c6-a9f07fb7eeae.png" />
|
```html
|
||||||
|
<div data-testid='product-card'>
|
||||||
|
<h3>Product 1</h3>
|
||||||
|
<button>Add to cart</button>
|
||||||
|
</div>
|
||||||
|
<div data-testid='product-card'>
|
||||||
|
<h3>Product 2</h3>
|
||||||
|
<button>Add to cart</button>
|
||||||
|
</div>
|
||||||
|
```
|
||||||
|
|
||||||
### Filter by another locator
|
### Filter by another locator
|
||||||
|
|
||||||
|
|
@ -894,32 +909,41 @@ Locators support an option to only select elements that have a descendant matchi
|
||||||
```js
|
```js
|
||||||
await page.getByTestId('product-card')
|
await page.getByTestId('product-card')
|
||||||
.filter({ has: page.getByRole('heading', { name: 'Product 2' })})
|
.filter({ has: page.getByRole('heading', { name: 'Product 2' })})
|
||||||
.getByRole('button', { name: 'Buy' })
|
.getByRole('button', { name: 'Add to cart' })
|
||||||
.click()
|
.click()
|
||||||
```
|
```
|
||||||
```java
|
```java
|
||||||
page.getByTestId("product-card")
|
page.getByTestId("product-card")
|
||||||
.filter(new Locator.FilterOptions().setHas(page.GetByRole(AriaRole.HEADING, new Page.GetByRoleOptions().setName("Product 2"))))
|
.filter(new Locator.FilterOptions().setHas(page.GetByRole(AriaRole.HEADING, new Page.GetByRoleOptions().setName("Product 2"))))
|
||||||
.getByRole(AriaRole.BUTTON, new Page.GetByRoleOptions().setName("Buy")))
|
.getByRole(AriaRole.BUTTON, new Page.GetByRoleOptions().setName("Add to cart")))
|
||||||
.click()
|
.click()
|
||||||
```
|
```
|
||||||
```python async
|
```python async
|
||||||
await page.get_by_test_id("product-card").filter(has=page.get_by_role("heading", name="Product 2")).get_by_role("button", name="Buy").click()
|
await page.get_by_test_id("product-card").filter(has=page.get_by_role("heading", name="Product 2")).get_by_role("button", name="Add to cart").click()
|
||||||
```
|
```
|
||||||
```python sync
|
```python sync
|
||||||
page.get_by_test_id("product-card")
|
page.get_by_test_id("product-card")
|
||||||
.filter(has=page.get_by_role("heading", name="Product 2"))
|
.filter(has=page.get_by_role("heading", name="Product 2"))
|
||||||
.get_by_role("button", name="Buy")
|
.get_by_role("button", name="Add to cart")
|
||||||
.click()
|
.click()
|
||||||
```
|
```
|
||||||
```csharp
|
```csharp
|
||||||
await page.GetByTestId("product-card")
|
await page.GetByTestId("product-card")
|
||||||
.Filter(new() { Has = page.GetByRole(AriaRole.Heading, new () { NameString = "Product 2" })})
|
.Filter(new() { Has = page.GetByRole(AriaRole.Heading, new () { NameString = "Product 2" })})
|
||||||
.GetByRole(AriaRole.Button, new () { NameString = "Buy" })
|
.GetByRole(AriaRole.Button, new () { NameString = "Add to cart" })
|
||||||
.ClickAsync();
|
.ClickAsync();
|
||||||
```
|
```
|
||||||
|
|
||||||
<img width="83" alt="2 product cards with text and a button and the second one being highlighted" src="https://user-images.githubusercontent.com/13063165/201182749-253ff808-cd70-4d42-88c6-a9f07fb7eeae.png" />
|
```html
|
||||||
|
<div data-testid='product-card'>
|
||||||
|
<h3>Product 1</h3>
|
||||||
|
<button>Add to cart</button>
|
||||||
|
</div>
|
||||||
|
<div data-testid='product-card'>
|
||||||
|
<h3>Product 2</h3>
|
||||||
|
<button>Add to cart</button>
|
||||||
|
</div>
|
||||||
|
```
|
||||||
|
|
||||||
We can also assert the product card to make sure there is only one
|
We can also assert the product card to make sure there is only one
|
||||||
|
|
||||||
|
|
@ -955,13 +979,13 @@ Note that the inner locator is matched starting from the outer one, not from the
|
||||||
|
|
||||||
You can chain methods that create a locator, like [`method: Page.getByText`] or [`method: Locator.getByRole`], to narrow down the search to a particular part of the page.
|
You can chain methods that create a locator, like [`method: Page.getByText`] or [`method: Locator.getByRole`], to narrow down the search to a particular part of the page.
|
||||||
|
|
||||||
In this example we first create a locator called product by locating the test id. We then filter by text. We can use the product locator again to get by role of button and click it and then use an assertion to make sure there is only one product with the text ' Product 2'.
|
In this example we first create a locator called product by locating the test id. We then filter by text. We can use the product locator again to get by role of button and click it and then use an assertion to make sure there is only one product with the text "Product 2".
|
||||||
|
|
||||||
```js
|
```js
|
||||||
const product = page.getByTestId('product-card')
|
const product = page.getByTestId('product-card')
|
||||||
.filter({ hasText: 'Product 2' });
|
.filter({ hasText: 'Product 2' });
|
||||||
|
|
||||||
await product.getByRole('button', { name: 'Buy' })
|
await product.getByRole('button', { name: 'Add to cart' })
|
||||||
.click();
|
.click();
|
||||||
|
|
||||||
await expect(product).toHaveCount(1);
|
await expect(product).toHaveCount(1);
|
||||||
|
|
@ -970,20 +994,20 @@ await expect(product).toHaveCount(1);
|
||||||
```python async
|
```python async
|
||||||
product = page.get_by_test_id("product-card").filter(has_text="Product 2")
|
product = page.get_by_test_id("product-card").filter(has_text="Product 2")
|
||||||
|
|
||||||
await product.get_by_role("button", name="Buy").click()
|
await product.get_by_role("button", name="Add to cart").click()
|
||||||
```
|
```
|
||||||
|
|
||||||
```python sync
|
```python sync
|
||||||
product = page.get_by_test_id("product-card").filter(has_text="Product 2")
|
product = page.get_by_test_id("product-card").filter(has_text="Product 2")
|
||||||
|
|
||||||
product.get_by_role("button", name="Buy").click()
|
product.get_by_role("button", name="Add to cart").click()
|
||||||
```
|
```
|
||||||
|
|
||||||
```java
|
```java
|
||||||
Locator product = page.getByTestId("product-card")
|
Locator product = page.getByTestId("product-card")
|
||||||
.filter(new Locator.FilterOptions().setHasText("Product 2"));
|
.filter(new Locator.FilterOptions().setHasText("Product 2"));
|
||||||
|
|
||||||
product.getByRole(AriaRole.BUTTON, new Locator.GetByRoleOptions().setName("Buy"))
|
product.getByRole(AriaRole.BUTTON, new Locator.GetByRoleOptions().setName("Add to cart"))
|
||||||
.click();
|
.click();
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
@ -991,11 +1015,20 @@ product.getByRole(AriaRole.BUTTON, new Locator.GetByRoleOptions().setName("Buy")
|
||||||
var product = page.GetByTestId("product-card")
|
var product = page.GetByTestId("product-card")
|
||||||
.Filter(new() { HasTextString = "Product 2" });
|
.Filter(new() { HasTextString = "Product 2" });
|
||||||
|
|
||||||
await product.GetByRole("button", new() { NameString = "Buy" })
|
await product.GetByRole("button", new() { NameString = "Add to cart" })
|
||||||
.ClickAsync();
|
.ClickAsync();
|
||||||
```
|
```
|
||||||
|
|
||||||
<img width="83" alt="2 product cards with text and a button and the second one being highlighted" src="https://user-images.githubusercontent.com/13063165/201182749-253ff808-cd70-4d42-88c6-a9f07fb7eeae.png" />
|
```html
|
||||||
|
<div data-testid='product-card'>
|
||||||
|
<h3>Product 1</h3>
|
||||||
|
<button>Add to cart</button>
|
||||||
|
</div>
|
||||||
|
<div data-testid='product-card'>
|
||||||
|
<h3>Product 2</h3>
|
||||||
|
<button>Add to cart</button>
|
||||||
|
</div>
|
||||||
|
```
|
||||||
|
|
||||||
## Lists
|
## Lists
|
||||||
|
|
||||||
|
|
@ -1013,8 +1046,6 @@ For example, consider the following DOM structure:
|
||||||
</ul>
|
</ul>
|
||||||
```
|
```
|
||||||
|
|
||||||
<img width="81" alt="list of 3 items, apple, banana and orange" src="https://user-images.githubusercontent.com/13063165/200641602-95a801ce-8a3e-4141-b4ac-926b890f4648.png" />
|
|
||||||
|
|
||||||
Use the count assertion to ensure that the list has 3 items.
|
Use the count assertion to ensure that the list has 3 items.
|
||||||
|
|
||||||
```js
|
```js
|
||||||
|
|
@ -1050,7 +1081,6 @@ For example, consider the following DOM structure:
|
||||||
<li>orange</li>
|
<li>orange</li>
|
||||||
</ul>
|
</ul>
|
||||||
```
|
```
|
||||||
<img width="81" alt="list of 3 items, apple, banana and orange" src="https://user-images.githubusercontent.com/13063165/200641602-95a801ce-8a3e-4141-b4ac-926b890f4648.png" />
|
|
||||||
|
|
||||||
Use [`method: LocatorAssertions.toHaveText`] to ensure that the list has the text "apple", "banana" and "orange".
|
Use [`method: LocatorAssertions.toHaveText`] to ensure that the list has the text "apple", "banana" and "orange".
|
||||||
|
|
||||||
|
|
@ -1119,7 +1149,13 @@ await page.GetByText("orange")
|
||||||
.ClickAsync();
|
.ClickAsync();
|
||||||
```
|
```
|
||||||
|
|
||||||
<img width="78" alt="list of apple, banana and orange highlighting orange" src="https://user-images.githubusercontent.com/13063165/201171918-0f689261-a48e-4660-9726-c8fcf29e9105.png" />
|
```html
|
||||||
|
<ul>
|
||||||
|
<li>apple</li>
|
||||||
|
<li>banana</li>
|
||||||
|
<li>orange</li>
|
||||||
|
</ul>
|
||||||
|
```
|
||||||
|
|
||||||
#### Filter by text
|
#### Filter by text
|
||||||
Use the [`method: Locator.filter`] to locate a specific item in a list.
|
Use the [`method: Locator.filter`] to locate a specific item in a list.
|
||||||
|
|
@ -1161,7 +1197,14 @@ await page.GetByRole("listitem")
|
||||||
.Filter(new() { HasTextString = "orange" })
|
.Filter(new() { HasTextString = "orange" })
|
||||||
.ClickAsync();
|
.ClickAsync();
|
||||||
```
|
```
|
||||||
<img width="78" alt="list of apple, banana and orange highlighting orange" src="https://user-images.githubusercontent.com/13063165/201171918-0f689261-a48e-4660-9726-c8fcf29e9105.png" />
|
|
||||||
|
```html
|
||||||
|
<ul>
|
||||||
|
<li>apple</li>
|
||||||
|
<li>banana</li>
|
||||||
|
<li>orange</li>
|
||||||
|
</ul>
|
||||||
|
```
|
||||||
|
|
||||||
#### Get by test id
|
#### Get by test id
|
||||||
|
|
||||||
|
|
@ -1202,7 +1245,13 @@ await page.GetByTestId("orange")
|
||||||
.ClickAsync();
|
.ClickAsync();
|
||||||
```
|
```
|
||||||
|
|
||||||
<img width="78" alt="list of apple, banana and orange highlighting orange" src="https://user-images.githubusercontent.com/13063165/201171918-0f689261-a48e-4660-9726-c8fcf29e9105.png" />
|
```html
|
||||||
|
<ul>
|
||||||
|
<li data-testid='apple'>apple</li>
|
||||||
|
<li data-testid='banana'>banana</li>
|
||||||
|
<li data-testid='orange'>orange</li>
|
||||||
|
</ul>
|
||||||
|
```
|
||||||
|
|
||||||
#### Get by nth item
|
#### Get by nth item
|
||||||
|
|
||||||
|
|
@ -1256,7 +1305,6 @@ For example, consider the following DOM structure:
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
```
|
```
|
||||||
<img width="112" alt="text John and Mary with buttons say hello and say goodbye beside their names" src="https://user-images.githubusercontent.com/13063165/201173459-4c560974-6712-48a6-8b6d-a636276f0dd3.png" />
|
|
||||||
|
|
||||||
To take a screenshot of the row with "Mary" and "Say goodbye":
|
To take a screenshot of the row with "Mary" and "Say goodbye":
|
||||||
|
|
||||||
|
|
@ -1299,8 +1347,10 @@ await rowLocator.Filter(new() { HasTextString = "Mary" })
|
||||||
|
|
||||||
You should now have a "screenshot.png" file in your project's root directory.
|
You should now have a "screenshot.png" file in your project's root directory.
|
||||||
|
|
||||||
<img width="153" alt="text Mary with buttons say goodbye" src="https://user-images.githubusercontent.com/13063165/201357594-7910f8ad-7626-48a4-85a2-2a3e63d67e34.png" />
|
```html
|
||||||
|
<div>Mary</div>
|
||||||
|
<div><button>Say goodbye</button></div>
|
||||||
|
```
|
||||||
### Rare use cases
|
### Rare use cases
|
||||||
|
|
||||||
#### Get All text contents
|
#### Get All text contents
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue