4

There is a type and search drodown which will appear after user type in the value. I need to click on the dropdown which contains the name of the drop down field.

The problem here is that there is no unique attribute present (No unique class, no unique name) & the id keeps on changing after every login so cannot take id also.enter image description here

  • class:x-boundlist-item , Does it contains list? – Helping Hands Nov 30 '15 at 4:56
  • @HelpingHands It doen't contain list and that is the issue – Som Ghosh Nov 30 '15 at 6:40
  • if it does not contain list then how you can find by selenium? that is development issue – Helping Hands Nov 30 '15 at 6:41
  • Have a look into the structure [1]: prntscr.com/98kv6l Is there anyway I can click on the names of the field ? – Som Ghosh Nov 30 '15 at 6:43
  • I see , it seems all are div in sequence , Did you try to find it using xpath? – Helping Hands Nov 30 '15 at 6:44
5

there is no unique attribute present (No unique class, no unique name) & the id keeps on changing after every login so cannot take id also.

This is a very common issue with many applications that are used on the web.

There are 4 general approaches to fix this:

  • Look for other existing css identifiers such as id, class and name used on other elements in the DOM hierarchy of the element, for example form#new_user may be unique and then form#new_user input.top might be unique even when input.top on its own is not unique and is in other forms on the page.
  • Look for data- attributes that you can use to identify the element
  • If working with the developers, ask them to add unique css identifiers such as id, class, name or data attribute to the element or elements in the hierarchy that can be used, in combination, to uniquely identify the element.
  • Use the full xpath of where the element is but be aware that this may break with future changes in the page structure
  • Why not generalize the 2nd point, look for any attributes that you can use to identify the element? – Adelin Jan 30 '18 at 9:17
  • point 1 covers this. point 2 is about data attributes – Michael Durrant Jan 30 '18 at 11:53
  • I thought point 1 is about heriarchy and uniqueness of parent elements – Adelin Jan 30 '18 at 11:56
  • Excellent points, I would add: use regular expression would help locate dynamic id as well. I just realized this is a very old question. :-D – Yu Zhang Jan 30 '18 at 19:40
4
+25

There are multiple ways to handle this problem, as others have said. The most important thing to remember is that implementation time is important - if a potential solution will take you several days to build and be fragile, where a solution involving programmers takes a few hours from you and a few hours from the programmers and will then be extremely stable, the solution with programmers is the best option.

I'm going to list the main options in the approximate order I prefer to use them:

  1. Work with developers to get every element you interact with a unique identifier - It doesn't matter if the identifier is ID (although that is best because it's fastest with Selenium), but if each element you need has a known attribute that will have a unique value, it will save you an immense amount of time and be more stable than using other methods.
  2. Find by some aspect of the element that is unique - If the element has an attribute or inner text that is unique on the page, you can located by this attribute or inner text. This is more fragile than a designated ID field because whatever makes the part of the element unique may be something that is edited often. For instance, if an element is the only <select> on the page, you can find by tag name - but if another <select> is added to the page, your scripts will have to be edited.
  3. Use DOM traversal from a unique element to your target - This method will break if the page structure changes, but you can do things like finding a sibling element with some unique factor like in point 2, then navigating to the parent element and doing a find using something unique to the target element within the parent. For a simplistic example, in the fake html snip below, if there was only a single submit element on the page and the labels on the forms weren't unique, and your target was the field2 input, you could find your target by first finding the submit field, then navigating to submit.parent(), and finally finding the input element in the paragraph tag where text.contains("field2")
<form target="someurl.html">
    <p>field1 <input type="text" /></p>
    <p>field2 <input type="text" /></p>
    <input type="submit" />
</form>
  1. Use Javascript DOM traversal - In some ways Javascript DOM traversal is easier than Selenium DOM traversal, in that you have more navigation methods to work with, but the coding to call this is more complex than just staying with the base Selenium methods. The principle is similar to method 3.
  2. Xpaths with page structure - This is the absolute last resort, simply because page structure can change a lot, and this method will create a maintenance nightmare, especially if your page is being dynamically altered as you interact with it. If you find that this is the only method you can use, I'd recommend you use estimated maintenance cost as an argument to convince your manager to try method 1 instead. You may have to suffer with this method for a while before you have the evidence to push method 1.
1

Try this and let me know If it works

driver.findElement(By.xpath("//*[@class='x-boundlist-item']/parent::div")).click();

//Wait until Element is visible

driver.findElement(By.xpath("//*[@class='x-boundlist-item']")).click()

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.