I need to be able to select a distinct dynamic xpath - selenium-webdriver

I need to select a distinct dynamic xpath in selenium between 2 pieces of xml that are identical (Dresses). I need to create the dynamic xpath for the second value which clicks the button itself. I have tried: //a[#title = 'Dresses'][#class = 'sf-with-ul'] which selects both the image and the button.
Here is the code:
<li class="sfHoverForce" xpath="1">
Dresses
<ul style="display: none;">
<li>Casual Dresses</li>
<li>Evening Dresses</li>
<li>Summer Dresses</li>
</ul>
</li>
<li id="category-thumbnail" xpath="1">
<div><img src="http://automationpractice.com/img/c/3-0_thumb.jpg" alt="Women" title="Women" class="imgm"></div>
<div><img src="http://automationpractice.com/img/c/3-1_thumb.jpg" alt="Women" title="Women" class="imgm"></div>
</li>
<li class="sfHoverForce" xpath="1">
Dresses
<ul class="submenu-container clearfix first-in-line-xs" style="display: none;">
<li>Casual Dresses</li>
<li>Evening Dresses</li>
<li>Summer Dresses</li>
</ul>
</li>

The only difference between the two nodes are the UL tag - class value. try this xpath to select the second node with anchor,
//ul[contains(#class,'submenu-container')]/preceding-sibling::a[#title='Dresses']

With the HTML you posted, this XPath will work
//a[#title='Dresses'][./following-sibling::ul[contains(#class,'submenu-container')]]
^ find an A tag with a specific title
^ the A tag should have a sibling UL
^ and that UL contains a specific class

You could try this:
//li[a[#title='Dresses']][2]/a
This will get the 2nd a element with title ‘Dresses’. If you want the first element, change the index from 2 to 1.

Related

Which id should i use in Select dropdown = new Select(browser.findElement(By.id(""))); in selenium to select the dropdown values

Which is the id that I need to use in the below code to access?
code in selenium
Select dropdown = new Select(browser.findElement(By.id("")));
Code for the drop down
<div class="form-inline form-group nb-city-selector">
<div class="wrapper-demo" style="border-right:0px"> <!-- adding class , dropdown will not work-->
<div id="nbCitySelector" class="wrapper-dropdown-2" tabindex="1">
<span class="selectedcity" data-key="mumbai">Mumbai</span>
<ul class="cityselector dropdown">
<li><a class="cityoption" data-key="mumbai">Mumbai</a></li>
<li><a class="cityoption" data-key="bangalore">Bangalore</a></li>
<li><a class="cityoption" data-key="pune">Pune</a></li>
<li><a class="cityoption" data-key="chennai">Chennai</a></li>
</ul>
</div>
</div>
</div
Hi please do it like below Take all of the value inside the list
List<WebElement> myddval = driver.findElements(By.xpath("//*[#id='nbCitySelector']/ul/li"));
now on the basis of index do the selection
myddval.get(1).click() //to select 2nd option

append some element after every nth element using angular js

I have a ul li structure like below and need to add blank li after every second element, how its possible with ng-repeat in angular js.
<ul>
<li>content</li>
<li>content</li>
<li class="filler"></li>
<li>content</li>
<li>content</li>
</ul>
<ul>
<li ng-repeat="item in items">item.content</li>
</ul>
One way is to use ng-repeat-start with ng-repeat-end
<li ng-repeat-start="item in items">{{item.content}}</li>
<li ng-repeat-end ng-if="$index % 2 == 1">Filler</li>
<!-- OR -->
<li ng-repeat-end ng-if="$odd">Filler</li>
If the filler is purely a style element you can use css to manage it without using ng-repeat-end
li:nth-child(odd):after{
display:block;
content: ' ';
/** other filler rules **/
}
DEMO

ng-repeat - content to show if array is empty or null

I've a deep nested ng-repeat lists, and only in the last loop I've to display alternate content if list was empty. I'm new to angular, saw some posts online please help me where can I use content if list is empty. The ng-repeat=sessions in day could be empty.
<ul class="day">
<li ng-repeat="sessions in day">
<ul class="table-view">
<li class="table-view-cell" ng-repeat="(heading, session) in sessions">
<span class="group">{{heading}}</span>
<ul class="cell">
<li class="cell-content" ng-repeat="val in session" ng-click="getSession(val.id)">
<div class="time" style="background-color:#{{val.color}}">
<span>{{val.start | date:"h:mma"}}</span>
<span>to</span>
<span>{{val.end | date:"h:mma"}}</span>
</div>
<div class="session" ng-class-odd="'odd'" ng-class-even="'even'">
<span class="name">{{val.name}}</span>
<span class="room">Room: {{val.room}}</span>
</div>
</li>
</ul>
</li>
</ul>
</li>
</ul>
1). CSS approach. I usually use pure CSS approach in such cases. With this markup (stripped extra-html):
<ul class="day">
<li ng-repeat="sessions in day">
...
</li>
<li class="no-sessions">
No sessions on this day.
</li>
</ul>
and CSS rules to hide .no-sessions li by default and make it visible only if there are no previous li tags:
li.no-sessions {
display: block;
}
li + li.no-sessions {
display: none;
}
So when sessions array is empty, there will be no li rendered and only no-sessions one will be visible. And if will hide as soon as there is at least one session on this day.
Demo: http://plnkr.co/edit/KqM9hfgTTiPlkdmEevDv?p=preview
2). ngIf approach. Of course you can use ngIf/ngShow directives for show no-records element when sessions array is empty:
<li ng-if="!day.length">
No sessions on this day.
</li>
I think this would work for your case:
<li ng-hide="day.length > 0">
No sessions on this day.
</li>
No extra CSS needed. Assumes day is an array.
http://plnkr.co/edit/WgDviOKjHKS1Vt5A5qrW
I would recommend handling that in your controller. Keeping your logic in the controller and javasript makes debugging easier and more manageable. I can think of 2 approaches: using ng-show/ng-hide or a condition for your day variable when its empty.
Option 1
ng-show/ng-hide approach:
$scope.isDayEmpty = function(){
return $scope.day.length > 0 ? false : true;
}
html:
<ul class="day">
<li ng-repeat="sessions in day" ng-hide="isDayEmpty">
...
</li>
<li ng-show="isDayEmpty">
No Sessions this Day
</li>
</ul>
Option 2:
ng-repeat approach
if($scope.day.length == 0){
$scope.day.push("No Sessions this Day");
}
This should get you essentially the same result. The first approach would make your CSS styling easier assuming you want to do something different in that case.
The second approach can vary in style depending on your code but thats an example of how you can do it. I don't know your javascript so I can't be more specific to your scenario.

How to select by class or id using selenium Webdriver?

i'm using Java/Selenium-webdriver/Eclipse
i want to click on an element which is in a menu of a webapp.
So i have to click on Menu and it shows a list and then i clik on an item.
i try to select the item "Chaine" with linkText and sometimes it's working
When i select with xpath it's working but i think it's not safe.
So i want to select by id or class.
How can i select "Chaine" by Id or class.
Or what is the best way to select this item.
THank you
So the html code is here:
<ul class="list">
<li class="component-panel-item" data-component="bar-graph">
<a>
Bar graph
</a>
</li>
<li class="component-panel-item" data-component="line-graph-ch">
<a>
Chaine
</a>
</li>
<li class="component-panel-item" data-component="line-graph-en">
<a>
En Graph
</a>
</li>
You can try out below code.
IWebElement ul = ie.FindElement(By.ClassName("list"));
ul.Click();
foreach (IWebElement li in ul.FindElements(By.ClassName("component-panel-item")))
{
if (li.Text.Equals("Chaine"))
{
li.Click();
}
}

ng-repeat inserting empty anchor tags

I'm trying to create a menu using angular. A menu item can have children requiring another ng-repeat to print the sub nav items. I'm noticing some strange behavior when attempting to insert an anchor tag within the 2nd ng-repeat.
Link to fiddle: http://jsfiddle.net/npU7t/
<li ng-repeat="sub_menu_item in menu_item.sub_menu">
<a href="">
{{ sub_menu_item.title }}
</a>
</li>
With
{
title: 'menu item with children',
sub_menu: [
{
title: '<-- empty anchor tag???'
}
]
}
Results in
<li ng-repeat="sub_menu_item in menu_item.sub_menu" class="ng-scope">
<-- empty anchor tag???
</li>
Where the did duplicate / empty anchor tag come from? How can I prevent it from being created?
Appreciate the help!
This isn't a bug with Angular, but rather how you have your markup.
UPDATE:
The issue is actually the nested <a> tag, not the <ul> tag.
<a href="">
<span class="title">{{ menu_item.title }}</span>
<ul class="sub-menu" ng-if="menu_item.sub_menu">
<li ng-repeat="sub_menu_item in menu_item.sub_menu">
<a href="">
{{ sub_menu_item.title }}
</a>
</li>
</ul>
</a>
In fact, if you remove Angular from the equation altogether, you will see that the extraneous <a> tag is still added to the DOM: http://jsfiddle.net/jwcarroll/cXkj4/
If you get rid of the nested <a> tag, then the extra element will disappear.
<a href="">
<span class="title">{{ menu_item.title }}</span>
</a>
<ul class="sub-menu" ng-if="menu_item.sub_menu">
<li ng-repeat="sub_menu_item in menu_item.sub_menu">
<a href="">
{{ sub_menu_item.title }}
</a>
</li>
</ul>
In both HTML 4.01, and HTML 5, having a nested <a> tag is a no no.
The simplest possible recreation of the problem I could come up with is this bit of markup:
<a href="">Outer
<p>Blah
Inner
</p>
</a>
Because you can't nest <a> elements within each other, the browser is doing it's best to recreate your intent while keeping the DOM clean. What you end up with is this:
Outer
<p>
Blah
Inner
</p>
This makes sense when you realize what the browser is trying to do. The browser is trying to do three things:
Keep Outer, Blah and Inner text elements inside hyperlinks
Contain Blah and <a>Inner</a> inside a single <p> tag
Ensure no <a> tags are nested within each other
The only sensible way to accomplish all three of these is to wrap both Outer and Blah text elements in separate <a> tags in a way that isn't nested. This is the closest approximation to the original intent without breaking the DOCTYPE rules.
I hope this helps.
Very strange. It doesn't appear with any tag besides <a> (like <p> or <div>). It looks like an outright bug to me - I'd submit a proper bug report.

Resources