XPath of an element in HTML code - java

I am trying to click on 'Select' button embedded in following HTML code using selenium webdriver-java. For this I am trying to write XPath for the 'select' button.
<div class="product eq-height" style="padding-bottom: 0px ! important; min-height: 329px;">
<h3 class="h4">BYOX Samsung S6 White</h3>
<input name="productModel" value="BYOX Samsung S6 White" type="hidden">
<div class="subtitle">
<span>Samsung</span>
</div>
<a class="select-device-button" href="javascript:void(0);">
<div class="item">
<img alt="" class="prod-img-lrg lazyloaded" data-src="https://vgeco-oat1.vodafone.com/images/Samsung_Galaxy_S6_White.jpg" src="https://vgeco-oat1.vodafone.com/images/Samsung_Galaxy_S6_White.jpg"> <noscript><img alt="" src="https://vgeco-oat1.vodafone.com/images/Samsung_Galaxy_S6_White.jpg"></noscript>
</div>
</a>
<div class="info">
<div class="inner">
<ul class="cost">
<li><b>Total cost</b></li>
<li class="price">£ 700.00</li>
</ul>
<ul class="cost">
<li><b>My cost</b></li>
<li class="price">£ 200.00</li>
</ul>
</div>
<div class="cta">
<a class="btn btn-sml select-device-button" href="javascript:void(0);">Select</a>
</div>
</div>
<div class="co-link-wrap txt-center"></div>
</div>
what would be the xpath to fetch the Select button in above code. the field: BYOX Samsung S6 White can be different in every piece of code. so i need a generic code to fetch the select element. I am trying to select the button based on the string: BYOX Samsung S6 White and there are a number of different product available on the webpage with associated Select button.

There is a simple locator that fits this use case perfectly:
driver.findElement(By.linkText("Select")).click();
Note that instead of driver in this case, there can be a WebElement used, for example, imagine you've already found a product and want to "select" it:
WebElement product = driver.findElement(By.cssSelector("div.product"));
product.findElement(By.linkText("Select")).click();
I need to click the 'Select' button only if the product name is BYOX Samsung S6 White in above div class. how can i do this ?
Sure:
WebElement product = driver.findElement(By.xpath("//div[contains(#class, 'product') and h3 = 'BYOX Samsung S6 White']"));
product.findElement(By.linkText("Select")).click();

There are two select elements (one is the big image the other the Select-link)
Do you mean the second element?
Xpath:
//div[#class='cta']/a[#class]
Css:
div.cta a.select-device-button
(similar but more efficient in Selenium and in my opinion easier to declare)
If you wanted the first element in both cases just leave out the declaration for the div element.
In Firefox you can easily try out locators and it is always a bit depending how strict or flexible you want to keep them.
To the edited point:
You might check independently for the value of the hidden input field (it seems here is no parsing necessary) and is not dependent on the localisation. Alternatively check the header element or the image reference.

You don't have to use xpath. Simpler way will be using other locators. You can use
className
WebElement button = driver.findElement(By.className("btn"));
WebElement button = driver.findElement(By.className("btn-sml"));
WebElement button = driver.findElement(By.className("select-device-button"));
linkdText
WebElement button = driver.findElement(By.linkText("Select"));
cssSelector
WebElement button = driver.findElement(By.cssSelector(".btn.btn-sml.select-device-button"));
Each one of those can give you the button element.

Related

Selenium (Java) message "Unable to locate element" but element and XPath exist

I am new to Selenium WebDriver, using NetBeans Java and Firebug for Firefox to get XPath.
The problem is even though some elements are visible and clickable in the browser, and Firebug finds the XPath expression, I still get an error "Unable to locate element". The problem is, the element is not in a frame (there aren’t any frames), not in another window, it's visible and clickable and it has a clear XPath expression.
I used Wait and Thread.sleep, but it didn't help.
Also, I tried all solutions I could find on Stack Overflow similar to this matter.
The element is inside of the table which has some "div" elements inside. This is the XPath expression:
.//*[#id='NavigationRadPanelBar_i2_i0_trvStandardView']/ul/li[3]/div/span[3]
It seems that the panel is a problem, because it can not locate the panel too. I tried another element inside the same panel which has a title and text with this:
driver.findElement(By.xpath("//*[contains(text(),'Technical Attributes')]")).click();
But still I got same message. Similar for all elements inside this panel and panel itself. It seems whatever I tried, it's unable to locate. Everything outside of this panel is working fine with drivers.
The page has a left panel where these elements are located. Some of them are nodes that can be expanded, and some are just links, but nothing can be located.
What can be the cause of element that is obviously existing and visible, but still cannot be located by WebDriver?
I tried to locate the main panel:
driver.findElement(By.xpath(".//*[#id='NavigationRadPane']")).click();
but still the same exception.
This is part of the HTML content (it's very long):
<div id="RAD_SLIDING_PANE_CONTENT_navigatiionRadSlidingPane" class="rspSlideContent" style="overflow: hidden; width: 200px; height: 579px;">
<div id="NavigationRadPanelBarPanel" style="display: block;">
<div id="NavigationRadPanelBar" class="RadPanelBar RadPanelBar_Office2007" postback="false" style="background-color:GhostWhite;height:100%;width:100%;">
<ul class="rpRootGroup">
<li class="rpItem rpFirst">
<li class="rpItem">
<li class="rpItem rpLast">
<a class="rpLink rpExpandable rpExpanded" href="#">
<div class="rpSlide" style="display:block;">
<ul class="rpGroup rpLevel1 111460" style="display: block; height: 274.731px; width: 100%;">
<li class="rpItem rpFirst rpLast">
<div class="rpTemplate">
<div id="NavigationRadPanelBar_i2_i0_trvStandardView" class="RadTreeView RadTreeView_Office2007">
<ul class="rtUL rtLines">
<li class="rtLI rtFirst">
<li class="rtLI">
<li class="rtLI">
<div class="rtMid">
<span class="rtSp" />
<span class="rtPlus rtPlusHover" />
<img class="rtImg" src="..." alt="Technical Attributes" />
<span class="rtIn" title="Technical Attributes">Technical Attributes</span>
</div>
<ul class="rtUL" style="display:none;">
</li>
<li class="rtLI rtLast">
Use:
driver.switchTo().activeElement();
This way, the driver will switch to the panel you have clicked. Then you can perform the rest of the operations you want in the panel.
Here is the answer to your question:
The error says it all, Unable to locate element, because the XPath expression seems incorrect to me.
If you want to click on the element with title set to Technical Attributes you can consider to try with the following XPath expressions:
//div[#id='NavigationRadPanelBar_i2_i0_trvStandardView']/ul/li/li/li/div/span[#class='rtIn']
or
//div[#id='NavigationRadPanelBar_i2_i0_trvStandardView']/ul/li/li/li/div/span[#title='Technical Attributes']

Unable to click on an element using Selenium

<div id="_PHYLINSPortlet_WAR_PHYLINSPortlet_INSTANCE_o3P5_:form_PolicyContent_UI2:flatQuoteMenuBar:j_id7:VEHICLES" class="iceMnuBarItem portlet-menu-cascade-item">
<a class="iceLink" href="javascript:;" onclick="return Ice.Menu.cancelEvent(event);">
<span class="iceMnuBarItemLabel">Vehicles (1)</span>
</a>
</div>
I have to click on vehicles (1) menu
I tried lots of xpath selectors. gettext() is working but .click is not.
//driver.findElement(By.xpath("//*[#id='_PHYLINSPortlet_WAR_PHYLINSPortlet_INSTANCE_o3P5_:form_PolicyContent_UI2:flatQuoteMenuBar:j_id7:VEHICLES']/a/span")).click();
my 2nd xpath:
//driver.findElement(By.xpath("//span[(#class='iceMnuBarItemLabel') and contains (text(),'Vehicles')]")).click();
I guess issue is inside your html due to javascript was not defined properly.
Your html code see the below line of code.
<a class="iceLink" href="javascript:;" onclick="return Ice.Menu.cancelEvent(event);">
After modified your html see the below line of code.
<a class="iceLink" href="#" onclick="return Ice.Menu.cancelEvent(event);">
Now try to click on webelement using anyone of these below method.
Try this way to click vehicle element.
driver.findElement(By.xpath("//a/span[contains(text(), 'Vehicles (1)')]")).click();
OR
Click Vehicle element using Java-script executor.
WebElement vehicle = driver.findElement(By.xpath("//a/span[contains(text(), 'Vehicles (1)')]"));
((JavascriptExecutor) driver).executeScript("arguments[0].click();", vehicle);

differentiate two html elements with same class

I have this html code below and I want to differentiate between these two PagePostsSectionPagelet as I only want to find web elements from the first PagePostsSectionPagelet. Is there any way I can do it without using <div id="PagePostsSectionPagelet-183102686112-0" as the value will not always be the same?
<div id="PagePostsSectionPagelet-183102686112-0" data-referrer="PagePostsSectionPagelet-183102686112-0">
<div class="_1k4h _5ay5">
<div class="_5sem">
</div>
</div>
<div id="PagePostsSectionPagelet-183102686112-1" class="" data-referrer="PagePostsSectionPagelet-183102686112-1" style="">
<div class="_1k4h _5ay5">
<div class="_5dro _5drq">
<div class="clearfix">
<span class="_5em9 lfloat _ohe _50f4 _50f7">Earlier in 2015</span>
<div id="u_jsonp_3_4e" class="_6a uiPopover rfloat _ohf">
</div>
</div>
<div id="u_jsonp_3_4j" class="_5sem">
<div id="u_jsonp_3_4g" class="_5t6j">
<div class="_1k4h _5ay5">
<div class="_5sem">
</div>
</div>
Tried using //div[#class='_1k4h _5ay5']//div[#class ='_5sem'] but it will return both.
Using //div[#class='_5dro _5drq']//span[contains(#class,'_5em9 lfloat _ohe _50f4 _50f7') and contains(text(), '')] will help me find the second PagePostsSectionPagelet instead.
you need to use the following xpath:
//div[contains(#class,'_1k4h') and contains(#class,'_5ay5')]
as selenium doesn't work properly with search of several classes in one attribute.
I mean By.Class("_1k4h _5ay5") will found nothing in any case and By.Xpath("//div[#class='_1k4h _5ay5']") can also found nothing in case of class will be "_5ay5 _1k4h" or " _5ay5 _1k4h".(as they possibly generated automatically, its may be have different position on page reload)
But for the best result by performance and by correctness I think will be the following xpath:
".//div[contains(#id, 'PagePostsSectionPagelet')][1]" -- for first div
".//div[contains(#id, 'PagePostsSectionPagelet')][2]" -- for second div
I see that dynamic in the div id is only the number so you can use something like:
WebElement element = driver.FindElements(By.XPath("//div[contains(.,'PagePostsSectionPagelet')])")[1];
This will take only the first web element.
Try using a css selector as below and refine further if required.
The code below returns a List of matching WebElements and then you grab the first one in the List.
List<WebElement> listOfElements = driver.findElements(By.cssSelector("div[data-referrer]"));
WebElement myElement = listOfElements.get(0);
Hint: use the Chrome console to test your css and xpath selectors directly. e.g. use
$$("div[data-referrer]") in the console to reveal what will get selected.

How to check for second element with class name and click it if it exists in Selenium Java

So I am writing automation tests using selenium and I am having a lot of trouble selecting the second element in a list of divs with the same class names
Boolean isExists2Accounts = driver.findElements(By.xpath("(//div[contains(#class, 'item-name')])[2]")).size() < 0;
if(isExists2Accounts)
{
//Finds second div element that has classname of item-name and clicks on it
driver.findElement(By.xpath("(//div[contains(#class, 'item-name')])[2]")).click();
}
else
{
driver.get("javascript:alert('There isn't a second account or you don't know how to select it!');");
Thread.sleep(5000);
org.testng.Assert.fail("transferTest6() Failed due to There isn't a second account or you don't know how to select it!");
}
HTML structure looks like this:
<div class="item-list">
<div class="item-name">
<div> clickable area </div>
<div class="button-wrap"></div>
</div>
<div class="item-name">
<div> clickable area </div>
<div class="button-wrap"></div>
</div>
<div class="item-name">
<div> clickable area</div>
<div class="button-wrap"></div>
</div>
<div class="item-name">
<div> clickable area </div>
<div class="button-wrap"></div>
</div>
</div>
Not really sure what I am doing wrong here, I looked at the html and there are 5 divs with the specified class name. Very new to selenium in general, using eclipse/junit/webdriver.
I have seen several questions similiar to this, and trying solutions people have posted have not worked. I have seen some suggestions to use .get(2) and I will try and implement that in the mean time.
Any help you could give would be good.
get(2) is THIRD element, not the second, as the countage begins from 0.
So:
driver.findElements(By.cssSelector(".item-name")).get(1).click();
OR depending on where is yr clickable
driver.findElements(By.cssSelector(".item-name div:not(.button-wrap)")).get(1).click();
Hey all the answer that was given by Stanjer works, I tested it with different markup, the developer that built the system I am testing through a random mousedown event (not click) for the html I am trying to interact with which was causing the problem.
So final solution with problem if it was a click event would be:
driver.findElements(By.cssSelector(".item-name")).get(1).click();
Just like he said.
However in this case I am instead going to send Javascript to the console to work with functions that have already been created by the developer.

Selectina String and Doubleclicking using Selenium Java

I got a disabled textbox with below tags:
<div
id="writingactivityId2" class="boxSize ng-pristine ng-untouched ng-valid ng-valid-required redactor_editor writingActivityDisabled" ng-focus="editing()" redactor="" readonly="" ng-model="workInProgress.wip" required="" contenteditable="false" dir="ltr" style="height: 300px;">
</div>
and it has a child:
<p>
Automated Test 04/03/2015 15:03:43
</p>
Can any one suggest how to select the Text "Automated" Or double click/single on the text "Automated"?
I tried to point the webElement on div and on p when I tried double click it selects the whole page rather than selecting the text.
An answer will be a bit different for different OS. For win it will be like:
WebElement textElement = driver.findElement(By.cssSelector("div#writingactivityId2 p"));
Actions action = new Actions(driver);
action.click(textElement).sendKeys(Keys.chord(Keys.CONTROL, "a")).perform();
You can get to the element using, for example, a CSS selector:
WebElement p = driver.findElement(By.cssSelector("div#writingactivityId2 p"));

Categories