5

According to A way to match on text using CSS locators, we should be able to use "^$" to find exact text match using CSS locators.

But with:

<div class="item"><div class="text">Trouble</div> 

the following two (xpath and css without "^$") can find the element:

css=div.item > div.text:contains("Trouble")
//div[@class='item']/div[@class='text' and text() ="Trouble"]

However this one (with "^$") can not: css=div.item > div.text:contains("^Trouble$")

Did I miss anything?

2 Answers 2

3

From typesetting standpoint, the following 3 cases are absolutely equal:

<div>123</div>

<div>
123</div>

<div>
123
</div>

while from the DOM standpoint, there are differences. The inner text from the first div is "123", for the second one it's "\n123" and the third one is "\n123\n" (\n stands for newline escape sequence). I have no idea which of these is yours, but in either case, you should try to handle all of them.

The regular expression you use is only fine with the first one, while it won't match both the second and the third ones. The solution is, to handle white spaces in the beginning and in the end of your string.

Consider using ^\s*Trouble\s*$ instead of ^Trouble$, to handle these cases:

css=div.item > div.text:contains("^\s*Trouble\s*$")
3
  • As in my original question, Firebug does not shows there is any space around Trouble. <br> It does not work and even css=div.item > div.text:contains("\sTrouble\s") does not work either. <br> So I would suspect if css can work together with regexp.
    – Cunzhi
    Commented Aug 24, 2011 at 19:51
  • @Cunzhi: you should probably provide a minimal html code that allows reproducing the behavior you describe. Commented Aug 24, 2011 at 19:54
  • I made it very clear that there is no space around Trouble. If regexp works with css, the simplified "\sTrouble\s" should match. Try this simple HTML code: <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "w3.org/TR/html4/strict.dtd" > <html lang="en"> <head> <title><!-- Insert your title here --></title> </head> <body> <div class="item"> <div class="text">Trouble</div></div> </body> </html> With Selenium IDE and see the difference: click | css=div.item > div.text:contains("Trouble") click | css=div.item > div.text:contains("\s*Trouble")
    – Cunzhi
    Commented Aug 24, 2011 at 21:03
1

Basically you can't in pure CSS. If you don't believe me check the spec below:

http://www.w3.org/TR/selectors/

You can however using sizzle.

Unfortunately, Selenium doesn't have a By.sizzle locator class, it does however fall back to sizzle in some cases if a browser doesn't support CSS3 (Just to make things complicated) so it may appear that sizzle commands work sometimes in some browsers.

For an exact text match in a locator your easiest option would be to switch to XPath:

//div[contains(@class, 'item']/div[.='Trouble'] 

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.