Reputation: 1589
I'm trying to select an element given by:
/html/body[@id='someid']/form[@id='formid']/div[@id='someid2']/div[@id='']/div[@id='']/div[@id='']/table/tbody[@id='tableid']/tr[7]/td[2]
Now the html of that row I'm trying to select looks like this:
<tr>
<td class="someClass">some text</td>
<td class="someClass2">my required text for verifying</td>
</tr>
I need to check whether my required text for verifying exists in the page.
I used selenium.isTextPresent("my required text for verifying");
and it doesnt work
So now I tried with selenium.isElementPresent("//td[contains(text(),'my required text for verifying')]")
This works sometimes but occassionally gives random failures.
Tried with selenium.isElementPresent(//*[contains(text(),'my required text for verifying')])
too..
How do I verify this text on the page using selenium?
The problem is not with the page taking time to load. I took screenshots before the failure occurs and found that the page was fully loaded so that shouldnt be the problem.
Could someone please suggest any way to select this element or any way to validate this text on the screen?
Upvotes: 3
Views: 6767
Reputation: 8223
Try locating it by CSS:
assertText(selenium.getText("css=.someClass2"), "my required text for verifying");
The above should give a better failure message than isElementPresent, but you can still use that with CSS locators:
assertTrue(selenium.isElementPresent("css=.someClass2"));
If there is an issue with the load times you could try waiting for the element to be present:
selenium.waitForCondition("var value = selenium.isElementPresent('css=.someClass2'); value == true", "60000");
Some other XPath locators that might work for you, if you prefer not to use CSS locators:
Upvotes: 4
Reputation: 48126
I've never heard of selenium; but your initial XPath is unnecessarily fragile and verbose.
If an element has an id, it's unique; using such a long XPath just to select a particular element is unnecessary; just select the last element with the id. Further, I see that you're occasionally selecting xyz[@id='']
- if you're trying to select elements without id attributes, you can do `xyz[not(@id)] instead.
Assuming your initial XPath is basically correct, it would suffice to do something like this:
//tbody[@id='tableid']/tr[7]/td[2]
However, using a specific row and column number like that is asking for trouble if ever anyhow changes details of the html. Also, it's atypical to have id's on tbody
elements, perhaps the table
element has the id?
Finally, you may be running into space-normalization issues. In xml, multiple consecutive spaces are often considered equivalent to a single space, and you're not accounting for that. In particular, if the xhtml is pretty-printed and contains a line-break in the middle of your sought-after text, it won't work.
//td[contains(normalize-space(text()),'my required text for verifying')]
Finally, text()
explicitly selects
child text nodes - so the above xpath won't select elements where the text isn't the immediate child of td (e.g. <td><b>my required text for verifying</b></td>
) won't match. Perhaps you mean to look up the concatenated text vale of all descendents:
//td[contains(normalize-space(string(.)),'my required text for verifying')]
Finally, type conversion can be implicit in XPath, so string(.)
can be replaced by .
in the above, leading to the version:
//td[contains(normalize-space(.),'my required text for verifying')]
This may be slow on large documents since it needs to normalize the spaces and perform a string search for each td
element. If you run into perf problems, try to be more specific about which td
elements need to be inspected, or, if you don't care where the text occurs, try to reduce the number of "calls" to normalize-space by normalizing the entire doc in one go (e.g. via /*[contains(normalize-space(.),'my required text for verifying')]
).
Upvotes: 1