1

I have a div element that has some text that I can locate like this -

1. page.getByTestId("parent").getByTestId("list").getByTestId("list-content").getByTestId("leaf-item").nth(1).getByTestId("leaf-item-name");

I can locate the same div in below ways as well -

2. page.getByTestId("list").getByTestId("list-content").getByTestId("leaf-item").nth(1).getByTestId("leaf-item-name");

3. page.getByTestId("list-content").getByTestId("leaf-item").nth(1).getByTestId("leaf-item-name");

4. page.getByTestId("leaf-item").nth(1).getByTestId("leaf-item-name");

5. page.getByTestId("leaf-item-name").first();

What I want to know : What is the best way to locate this element.

My line of thought : Even though 1 seems to be long locator but it gives us the sense of where that element is located in the hierarchy and also it will ensure an expected match. For example if there is another div with data-testid="leaf-item-name" in the page, it will not interfere with this locator because it is a very specific drilled down locator and not a loose locator like 5.

Please share your feedback and line of thought keeping in mind these tests are being written for a large application.

utkarsh-k
  • 836
  • 8
  • 17
  • 1
    It's hard to say without seeing full context of the page and what you're trying to test. That said, usually, `nth` is poor practice since the page can easily change and what used to be, say, `nth(1)` now points to the wrong thing. So if you're not iterating the items with a particular test id, maybe you need more specific test ids that don't require nth. Also, test ids are discouraged anyway since they're not user-visible. – ggorlen Aug 23 '23 at 15:47
  • @ggorlen I agree that using nth() can lead to issues if you don't use it the way it should be used. However I don't agree with your point of not using test ids and I don't know where it is mentioned that it is discouraged in playwright. See https://playwright.dev/docs/locators#locate-by-test-id – utkarsh-k Aug 23 '23 at 17:38
  • Maybe it isn't explicitly in the Playwright docs (I can't remember offhand), but Playwright seems heavily influenced by the "user visible behavior" philosophy that was (I think) introduced by the Testing Library ecosystem. See [`byTestId`](https://testing-library.com/docs/queries/bytestid/): "...it is recommended to use this only after the other queries don't work for your use case. Using data-testid attributes do not resemble how your software is used and should be avoided if possible. That said, they are way better than querying based on DOM structure or styling css class names". – ggorlen Aug 23 '23 at 17:42
  • RTL uses the same rough [priority of selection](https://testing-library.com/docs/queries/about#priority) as Playwright. First, queries accessible to everyone (such as visible text or aria role), secondly, semantic queries, lastly, test ids. In any case, all of this is beside the point--my point stands that it's really hard to offer a recommendation without full page context. Selection is an art, not a science that can be objectively determined by glancing at a single element taken in isolation. You can also try Playwright's code generator to make the determination for you automatically. – ggorlen Aug 23 '23 at 17:43
  • https://playwright.dev/docs/locators#locate-by-test-id "Testing by test ids is the most resilient way of testing as even if your text or role of the attribute changes the test will still pass. QA's and developers should define explicit test ids and query them with page.getByTestId(). However testing by test ids is not user facing. If the role or text value is important to you then consider using user facing locators such as role and text locators." – utkarsh-k Aug 23 '23 at 17:47
  • Good to know, but still all beside the point. If you're using test ids, fine if you don't care about user visibility, but the point is that if you want to select a specific one, give it a specific id. Generally, only use multiple ids when you don't care about their order and plan to iterate them as a group. Once you have to resort to `nth()`, there's a potential code smell suggesting your test ids are poorly chosen. But maybe this is a rare time where `nth()` is appropriate for some reason based on the context that isn't shown. Impossible to say. – ggorlen Aug 23 '23 at 18:29
  • @ggorlen agreed. Also in the example in my question I just want the text from the target. It could be first or second and so on. It's a file name that I will use to perform a search in a search box. – utkarsh-k Aug 23 '23 at 18:59
  • If the text is unique, consider `getByText()` or some other display query rather than the test id. Another side point: it's a little unusual to chain test id queries like you have in most options in your original post--if you have to do this, it's another sign that they're not distinct enough. Option 5 looks best and most normal among the ones you showed in your original post. – ggorlen Aug 23 '23 at 19:20
  • @ggorlen yeah thanks for sharing. I now think the testid should be unique to the target element and should not be tangled up inside a chain that doesn't necessarily add any usefulness to the locator in terms of locating it or managing it for a large project especially instead making it looks more complex and difficult to manage. – utkarsh-k Aug 24 '23 at 05:19

0 Answers0