docs: add examples and clarifications to getByText (#18380)
Also be more explicit about normalizing whitespace, event with exact match. Fixes #17831.
This commit is contained in:
parent
3e112193a6
commit
c4404ea98f
|
|
@ -1074,7 +1074,7 @@ Text to locate the element for.
|
|||
* since: v1.27
|
||||
- `exact` <[boolean]>
|
||||
|
||||
Whether to find an exact match: case-sensitive and whole-string. Default to false. Ignored when locating by a regular expression.
|
||||
Whether to find an exact match: case-sensitive and whole-string. Default to false. Ignored when locating by a regular expression. Note that exact match still trims whitespace.
|
||||
|
||||
## locator-get-by-role-role
|
||||
* since: v1.27
|
||||
|
|
@ -1185,7 +1185,109 @@ use: {
|
|||
|
||||
## template-locator-get-by-text
|
||||
|
||||
Allows locating elements that contain given text.
|
||||
Allows locating elements that contain given text. Consider the following DOM structure:
|
||||
|
||||
```html
|
||||
<div>Hello <span>world</span></div>
|
||||
<div>Hello</div>
|
||||
```
|
||||
|
||||
You can locate by text substring, exact string, or a regular expression:
|
||||
|
||||
```js
|
||||
// Matches <span>
|
||||
page.getByText('world')
|
||||
|
||||
// Matches first <div>
|
||||
page.getByText('Hello world')
|
||||
|
||||
// Matches second <div>
|
||||
page.getByText('Hello', { exact: true })
|
||||
|
||||
// Matches both <div>s
|
||||
page.getByText(/Hello/)
|
||||
|
||||
// Matches second <div>
|
||||
page.getByText(/^hello$/i)
|
||||
```
|
||||
|
||||
```python async
|
||||
# Matches <span>
|
||||
page.get_by_text("world")
|
||||
|
||||
# Matches first <div>
|
||||
page.get_by_text("Hello world")
|
||||
|
||||
# Matches second <div>
|
||||
page.get_by_text("Hello", exact=True)
|
||||
|
||||
# Matches both <div>s
|
||||
page.get_by_text(re.compile("Hello"))
|
||||
|
||||
# Matches second <div>
|
||||
page.get_by_text(re.compile("^hello$", re.IGNORECASE))
|
||||
```
|
||||
|
||||
```python sync
|
||||
# Matches <span>
|
||||
page.get_by_text("world")
|
||||
|
||||
# Matches first <div>
|
||||
page.get_by_text("Hello world")
|
||||
|
||||
# Matches second <div>
|
||||
page.get_by_text("Hello", exact=True)
|
||||
|
||||
# Matches both <div>s
|
||||
page.get_by_text(re.compile("Hello"))
|
||||
|
||||
# Matches second <div>
|
||||
page.get_by_text(re.compile("^hello$", re.IGNORECASE))
|
||||
```
|
||||
|
||||
```java
|
||||
// Matches <span>
|
||||
page.getByText("world")
|
||||
|
||||
// Matches first <div>
|
||||
page.getByText("Hello world")
|
||||
|
||||
// Matches second <div>
|
||||
page.getByText("Hello", new Page.GetByTextOptions().setExact(true))
|
||||
|
||||
// Matches both <div>s
|
||||
page.getByText(Pattern.compile("Hello"))
|
||||
|
||||
// Matches second <div>
|
||||
page.getByText(Pattern.compile("^hello$", Pattern.CASE_INSENSITIVE))
|
||||
```
|
||||
|
||||
```csharp
|
||||
// Matches <span>
|
||||
page.GetByText("world")
|
||||
|
||||
// Matches first <div>
|
||||
page.GetByText("Hello world")
|
||||
|
||||
// Matches second <div>
|
||||
page.GetByText("Hello", new() { Exact: true })
|
||||
|
||||
// Matches both <div>s
|
||||
page.GetByText(new Regex("Hello"))
|
||||
|
||||
// Matches second <div>
|
||||
page.GetByText(new Regex("^hello$", RegexOptions.IgnoreCase))
|
||||
```
|
||||
|
||||
See also [`method: Locator.filter`] that allows to match by another criteria, like an accessible role, and then filter by the text content.
|
||||
|
||||
:::note
|
||||
Matching by text always normalizes whitespace, even with exact match. For example, it turns multiple spaces into one, turns line breaks into spaces and ignores leading and trailing whitespace.
|
||||
:::
|
||||
|
||||
:::note
|
||||
Input elements of the type `button` and `submit` are matched by their `value` instead of the text content. For example, locating by text `"Log in"` matches `<input type=button value="Log in">`.
|
||||
:::
|
||||
|
||||
## template-locator-get-by-alt-text
|
||||
|
||||
|
|
|
|||
|
|
@ -217,6 +217,10 @@ page.get_by_test_id("product-item").filter(has_text="Playwright Book").click()
|
|||
await page.GetByTestId("product-item").Filter(new() { HasText = "Playwright Book" }).ClickAsync();
|
||||
```
|
||||
|
||||
:::note
|
||||
Matching by text always normalizes whitespace, even with exact match. For example, it turns multiple spaces into one, turns line breaks into spaces and ignores leading and trailing whitespace.
|
||||
:::
|
||||
|
||||
### Locate based on accessible attributes with [`method: Page.getByRole`]
|
||||
|
||||
The [`method: Page.getByRole`] locator reflects how users and assistive technology percieve the page, for example whether some element is a button or a checkbox. When locating by role, you should usually pass the accessible name as well, so that locator pinpoints the exact element.
|
||||
|
|
|
|||
|
|
@ -236,7 +236,7 @@ await page.Locator("text=Log in").ClickAsync();
|
|||
|
||||
Text selector has a few variations:
|
||||
|
||||
- `text=Log in` - default matching is case-insensitive and searches for a substring. For example, `text=Log` matches `<button>Log in</button>`.
|
||||
- `text=Log in` - default matching is case-insensitive, trims whitespace and searches for a substring. For example, `text=Log` matches `<button>Log in</button>`.
|
||||
|
||||
```js
|
||||
await page.locator('text=Log in').click();
|
||||
|
|
@ -254,7 +254,7 @@ Text selector has a few variations:
|
|||
await page.Locator("text=Log in").ClickAsync();
|
||||
```
|
||||
|
||||
- `text="Log in"` - text body can be escaped with single or double quotes to search for a text node with exact content. For example, `text="Log"` does not match `<button>Log in</button>` because `<button>` contains a single text node `"Log in"` that is not equal to `"Log"`. However, `text="Log"` matches `<button>Log<span>in</span></button>`, because `<button>` contains a text node `"Log"`. This exact mode implies case-sensitive matching, so `text="Download"` will not match `<button>download</button>`.
|
||||
- `text="Log in"` - text body can be escaped with single or double quotes to search for a text node with exact content after trimming whitespace. For example, `text="Log"` does not match `<button>Log in</button>` because `<button>` contains a single text node `"Log in"` that is not equal to `"Log"`. However, `text="Log"` matches `<button> Log <span>in</span></button>`, because `<button>` contains a text node `" Log "`. This exact mode implies case-sensitive matching, so `text="Download"` will not match `<button>download</button>`.
|
||||
|
||||
Quoted body follows the usual escaping rules, e.g. use `\"` to escape double quote in a double-quoted string: `text="foo\"bar"`.
|
||||
|
||||
|
|
@ -310,7 +310,7 @@ Text selector has a few variations:
|
|||
await page.Locator("text=/Log\\s*in/i").ClickAsync();
|
||||
```
|
||||
|
||||
- `article:has-text("Playwright")` - the `:has-text()` pseudo-class can be used inside a [css] selector. It matches any element containing specified text somewhere inside, possibly in a child or a descendant element. Matching is case-insensitive and searches for a substring. For example, `article:has-text("Playwright")` matches `<article><div>Playwright</div></article>`.
|
||||
- `article:has-text("Playwright")` - the `:has-text()` pseudo-class can be used inside a [css] selector. It matches any element containing specified text somewhere inside, possibly in a child or a descendant element. Matching is case-insensitive, trims whitestapce and searches for a substring. For example, `article:has-text("Playwright")` matches `<article><div>Playwright</div></article>`.
|
||||
|
||||
Note that `:has-text()` should be used together with other `css` specifiers, otherwise it will match all the elements containing specified text, including the `<body>`.
|
||||
```js
|
||||
|
|
|
|||
176
packages/playwright-core/types/types.d.ts
vendored
176
packages/playwright-core/types/types.d.ts
vendored
|
|
@ -2498,7 +2498,7 @@ export interface Page {
|
|||
getByAltText(text: string|RegExp, options?: {
|
||||
/**
|
||||
* Whether to find an exact match: case-sensitive and whole-string. Default to false. Ignored when locating by a regular
|
||||
* expression.
|
||||
* expression. Note that exact match still trims whitespace.
|
||||
*/
|
||||
exact?: boolean;
|
||||
}): Locator;
|
||||
|
|
@ -2518,7 +2518,7 @@ export interface Page {
|
|||
getByLabel(text: string|RegExp, options?: {
|
||||
/**
|
||||
* Whether to find an exact match: case-sensitive and whole-string. Default to false. Ignored when locating by a regular
|
||||
* expression.
|
||||
* expression. Note that exact match still trims whitespace.
|
||||
*/
|
||||
exact?: boolean;
|
||||
}): Locator;
|
||||
|
|
@ -2537,7 +2537,7 @@ export interface Page {
|
|||
getByPlaceholder(text: string|RegExp, options?: {
|
||||
/**
|
||||
* Whether to find an exact match: case-sensitive and whole-string. Default to false. Ignored when locating by a regular
|
||||
* expression.
|
||||
* expression. Note that exact match still trims whitespace.
|
||||
*/
|
||||
exact?: boolean;
|
||||
}): Locator;
|
||||
|
|
@ -2634,14 +2634,46 @@ export interface Page {
|
|||
getByTestId(testId: string): Locator;
|
||||
|
||||
/**
|
||||
* Allows locating elements that contain given text.
|
||||
* Allows locating elements that contain given text. Consider the following DOM structure:
|
||||
*
|
||||
* ```html
|
||||
* <div>Hello <span>world</span></div>
|
||||
* <div>Hello</div>
|
||||
* ```
|
||||
*
|
||||
* You can locate by text substring, exact string, or a regular expression:
|
||||
*
|
||||
* ```js
|
||||
* // Matches <span>
|
||||
* page.getByText('world')
|
||||
*
|
||||
* // Matches first <div>
|
||||
* page.getByText('Hello world')
|
||||
*
|
||||
* // Matches second <div>
|
||||
* page.getByText('Hello', { exact: true })
|
||||
*
|
||||
* // Matches both <div>s
|
||||
* page.getByText(/Hello/)
|
||||
*
|
||||
* // Matches second <div>
|
||||
* page.getByText(/^hello$/i)
|
||||
* ```
|
||||
*
|
||||
* See also [locator.filter([options])](https://playwright.dev/docs/api/class-locator#locator-filter) that allows to match
|
||||
* by another criteria, like an accessible role, and then filter by the text content.
|
||||
*
|
||||
* > NOTE: Matching by text always normalizes whitespace, even with exact match. For example, it turns multiple spaces into
|
||||
* one, turns line breaks into spaces and ignores leading and trailing whitespace.
|
||||
* > NOTE: Input elements of the type `button` and `submit` are matched by their `value` instead of the text content. For
|
||||
* example, locating by text `"Log in"` matches `<input type=button value="Log in">`.
|
||||
* @param text Text to locate the element for.
|
||||
* @param options
|
||||
*/
|
||||
getByText(text: string|RegExp, options?: {
|
||||
/**
|
||||
* Whether to find an exact match: case-sensitive and whole-string. Default to false. Ignored when locating by a regular
|
||||
* expression.
|
||||
* expression. Note that exact match still trims whitespace.
|
||||
*/
|
||||
exact?: boolean;
|
||||
}): Locator;
|
||||
|
|
@ -2659,7 +2691,7 @@ export interface Page {
|
|||
getByTitle(text: string|RegExp, options?: {
|
||||
/**
|
||||
* Whether to find an exact match: case-sensitive and whole-string. Default to false. Ignored when locating by a regular
|
||||
* expression.
|
||||
* expression. Note that exact match still trims whitespace.
|
||||
*/
|
||||
exact?: boolean;
|
||||
}): Locator;
|
||||
|
|
@ -5645,7 +5677,7 @@ export interface Frame {
|
|||
getByAltText(text: string|RegExp, options?: {
|
||||
/**
|
||||
* Whether to find an exact match: case-sensitive and whole-string. Default to false. Ignored when locating by a regular
|
||||
* expression.
|
||||
* expression. Note that exact match still trims whitespace.
|
||||
*/
|
||||
exact?: boolean;
|
||||
}): Locator;
|
||||
|
|
@ -5665,7 +5697,7 @@ export interface Frame {
|
|||
getByLabel(text: string|RegExp, options?: {
|
||||
/**
|
||||
* Whether to find an exact match: case-sensitive and whole-string. Default to false. Ignored when locating by a regular
|
||||
* expression.
|
||||
* expression. Note that exact match still trims whitespace.
|
||||
*/
|
||||
exact?: boolean;
|
||||
}): Locator;
|
||||
|
|
@ -5684,7 +5716,7 @@ export interface Frame {
|
|||
getByPlaceholder(text: string|RegExp, options?: {
|
||||
/**
|
||||
* Whether to find an exact match: case-sensitive and whole-string. Default to false. Ignored when locating by a regular
|
||||
* expression.
|
||||
* expression. Note that exact match still trims whitespace.
|
||||
*/
|
||||
exact?: boolean;
|
||||
}): Locator;
|
||||
|
|
@ -5781,14 +5813,46 @@ export interface Frame {
|
|||
getByTestId(testId: string): Locator;
|
||||
|
||||
/**
|
||||
* Allows locating elements that contain given text.
|
||||
* Allows locating elements that contain given text. Consider the following DOM structure:
|
||||
*
|
||||
* ```html
|
||||
* <div>Hello <span>world</span></div>
|
||||
* <div>Hello</div>
|
||||
* ```
|
||||
*
|
||||
* You can locate by text substring, exact string, or a regular expression:
|
||||
*
|
||||
* ```js
|
||||
* // Matches <span>
|
||||
* page.getByText('world')
|
||||
*
|
||||
* // Matches first <div>
|
||||
* page.getByText('Hello world')
|
||||
*
|
||||
* // Matches second <div>
|
||||
* page.getByText('Hello', { exact: true })
|
||||
*
|
||||
* // Matches both <div>s
|
||||
* page.getByText(/Hello/)
|
||||
*
|
||||
* // Matches second <div>
|
||||
* page.getByText(/^hello$/i)
|
||||
* ```
|
||||
*
|
||||
* See also [locator.filter([options])](https://playwright.dev/docs/api/class-locator#locator-filter) that allows to match
|
||||
* by another criteria, like an accessible role, and then filter by the text content.
|
||||
*
|
||||
* > NOTE: Matching by text always normalizes whitespace, even with exact match. For example, it turns multiple spaces into
|
||||
* one, turns line breaks into spaces and ignores leading and trailing whitespace.
|
||||
* > NOTE: Input elements of the type `button` and `submit` are matched by their `value` instead of the text content. For
|
||||
* example, locating by text `"Log in"` matches `<input type=button value="Log in">`.
|
||||
* @param text Text to locate the element for.
|
||||
* @param options
|
||||
*/
|
||||
getByText(text: string|RegExp, options?: {
|
||||
/**
|
||||
* Whether to find an exact match: case-sensitive and whole-string. Default to false. Ignored when locating by a regular
|
||||
* expression.
|
||||
* expression. Note that exact match still trims whitespace.
|
||||
*/
|
||||
exact?: boolean;
|
||||
}): Locator;
|
||||
|
|
@ -5806,7 +5870,7 @@ export interface Frame {
|
|||
getByTitle(text: string|RegExp, options?: {
|
||||
/**
|
||||
* Whether to find an exact match: case-sensitive and whole-string. Default to false. Ignored when locating by a regular
|
||||
* expression.
|
||||
* expression. Note that exact match still trims whitespace.
|
||||
*/
|
||||
exact?: boolean;
|
||||
}): Locator;
|
||||
|
|
@ -10175,7 +10239,7 @@ export interface Locator {
|
|||
getByAltText(text: string|RegExp, options?: {
|
||||
/**
|
||||
* Whether to find an exact match: case-sensitive and whole-string. Default to false. Ignored when locating by a regular
|
||||
* expression.
|
||||
* expression. Note that exact match still trims whitespace.
|
||||
*/
|
||||
exact?: boolean;
|
||||
}): Locator;
|
||||
|
|
@ -10195,7 +10259,7 @@ export interface Locator {
|
|||
getByLabel(text: string|RegExp, options?: {
|
||||
/**
|
||||
* Whether to find an exact match: case-sensitive and whole-string. Default to false. Ignored when locating by a regular
|
||||
* expression.
|
||||
* expression. Note that exact match still trims whitespace.
|
||||
*/
|
||||
exact?: boolean;
|
||||
}): Locator;
|
||||
|
|
@ -10214,7 +10278,7 @@ export interface Locator {
|
|||
getByPlaceholder(text: string|RegExp, options?: {
|
||||
/**
|
||||
* Whether to find an exact match: case-sensitive and whole-string. Default to false. Ignored when locating by a regular
|
||||
* expression.
|
||||
* expression. Note that exact match still trims whitespace.
|
||||
*/
|
||||
exact?: boolean;
|
||||
}): Locator;
|
||||
|
|
@ -10311,14 +10375,46 @@ export interface Locator {
|
|||
getByTestId(testId: string): Locator;
|
||||
|
||||
/**
|
||||
* Allows locating elements that contain given text.
|
||||
* Allows locating elements that contain given text. Consider the following DOM structure:
|
||||
*
|
||||
* ```html
|
||||
* <div>Hello <span>world</span></div>
|
||||
* <div>Hello</div>
|
||||
* ```
|
||||
*
|
||||
* You can locate by text substring, exact string, or a regular expression:
|
||||
*
|
||||
* ```js
|
||||
* // Matches <span>
|
||||
* page.getByText('world')
|
||||
*
|
||||
* // Matches first <div>
|
||||
* page.getByText('Hello world')
|
||||
*
|
||||
* // Matches second <div>
|
||||
* page.getByText('Hello', { exact: true })
|
||||
*
|
||||
* // Matches both <div>s
|
||||
* page.getByText(/Hello/)
|
||||
*
|
||||
* // Matches second <div>
|
||||
* page.getByText(/^hello$/i)
|
||||
* ```
|
||||
*
|
||||
* See also [locator.filter([options])](https://playwright.dev/docs/api/class-locator#locator-filter) that allows to match
|
||||
* by another criteria, like an accessible role, and then filter by the text content.
|
||||
*
|
||||
* > NOTE: Matching by text always normalizes whitespace, even with exact match. For example, it turns multiple spaces into
|
||||
* one, turns line breaks into spaces and ignores leading and trailing whitespace.
|
||||
* > NOTE: Input elements of the type `button` and `submit` are matched by their `value` instead of the text content. For
|
||||
* example, locating by text `"Log in"` matches `<input type=button value="Log in">`.
|
||||
* @param text Text to locate the element for.
|
||||
* @param options
|
||||
*/
|
||||
getByText(text: string|RegExp, options?: {
|
||||
/**
|
||||
* Whether to find an exact match: case-sensitive and whole-string. Default to false. Ignored when locating by a regular
|
||||
* expression.
|
||||
* expression. Note that exact match still trims whitespace.
|
||||
*/
|
||||
exact?: boolean;
|
||||
}): Locator;
|
||||
|
|
@ -10336,7 +10432,7 @@ export interface Locator {
|
|||
getByTitle(text: string|RegExp, options?: {
|
||||
/**
|
||||
* Whether to find an exact match: case-sensitive and whole-string. Default to false. Ignored when locating by a regular
|
||||
* expression.
|
||||
* expression. Note that exact match still trims whitespace.
|
||||
*/
|
||||
exact?: boolean;
|
||||
}): Locator;
|
||||
|
|
@ -15604,7 +15700,7 @@ export interface FrameLocator {
|
|||
getByAltText(text: string|RegExp, options?: {
|
||||
/**
|
||||
* Whether to find an exact match: case-sensitive and whole-string. Default to false. Ignored when locating by a regular
|
||||
* expression.
|
||||
* expression. Note that exact match still trims whitespace.
|
||||
*/
|
||||
exact?: boolean;
|
||||
}): Locator;
|
||||
|
|
@ -15624,7 +15720,7 @@ export interface FrameLocator {
|
|||
getByLabel(text: string|RegExp, options?: {
|
||||
/**
|
||||
* Whether to find an exact match: case-sensitive and whole-string. Default to false. Ignored when locating by a regular
|
||||
* expression.
|
||||
* expression. Note that exact match still trims whitespace.
|
||||
*/
|
||||
exact?: boolean;
|
||||
}): Locator;
|
||||
|
|
@ -15643,7 +15739,7 @@ export interface FrameLocator {
|
|||
getByPlaceholder(text: string|RegExp, options?: {
|
||||
/**
|
||||
* Whether to find an exact match: case-sensitive and whole-string. Default to false. Ignored when locating by a regular
|
||||
* expression.
|
||||
* expression. Note that exact match still trims whitespace.
|
||||
*/
|
||||
exact?: boolean;
|
||||
}): Locator;
|
||||
|
|
@ -15740,14 +15836,46 @@ export interface FrameLocator {
|
|||
getByTestId(testId: string): Locator;
|
||||
|
||||
/**
|
||||
* Allows locating elements that contain given text.
|
||||
* Allows locating elements that contain given text. Consider the following DOM structure:
|
||||
*
|
||||
* ```html
|
||||
* <div>Hello <span>world</span></div>
|
||||
* <div>Hello</div>
|
||||
* ```
|
||||
*
|
||||
* You can locate by text substring, exact string, or a regular expression:
|
||||
*
|
||||
* ```js
|
||||
* // Matches <span>
|
||||
* page.getByText('world')
|
||||
*
|
||||
* // Matches first <div>
|
||||
* page.getByText('Hello world')
|
||||
*
|
||||
* // Matches second <div>
|
||||
* page.getByText('Hello', { exact: true })
|
||||
*
|
||||
* // Matches both <div>s
|
||||
* page.getByText(/Hello/)
|
||||
*
|
||||
* // Matches second <div>
|
||||
* page.getByText(/^hello$/i)
|
||||
* ```
|
||||
*
|
||||
* See also [locator.filter([options])](https://playwright.dev/docs/api/class-locator#locator-filter) that allows to match
|
||||
* by another criteria, like an accessible role, and then filter by the text content.
|
||||
*
|
||||
* > NOTE: Matching by text always normalizes whitespace, even with exact match. For example, it turns multiple spaces into
|
||||
* one, turns line breaks into spaces and ignores leading and trailing whitespace.
|
||||
* > NOTE: Input elements of the type `button` and `submit` are matched by their `value` instead of the text content. For
|
||||
* example, locating by text `"Log in"` matches `<input type=button value="Log in">`.
|
||||
* @param text Text to locate the element for.
|
||||
* @param options
|
||||
*/
|
||||
getByText(text: string|RegExp, options?: {
|
||||
/**
|
||||
* Whether to find an exact match: case-sensitive and whole-string. Default to false. Ignored when locating by a regular
|
||||
* expression.
|
||||
* expression. Note that exact match still trims whitespace.
|
||||
*/
|
||||
exact?: boolean;
|
||||
}): Locator;
|
||||
|
|
@ -15765,7 +15893,7 @@ export interface FrameLocator {
|
|||
getByTitle(text: string|RegExp, options?: {
|
||||
/**
|
||||
* Whether to find an exact match: case-sensitive and whole-string. Default to false. Ignored when locating by a regular
|
||||
* expression.
|
||||
* expression. Note that exact match still trims whitespace.
|
||||
*/
|
||||
exact?: boolean;
|
||||
}): Locator;
|
||||
|
|
|
|||
Loading…
Reference in a new issue