Finding link using text in CSS Selector is not working - selenium

I am trying to locate below link by using a[text='This is a link'] and a[innertext='This is a link'] but both of them are not working.
I know this can be achieved by using XPath or other ways, but I am curious why CSS Selector that I have used is not working. refer this link.
<a title="seleniumframework" href="http://www.seleniumframework.com" target="_blank">This is a link</a>

You are trying to locate a link by using the following CssSelectors:
a[text='This is a link']
a[innertext='This is a link']
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).
You can find a detailed discussion in selenium.common.exceptions.InvalidSelectorException with “span:contains('string')”
Solution
As per the HTML you can use either of the following solutions:
CssSelector using the attribute title:
"a[title='seleniumframework']"
CssSelector using the attribute href:
"a[href='http://www.seleniumframework.com']"
CssSelector using the attributes title and href:
"a[title='seleniumframework'][href='http://www.seleniumframework.com']"

The right CSS Selector for your case is:
a[title="seleniumframework"]
or
a[href="http://www.seleniumframework.com"]
You can also use this one: a[target="_blank"], but the ones above are more unique.
Hope it helps you!

Since you are trying to use attribute selector, you can only select from available attributes that the hyperlink element currently has.
text is not available attribute in html so selecting it this way through css will not work.Rather you should try to use other attribute like a[title=seleniumframework] for example.

Related

How to handle changing of absolute xpath?

Html:
<div class="component-multi-row-slide-title"> Cloth </div>
The xpath
/html/body/div/main/div/div/div[2]/div/div/div/div[1]/div/div***[4]***/div/div[2] the div[4]
keep changing. If new item come into web, developer will change the div number.
I want to click on 'Cloth'. The xpath keep changing when new category is added.
To start with using absolute xpath have certain disadvantages, as when new elements are added the xpath of the previously identified elements will keep on changing. Hence the solution would be to use Relative Xpath.
As per the HTML you have provided, to click on the element with text as Cloth you can use the following Locator Strategy:
XPath A:
//div[#class='component-multi-row-slide-title' and contains(., 'Cloth')]
XPath B:
//div[#class='component-multi-row-slide-title' and normalize-space()='Cloth']
Absolute Xpath: It contains the complete path from the Root Element to the desire element.
Relative Xpath: This is more like starting simply by referencing the element you want and go from the particular location.
You use always the Relative Path for testing of an element. The reason behind that is if you make any architectural change in the website the change won't effect the testing or selecting of the element.
So Use relative xpath which is as follows
WebElement cloth = driver.findElement(By.xpath("//div[normalize-space()='Cloth']"));
cloth.click();
Let me know if this doesn't help
I would recommend to use customized xpath. As given below:
driver.findElement(By.xpath("//div[contains(text(), 'Cloth')]").click
driver.findElement(By.xpath("//div[contains(text(), 'Fashion Acessories')]").click
It will work for sure. Feel free to let me know if something is wrong regarding xpath.
Thanks
You need to use relative xpath in this case.
You can use any xpath from the below options. The first two will find the element by text and the 3rd option by class.
1>>driver.findElement(By.xpath("//div[contains(text(),'Cloth')]")).click();
2>>driver.findElement(By.xpath("//*[contains(text(),'Cloth')]")).click();
3>>driver.findElement(By.xpath("//div[#class='component-multi-row-slide-title']")).click();
Let me know if the same class name exist for other elements also.
Just for you reference: XPath is used to find the location of any element on a webpage using HTML DOM structure.
The disadvantage of the absolute XPath is that if there are any changes made in the path of the element then that XPath gets failed.
So, in that case Relative Xpaths can be used:
//div[contains(text(),'Cloth')] or //*[contains(text(),'Cloth')]
//div[contains(text(),'Fashion Acessories')] or //*[contains(text(),'Fashion
Acessories')]
How to use:
driver.findElement(By.xpath("//div[contains(text(),'Cloth')]"));
You write the following code
driver.findElement(By.xpath("//div[normalize-space()='Cloth']").click
The above code will identify the element directly and also it would not be brittle in nature when developer changes the page elements.

xpath: find element with attribute AND contains?

I am writing selenium tests, and I need to switch to an iframe with no id or name and which parent element contains variable id's (so not helpful. Also, the src attribute has variable data in it as well, so I can't target it directly like By.cssSelector("iframe[src='example']"). I need an xpath selector that targets the src, but also that uses contains. I am trying to learn how to build xpaths outside of Chrome's Copy XPath but I can't figure this one out. Thanks for your help! Here is the iframe html:
<iframe scrolling="auto"
src="/admin/catalog/manage_variants_in_product.jsp?productId=160502"
width="100%" height="100%" frameborder="no"
style="position:absolute; top:0px; left:0px;">
</iframe>
The "contains" CSS selector might help here:
iframe[src*=manage_variants_in_product]
FYI, there are also ^= and $= that mean "starts with" and "ends with" respectively.
The better way I would recommend to learn building xpath or csspath is Firepath add-on of Firefox
First install Firebug in your Firefox browse and then install Firepath.
There you will get the efficient way to get the xpath or evaluate the xpath build by yourself

Get span text using CSS Selector (with xpath this works fine)

So i have this element:
<span class="clas">Create new form</span>
And i want to get this elemen:
span:contains('Create new')
Why this is not working ?
Based on your selector, I assume that you are trying to use the :contains() CSS pseudo-class selector, which has been removed from the CSS3 spec. This won't work because the latest browsers conform to the new CSS standards.
If the class attribute for this specific element is unique, then you can use:
span.clas
If not, then you are forced to use xpath:
//span[contains(text(), 'Create new')]

Locating elements in selenium IDE

I have tried to locate button in my web app using xpath but it changes automatically each time I open selenium IDE. Is there any other way to locate it except using xpath or position? can I locate it using class name? If yes then how can I do it?
You can use xpath to find element by class name.
//*[#class='someClass']
where, someClass is the class name of your element.
Since it is your webapp, consider adding an id or a name to uniquely identify the element. It also makes the xpaths easier to write as you don't need to consider the possibility where you might be grabbing too many elements.
Answer - If by default recorded xpath are not working for your application, then you can define your own xpath for those components which should remain same throughout execution.
Please refer below URL which shows ways to develop userdefined xpath :-
http://docs.seleniumhq.org/docs/appendix_locating_techniques.jsp
Use a CSS selector. This site really helped me: http://saucelabs.com/resources/selenium/css-selectors
if it has an id on it you can just say "id=yourid"
for css it could be something like this: "css=button[class*='yourclass']" <-- that says it's a button, and that in class it contains yourclass.

Selenium how to select an object by class

I have a web page with a form and has a field that uses the jquery autocomplete function.
This is how the HTML renders after a user name returns 1 or more results.
However I cannot figure out how to make Selenium "click" a result.
Can I do a jQuery type of selector.
e.g.
$(".ul.ui-autocomplete li:first a")
Use XPath selector in Selenium:
xpath=//li[contains(#class, 'ui-autocomplete')]/li[1]/a
not checked, might require some corrections.
in response to "Can I do a jQuery type of selector," jQuery uses CSS selectors. Selenium can also use CSS selectors; just prefix the selector with "css=". so:
css=.ul.ui-autocomplete li:first a
Next way to use xpath like this
xpath=/html/body/ul[2]/li[1]/a
Suppose you have a dynamic XPATH then you can point to an element like this
driver.findElement(By.className(""));