playwright icon indicating copy to clipboard operation
playwright copied to clipboard

[Feature] Ability to use layout selectors ('right-of', 'above', etc) if inner selector is Locator

Open Shaddix opened this issue 3 years ago • 5 comments

I have a Locator instance (DOM element located using page.locator()). I'd like to find the input that is 'near' to my Locator. Seems like currently it's not possible, or at least I haven't found it in docs. What I could use is page.locator('input:near(__repeat_whole_locator_xpath_here__') but it seems inconvenient.

My use case: we use a PageObject pattern, and each PageObject class has a Locator that refers to page area of the object. Let's say one of the smallest PageObjects is a drop-down element using e.g. FluentUI. I create a Locator for the DropDown, click on Locator, and would like to find the list of elements that are opened. Usually this drop-down-list appears somewhere far away in DOM, but close to the object visually, so using 'near' selector makes sense. So, I'd like to find this drop-down-list that is near to my Locator, and I don't see a convenient way to achieve that.

Shaddix avatar Mar 05 '22 05:03 Shaddix

This would make testing patterns like this possible:

const a = page.locator('"My element"')
const b = page.locator('"My other element"')

expect(a.above(b)).toBeVisible()

Could even be neat to have a matcher like this:

const a = page.locator('"My element"')
const b = page.locator('"My other element"')

expect(a).toBeAbove(b)

I'm doing some testing like this to test sorted lists of data. Using the layout selectors are pretty powerful for testing sorting.

mskelton avatar Mar 25 '22 15:03 mskelton

@dgozman Too bad that these selectors were removed with 0e2855348cba314de3484364eb926626ca97fbd2 after adding them with commit 54dd6d01e5cf4847b40ded0663e8c3e6a60cd939. What was the reason for doing so? I definitely have a use case for that - it would be great to get that back.

Camo30 avatar Jul 20 '22 17:07 Camo30

@Camo30 We were not satisfied with the API, so decided to remove for now. We'll probably bring them back in one of the future release. Let me reopen the issue.

dgozman avatar Jul 20 '22 18:07 dgozman

@dgozman Thanks for reopening. In my opinion the api was a great improvement. I'm heavily using the page objects pattern for locators and because of this I often need to get from one locator to the next one without reusing the same selector twice.

For example:

<div class="form-group">
  <input type="text" class="form-control" id="username"></input>
  <div>
    <span class="validation-error"></span>
  </div>
</div>
class LoginPage {
    readonly page: Page;

    constructor(page: Page) {
        this.page = page;
    }

    get userTextBox(): Locator {
        return this.page.locator("id=username");
    }

    get userTextBoxValidationAlert(): Locator {
        // The line below works but here I have to reuse the selector which is error prone
        return this.page.locator('#username + div span.validation-error');

        // It would be great to be able to use it like that
        // return this.userTextBox.locatorBelow("div span.validation-error");
    }

Camo30 avatar Jul 25 '22 08:07 Camo30

Would love to see this. Would allow removing a bunch of hacks.

Faithfinder avatar May 25 '23 18:05 Faithfinder