Choose the correct element from the list of objects with the same className - selenium

Quick one, i am trying to avoid using xpath and using css selectors due to performance issues xpath can have so i would like to know the right approach of locating for example "A" in the list
<div class="input-search-suggests" xpath="1">
<div class="input-search-suggests-item">A</div>
<div class="input-search-suggests-item">B</div>
<div class="input-search-suggests-item">C</div>
</div>
Currently i am locating A using xpath / span but it would be indeed sufficient locating all elements and then grabbing A from the list that have same class which is "input-search-suggests-item"
#FindBy(xpath = "//span[contains(text(),'A')]")

CSS_SELECTOR does not have support for direct text what xpath has.
What this means is, for the below xpath
xpath = "//span[contains(text(),'A')]"
based on text A you can not write a css selector.
Instead to locate A using css selector, you can do :
div.input-search-suggests > div.input-search-suggests-item
In Selenium something like this :
#FindBy(cssSelector= "div.input-search-suggests > div.input-search-suggests-item")
Even though it will have 3 matching nodes, but findElement will take the first web element.
Also you may wanna look at nth-child(n)
div.input-search-suggests > nth-child(1)
to make use of index to locate A, B, C
Here is the Reference Link

Related

Protractor Conditional Selector

I am using Selenium Protractor and want to select all elements from the following list except one that contains text "Cat" and then perform some operations on the remaining ones.
<div class="mainDiv">
<div class="childDiv">Dog</div>
<div class="childDiv">Goat</div>
<div class="childDiv">Bird</div>
<div class="childDiv">Cat</div>
<div class="childDiv">Zebra</div>
</div>
Is there a selector by cssContainingText (or some other) in which I can give a condition to select all elements except the one containing text "Cat"?
You can create a List selecting all the elements except one that contains text Cat using the following Locator Strategy:
xpath:
//div[#class='mainDiv']//div[#class='childDiv'][not(contains(.,'Cat'))]
When using Selenium and css-selectors:
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')”
However, if the elements always appears within the DOM Tree in a specific order, e.g. Cat always at the forth child, you can also use:
cssSelector:
div.mainDiv div.childDiv:not(:nth-child(4))
Reference
You can find a couple of relevant discussions in:
While fetching all links,Ignore logout link from the loop and continue navigation in selenium java
How to write a CSS Selector selecting elements NOT having a certain attribute?

Is it okay to use such xpath to find web elements?

Consider this xpath which should always return one element.
//div[#id='MyDiv123']/div[contains(#class, 'super')]
Assume that we won't add anymore divs whose class is super. Given that info, I don't think that it is a good idea to use /div[contains(#class, 'super')]because the xpath will break if div[contains(#class, 'super')] is placed inside another element.
Shouldn't we be using //div[contains(#class, 'super')] instead ?
I don't like using XPaths for locators that can be written as a CSS selector. I think it's much simpler as
#MyDiv123 > div.super
or just
div.super
if it's unique on the page.
XPath contains() is a string match. All the elements below will match your XPath locator but none of them will match the CSS selectors above.
<div class="super-duper" ...>
<div class="superior" ...>
<div class="abcsuperdef" ...>
... you get the idea...
There is no defined Best Practices while writing xpaths. It all boils down to how effective xpath can be written.
I don't see any issue with the xpath as :
//div[#id='MyDiv123']/div[contains(#class, 'super')]
Of-coarse there ca be some improvements as follows :
As an enduser you won't be sure how the class attribute super impacts the HTML or which elements have this attribute. So in that case to identify the WebElement uniquely it would be wise to include the ancestor <div> tag with id as MyDiv123.
But it doesn't looks like the classname super can be dynamic. Hence you can avoid the keyword contains within the xpath and rewrite it as :
//div[#id='MyDiv123']/div[#class='super']

How to get value from an attribute in selenium RC in java?

I have this code for xpath and html:
<a class="WatchButton inicon" rel="nofollow" data-productid="111124">
xpath=/html/body/div[2]/div[2]/div/div[2]/div[1]/div[1]/div[2]/div[8]/a
How can I get the data-productid value?
Just add #data-productid to the xpath expression:
/html/body/div[2]/div[2]/div/div[2]/div[1]/div[1]/div[2]/div[8]/a/#data-productid
Note that the xpath expression you have is very fragile since it depends on a bunch of elements and their relevant positions. Try to rely on the element's attributes or one of it's containers - look for id and class attributes. For example:
//a[contains(#class, "WatchButton")]/#data-productid
This gets the first link anywhere on a page that contains WatchButton class and retrieves it's data-productid attribute value.
* Sharing the link to the web page or showing the complete HTML could help to provide you with a more reliable xpath expression.

how to locate element with selenium webdriver for below html

I have an issue clicking on the below HTML:
<div id="P7d2205a39cb24114b60b80b3c14cc45b_1_26iT0C0x0" style="word-wrap:break-word;white-space:pre-wrap;font-weight:500;" class="Ab73b430b430a49ebb0a0e8a49c8d71af3"><a tabindex="1" style="cursor:pointer;" onclick="var rp=$get('ctl00_ContentPlaceHolder1_ReportViewer1_ctl10_ReportControl');if(rp&&rp.control)rp.control.InvokeReportAction('Toggle','26iT0C0x0');return false;" onkeypress="if(event.keyCode == 13 || event.which == 13){var rp=$get('ctl00_ContentPlaceHolder1_ReportViewer1_ctl10_ReportControl');if(rp&&rp.control)rp.control.InvokeReportAction('Toggle','26iT0C0x0');}return false;"><img border="0" src="/Reserved.ReportViewerWebControl.axd?OpType=Resource&Version=10.0.30319.1&Name=Microsoft.ReportingServices.Rendering.HtmlRenderer.RendererResources.TogglePlus.gif" alt="+"></a> 2013</div>
I have used the below script to click anchor inside a div tag. For the above html code it is not fixed only end part of id example "26iT0C0x0" is fixed. The script that I have used is:
WebElement e1=wait.until(ExpectedConditions.elementToBeClickable(By.xpath("//div[ends-with(#id,'26iT0C0x0')]/a")));
e1.click();
You can use the 'contains' method within an xpath lookup:
driver.findElement(By.xpath("//div[contains(#id,'26iT0C0x0')]")
I would recommend you to consider CSS selector alternative as CSS working faster, than xpath.
So 'contains' in attribute in CSS stands for '*=', for example
if we want to find attribute by 'CSS' ending in this: <htmlTag A="blablaCSS" > we need do the following:
String CSSselector="htmlTag[A*=CSS]";
and you get this element searched.
So considering your example CSS selector be like:
String cssSearched="div[id*=26iT0C0x0] a";
also try to click not on link - a
but on parent div as well:
String cssSearched="div[id*=26iT0C0x0]";
driver.findElement(By.cssSelector(cssSearched));
hope this works for you.
As Mark Rwolands already mentioned: the xpath-Function 'ends-with()' isn't supported in Selenium 2.
Also, if you maybe consider to use chromeDriver in the future, I would recommend clicking the image, not the anchor, see:
https://sites.google.com/a/chromium.org/chromedriver/help/clicking-issues
edit:
Also your IDs are looking generated. I wouldn't count on them for a stable test-environment.

CSS locator for corresponding xpath for selenium

The some part of the html of the webpage which I'm testing looks like this
<div id="twoWideCallouts">
<div class="callout">
<a target="_blank" href="http://facebook.com">Facebook</a>
</div>
<div class="callout last">
<a target="_blank" href="http://youtube.com">Youtube</a>
</div>
I've to check using selenium that when I click on text, the URL opened is the same that is given in href and not error page.
Using Xpath I've written the following command
//i is iterator
selenium.getAttribute("//div[contains(#class, 'callout')]["+i+"]/a/#href")
However, this is very slow and for some of the links doesn't work. By reading many answers and comments on this site I've come to know that CSS loactors are faster and cleaner to maintain so I wrote it again as
css = div:contains(callout)
Firstly, I'm not able to reach to the anchor tag.
Secondly, This page can have any number of div where id = callout. Using xpathcount i can get the count of this, and I'll be iterating on that count and performing the href check. How can something similar be done using CSS locator?
Any help would be appreciated.
EDIT
I can click on the link using the locator css=div.callout a, but when I try to read the href value using String str = "css=div.callout a[href]";
selenium.getAttribute(str);. I get the Error - element not found. Console description is given below.
19:12:33.968 INFO - Command request: getAttribute[css=div.callout a[href], ] on session
19:12:33.993 INFO - Got result: ERROR: Element css=div.callout a[href not found on session
I tried to get the href attribute using xpath like this
"xpath=(//div[contains(#class, 'callout')])["+1+"]/a/#href" and it worked fine.
Please tell me what should be the corresponding CSS locator for this.
It should be -
css = div:contains(callout)
Did you notice ":" instead of "." you used?
For CSSCount this might help -
http://www.eviltester.com/index.php/2010/03/13/a-simple-getcsscount-helper-method-for-use-with-selenium-rc/
#
On a different note, did you see proposal of new selenium site on area 51 - http://area51.stackexchange.com/proposals/4693/selenium.
#
To read the sttribute I used css=div.callout a#href and it worked. The problem was with use of square brackets around attribute name.
For the first part of your question, anchor your identifier on the hyperlink:
css=a[href=http://youtube.com]
For achieving a count of elements in the DOM, based on CSS selectors, here's an excellent article.