Question

Is it possible for Selenium to evaluate all the elements that may match a certain XPath?

For instance, I'd like to evaluate whether all checkboxes are checked with //input[type='checkbox']--problem is I only get one element returned.

Was it helpful?

Solution

You can use the getXpathCount command to determine the number of matching elements. You can then loop through them using an increment to locate each element individually. The following Java (TestNG/JUnit) example would check that all checkboxes on a page are checked:

int totalCheckboxes = session().getXpathCount("//input[@type='checkbox']").intValue();
for (int i = 1; i < totalCheckboxes+1; i++) {
    assertTrue(session().isChecked("//input[@type='checkbox'][" + i + "]"));
}

OTHER TIPS

I tried the above approach and selenium was throwing exceptions that element is not found.Adding prefix xpath= resolved the problem.

example

xpath=(//td[@class='cell name bold'])[1]
xpath=(//td[@class='cell name bold'])[2] 

With

/descendant::input[@type='text'][1]
/descendant::input[@type='text'][2]

you can only search for all input elements in the tree. It won't work if you just want to parse a subtree.

A better way is:

(/form/div/input[@type='text'])[1]
(/form/div/input[@type='text'])[2]

which will return result #1, #2 etc. of the XPath expression within the brackets.

Of course you could also do

(//input[@type='text'])[1]

This is quite handy as Selenium just uses the first match and can't deal with a result set, which is what XPath usually returns.

There's no way selenium could evaluate a list of items returned by a locator. It just grabs the first one and does it's stuff with it.

Dave answer is the best alternative for what you're looking for.

I am trying to do the exact same thing in Selenium and tried using @dave-hunt 's example but it is an incorrect method for finding an individual element in a collection.

Consider the following example:

<form>
 <div>
  <input type="text" name="field1" />
 </div>
 <div>
  <input type="text" name="field2" />
 </div>
</form>

If you use an expression like:

//input[@type='text'][1]

this will return all text inputs in the page. Why? Because each input is the first matching element within its own tree.

However, if you use an expression like:

/descendant::input[@type='text'][1]

or

/descendant::input[@type='text'][2]

the first expression will grab the first input and the second expression will grab the second input. It is very important that you use a single "/" and NOT a double "//".

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top