playwright
playwright copied to clipboard
[BUG] Presence of >> selector corrupts independent evaluation of other selectors in list
Context:
- Playwright Version: 1.24.2
- Operating System: Mac
- Node.js version: 18.5
- Browser: All
- Extra: N/A
Describe the bug
I'm using the >>
selector in a broader statement made up of multiple selectors that is passed to a PlaywrightPage.locator
, specifically, this:
fieldset:has-text('URL') >> input, button:has-text('Link Your Project')
Each of these independently (fieldset:has-text('URL') >> input
and button:has-text('Link Your Project')
) matches elements on the page, but when combined together, only the elements matching fieldset:has-text('URL') >> input
are selected. This leads me to believe that the >>
operator is corrupting the whole statement; Just like with CSS selectors, I'd expect the ,
to separate the individual statements so they can be evaluated independently, and their results combined.
Is there something I am misunderstanding about the >>
operator, or is this a bug?
The below test passes for me. Can you share a self-contained example like I have below that illustrates the issue you are facing? I want to make sure we're debugging and solving the same issue. Thanks!
import { test, expect, Page } from '@playwright/test';
test('should work', async ({ page }) => {
await page.setContent(`
<form>
<fieldset>
<label for="url">URL</label><br/>
<input type="text" id="url" name="url">
</fieldset>
<button>Link Your Project</button>
</form>
`);
expect(page.locator("fieldset:has-text('URL') >> input")).toBeVisible();
expect(page.locator("button:has-text('Link Your Project')")).toBeVisible();
expect(page.locator("fieldset:has-text('URL') >> input, button:has-text('Link Your Project')')")).toHaveCount(2);
});
hey @rwoll, I can repro what @Boeing787 is saying
the code
from lib.test_base import TestBase
issue_url = "https://github.com/microsoft/playwright/issues/17429"
url = "https://the-internet.herokuapp.com/"
TestBase.get_page().goto(url)
loc1 = TestBase.get_page().locator("xpath=//ul")
list1 = loc1.locator("a:has-text('Dropdown'), a:has-text('Checkboxes')")
list2 = loc1.locator("a:has-text('Dropdown') >> visible=true, a:has-text('Checkboxes') >> visible=true")
list3 = loc1.locator("a:has-text('Dropdown') >> visible=true, a:has-text('Checkboxes')")
print("Not using the >> operator, the count is : ", list1.count())
print("while using the >> operator, the count is : ", list2.count())
print("partially using the >> operator, the count is : ", list3.count())
@GunjanSheth Thanks for your example! Looks like I forgot the await
s in my JS example leading me to the wrong conclusion. 🤦
Let me touch base with the team to sort out expected precedence of these operators so we can clarify in the docs as needed or apply fixes depending on the conclusion.
I reviewed the following with @dgozman. It is working as expected and the last statement will fail:
import { test, expect } from '@playwright/test';
test('should work', async ({ page }) => {
await page.setContent(`
<form>
<fieldset>
<label for="url">URL</label><br/>
<input type="text" id="url" name="url">
</fieldset>
<button>Link Your Project</button>
</form>
`);
await expect(page.locator("fieldset:has-text('URL') >> input")).toBeVisible();
await expect(page.locator("button:has-text('Link Your Project')")).toBeVisible();
await expect(page.locator("fieldset:has-text('URL') >> input, button:has-text('Link Your Project')")).toHaveCount(2);
});
In this particular case, it can simply be fixed by dropping the use of >>
:
await expect(page.locator("fieldset:has-text('URL') input, button:has-text('Link Your Project')")).toHaveCount(2);
There's currently not a great way of expressing OR
semantics when using the Playwright chaining (>>
) locator.
@Boeing787 Let me know if fieldset:has-text('URL') input, button:has-text('Link Your Project')
works for your use case! If not, we'll convert this issue into a feature request for OR
semantics with >>
(through some yet-to-be determined API). (We've put some thought into the topic in the past, but have not introduced a solution yet.)
Thanks!
There's currently not a great way of expressing OR semantics when using the Playwright chaining (>>) locator.
thanks @rwoll for looking into this and thanks @Boeing787 for bringing this out. Atleast for now we have a work around for the selector, but i guess we wont have the workaround while using >> visible=true, straightaway
also please add OR semantics for getByTestId
for example with locator works perfectly.
await page.locator('[data-testid=selector1], [data-testid=selector2').waitFor();
but with getByTestId
await page.getByTestId('selector1, selector2').waitFor();
result is following:
waiting for selector "internal:attr=[data-testid=selector1, selector2"]" to be visible
This will be possible to achieve in the next version with Locator.or()
, implemented in #21884.