docs: OR for css and xpath selectors (#10285)
This commit is contained in:
parent
638ebd6dd6
commit
c5cb73003f
|
|
@ -503,34 +503,67 @@ await page.TextContentAsync("article:has(div.promo)");
|
||||||
|
|
||||||
## Selecting elements matching one of the conditions
|
## Selecting elements matching one of the conditions
|
||||||
|
|
||||||
The `:is()` pseudo-class is an [experimental CSS pseudo-class](https://developer.mozilla.org/en-US/docs/Web/CSS/:is).
|
### CSS selector list
|
||||||
It is a function that takes a selector list as its argument, and selects any element that
|
|
||||||
can be selected by one of the selectors in that list. This is useful for writing large
|
Comma separated list of CSS selectors will match all elements that can be selected by
|
||||||
selectors in a more compact form.
|
one of the selectors in that list.
|
||||||
|
|
||||||
```js
|
```js
|
||||||
// Clicks a <button> that has either a "Log in" or "Sign in" text.
|
// Clicks a <button> that has either a "Log in" or "Sign in" text.
|
||||||
await page.click(':is(button:has-text("Log in"), button:has-text("Sign in"))');
|
await page.click('button:has-text("Log in"), button:has-text("Sign in")');
|
||||||
```
|
```
|
||||||
|
|
||||||
```java
|
```java
|
||||||
// Clicks a <button> that has either a "Log in" or "Sign in" text.
|
// Clicks a <button> that has either a "Log in" or "Sign in" text.
|
||||||
page.click(":is(button:has-text(\"Log in\"), button:has-text(\"Sign in\"))");
|
page.click("button:has-text(\"Log in\"), button:has-text(\"Sign in\")");
|
||||||
```
|
```
|
||||||
|
|
||||||
```python async
|
```python async
|
||||||
# Clicks a <button> that has either a "Log in" or "Sign in" text.
|
# Clicks a <button> that has either a "Log in" or "Sign in" text.
|
||||||
await page.click(':is(button:has-text("Log in"), button:has-text("Sign in"))')
|
await page.click('button:has-text("Log in"), button:has-text("Sign in")')
|
||||||
```
|
```
|
||||||
|
|
||||||
```python sync
|
```python sync
|
||||||
# Clicks a <button> that has either a "Log in" or "Sign in" text.
|
# Clicks a <button> that has either a "Log in" or "Sign in" text.
|
||||||
page.click(':is(button:has-text("Log in"), button:has-text("Sign in"))')
|
page.click('button:has-text("Log in"), button:has-text("Sign in")')
|
||||||
```
|
```
|
||||||
|
|
||||||
```csharp
|
```csharp
|
||||||
// Clicks a <button> that has either a "Log in" or "Sign in" text.
|
// Clicks a <button> that has either a "Log in" or "Sign in" text.
|
||||||
await page.ClickAsync(":is(button:has-text(\"Log in\"), button:has-text(\"Sign in\"))");
|
await page.ClickAsync("button:has-text(\"Log in\"), button:has-text(\"Sign in\")");
|
||||||
|
```
|
||||||
|
|
||||||
|
The `:is()` pseudo-class is an [experimental CSS pseudo-class](https://developer.mozilla.org/en-US/docs/Web/CSS/:is) that
|
||||||
|
may be useful for specifying a list of extra conditions on an element.
|
||||||
|
|
||||||
|
### XPath union
|
||||||
|
|
||||||
|
Pipe operator (`|`) can be used to specify multiple selectors in XPath. It will match all
|
||||||
|
elements that can be selected by one of the selectors in that list.
|
||||||
|
|
||||||
|
```js
|
||||||
|
// Waits for either confirmation dialog or load spinner.
|
||||||
|
await page.waitForSelector(`//span[contains(@class, 'spinner__loading')]|//div[@id='confirmation']`);
|
||||||
|
```
|
||||||
|
|
||||||
|
```java
|
||||||
|
// Waits for either confirmation dialog or load spinner.
|
||||||
|
page.waitForSelector("//span[contains(@class, 'spinner__loading')]|//div[@id='confirmation']");
|
||||||
|
```
|
||||||
|
|
||||||
|
```python async
|
||||||
|
# Waits for either confirmation dialog or load spinner.
|
||||||
|
await page.click("//span[contains(@class, 'spinner__loading')]|//div[@id='confirmation']")
|
||||||
|
```
|
||||||
|
|
||||||
|
```python sync
|
||||||
|
# Waits for either confirmation dialog or load spinner.
|
||||||
|
page.click("//span[contains(@class, 'spinner__loading')]|//div[@id='confirmation']")
|
||||||
|
```
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
// Waits for either confirmation dialog or load spinner.
|
||||||
|
await page.ClickAsync("//span[contains(@class, 'spinner__loading')]|//div[@id='confirmation']");
|
||||||
```
|
```
|
||||||
|
|
||||||
## Selecting elements in Shadow DOM
|
## Selecting elements in Shadow DOM
|
||||||
|
|
|
||||||
|
|
@ -271,6 +271,27 @@ it('xpath should be relative', async ({ page }) => {
|
||||||
expect(await page.$eval(`div >> xpath=/*[@class="find-me"]`, e => e.id)).toBe('target2');
|
expect(await page.$eval(`div >> xpath=/*[@class="find-me"]`, e => e.id)).toBe('target2');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should work with pipe in xpath', async ({ page, server }) => {
|
||||||
|
await page.setContent(`
|
||||||
|
<span class="find-me" id=t1>1</span>
|
||||||
|
<div>
|
||||||
|
<span class="find-me" id=t2>2</span>
|
||||||
|
</div>
|
||||||
|
<div id=t3>3</span>
|
||||||
|
`);
|
||||||
|
expect(await page.$$eval(`//*[@id="t1"]|//*[@id="t3"]`, els => els.length)).toBe(2);
|
||||||
|
|
||||||
|
const e1 = await page.waitForSelector(`//*[@id="t1"]|//*[@id="t3"]`);
|
||||||
|
expect(e1).toBeTruthy();
|
||||||
|
expect(await e1.evaluate(e => e.id)).toBe('t1');
|
||||||
|
|
||||||
|
const e2 = await page.waitForSelector(`//*[@id="unknown"]|//*[@id="t2"]`);
|
||||||
|
expect(e2).toBeTruthy();
|
||||||
|
expect(await e2.evaluate(e => e.id)).toBe('t2');
|
||||||
|
|
||||||
|
await page.click(`//code|//span[@id="t2"]`);
|
||||||
|
});
|
||||||
|
|
||||||
it('data-testid on the handle should be relative', async ({ page }) => {
|
it('data-testid on the handle should be relative', async ({ page }) => {
|
||||||
await page.setContent(`
|
await page.setContent(`
|
||||||
<span data-testid="find-me" id=target1>1</span>
|
<span data-testid="find-me" id=target1>1</span>
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue