xpath element identification -- Cleaner Xpath - java

I was able to identify the element using the actual xpath copied from the code directly, however can someone help me write a simpler xpath using the following code? The following code is a working code!
WebElement oCheckbox = myDriver.findElement(By.xpath(".//*[#id='app']/div[1]/div[2]/div/div/div[2]/div/div[1]/div/div/div[2]/div[2]/table/tbody/tr[1]/td[1]/div/label/div/i"));
WebElement oCheckbox1 = myDriver.findElement(By.xpath(".//*[#id='app']/div[1]/div[2]/div/div/div[2]/div/div[1]/div/div/div[2]/div[2]/table/tbody/tr[2]/td[1]/div/label/div/i"));
oCheckbox.click();
oCheckbox1.click();
HTML:
<head>
<body class="">
<div id="app">
<section class="bottom-padding cf top-padding white-bg">
<div class="container">
<div class="row">
<div class="row">
<div class="col">
<div class="row">
<div class="col-lg-3 push-lg-9 padding-l-r-30 padding-bottom">
<div class="col-lg-9 pull-lg-3 padding-l-r-15">
<div class="row dropshadow">
<div class="col-lg-5 padding-none">
<div class="left-round fixed-height gray-bg">
<div>
<div class="section-title">
<div class="floatThead-wrapper" style="position: relative; clear: both;">
<div class="floatThead-container" style="overflow: hidden; padding-left: 0px; padding-right: 0px; position: absolute; margin-top: 0px; top: 0px; z-index: 1001; will-change: transform; transform: translateX(0px) translateY(0px); left: 0px; width: 410.867px;" aria-hidden="true">
<div class="table-wrapper">
<table class="table protocol-table" style="table-layout: fixed; min-width: 410.867px;">
<colgroup>
<thead>
<tbody>
<tr>
<td>
<div>
<input id="select-pcsl-9777-protocol" type="checkbox"/>
<label for="select-pcsl-9777-protocol">
<div>
<i class="fa fa-check" aria-hidden="true"/>
</div>
<span class="sr-only">Select</span>
</label>

try this :
myDriver.findElement.ById("select-pcsl-9777-protocol")

I don't know why #peter solution not work but you can use JavascriptExecutor
WebElement element= driver.findElement(By.id("select-pcsl-9777-protocol"));
JavascriptExecutor executor = (JavascriptExecutor)driver;
executor.executeScript("arguments[0].click();", element);
You can also use xpath
WebElement element= driver.findElement(By.xpath("//input[#id='select-pcsl-9777-protocol']"));
JavascriptExecutor executor = (JavascriptExecutor)driver;
executor.executeScript("arguments[0].click();", element);

As you mentioned both the following xpath are working but those are absolute paths:
WebElement oCheckbox = myDriver.findElement(By.xpath(".//*[#id='app']/div[1]/div[2]/div/div/div[2]/div/div[1]/div/div/div[2]/div[2]/table/tbody/tr[1]/td[1]/div/label/div/i"));
WebElement oCheckbox1 = myDriver.findElement(By.xpath(".//*[#id='app']/div[1]/div[2]/div/div/div[2]/div/div[1]/div/div/div[2]/div[2]/table/tbody/tr[2]/td[1]/div/label/div/i"));
Here is the equivalent logical xpath:
WebElement oCheckbox = myDriver.findElement(By.xpath("//i[#class='fa fa-check']"));
Incase you are trying to click on the Select element, you can get a bit granular as:
WebElement oCheckbox1 = myDriver.findElement(By.xpath("//i[#class='fa fa-check']/span[#class='sr-only']"));
But, I am a bit doubtful with the aria-hidden="true" attribute, so a garunteed xpath would be:
WebElement oCheckbox2 = myDriver.findElement(By.xpath("//input[#id='select-pcsl-9777-protocol']//following::span[1]))"));

Related

How to check the checkboxes using the Selenium Java WebDriver?

I was trying to figure out a way to check the checkboxes in the table grid. Usually they are defined as type='checkbox'. So I'm finding it difficult to implement using the webDriver to check the checkboxes since they are in the tags.
A sample HTML code is given below.
<tbody id="gridview-2345-body">
<tr id="gridview-2345-record-/DNA/Study1_HS.xml" class="x4-grid-row x4-grid-data-row x4-grid-row-selected" data-boundview="gridview-1270" role="row">
<td id="ext4-ext-gen1234" class="x4-grid-cell x4-grid-td" role="gridcell">
<div class="x4-grid-cell-inner " style="text-align:left;" unselectable="on">
<div class="x4-grid-row-checker"/>
</div>
</td>
<td id="ext4-ext-1235" class="x4-grid-cell x4-grid-td" role="gridcell">
<div class="x4-grid-cell-inner " style="text-align:left;" unselectable="on">
<span id="ext4-icon1568" class="fa fa-file-code-o labkey-file-icon"/>
</div>
</td>
<td id="ext4-ext-gen1236" class="x4-grid-cell x4-grid-td" role="gridcell">
<div class="x4-grid-cell-inner " style="text-align:left;" unselectable="on">
<div width="100%" height="16px">
<div style="float: left;"/>
<div style="padding-left: 8px; white-space:normal !important;">
<span style="display: inline-block; white-space: nowrap;">Study1_HS.xml</span>
</div>
</div>
</div>
</td>
</tr>
</tbody>
I tried using 'contains' in the xpath
driver.findElement(By.xpath("//*[contains(#id, 'Study1_HS.xml')]/td[1]/div/div")).click();
I'm wondering... since the TR contains the class change when the checkbox is checked, maybe clicking the TR will trigger the check. Try this and see.
String searchText = "Study1_HS.xml";
List<WebElement> rows = driver.findElements(By.tagName("tr"));
for (WebElement row : rows)
{
if (row.getText().contains(searchText))
{
row.click();
break;
}
}
So I used 'preceding' in the xpath to make it work
//span[text()='Study1_HS.xml']/preceding::td/div/div[#class='x4-grid-row-checker']
http://www.xpathtester.com/xpath/b1d50008dd4be8ab7545548c4b8238f5

handle a dynamically changing element and a scroll bar

This is a screen shot of my webpage
Here is the html code
<div class="slimScrollDiv" style="position: relative; overflow: hidden; width: auto; height: 350px;"><div class="scroller" style="height: 350px; overflow: hidden; width: auto;" data-always-visible="1" data-rail-visible1="0" data-handle-color="#D7DCE2">
<div class="tsk-row clearfix">
<div class="tsk-left">
New task to check new build of 2016.4.18.1
</div>
test
<div class="tsk-right">
<span class="label label-warning">Assigned</span>
</div>
</div>
<div class="tsk-row clearfix">
<div class="tsk-left">
test 2
</div>
test
<div class="tsk-right">
<span class="label label-warning">Assigned</span>
</div>
</div>
<div class="tsk-row clearfix">
<div class="tsk-left">
test
</div>
test
<div class="tsk-right">
<span class="label label-warning">Assigned</span>
</div>
</div>
<div class="tsk-row clearfix">
<div class="tsk-left">
New login page
</div>
test
<div class="tsk-right">
<span class="label label-warning">Assigned</span>
</div>
</div>
<div class="tsk-row clearfix">
<div class="tsk-left">
new task
</div>
Ongoing
<div class="tsk-right">
<span class="label label-warning">Assigned</span>
</div>
</div>
<div class="tsk-row clearfix">
<div class="tsk-left">
This is testing
</div>
test
<div class="tsk-right">
<span class="label label-warning">Assigned</span>
</div>
</div>
</div>
</div><div class="slimScrollBar" style="width: 7px; position: absolute; top: 0px; opacity: 0.4; display: none; border-radius: 7px; z-index: 99; right: 0px; height: 300.245px; background: rgb(0, 0, 0);"></div><div class="slimScrollRail" style="width: 7px; height: 100%; position: absolute; top: 0px; display: none; border-radius: 7px; opacity: 0.2; z-index: 90; right: 0px; background: rgb(51, 51, 51);"></div></div>
Here is my automation test case
public void openAllTask() throws InterruptedException{
List<WebElement> task=driver.findElements(By.cssSelector(".tsk-row.clearfix")); // get the list of total no of elements present in the task window
System.out.println("size of i loop "+task.size());
for(int i=1; i<=task.size(); i++){
//find the element one by one using xpath
System.out.println(driver.findElement(By.xpath("html/body/div[2]/div[3]/div/div/div/div[3]/div/div[1]/div["+i+"]/div[1]/a")).getText());
driver.findElement(By.xpath("html/body/div[2]/div[3]/div/div/div/div[3]/div/div[1]/div["+i+"]/div[1]/a")).click();
Thread.sleep(3000);
driver.navigate().back();
Thread.sleep(3000);
// find the scroll bar and move the scroll bar by cirten pixles
WebElement element=driver.findElement(By.xpath("html/body/div[2]/div[3]/div/div/div/div[3]/div/div[2]"));
Actions act=new Actions(driver);
act.dragAndDropBy(element, 0, (i*10)).build().perform();
Thread.sleep(3000);
}
I want to select each element from the window which is highlighted and also scroll the window down so that when dynamically elements are added then I can scroll down and read all the elements.
Try like below:
//i am not sure about my css path is correct or not as no way to check it
// if it prints the text and size correctly, than it will fine but if not than please give the right css path.
List<WebElement> elements = driver.findElements(By.cssSelector(".tsk-row.clearfix > div.tsk-left> a");
System.out.println("size is "+elements.size());
for(int i = 0; i < elements.size(); i++){
JavascriptExecutor js = (JavascriptExecutor)driver;
WebElement elem = elements.get(i);
//this line will scroll down to make element visible
js.executeScript("window.scrollTo(" + elem.getLocation().x + "," +(elem.getLocation().y- 100) + ");");
//don't use this kind of wait, use explicit wait
Thread.sleep(1000);
System.out.println(elem.getText());
elem.click();
Thread.sleep(3000);
driver.navigate().back();
Thread.sleep(3000);
}

Not able to click ExtJS Dropdown button and select list elements - Selenium Webdriver Java

I am having difficulty in clicking a drop down and selecting option from the list. Below screenshot of the application.
Our application uses heavy ExtJS and below is the HTML code for dropdown button and textbox.
<div id="combobox-1115-bodyEl" class="x-form-item-body x-form-trigger-wrap-focus" role="presentation" style="width: 325px;">
<div id="ext-gen1273" class="x-hide-display x-form-data-hidden" role="presentation"></div>
<input id="ext-gen1272" class="x-form-field x-form-text x-form-focus" type="text" autocomplete="off" tabindex="2" size="20" aria-invalid="false" placeholder="Please Select a XXXX..." data-errorqtip="" style="width: 305px; -moz-user-select: text;" role="textbox" aria-describedby="combobox-1115-errorEl" aria-required="true"></input>
<div id="combobox-1115-triggerWrap" class="x-form-trigger-wrap" role="presentation" style="width: 20px;">
<div id="ext-gen1274" class="x-trigger-index-0 x-form-trigger x-form-arrow-trigger x-form-trigger-last x-unselectable" role="button" style="-moz-user-select: none;"></div>
Below is the code for dropdown list options.
<div id="boundlist-1132" class="x-boundlist x-boundlist-floating x-boundlist-default x-layer x-boundlist-above" style="position: absolute; left: 582px; top: 93px; width: 325px; z-index: 19061;" role="listbox" tabindex="-1">
<div id="boundlist-1132-listEl" class="list-ct" style="overflow: auto;">
<ul>
<li id="ext-gen1312" class="x-boundlist-item" role="option">6757</li>
<li id="ext-gen1309" class="x-boundlist-item" role="option">Customer 1</li>
<li id="ext-gen1300" class="x-boundlist-item" role="option">Customer 2</li>
<li id="ext-gen1301" class="x-boundlist-item" role="option">Customer 3</li>
<li id="ext-gen1302" class="x-boundlist-item" role="option">Customer 4</li>
<li id="ext-gen1310" class="x-boundlist-item" role="option">XYZ Company1</li>
</ul>
</div>
Please help me locate the dropdown button and select a list item from it. Thanks in advance!!
Try using explicit wait with more precise selectors.
By css = By.cssSelector("[placeholder='Please Select a Customer...']");
By option = By.xpath("//li[#role='option'][text()='Customer 2']");
WebDriverWait wait = new WebDriverWait(driver, 10);
//Click the dropdown to populate the list
WebElement dropdown = wait.until(ExpectedConditions.presenceOfElementLocated(css));
dropdown.click();
//Click the option. Notice the xpath is using the text of the customer
WebElement value = wait.until(ExpectedConditions.presenceOfElementLocated(xpath));
value.click();
First you have to click dropdown element(mostly with input tag) and then wait for the li webelemnt to appear .. below is the function which expects webelement with ul tag and value.
public void selectValueFromUnorderedList(WebElement unorderedList, final String value) {
List<WebElement> options = unorderedList.findElements(By.tagName("li"));
for (WebElement option : options) {
//System.out.println(option.getText());
if (value.equalsIgnoreCase(option.getText())) {
option.click();
break;
}
}
}

Get text from textbox with up and down arrows in Selenium Webdriver

I have a textbox in the footer of the pagination table. This textbox contains a textbox with up and down arrows as shown in the below Image. This textbox values will dynamically changed when we click on next, previous buttons.
Image URL: http://i.msdn.microsoft.com/dynimg/IC1380.jpg
This is the input from DOM
<div ng-grid-footer="" class="ng-scope"><div ng-show="showFooter" class="ngFooterPanel ng-scope ui-widget-content ui-corner-bottom" ng-class="{'ui-widget-content': jqueryUITheme, 'ui-corner-bottom': jqueryUITheme}" ng-style="footerStyle()" style="width: 1920px; height: 55px;">
<div class="ngTotalSelectContainer">
<div class="ngFooterTotalItems ngNoMultiSelect" ng-class="{'ngNoMultiSelect': !multiSelect}" style="margin-top: 8px">
<span class="ngLabel ng-binding">Total Items: 810</span><span ng-show="filterText.length > 0" class="ngLabel ng-binding ng-hide">(Showing Items: 100)</span>
</div>
<div class="ngFooterSelectedItems ng-hide" ng-show="multiSelect">
<span class="ngLabel ng-binding">Selected Items: 0</span>
</div>
</div>
<div class="ngPagerContainer ngNoMultiSelect" style="float: right; margin-top: 10px" ng-show="enablePaging" ng-class="{'ngNoMultiSelect': !multiSelect}">
<div style="float:left; margin-right: 10px" class="ngRowCountPicker">
<span style="float: left; margin-top: 8px" class="ngLabel ng-binding">Page Size:</span>
<select style="float: left;height: 29px; width: 100px" ng-model="pagingOptions.pageSize" class="ng-valid ng-dirty">
<!-- ngRepeat: size in pagingOptions.pageSizes --><option ng-repeat="size in pagingOptions.pageSizes" class="ng-scope ng-binding" value="10">10</option><!-- end ngRepeat: size in pagingOptions.pageSizes --><option ng-repeat="size in pagingOptions.pageSizes" class="ng-scope ng-binding" value="25">25</option><!-- end ngRepeat: size in pagingOptions.pageSizes --><option ng-repeat="size in pagingOptions.pageSizes" class="ng-scope ng-binding" value="50">50</option><!-- end ngRepeat: size in pagingOptions.pageSizes --><option ng-repeat="size in pagingOptions.pageSizes" class="ng-scope ng-binding" value="100">100</option><!-- end ngRepeat: size in pagingOptions.pageSizes -->
</select>
</div>
<div style="float:left; margin-right: 10px; line-height:25px" class="ngPagerControl">
<button class="ngPagerButton" ng-click="pageToFirst()" ng-disabled="cantPageBackward()" title="First Page"><div class="ngPagerFirstTriangle"><div class="ngPagerFirstBar"></div></div></button>
<button class="ngPagerButton" ng-click="pageBackward()" ng-disabled="cantPageBackward()" title="Previous Page"><div class="ngPagerFirstTriangle ngPagerPrevTriangle"></div></button>
<!--Input Textbox Which I want to Inspect -->
<input class="ngPagerCurrent ng-valid-number ng-valid-min ng-valid ng-valid-max ng-dirty" min="1" max="9" type="number" style="width:50px; height: 26px; margin-top: 1px; padding: 0 4px" ng-model="pagingOptions.currentPage">
<!--END-->
<button class="ngPagerButton" ng-click="pageForward()" ng-disabled="cantPageForward()" title="Next Page"><div class="ngPagerLastTriangle ngPagerNextTriangle"></div></button>
<button class="ngPagerButton" ng-click="pageToLast()" ng-disabled="cantPageToLast()" title="Last Page"><div class="ngPagerLastTriangle"><div class="ngPagerLastBar"></div></div></button>
<button ng-controller="OmniSearchViewCtrl" id="page-summary-help-button" title="Help" class="ngPagerButton ng-scope" ng-click="handlePageSummaryHelpButtonClick()">
<span class="ptipsicon ptipsicon-help" style="padding:0 6px; float:left"></span>
</button>
</div>
</div>
This is Xpath
//*[#id="PageViewContainer"]/div/div[3]/div/div[2]/div[2]/input
My problem is, I am unable to get the values from the textbox since the textbox doesn't have any attribute:value. I have tried using the below lines to get the text but it just displays a blank. However, I didn't get any exceptions
pageNumber = findElement(By.xpath(properties.getString("PageNumber"))).getText();
pageNumber = findElement(By.xpath(properties.getString("PageNumber"))).getAttribute("value");
Whereas, when I tried this I am getting no such element found exception.
pageNumber = findElement(By.xpath("//input[#id=\"PageViewContainer\"]"))).getText();
Any help would be much appreciated.
//*[#id="PageViewContainer"]
Your xpath begins with a search for an element with an id="PageViewContainer". There is no such element in your HTML, so your xpath returns nothing.
Based on the snippet you have given, you can find the input element by:
//div[#class='ngPagerControl']/input
You can then use the getText() method to extract the text value.

not able to locate an element present in a frame

element i needed is present in a frame. Code is identifying the frame but not the element present in that frame.
<div id="cod-info" class="lightbox infobox">
<div id="returns-info" class="lightbox infobox">
<div id="lb-coupon-widget" class="lightbox">
<div id="lb-login" class="lightbox loginbox loginsignupV2" data-signupsplashpageload="2">
<div id="lightbox-shim" class="lightbox-shim" style="display: block;"></div>
<iframe id="mklogin-iframe" src="javascript:void(0)" name="mklogin-iframe" style="position: absolute; height: 0px; top: -100px;">-----> Frame
<div class="myntra-tooltip">
<div id="lb-sizechart" class="lightbox lb-sizechart" style="display: block;">
<div class="mod" style="min-height: 478px; margin-top: 20px; margin-bottom: 20px;">
<div class="close"></div>
<div class="loading" style="display: none;"></div>
<div class="hd">
<div class="bd mk-cf">
<div>
<div id="tab-list" class="mk-f-left lft-cont">
<div class="tab-btns">----> Want to locate element present in this div
Code : driver.switchTo().frame(driver.findElement(By.xpath("//iframe[#id='mklogin-iframe']")));---- to switch to frame
driver.findElement(By.xpath("(//div[#class='tab-btns']/ul/li)["+2+"]"));---> to locate element.
It is showing unable to locate element
I think you are not waiting for the element to appear,you can try using Explicit Wait...
WebDriverWait wait = new WebDriverWait(driver,60);
wait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("selector_of_element")));
Note : 'cssSelector' can be replaced with xpath,id,name,className..etc as per your convinience.
OR
If there are more than one element with the same selector or xpath,you can try the combination of Implicit Wait and findElements...
driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
List <WebElement> elements = driver.findElements(By.xpath("(//div[#class='tab-btns']/ul/li)["+2+"]"));

Categories