Let's say I have two lists on the page, one with a single item and one with two:
<ul>
<li>One</li>
</ul>
<ul>
<li>One</li>
<li>Two</li>
</ul>
I know I can find the ul
that has the "Two" li
, like so:
page.locator('ul', {has: page.locator('li:text("Two")')});
But is there any way to find the ul
that has two li
s? Something like:
page.locator('ul', {hasCount: [page.locator('li'),2]});
XPath is discouraged in Playwright, but the following locator seems to meet your needs:
await page.locator("xpath=//ul[count(li)=2]")
Variants like "//ul[count(li) >= 2]"
and "//ul[count(li)=2][2]"
are possible.
This can be done without XPath, but it pretty much amounts to the same thing (selecting using a count), so I don't think this makes the locator better practice. Here's a complete example:
const playwright = require("playwright"); // ^1.39.0
const html = `
<ul>
<li>One</li>
</ul>
<ul>
<li>One</li>
<li>Two</li>
</ul>
<ul>
<li>One</li>
<li>Two</li>
<li>Three</li>
</ul>`;
let browser;
(async () => {
browser = await playwright.firefox.launch();
const page = await browser.newPage();
await page.setContent(html);
const ul = page.locator("ul", {
has: page.locator("li:nth-child(2)"),
hasNot: page.locator("li:nth-child(3)"),
});
console.log(await ul.textContent()); // => One Two
})()
.catch(err => console.error(err))
.finally(() => browser?.close());
See also Can CSS detect the number of children an element has?