what i want to accomplish is detect first the changes on the div(ng-repeat) list which is is the result of a search query and click the first result ,but my problem is the click event are already firing and selecting the already listed item which is must be the result the search
Search event
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
driver.findElement(By.xpath("//*[#id='bs-example-navbar-collapse-1']/ul[2]/li[1]/div/input")).sendKeys(fname);
Click Event
WebDriverWait dList = new WebDriverWait(driver, 10);
dList.until(ExpectedConditions.presenceOfElementLocated(By.xpath("//*[#id=\"top-menu-members\"]/div[1]/div")));
here is the div listing
<div class="list cursor-pointer ng-scope" ng-mouseenter="memberEntered(member)" ng-mouseleave="memberLeft(member)" ng-repeat="member in (members | orderBy:['-new','firstname'])" ng-hide="member.id == user.id" ng-init="member.name = member.firstname + ' ' + member.lastname;" ng-if="members.length">
<div class="settings pull-left blue" ng-click="selectMemberSubmenu(member); moveSubmenu($event, 2);">
<a href="#" ng-class="{ 'open': member.id == selectedMember.id }">
<i class="fa fa-caret-left" aria-hidden="true"></i>
</a>
</div>
<a ui-sref="members.task({ id: member.id })" ng-click="markAsSeen('member', member, $event, false)" href="/members/7E1C4A77-C29A-4121-B305-8766340F4DDA">
<div class="profpic members pull-left">
<div class="bg-image" style="background-image: url(/img/avatar-man.png)"></div>
</div>
<div class="info pull-left">
<p class="pull-left ng-binding">Kyben Jal</p>
<p class="pull-left role ng-binding">Company Manager</p>
</div>
<!-- ngIf: member.new --><div class="member-circle pull-right ng-scope" ng-if="member.new" ng-click="markAsSeen('member', member, $event)">
<img src="/img/notif.png">
</div><!-- end ngIf: member.new -->
</a>
</div>
Related
I'm using thymeleaf and I want to iterate a loop and group by every n items. Right now my code wants to group by every 4 items. After a search in most of the questions, this is my code:
<div th:each="items, iter: ${myList}" th:if="${iter.count} % 4 == 0" th:class="${iter.first}? 'nice-slider-slide active first' : 'nice-slider-slide'">
<div class="nice-slider-entry" th:each="item, iter: ${items}">
<span th:text="${item.getName}"></span>
</div>
</div>
The result is blank and it is printing nothing. But the result I want is:
<div class="nice-slider-slide active first">
<div class="nice-slider-entry">
<span>Name</span>
</div>
<div class="nice-slider-entry">
<span>Name</span>
</div>
<div class="nice-slider-entry">
<span>Name</span>
</div>
<div class="nice-slider-entry">
<span>Name</span>
</div>
</div>
<div class="nice-slider-slide">
<div class="nice-slider-entry">
<span>Name</span>
</div>
<div class="nice-slider-entry">
<span>Name</span>
</div>
<div class="nice-slider-entry">
<span>Name</span>
</div>
<div class="nice-slider-entry">
<span>Name</span>
</div>
</div>
Why not move the logic of the grouping outside view layer? Thymeleaf is not so friendly with data computation.
Instead of a simple list to have a list of lists:
List<String> myList;
to be replaced by:
List<List<String>> myList;
Your thymeleaf code will be something like this:
<div th:each="subList,iter : ${myList}" th:class="${iter.first}? 'nice-slider-slide active first' : 'nice-slider-slide'">
<div class="nice-slider-entry" th:each="index: ${subList}">
<span th:text="${index}"></span>
</div>
</div>
UPDATE with pure Thymeleaf solution:
<th:block th:with="noEl = 4,totalSize = ${#lists.size(myList)} - 1">
<th:block th:each=" listIndex: ${#numbers.sequence(0, totalSize, noEl)}">
<div th:class="${listIndex eq 0 }? 'nice-slider-slide active first' : 'nice-slider-slide'"
th:with="maxValue = ${ totalSize lt (listIndex + noEl -1) ? totalSize : listIndex + noEl -1}">
<div class="nice-slider-entry" th:each="index : ${#numbers.sequence(listIndex, maxValue)}">
<span th:text="${myList[index]}"></span>
</div>
</div>
</th:block>
</th:block>
I have a page where I need to extract the text from an xpath and the status of the radio or checkbox that is associated with the text.
Each element is contained in a class called "c-form-group", so i have written a loop to iterate through to extract the "Text" the will be 4 elements found on the page. But it is failing on element 3 & 4, i must have something wrong with my xpath. I have yet to add in the check for the checkbox/radio button,
The first two elements are returning the values i require, then fails on element3.
Here are the 4 text elements i am trying to extract:
Plan B Warranty (Taxi) & Breakdown Recovery
Vehicle Asset Protection - Standard Cover
Negative Equity Cover
You confirm that you have received the VAP key facts leaflet?
Here is the code for the loop.
WebElement elem = driver.findElement(By.className("c-form-group"));
System.out.println("a");
List<WebElement> elementz = elem.findElements(By.xpath("//label[contains(#class,'c-option')]"));
for(int i = 0 ; i< elementz.size() ; i++){
System.out.println("Loop : " + i);
String vapval1 = elementz.get(i).findElement(By.xpath("//label[#class='c-option c-option--right u-px u-py-sm u-clearfix ng-scope' and not(#class='ng-pristine ng-untouched ng-valid ng-valid-required') and not (#class='c-option__radio')]")).getText();
System.out.println("0 = " + vapval1);
String vapval2 = elementz.get(i).findElement(By.xpath("//label[#class='c-option c-option--right u-px u-py-sm u-clearfix' and not(#class='ng-pristine ng-untouched ng-valid ng-valid-required') and not (#class='c-option__radio')]")).getText();
System.out.println("1 = " + vapval2);
String vapval3 = elementz.get(i).findElement(By.xpath("//label[#class,'c-option c-option--right u-px u-py-sm u-clearfix ng-scope' and not(#class='ng-pristine ng-untouched ng-valid') and not (#class='c-option__checkbox')]")).getText();
System.out.println("3 = " + vapval3);
String vapval4 = elementz.get(i).findElement(By.xpath("//label[#class,'c-option c-option--right u-px u-py-sm u-clearfix' and not(#class='ng-pristine ng-untouched ng-valid ng-valid-required') and not (#class='c-option__checkbox')]")).getText();
System.out.println("4 = " + vapval4);
}
Here is the full html, which may help.
<!DOCTYPE html>
<html class="ng-scope" ng-app="dan">
<head>
<body class="u-scroll-y ng-scope" ng-controller="CoreController as cc">
<div class="c-animate c-animate--show u-pos-f-t ng-hide" ng-show="global.alerts.length">
<div class="o-grid-fluid u-h-100 u-pl-0">
<div class="o-grid__row u-ml-0 u-h-100">
<div class="c-loader ng-hide" ng-show="loadingHome" style="">
<nav class="o-grid__col-xl-2 o-grid__col-lg-3 o-grid__col-xs-4 u-p-0 c-card__block u-h-100 u-shadowed u-pos-f-t ng-scope" ng-if="global.loggedIn">
<div class="u-p-0 u-h-100 o-grid__col-xl-10 o-grid__col-lg-9 o-grid__col-xs-8 u-pull-right" ng-class="{ 'o-grid__col-xl-10 o-grid__col-lg-9 o-grid__col-xs-8 u-pull-right' : global.loggedIn }">
<header class="o-layout-table__row u-bg-primary u-shadowed u-clearfix u-px ng-scope" ng-if="global.loggedIn">
<main class="o-view-container">
<div class="o-grid-fluid u-py-md">
<div class="o-grid__row">
<div class="c-animate c-animate--view-slide-in-right c-animate--view-slide-out-right ng-scope" ng-view="" style="">
<div class="o-grid__col-md-10 o-grid__col-xl-8 o-grid__col-xl-offset-2 o-grid__col-md-offset-1 ng-scope">
<div class="u-mb-lg u-text-center">
<h1 class="u-text-bold">Recommendations</h1>
</div>
<form class="ng-valid ng-valid-min ng-valid-max ng-valid-required ng-dirty ng-valid-parse" name="recommend" ng-submit="recommend.$valid" style="">
<div class="o-media c-card c-card__block u-shadowed u-mb-lg ng-scope" ng-if="rc.WarrantyEligible && !rc.prevWarranty()">
<label class="c-form-control-label u-px u-py-sm u-w-100">Warranty Options:</label>
<div class="c-form-group u-p-0 u-mb-sm u-clearfix">
<div class="o-grid__col-md-8">
<label class="c-form-control-label u-text-normal">Product Recommendations (Years):</label>
</div>
<div class="o-grid__col-md-4">
<input class="c-form-control ng-pristine ng-untouched ng-valid ng-valid-min ng-valid-max ng-valid-required" required="" placeholder="Years" ng-model="rc.recommend.year" min="1" max="3" type="number">
</div>
</div>
<div class="c-form-group ng-scope" ng-if="data.answer_taxi">
<label class="c-option c-option--right u-px u-py-sm u-clearfix ng-scope" ng-if="!rc.planA && !rc.prestige" ng-click="cc.utils.audit('recommendation_warranty_plan_taxi_b')">
<input class="ng-pristine ng-untouched ng-valid ng-valid-required" required="" ng-model="rc.recommend.warrantyPlan" value="taxiB" name="warrantyPlan" type="radio">
<i class="c-option__radio"></i>
Plan B Warranty (Taxi) & Breakdown Recovery
</label>
</div>
</div>
<div class="o-media c-card c-card__block u-shadowed u-mb-lg u-text-body u-bg-success" ng-if="!rc.prevVap() && rc.VapEligible ">
<div class="c-form-group">
<label class="c-form-control-label u-px u-py-sm u-w-100">Vehicle Asset Protection Options:</label>
<label class="c-option c-option--right u-px u-py-sm u-clearfix" ng-click="cc.utils.audit('recommend_vap')">
<input class="ng-pristine ng-untouched ng-valid ng-valid-required" required="" ng-model="rc.recommend.vapPlan.plan" value="standard" name="vapPlan" type="radio">
<i class="c-option__radio"></i>
Vehicle Asset Protection - Standard Cover
</label>
<label class="c-option c-option--right u-px u-py-sm u-clearfix ng-scope" ng-if="data.answer_equity == true" ng-click="cc.utils.audit('recommend_negative_equity')">
<input class="ng-untouched ng-valid ng-dirty ng-valid-parse" ng-model="rc.recommend.vapPlan.equity" name="vapPlanEquity" type="checkbox" style="">
<i class="c-option__checkbox"></i>
Negative Equity Cover
</label>
<label class="c-option c-option--right u-px u-py-sm u-clearfix" ng-click="cc.utils.audit('vap_key_facts_checked')">
<input class="ng-pristine ng-untouched ng-valid ng-valid-required" required="" ng-model="rc.recommend.vapCheck" name="vapCheck" type="checkbox">
<i class="c-option__checkbox"></i>
You confirm that you have received the VAP key facts leaflet?
</label>
</div>
</div>
</form>
<div class="c-form-group">
</div>
</div>
</div>
</div>
</main>
</div>
</div>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.9/angular.min.js">
<script src="./build/app.js?v=2.13" defer="">
<script src="/build/standalone/jspdf.js" defer="">
<script src="/build/standalone/sigWebTablet.js" defer="">
</body>
</html>
I'm a little confused as to what you are trying to do. You mention getting the text from the elements and also getting the state of the checkboxes. Your XPaths on the outer and inner loop overlap. Your elementz list is pulled from a LABEL that contains the c-option class but then you start with an element from elementz and the first part of your XPath you repeat the search for a LABEL that contains the c-option class.
There is an much easier way to do this. Each of these checkboxes/radiobuttons are INPUT tags and have a name specific to their value.
Plan B Warranty (Taxi) & Breakdown Recovery: <input ... name="warrantyPlan" type="radio">
Vehicle Asset Protection - Standard Cover: <input ... name="vapPlan" type="radio">
Negative Equity Cover: <input ... name="vapPlanEquity" type="checkbox" style="">
You confirm that you have received the VAP key facts leaflet?: <input ... name="vapCheck" type="checkbox">
So with that info, you can just get each INPUT with CSS selectors like
By.cssSelector("input[name='warrantyPlan']")
Once you have the INPUT element, you can check if it's selected using .isSelected().
If you really do need the text, you can get the label because it's the parent of the INPUT we just got. We can do this with an XPath, By.xpath(".."), which gets the parent of the current element.
We can put this all together like
// Plan B Warranty (Taxi) & Breakdown Recovery
WebElement e = driver.findElement(By.cssSelector("input[name='warrantyPlan']"));
System.out.println(e.isSelected()); // false
System.out.println(e.findElement(By.xpath("..")).getText()); // Plan B Warranty (Taxi) & Breakdown Recovery
// Vehicle Asset Protection - Standard Cover
e = driver.findElement(By.cssSelector("input[name='vapPlan']"));
System.out.println(e.isSelected()); // false
System.out.println(e.findElement(By.xpath("..")).getText()); // Vehicle Asset Protection - Standard Cover
I just did the first two. You can see the pattern and apply it for the last two.
I have a button with drop down item,
if i click the button it's open the list and choose the item
below is the html
<button id="btn-append-to-body" class="btn btn-primary mobile-quick-button dropdown-toggle" type="button" uib-dropdown-toggle="" aria-haspopup="true" aria-expanded="false">
<div class="clearfix">
<span class="pull-left text-left ng-binding" tabindex="0"> Select one </span>
<span class="pull-right text-right ng-binding">
</div>
</button>
<ul class="uib-dropdown-menu dropdown-menu" role="menu" aria-labelledby="btn-append-to-body">
<!-- ngRepeat: option in dropOptions -->
<li id="quickOption" class="ng-scope" role="presentation" name="quickOption" ng-repeat="option in dropOptions" ng-click="selectOption(option)" required="" tabindex="0" style="">
<a href="">
<div class="clearfix">
<span class="pull-left ng-binding">frame number</span>
</div>
</a>
</li>
<!-- end ngRepeat: option in dropOptions -->
<li id="quickOption" class="ng-scope" role="presentation" name="quickOption" ng-repeat="option in dropOptions" ng-click="selectOption(option)" required="" tabindex="0">
<a href="">
<div class="clearfix">
<span class="pull-left ng-binding">serial number</span>
</div>
</a>
</li>
</ul>
I want to choose any one of the item from this list,
public void lookupSearch (String item){
driver.findElement(By.xpath("//*[#id='btn-append-to-body']")).click();
//then i choose/click the parameter item (i.e frame number or serial number)
}
passing the item as parameter
please guide me how should i choose the item
To click on the button with drop down item and choose any one of the item from this list you can use the following code block :
public void lookupSearch (String item)
{
driver.findElement(By.xpath("//button[#id='btn-append-to-body']/div/span[contains(.,'Select one')]")).click();
WebDriverWait wait4elements = new WebDriverWait(driver, 10);
List<WebElement> myElements = wait4elements.until(ExpectedConditions.numberOfElementsToBe(By.xpath("//ul[#class='uib-dropdown-menu dropdown-menu']/li/a/div/span"), 2));
for(WebElement elem:myElements)
if(elem.getAttribute("innerHTML").contains(item))
{
elem.click();
break;
}
System.out.println("Element with text as "+ item +" is selected");
}
below is the answer from ul find the Li count, then getting each li text and compare with item string
WebElement uList = driver.findElement(By.xpath("//*[#id='quick-search-dropdown']/ul"));
List<WebElement> listCount = uList.findElements(By.tagName("li"));
for (int i = 1; i <= listCount.size(); i++) {
WebElement lookupItem = driver.findElement(By.xpath("(//li[#id='quickOption']/a/div/span[1])[" + i + "]"));
String lookupItemValue = lookupItem.getText();
if (lookupItemValue.equalsIgnoreCase(Item)) {
lookupItem.click();
}
}
I've tried below code :
Select dropdown = new Select(driver.findElement(By.xpath("//a[contains(text(),'--None--')]")));
dropdown.selectByIndex(1);
Getting below error :
Exception in thread "main"
org.openqa.selenium.support.ui.UnexpectedTagNameException: Element
should have been "select" but was "a"
This is my full DOM structure :
<div class="compoundTLRadius compoundTRRadius compoundBorderBottom form-element__row uiMenu" data-aura-rendered-by="2600:0" data-aura-class="uiMenu">
<div id="2574:0" data-aura-rendered-by="2581:0" class="uiPopupTrigger" data-aura-class="uiPopupTrigger" data-interactive-uid="19">
<div data-aura-rendered-by="2583:0"><div data-aura-rendered-by="2576:0">
<a aria-required="false" class="select" aria-disabled="false" aria-haspopup="true" tabindex="0" role="button" aria-label="Salutation" title="" href="javascript:void(0);" data-aura-rendered-by="2577:0" data-interactive-lib-uid="45">--None--</a>
</div>
</div>
</div>
<div class="select-options popupTargetContainer uiPopupTarget uiMenuList uiMenuList--default uiMenuList--left uiMenuList--short" data-aura-rendered-by="2595:0" data-aura-class="uiPopupTarget uiMenuList uiMenuList--default uiMenuList--left uiMenuList--short" aria-labelledby="2574:0"><div class="select-options" role="menu" data-aura-rendered-by="2589:0"><!--render facet: 2590:0-->
<ul class="scrollable" role="presentation" data-aura-rendered-by="2591:0" data- scoped-scroll="true"><!--render facet: 2592:0--></ul>
</div></div></div>
I want code for locating dropdown icon and select a first value from that.
Currently facing the issue in navigating to many div tags.
In my application, I have a grid which populates or load data in multiple div tags.
On mouseover, I have to click add comment option which gets loaded as lightbox popup.
Please guide me how to select add comment option.
<div ng-cell="">
<div class="inCell ng-scope">
<div class="cellDarkGray" ng2-class="{cellDarkGray: (row.getProperty('returnedRecordsNumber') != '0'),cellDarkGray: (row.getProperty('activityid') != '0'),cellDarkGray: (row.getProperty('returnedRecordsNumber') != '0')}">
<div class="cellOrange" ng-class="{cellRed: (row.getProperty('Impact') == '0'),cellOrange: (row.getProperty('activityid') != '0'), cellBlue: (row.getProperty('Impact') == '2')}"/>
<div class="cellWhite">
<div style="height:60px">
<div class="ng-hide" ng-show="(row.getProperty('commentFlag')== true) && (userRole =='ROLE_2') ">
<div class="ng-hide" ng-show="(row.getProperty('commentFlag')== true) && (userRole =='ROLE_1') ">
</div>
<div class="inCellData">
<div class="line1" ng-click="openDetails(row,'viewDetail')">
<span class="title1 ng-binding" ng-hide="row.getProperty('planned_typ')== 'NULL'">ORANGE PLANNED MAINTENANCE - </span>
<span class="title2 ng-binding" ng-hide="row.getProperty('deviceid')== 'NULL'"> BLCY810</span>
<!-- <span ng-hide="row.getProperty('myRouterName')== ''"> ||{{row.getProperty('myRouterName')}} ||</span> -->
</div>
<div class="line2">
<span class="title3"/>
<span class="ng-binding" ng-hide="row.getProperty('service_impact')== ''"> 1 - 5 MINS ||</span>
<span class="title3 ng-binding">09/JUN/2017 01:30:00 AM</span>
up to
<span class="title2 ng-binding">09/JUN/2017 03:30:00 AM</span>
||
<span class="ng-binding">EQUANT SHARED NETWORK</span>
</div>
<div class="line3">
</div>
<div>
<nav id="cbp-spmenu-s1" class="cbp-spmenu cbp-spmenu-vertical cbp-spmenu-left cbp-spmenu-open">
<a ng-click="openDetails(row,'viewDetail')">view details</a>
<div class="" ng-show="userRole =='ROLE_1'">
<a class="" ng-show="row.getProperty('internalFlag')=='Y'" ng-click="setUnsetInternal(row)">invisible to customer</a>
<a class="ng-hide" ng-show="row.getProperty('internalFlag')=='Z'" ng-click="row.getProperty('sourcesystem')=='Carrier Changes' && (row.getProperty('urgency')=='EMERGENCY' || row.getProperty('urgency')=='EXPEDITE') ? alertPastDataZEmergency() : alertPastDataZ() ">invisible to customer</a>
<a class="ng-hide" ng-show="row.getProperty('internalFlag')=='N'" ng-click="setUnsetInternal(row)">visible to customer</a>
<a class="ng-hide" ng-show="row.getProperty('internalFlag')=='X' || row.getProperty('internalFlag')=='H'" ng-click="alertPastDataX()">visible to customer</a>
</div>
<!-- Prod Consol Start -->
<a ng-show="userRole =='ROLE_1'" ng-click="openDetails(row, 'comment')">add a comment</a>
<!-- Prod Consol End -->
</nav>
</div>
</div>
</div>
First of all you have to move the mouse using Action class to the element so that Comment link will be visible. Then you have to perform action on that element.
You can do so like this -
WebElement elem = driver.findElement(By.xpath("//a[contains(text(), 'add a comment')]"));
Actions action = new Actions(driver);
action.moveToElement(elem).click().build().perform();
Hope this helps.
Do mouse hover to the parent element to make the comment visible. Below code might give you some idea.
Actions action = new Actions(driver);
action.moveToElement("//nav[#id='cbp-spmenu-s1']").perform();
//Now the comment button will be visible
driver.findElement(By.xpath("//a[contains(text(), 'add a comment')]")).click();
Hope this helps. Thanks.
I resolved this issue by using below code
WebElement we1 = driver.findElement(By.xpath("(//a[contains(text(),'add a comment')])[1]"));
JavascriptExecutor elem = (JavascriptExecutor)driver;
elem.executeScript("arguments[0].click();", we1);