I've read that "the css2 contains function is not in css3, however selenium supports the superset of css 1,2 and 3."
Will contains be supported by Selenium Server using webDriver or it only supported when using the Selenium IDE?
I recently came across some more information that may be useful to you. To use contains in css selector. You will have to use :contains pseudo class however this is not properly supported in recent versions of CSS selector engines,upon which WebDriver relies for CSS selector, hence it is not a preferred way these days. To get the same effect of using a contains use
div[name*='part'] in CSS Selector and will match all div tags where id contains 'part'. This is equivalent to using //div[contains(#name,'part')] in XPath selector.
This question has similar discussions as your own.
Check this stackexchange answer for more information.
Related
I am working on selenium python in firefox. I am trying to find element by css selector
element = "span:contains('Control panel')"
my_driver.find_element_by_css_selector(element)
I am getting below error
raise exception_class(message, screen, stacktrace)
selenium.common.exceptions.InvalidSelectorException: Message: Given css selector expression "span:contains('Control panel')" is invalid: InvalidSelectorError: 'span:contains('Control panel')' is not a valid selector: "span:contains('Control panel')"
In selenium IDE I am successfully able to find element by this field but in Python it is not working
The error says it all :
selenium.common.exceptions.InvalidSelectorException: Message: Given css selector expression "span:contains('Control panel')" is invalid: InvalidSelectorError: 'span:contains('Control panel')' is not a valid selector: "span:contains('Control panel')"
As per Issue#987 and Issue#1547:
The :contains pseudo-class isn't in the CSS Spec and is not supported by either Firefox or Chrome (even outside WebDriver).
The pseudo-class was specific to the Sizzle Selector Engine that Selenium 1.0 relied on. But, it was decided that WebDriver was not going to support the Sizzle style CSS selectors that Selenium 1.0 used.
Now, an interesting fact is the :contains pseudo-class will work for browsers that don't natively support CSS selectors (IE7, IE8, etc) which causes
inconsistencies between browsers and selectors.
Hence a better solution would have been to go with any other attribute of the <span> tag as follows :
element = "span[attribute_name=attribute_value]"
Alternate Solution
You can use either of the following xpaths as per the prevailing DOM Tree:
Using text():
element = my_driver.find_element_by_xpath("//span[text()='Control panel']")
Using contains():
element = my_driver.find_element_by_xpath("//span[contains(.,'Control panel')]")
Using normalize-space():
element = my_driver.find_element_by_xpath("//span[normalize-space()='Control panel']")
Using jQuery
You can also use jQuery as follows:
$('span:contains("Control panel")')
Trivia :
A valuable comment from #FlorentB.
CSS selector is not supported by the console either, but JQuery supports it. The $('...') from the console is a shorthand for document.querySelector which is generally overridden with JQuery when the page has it.
Using css_selector to locate element by text is not supported in Selenium (although it will work in the developer tools console). The only possibility is xpath
element = "//span[contains(text(), 'Control panel')]"
my_driver.find_element_by_xpath(element)
Edit: a comment by #FlorentB:
A css selector is not supported by the console either, but JQuery supports it. The $('...') from the console is a shorthand for document.querySelector which is generally overridden with JQuery when the page has it.
How would I go about looking up or comprehensively testing the browser compatibility of a particular CSS selector?
The selector in question has this form:
#idValue.classValue
Which will find an element with id idValue with a class of classValue - so, like this thing:
<div id="idValue" class="classValue">
How compatible is this with the major browsers? How would I research the compatibility of this selector without running all the browsers? Is there a name for this kind of compound selector?
Every browser supports this selector fully. There is no special name for it, although it's interesting to note that it is called a "compound selector", as it's a combination of two simple selectors.
If you flip the selector around, it should work just as well:
.classValue#idValue
See also:
Browser support for the combined type, ID and class selectors?
Combining a Class selector with an ID
As for researching browser support, QuirksMode.org's CSS compatibility table is a good resource, although it doesn't mention every available selector. l–c–n.com has a much more comprehensive table.
I would like to use the following css in my selenium function:
nth-of-type()
is this supported on all browsers and all versions, or do i need to be careful in using it.
If so, what all browsers/versions are supported?
thanks
Quoted from the Sauce Labs blog:
For those of you using or willing to use Selenium 2/Webdriver, you may want to re-consider the special Sizzle pseudoclases like :contains or :nth that I’m talking about in this blog post. For technical reasons, injecting Sizzle in browsers driven by Selenium 2 is not as cheap as with Selenium 1, so the Devs have decided to rely on the browsers’ implementation of CSS (standard CSS only) and fallback to Sizzle when needed (in case of old browsers which don’t provide native css selecting for JavaScript). In Selenium 2 land, my advice, sadly, is to stick to the standard and avoid most of these shortcuts.
So, it is dependent on the browser if you use a recent Selenium version. Use a CSS support overview site to determine it for individual browsers by searching for the locator you're interested in.
I am using CSS selectors as the element locators for selenium test scripts.
Now, I want to check if an element has a rel="nofollow" attribute using CSS.
Does any one know how to check this?
The question isn't 100% clear on what you're trying to do, but I'll try to answer anyway.
If I'm reading you correctly, you're working within the Selenium script language, and you want to determine your the Selenium script that the page contains an <a> element that has rel='nofollow' attribute.
According to the Selenium reference page, this should be possible, as Selenium supports most CSS selectors (the exception except pseudo selectors, but they're not relevant for you here).
It also supports DOM references and XPath references, so one way or the other you should be able to check just about anything.
For CSS, the syntax is css=cssSelector, so in your case this would be css=a[rel=nofollow].
This selector will check the page for any <a> element with the rel=nofollow attribute. If you need to check if a specific element has this attribute, then modify the selector to include the ID or class of the element you want - eg a#myspecificelement[rel=nofollow]
This would be used with a Selenium command such as assertElementPresent() to check that the element is present, or a range of other possible Selenium commands.
Hope that helps.
a[rel="nofollow"]
Won't work in all browsers.
A better solution would be to use jquery who selectors are supported in all browsers
$('a[rel="nofollow"]')
I check this selector:
h3:nth-child(1):contains('a')
selector doesn't work?
I check this in firefinder and does return nothing (not info that there is zero elements)
Then check this:
h3:nth-child(1)
and it returns h3, so selector is almost good, but something with this(h3 has text 'a') text goes wrong.
:contains() is not was going to be a CSS3 selector (thanks T.J. Crowder for the link), but it didn't make it, most likely because the way it works tends to lead to severe performance and over-selection issues. For example, if an element E matches :contains() for a given string argument, then all of its ancestors would also match; using it with a universal selector would lead to unexpected results with certain style properties, on top of being slow for the browser.
There is no other CSS selector that serves a purpose like :contains(). So you'll have to find some other way, either by modifying your HTML or even by using jQuery's :contains(), to achieve the effect you want:
Select an h3 element
if it is the first child of its parent
and its text contains the letter 'a'.
For jQuery and Selenium RC users: :contains() is implemented in the Sizzle selector engine used by jQuery, which is also used in Selenium RC (but not Selenium WebDriver). It works as described in this decade-old revision of the CSS3 spec, but again, due to how the spec describes it, you need to use it with care or it may lead to unexpected selections.
On a final note, h3:nth-child(1) can be replaced with h3:first-child, which as a CSS2 selector has better browser support.
If you're trying to use :contains(a) to find an anchor tag (rather than the letter A), you could use:
h3:nth-child(1) a
or
h3:first-child a
The :contains() pseudo-class isn't in the CSS Spec and is not supported by either Firefox or Chrome.
You can find a couple of detailed discussion in:
selenium.common.exceptions.InvalidSelectorException with "span:contains('string')"
Finding link using text in CSS Selector is not working
Solution
As a solution you have to drop the contains() part and your effective locator will be:
h3:nth-child(1)
Further as #BoltClock mentioned within his answer, you can also use:
h3:first-child
As an alternative, you can also use:
h3:first-of-type
tl; dr
selenium.common.exceptions.InvalidSelectorException with "span:contains('string')"
Finding link using text in CSS Selector is not working