As we already mentioned in our previous posts CSS Selectors in Selenium Demystified and Start improving your locators, CSS as a location strategy generally far outperforms XPATH.
That’s why for this Tip of the Week, we are presenting our users one more CSS pseudo-class to keep moving their test suites to this faster and cleaner location strategy.
Let’s imagine you have an element like the following:
<div>Click here</div>
The easiest way to locate it is using it’s “Click here” inner text and in XPATH you would do it using XPATH’s text() function:
//div[text() = "Click here"]
or even better (because the previous version can sometimes fail depending on the browser):
//div[contains(text(), "Click here")]
Now, if you want to move your locators to CSS in situations like this one, all you have to do is use the :contains() pseudo-class, with which your tests would end up using the following locator:
css=div:contains("Click here")
Did you find this useful? Are you still fighting with another XPATH functionality to completely move your tests to CSS? Let us know about it in the comments.
Related posts:
Selenium Tips: Start improving your locators
Selenium Tips: CSS Selectors in Selenium Demystified
Selenium Tips: Improving your waiting skills
Selenium Tips: Parametrizing Selenese tests

I would like to add one useful tip regarding “:contains()”.
It’s possible to find the _exact_ match using this pseudo-class.
For example, we have the following elements:
abc ab
Locator css=div:contains(“ab”) will find the 1st element.
While the css=div:contains(“^ab$”) will find the 2nd one.
It’s similar to regex syntax.
P.S. Thanks for the great blog, guys.
P.P.S. The parser has eaten my “div” tags, but I hope the point is clear.
Hi Santi,
If i wanted to do a exact text(not like ‘contains’) match with CSS, what could be the locator?
Hi guys, thanks for the very good tips.
I’ve got an intersting XPath which takes an horrible time to run on IE. Is is possible to use a CSS locator instead ?
Here it is:
//input[@id=(//label[text()='Fax']/@for)]
I have no other way to get the good input. I can only use the to differenciate them.
Use the following simplified HTML to get an idea.
ctl01,ctl02,ctl03 are dynamic ids, they change each time the page is refresh so I can’t base my test on that.
——
Courrier
Fax
Courrier en nombre
—
Thx anyways ;)
Dammit HTML is protected:
I’ve pasted the code here: http://pastebin.com/FQ5HYZS4
and here: http://jsbin.com/ogeto3/edit
Hey Jayakumar, great question.
As Alex kindly pointed out, it’s possible to use regular expression (or regex) syntax to specify your matches. For example:
css=div:contains(“example”)
css=div:contains(“^example”)
css=div:contains(“^example$”)
1. Finds any div that has the text “example” anywhere
2. In regex syntax, ^ signifies the beginning of the line. Thus, this will find any div with text that begins with “example”, though anything can follow it.
3. Finally, $ identifies the end of a line. So this version will find any divs with text that contains exactly “example”.
For more information on Regex, check out http://www.regular-expressions.info/.
Hi TiTi.
I don’t know how to convert your xpath to css, but I can suggest you the workaround:
String id = selenium.getAttribute(“css=label:contains(‘^Fax$’)@for”);
selenium.check(“css=input#” + id);
This should work faster than a complex xpath in IE.
Hi TiTi,
Indeed, as Alex pointed out, you can use css=label:contains(^Fax$’)@for.
Thanks again Alex for that great tip to match exact content!
Hi,
Thank you for the tip Alex. I tried it, working on FF but not on IE :-(
>tr<
>td<storeAttribute>/td<
>td<css=label:contains(‘^Fax$’)@for>/td<
>td<plopz>/td<
>/tr<
>tr<
>td<click>/td<
>td<css=input#${plopz}>/td<
>td<>/td<
>/tr<
I also managed to optimise my XPath with the following expression, which is significantly faster:
//td[label/text()='Fax en nombre']/input”
1 second for this one. The other one was taking 12 seconds on my computer ^^
In the good order:
<tr>
<td>storeAttribute</td>
<td>css=label:contains(‘^Fax$’)@for</td>
<td>plopz</td>
</tr>
<tr>
<td>click</td>
<td>css=input#${plopz}</td>
<td></td>
</tr>
HI,
Anyone can tell me how to use the css method to write the deep xpath?
Such as,
@selenium.get_text(“//div[@id='App']/div/div[1]/h4[@class='Online']“)
How to use the css selector to write the above deep xpath?
Thanks!
Hi strawberry, it’s me again :)
Try this one:
“css=div#App > div > div:first-child > h4.Online”
It should work exactly like your xpath.
Thanks for this article!
However, I’m running into an issue and I was wondering if you could help. I have two tables with similar data, but I would like to assert that they are different. I have a table that contains a particular header text:
css=table:contains(User Entered Information)
That assertion passes. Now I would like to assert that the table has a table row that contains the right text:
css=table:contains(User Entered Information) tr:contains(Name):contains(Andrew)
So I would like to use multiple :contains() within an assertion, but it doesn’t seem to be working. What am I doing wrong?
Just wanted to leave an update. I think the problem is with Selenium and trying to select descendants. I was able to get it to work when I specified an ID on the table.
css=#user-entered-information tr:contains(Name):contains(Andrew)
Hi, how can i check, if a link is underlined while the mouse is over it?
My CSS looks like:
a:hover, a:active{
text-decoration: underline;
}
Thanks for your help!
ДВЕ электронные сигареты по цене ОДНОЙ! До 21 апреля!
http://ELCIGAR-SHOP.ru
ДВЕ электронные сигареты по цене ОДНОЙ! До конца апреля!
http://ELCIGAR-SHOP.ru
Успевайте!
ДВЕ электронные сигареты по цене ОДНОЙ! До конца апреля!
http://ELCIGAR-SHOP.ru
Успевайте!
Извините, что я вмешиваюсь, но я предлагаю пойти другим путём.
Пойдет!
I have a problem with :contains. I cannot locate element using Firefinder by td:contains(“group1″). Does Firefinder support css contains selector?
Hi qw,
I forgot to mention that :contains is actually only supported by Selenium one and its CSS engine (Sizzle). You should be able to use Selenium IDE to test your locator, but other CSS finders, like Firefinder may not work. :(
What should be the solution for a bit modified element like the following?
Click variable_string here
where “variable_string” is changeable or not known
css=div:contains(‘^ab$’) doesn’t work with FF7 and IDE 1.3.0
Thanks for the tip! :)
Thank you! I’m totally new to Selenium and I could not work out how to check that text stored in a table was present but changing div to table worked for me.
Hi Guys,
I’m having trouble with selenium locating the element in the page. Below is the css that I’m using. It can be detected in Selenium IDE but in Selenium RC, the object can’t be detected. Any suggestions guys? Thanks!
CSS Locator:
css=td.lbl:contains(“(if ‘Yes’ provide full details in adjacent box)”)
Actual HTML:
(if ‘Yes’ provide full details in adjacent box)