xpath: find element with attribute AND contains? - selenium

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

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.

Finding link using text in CSS Selector is not working

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.

How to click on checkbox on webpage using selenium vba

I have a query,how to click on checkbox on webpage using selenium vba.
Below is the screen shot where i want to click
Below is the html code.
<span name="locSpans[]" value="Nerul" style="display:block">
<input type="checkbox" name="locArr[]" value="8897" onclick="enableDisableLocality(); showSelectedLoc();">Nerul
<br>
<input type="hidden" name="locArrVal[]" disabled="disabled" value="Nerul">
</span>
FindElementByCss is generally faster unless using IE, and then it depends which version of IE and what type of traversal is required.
Repeated tests have proven FindElementByCss to be more performant than FindElementByXPath (Note: that if there is a unique id present then selecting by id is always the first choice!)
In benchmarked tests Chrome and FireFox saw faster matching using CSS consistently across different traversal paths. They are optimized with CSS in mind and using CSS selectors is advocated as selenium best practice. IE was more variable with most instances of XPath being slightly more performant, but there being some clear paths that favoured CSS selection. Long XPath selectors will be costly and prone to breakage. Later versions of IE saw more variability. Opera12 browser came in with mixed results.
I would use a CSS selector:
So, for a simple selection based on likely unique attribute, I would go with an attribute CSS selector of [value='8897'] to target the value attribute. The [] means attribute selector. So value attribute with value of 8897.
driver.FindElementByCss("[value='8897']").Click
If you want to be more selective you can throw in an additional attribute selector, as follows, to target the type attribute.
driver.FindElementByCss("[type=checkbox][value='8897']").Click
When should I use XPath then?
Older IE versions for sure.
Any requirement for walking up the DOM would point to XPath usage.
XPath has some great additional locator strategies for hard to find elements, but that is not necessary AFAIK here. You can see some of the additional considerations here.
You can use xpath below to get checkbox, it means: find input with type="checkbox" and parent SPAN with text "Nerul".
driver.FindElementByXPath("//input[ancestor::span[normalize-space(.)='Nerul'] and #type='checkbox']").Click
Try this if not go for CSS Selector Option
bot.Window.Maximize
bot.FindElementByName("locArrVal").Click
bot.Wait 1000

How to identify button without Xpath in selenium

Code is below
<button type="submit" class="login-button">Login</button>
In selenium I tried below code:-
driver.findElement(By.classname("Login")).click();
please help me in this code without Xpath
Your classname is login-button not Login
driver.findElement(By.classname("login-button")).click();
You can use also partialLinkText
driver.findElement(By.partialLinkText("Login")).click();
partialLinkText is looking the Sub-String on HTML DOM
You can use also linkText
driver.findElement(By.linkText("Login")).click();
LinkText is looking the same String on HTML DOM
Using CSS-Selector
driver.findElement(By.cssSelector("button[class='login-button']")).click();
Hope it will help you :)
I always Prefer Cssselector rather than Xpath, it's up to the user to choose which they want and what they are comfortable with finding element.
The below link will be very useful if you want to know about CSSSELECTOR.
http://www.w3schools.com/cssref/css_selectors.asp
driver.findElement(By.cssSelector(".login-button")).click();
My suggestion would be Please inspect element and open console
$('.login-button')
Try this one until you get the required element you want. In that way you will be more flexible in getting the most required element.

Selenium object identification

I am using Selenium webdriver to test my application & i am facing difficulties in identifiying button on the same. the code snippet is like :
<input type="submit" onclick="return sign(this);" value="Login">
and its xpath is :
html/body/table/tbody/tr[2]/td/center/form/center/table/tbody/tr[3]/td/center/input[1]
Which object property to use and how?
You should not use that XPath.
I would hazard a guess that you used some sort of tool, whether it's Firebug or IDE, to generate that XPath. Stop that now!
XPath is fine to use, and can be used here, just not relying on the tools to generate it for you! That XPath is destined for failure!
You will need to provide more HTML, specifically around that button.
However, you should just be able to use something as simple as:
//input[#value='Login']
You can use the xpath, if that is really stable. I found that it is much easier to define id tags in the html elements and the use a By.id locator. Alternatively you can use css selectors, depending on the "uniqueness" of your button something like this could work:
By.cssSelector("input[value='Login']")