7

I have a problem with the two same XPath with dynamic ID on the same page. I have tested for selenium in java, when I need to confirm button on delete upload file. Instead of this, test first submits the first button in order on delete whole record.

Both buttons are connected with a modal window so I need to locate the second button instead of the first button on the page. XPath looks like this:

//*[@id="button-with-dialog-modal-confirm-action-button-0XP"]/span
  • You can simply select it by index. i.e for first button (//*[@id="button-with-dialog-modal-confirm-action-button-0XP"]/span)[1] – Helping Hands Dec 29 '17 at 18:24
  • I already used this but it didn´t work because id is always different (0XP-it is dynamic ID even this is not functional By.xpath("//*[starts-with(@id,'button-with-dialog-modal-confirm-action-button--')]/ span)[1]"))); :-( – Hana Puklická Jan 2 '18 at 13:17
  • 1
    I would not spend time designing such complicated (and as you found, fragile) Xpath locators. For more complicated logic, program it in Java. See the debate in comments in sqa.stackexchange.com/questions/27978/… – Peter M. Jan 2 '18 at 16:28
3

XPath is worst (least preferred) way to locate elements. See What makes a good Selenium locator

When I do not have a good unique name/CSS locator, I often get a list, and loop over it (using programming language, not XPath expression) to select the desired element by some other attributes. XPath is flaky, can change after very minor design change.

This allows me to:

  • use more stable locators,
  • avoid spending time to debug complicated XPath expressions (I prefer to debug loops in real programming language, which I already mastered, so it is much quicker to write),
  • select elements in a way hard to express in XPath.
  • As long as you using the ID for element selection, does it make any difference if you are using xpath or css? – Vishal Aggarwal Dec 29 '17 at 23:57
  • Peter, how does the looping over a collection of elements will help in this given situation? – Vishal Aggarwal Dec 30 '17 at 0:01
  • @VishalAggarwal - OP said that ID is dynamic (changes every time). When you use non-unique locator, you will get a list of located elements. – Peter M. Dec 31 '17 at 17:51
  • Peter, OP is trying to click a button whose ID may be dynamic but button label would be unique. – Vishal Aggarwal Dec 31 '17 at 19:44
  • @VishalAggarwal - If label is unique, we are all set of course. But how do you know if button label is unique? And what if label is dynamic too? – Peter M. Jan 1 '18 at 17:13
1

Just simplifying MivaScott answer, Use button Label.

By.xpath("//button[contains(text(),'Confirm')]")
  • I couldn´t use label button, because the first problem is that the title in html is the same for both buttons and another problem is that button which I need hasn´t label on the page( so I coudn´t use something like by linktext or contains text)but it´s contain img some similarly like this google.cz/…: – Hana Puklická Jan 2 '18 at 13:03
0

XPath gets a bad rap as it can be very fragile/brittle; any little change in the UI and it all goes to pot.

However, with the lack of good class names and IDs, XPath can be the only option. As another answer suggests, you can try making a list of all the similar elements and iterate through them until you find the right element. But that seems overkill if you're just talking about two buttons.

I'd go with the text()[contains()] route to identify each.

driver.findElement(By.xpath("//*[@id='dynamic-1']/span/button[text()[contains(.,'Save')]]"));

Do something like this for each (obviously with accurate xpathing).

0

Problem might be that you are using only ID to check the element. This is in most cases the best and ultimate way of finding element. Nonetheless, in your case you are not using the whole ID, so there might be more elements meeting that condition.

In this case you can do one of these:

  • Rely on the text (or some other attribute – for example find bigger element using size) as MivaScott and Vishal Aggarwal suggested.
  • Check parent WebElement from the selected one (using ".." in xpath). This may differ in element you are trying to reach and element that is causing you this trouble.
  • Do not use ID, but rather use identifier of parent element and then select the element you want to use from this element.

I don't understand the "hateful" comments about XPATH. XPATH used in OP's example is not some crazy XPATH (where "hateful" comments would apply), it is just xpath containing ID (In my opinion, using xpath for "contains" or "startswith" when dealing with IDs is in many cases a good thing).

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.