0

/html/body/div/main/div/div/div[2]/div/div/div/div[1]/div/div***[4]***/div/div[2]

The div[4] element keeps changing. If a new item comes into the web, the div number changes.

How do I handle this?

  • 1
    Always prefer Relative XPath and design your own relative XPath using XPath axes.(contains, following, siblings, parent, etc...) – Bharat Mane Oct 31 at 6:50
  • Could you share the HTML starting around "div/div***[4]***/div/div[2]" or maybe a screenshot. This might help us find you a relative path from there. – Niels van Reijmersdal Nov 1 at 11:53
  • 1
    If you try to convince me, that you have no styles/classes there... then you are doomed and the app with its developer as well. I consider this question as incomplete – Dee Nov 17 at 20:22
4

If nothing in the web page is predictable, then you're hosed: you can't find gold in a sea of shifting data unless you have something to hold on to.

If there's some constant factor in the web page that is stable, whether it's the structure, an ID value, or some textual content, then tell us what it is, and we can help you translate that description into XPath.

3

We should always prefer the relative path to avoid these situations, don't use absolute XPath

  • 2
    This would be a much better answer if you were to edit it and explain ways to use a relative path. – Kate Paulk Oct 31 at 11:37
  • can you share your locator element details by inspecting browser ? – Bendi Vasundhara Oct 31 at 12:30
  • That's one way to do it - inspect the element with the browser tools and look for a unique attribute or combination of attributes. – Kate Paulk Oct 31 at 13:18
  • Although I agree, maybe that is not possible in this case. So I do not think this answers the question. – Niels van Reijmersdal Nov 1 at 11:52
2

Don't use absolute xpath at all. Use relative xpath.

It is recommended to use CSS over XPath as it is faster

Web elements could be located using tag, attributes, parent, child, text and lot more. Just see what is the easiest approach and clearest approach.

For instance, the xpath you mentioned doesn't give any idea about the element. The locator we use should be mostly self-descriptive.

One should be able to tell what element the locator is pointing to without the need of rechecking the DOM.

Eg: //button[@id="login"], one can easily say that it's a login button by just seeing the locator.

0

In your particular case as far as I understood your target element is getting shifted in the list after a new item is added before it. If this is the case you can get the access to that element from the end of the list.

For example this element could be always the last one. Then you should use:

/html/body/div/main/div/div/div[2]/div/div/div/div[1]/div/div[last()]/div/div[2]

or if it is always pre-last then

/html/body/div/main/div/div/div[2]/div/div/div/div[1]/div/div[last()-1]/div/div[2]
  • 2
    This is very fragile as it still depends on absolute path. – Vishal Aggarwal Nov 1 at 10:44
  • This is just the OPs case. The concrete issue we're trying to solve. Personally I do not appreciate answers which actually do not answer OPs question but rather give some very generic advice.. By the way I am not quite sure that terminology "absolute"/"relative" is correct for xpath. XPath is all about the relativeness. For example the expression like //div is absolute or relative? In xpath you just push off the previously located node(s) when look up the next one. And this does not really matter if the previous one is the root or not. It is all relative. – wec Nov 1 at 11:34
0

Always write short relative path

which is independent of DOM hirarachy changes as much as possible.

In your particular case how about focusing on just last div unique properties for identification.

Ex: 'div[AnyUniqueProperty="Value"]

0

Some things to try when handling this:

  • Learn how to make better selectors, non-relative selectors are a bad-practise most of the time. Read: What makes a good selenium locator?
  • Sit with the developers and add stuff (e.g. CSS, Id's, etc) that MAKES it testable! Adding code to an application to test it is a GOOD thing! <= prefer this
  • Clean the data before you start your test, so you know how many records to expect
  • Make smart logic to detect the location, by breaking the path in steps
-1

One note: You should consider not only brittle, accessibility and performance is important. Performance will vary depending on the method you use. For example ID is faster than XPath.

This will be important as your tests increase.

  • Performance is not important, I dont see how your answer related or solves to the problem in the question. – Niels van Reijmersdal Nov 1 at 11:47
  • 1
    @Mehmet, Despite performance might be important in general (however this is not the issue OP emphasizes their question) what you're saying is not true. ID is not faster than xpath. At first WebDriver specification (w3.org/TR/webdriver/#locator-strategies) does not imply ID locator so that it is not sort of "native" thing webdrivers are to support. Second thing is that for Java Selenium bindings (not really sure how the things are done in other languages) the sources show that when you locate element by ID it tries to lookup the it by xpath like //*[@id='...'] under the hood. – wec Nov 1 at 12:00
  • Hi, you're both right. I just aimed to provide information only, like suggesting the relative path. And @Wec you are right. "ID it tries to lookup it by xpath like // * [@ id = '...'] under the hood." is true. I gave the wrong example, sorry. When ı said Xpath, ı mean like "//customers[contains(categorie,'sme')]/input" I want to say, as far as I know, selectors which return unique value is the fast.If you have set the true path, xpath or css selector returns unique elements but Selenium has to traverse through the whole path to arrive at the element.(relative or absolute) – MhmtMelek Nov 1 at 13:29

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.