1

I am trying to count the number of times a element with a partial text of "25516.B1-" appears on the page.

Right now I am trying this. However it returns 17 even though there are only 3 instances of the element on the page.

Count 3 basiskerntaken
${count}=  Get Element Count   //*[contains(.,"25516.B1-")]
Log To Console  ${count}
kjhughes
  • 106,133
  • 27
  • 181
  • 240
Mwiendels
  • 47
  • 5
  • this doesn't seem like python at all, is it? – Mahrkeenerh Nov 12 '21 at 15:28
  • `//*[contains(.,"25516.B1-")]` includes child nodes. Try `//*[contains(text(),"25516.B1-")]` – Trapli Nov 12 '21 at 15:34
  • @Trapli: Closer, but see [Why is XPath contains(text(),'substring') not working as expected?](https://stackoverflow.com/q/69909751/290085) for a problem with that approach and [my answer below](https://stackoverflow.com/a/69945660/290085) for a better way to count substrings within text nodes. – kjhughes Nov 12 '21 at 16:28
  • @kjhughes your answer will not work with python + selenium, since the selenium insists to return webelements only, it won't return text nodes (https://stackoverflow.com/questions/20375096). It might work if the xml/html source is an lxml tree or something, which is not _that picky_ – Trapli Nov 12 '21 at 19:57
  • 1
    @Trapli: Selenium is a handicapped host of XPath if it has such a limitation. Alright, well, I've updated my answer for a workaround for XPath hosts that can only evaluate XPaths that return elements. Thanks for the information. – kjhughes Nov 12 '21 at 23:05

4 Answers4

3

I will use generic XPath and XML for the benefit of future readers, but the concepts are the same and can be applied to any framework that uses XPath, including . See addendum regarding selenium's limitations, however.

Counting the number of elements whose string value contains a substring,

count(//*[contains(.,"substring")])

will overcount the number of occurrences of the "substring" due to the nesting of elements. For example, both e and r have string values that contain "substring":

<r>
  <e>substring</e>
</r>

Instead, count the number of text nodes that contain the substring:

count(//text()[contains(.,"substring")])

There is only one such text node in the above example.

Note that this assumes that text is not partitioned across child elements:

<r>
  <e><b>subs</b>tring</e>
</r>

See also


Selenium-specific Addendum

@Trapli reports that "selenium insists to return webelements only, it won't return text nodes", here's a work-around that will return elements that selenium can then count:

//*[text()[contains(.,"substring")]]

This returns all elements that have a text node child that contains the provided "substring". It is unfortunate that selenium is limited in how it hosts XPath — most hosts are not so restrictive.

kjhughes
  • 106,133
  • 27
  • 181
  • 240
0

If you know you have elements with that partial text, I would say using FindElements method to find all occurences of that method, it returns a list of elements , you can simply call List.count ();

List<WebElement> elementName = driver.findElements(By.LocatorStrategy("LocatorValue"));

elementname.count is your answer.

undetected Selenium
  • 183,867
  • 41
  • 278
  • 352
  • Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – jahantaila Nov 12 '21 at 16:05
0

I fixed it by doing the following

${count}=  Get Element Count     //td[contains(text(),'25516.B1-')]
Should Be Equal As Integers     ${count}    3

This returns 3 elements and passed the test.

Thanks for all the answers!

Mwiendels
  • 47
  • 5
-1

Update the generic xpath to a bit more specific xpath as follows:

${count}=  Get Element Count   //tag_name[contains(.,"25516.B1-")]

More canonically:

${count}=  Get Element Count   //tag_name[contains(.,"25516") and contains(.,"B1-")]
undetected Selenium
  • 183,867
  • 41
  • 278
  • 352
  • This is good if `tag_name` is known (+1). When unknown, see [my answer](https://stackoverflow.com/a/69945660/290085) for an explanation of why OP's XPath was overcounting and how to correct the problem. – kjhughes Nov 12 '21 at 16:04