Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Feature] .$ and .$$ for locators? #15044

Closed
mgenware opened this issue Jun 22, 2022 · 4 comments
Closed

[Feature] .$ and .$$ for locators? #15044

mgenware opened this issue Jun 22, 2022 · 4 comments

Comments

@mgenware
Copy link

mgenware commented Jun 22, 2022

I'm migrating a playwright codebase using ElementHandle to locators. I really miss the $ and $$. I found locator code tends to be longer and also requires you to pay a bit more attention not to fall into runtime errors.

Some examples:

// Example 1
// === ElementHandle
element.$(sel).click();
// === Locator
// Might cause runtime error when there're more than 1 matches in strict mode.
element.locator(sel).click();
// Better to select the first child.
element.locator(sel).nth(0).click();

// Example 2
// Let's say there's a bug in your code where you accidentally called `click` on a list of elements.
// === ElementHandle
(await element.$$(listSel)).click(); // Compile error! You can't call click() on an array.
// === Locator
element.locator(listSel).click(); // Compiles fine. If it happens to get a list with only 1 child, it also runs fine.

Would it be possible to add 2 helper functions like .locate$ and .locate$$ for locators? thanks!

@mxschmitt
Copy link
Member

Could you provide us examples how these functions should behave? Its not very clear to me.

Seems a bit related to #12336?

@mgenware
Copy link
Author

These function should behave like $ and $$, or like querySelector and querySelectorAll in standard DOM. Right now the only locator function looks like a mixture of $ and $$.

Seems a bit related to #12336?

Exactly!

Examples:

element.$ForLocator('sel').click();
// Is equivalent to
element.locator('sel').nth(0).click();

element.$$ForLocator('li').click();
// Compile error. No click function found on a list of locators. Use `nth` or `$ForLocator` to select a child.

@mxschmitt
Copy link
Member

We strongly recommend to use Locators and avoid methods which accept an "unpredictable" amount of elements to reduce flakiness. Thats why I think introducing another method which "works fine" when there are more than 1 element on the DOM would be confusing and go into the opposite direction as we want to.

Imagine the scenario, that sometimes there are two elements, and your proposed method would just click the first element on the page. Locators on the other side would throw and the user would directly know that its unexpected instead of clicking on the wrong element.

@mgenware
Copy link
Author

That makes sense. Tho it might introduce some nth(0) boilerplate in some circumstances. Like the one I ran into, where we have nested comments (like reddit), the auto shadow dom piercing feature makes locator calls always end up with a bunch of elements from all its descendants.. we're sure the first matched one is what we need. Therefore, a lot of nth(0) calls were added after locator (previously using $ without issues). Overall, not a big deal.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants