Selenium webdriver: finding all elements with similar id

54,852

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.

Share:
54,852
CosminO
Author by

CosminO

JS/C#/Java/Python automation.

Updated on July 19, 2022

Comments

  • CosminO
    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