I need to find the button
within the li
that contains in its children both the text 6:00pm
and the text Alpha
.
<li>
<div>6:00pm</div>
<div>Alpha</div>
<button>Do it!</button>
</li>
<li>
<div>6:00pm</div>
<div>Beta</div>
<button>Do it!</button>
</li>
...
I have
li:has(div:text("6:00pm")) button
which gives me both button
s for "6:00pm", but how to limit the selector to also match Alpha
so I only get one button?
I basically need to add a conjunction to the predicate.
You can combine filter
calls to create a logical "and" of your conditions:
const playwright = require("playwright"); // ^1.30.0
const html = `<!DOCTYPE html>
<li>
<div>6:00pm</div>
<div>Alpha</div>
<button>Do it!</button>
</li>
<li>
<div>6:00pm</div>
<div>Beta</div>
<button>Do it!</button>
</li>`;
let browser;
(async () => {
browser = await playwright.chromium.launch();
const page = await browser.newPage();
await page.setContent(html);
const btn = page
.getByRole("listitem")
.filter({hasText: "Alpha"})
.filter({hasText: "6:00pm"})
.getByRole("button");
console.log(await btn.textContent()); // => Do it!
})()
.catch(err => console.error(err))
.finally(() => browser?.close());
Although this doesn't use the preferred role locator and presupposes a text ordering, the following is also possible:
page.locator("li:text('6:00pm Alpha') button");