Selenium webdriver: finding all elements with similar id
Solution 1
As a rule of thumb, try to select more elements by one query, if possible. Searching for many elements one-by-one will get seriously slow.
If I understand your needs well, a good way to do this would be using
driver.findElement(By.id("someId::button")).click();
driver.findElement(By.xpath("//*[contains(@id, 'someId--popup::popupItem') " +
"and text()='" + myDesiredValue + "']"))
.click();
For more information about XPath, see the spec. It's surprisingly a very good read if you can skip the crap!
That finds and clicks an element with text equal to you desired value which contains "someId--popup::popupItem" in its ID.
List<WebElement> list = driver.findElements(By.xpath("//*[contains(@id, 'someId--popup::popupItem')]"));
That finds all just all elements that contain "someId--popup::popupItem" in their ID. You can then traverse the list and look for your desired element.
Did you know you can call findElement()
on a WebElement
to search just it's children?
- driver.findElement(By.id("someId")).findElements(By.className("clickable"))
Without a peek on the underlying HTML, I guess I can't offer the best approach, but I have some in my head.
Solution 2
Have you tried using JavascriptExecutor?
If you are willing to write a little JavaScript then this would be straightforward than in java (I think)
All you will need to do is have some JavaScript crawl through the DOM subtree, and return a list of DOM elements matching your criteria. WebDriver will then happily marshall this as List<WebElement>
in the java world.
Solution 3
The Safer Method to use here is
int size=driver.findElements(By.xpath("//*[@id='someId::button']")).size();
Start using Index Now
String builtString="//*[@id='someId::button'][";
for(int index=1;index<=size();index++)
{
try
{
WebElement aux= driver.findElement(By.xpath(builtString+index+"\"]"));
if(aux.getText().equals(myDesiredValue))
aux.click();
}
catch(Exception e){}
}
Please Let me know is the above funda is working or not.
![CosminO](https://i.stack.imgur.com/awvUS.jpg?s=256&g=1)
Comments
-
CosminO almost 2 years
I have this xpath:
//*[@id="someId::button"]
Pressing it shows a dropdown list of values.
Now, I know all the elements in the list have an id like this :
//*[@id="someId--popup::popupItemINDEX"]
, where INDEX is a number from 1 to whatever the number of options are.
I also know the value which I must click.
One question would be: since I will always know the id of the button which generates the dropdown, can I get all the elements in the dropdown with a reusable method? (I need to interact with more than one dropdown)
The way I thought about it is: get the root of the initial ID, as in:
//*[@id="someId
then add the rest :
--popup::popupItem
. I also need to add the index and I thought I could use a try block (in order to get though the exceptions when I give a bigger than expected index) like this:for(int index=1;index<someBiggerThanExpectedNumber;index++){ try{ WebElement aux= driver.findElement(By.xpath(builtString+index+"\"]")); if(aux.getText().equals(myDesiredValue)) aux.click(); }catch(Exception e){} }
Note that I am using the webdriver api and java.
I would like to know if this would work and if there is an easier way of doing this, given the initial information I have.
EDIT: The way I suggested works, but for an easier solution, the accepted answer should be seen