How to select by class or id using selenium Webdriver? - 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();
}
}

Related

I need to be able to select a distinct dynamic xpath

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.

add active class to menu item clicked add remove from others

I want to add isActive class to an item menu when user click on this item, and remove isActive class from all others items.
I am trying to compare the id, this is the angularJS code:
$rootScope.isActive = function(idVal, event){
return idVal === event.target.id;
}
This is a part from Menu Html code:
<ul class="sidebar-nav">
<li>
<a ui-sref="" id='101' ng-class="{active: isActive($event, 101)}">
<span class='glyphicon glyphicon-ban-circle glyph-sidebar'></span>
Rules
</a>
<ul class='dropdown sidebar-nav-dropdown' >
<li>
Transaction Mapping
</li>
<li>
File Setup
</li>
<li>
Code Setup
</li>
</ul>
</li>
<li>
<a href="#" id='102' ng-class="{active: isActive($event, 102)}">
<span class='glyphicon glyphicon-ban-circle glyph-sidebar'></span>
Administrative Rules
</a>
<ul class='dropdown sidebar-nav-dropdown'>
<li>
<a ui-sref="admin.mapping-rules">Transaction Mapping</a>
</li>
<li>
<a ui-sref="admin.mapping-rules">File Setup</a>
</li>
<li>
<a ui-sref="admin.mapping-rules">Code Setup</a>
</li>
</ul>
</li>
</ul>
Thanks,
First of all, you shouldn't use the root scope. You should use the scope of the controller associated to that view.
Second, your code doesn't make much sense. $event can be used as a parameter of a function called... to react to an event:
ng-click="doSomething($event)"
But with ng-class, there is no $event.
All you need to have in your scope is the ID (or name, or whatever identifies a menu item) of the selected menu item:
$scope.selectedMenuItem = null;
When an item is clicked, you need to change the selected menu item:
ng-click="selectMenuItem(101)"
$scope.selectMenuItem(item) {
$scope.selectedMenuItem = item;
}
Then to associated a css class with the selected menu item, you simply need
ng-class="{active: selectedMenuItem === 101}"
That said, if all your links navigate to a given router state, you don't even need that selectedMenuItem. All you need is to add the active class if the current router state is the one the that the link allows navigating to (assuming $state is on your scope):
ng-class="{active: $state.includes('admin.mapping-rules')}

UI-Router ui-sref-active throws error when using ui-sref params

I've got a Bootstrap navbar dropdown menu, where clicking the parent link produces the dropdown list (default behaviour). The dropdown list of the parent is built using ngRepeat from an array of navigation data, and each has a ui-router state parameter, so it looks like:
<li class="dropdown">
<a href class="dropdown-toggle" data-toggle="dropdown">
Parent Link
</a>
<ul class="dropdown-menu" role="menu">
<li ng-repeat="item in navCtrl.items()"
ui-sref-active="active">
<a ui-sref="some.state({ paramKey: paramValue })">
{{item.link}}
</a>
</li>
</ul>
</li>
But, even though it does seem to drop the active class on my link it throws this error in the console:
TypeError: Cannot read property 'name' of undefined
I am not entirely sure about the answer, but, as far as I know, why would you use navCtrl.items() using brackets? I have never seen it used like that before. Wouldn't the old item in items ng-repeat work? Sorry if it does not help at all.

Unable to click the submenu in selenium webdriver

Mouse hover menu’s does not work. Please see further details below:-
When I click start --> I get the submenus.
When I click customer submenu--> element not clickable
a. I should be able to go to “Search for Customers” or “Create Top level Customer”
<div class="TidyMenu Horizontal" id="mainNav">
<ul class="level1">
<li><a class="popout level1" href="#" onclick="__doPostBack('ctl00$mainNav','Start')">Start</a>
<ul class="level2">
<li><a class="popout level2" href="#" onclick="__doPostBack('ctl00$mainNav','Start\\Customers')">Customers</a>
<ul class="level3">
<li><a title="Search for Customers" class="level3" href="#" onclick="__doPostBack('ctl00$mainNav','Start\\Customers\\3')">Search for Customers</a></li>
<li><a title="Create Top level Customer" class="level3" href="#" onclick="__doPostBack('ctl00$mainNav','Start\\Customers\\8')">Create Top level Customer</a></li>
</ul>
</li>
</ul>
</li>
<div>
Use Actions utility to first mouse hover on Start and then click on the desired sub menu. Sample code should look like below:
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;
using OpenQA.Selenium.Interactions.Internal;
using OpenQA.Selenium.Support.UI;
//create Actions object
Actions builder = new Actions(driver);
IWebElement menuHoverLink = driver.FindElement(By.XPath("//a[text()='Start']"));
builder.MoveToElement(menuHoverLink);
IWebElement subLink = driver.FindElement(By.LinkText("Customers"));
builder.MoveToElement(subLink);
builder.Click();
builder.Build().Perform();
Lemme know if this helps!
We can use the keys to move over and click, instead of trying with the mouse coordinates this is with the keyboard.
Please try this
Mousehover:
String hover=Keys.chord(Keys.DOWN);
driver.findElement(By.linkText("the text which has to be clicked")).sendKeys(hover);
Click:
String clickdown=Keys.chord(Keys.ENTER);
driver.findElement(By.linkText("sub menu which has to be clicked")).sendKeys(clickdown);

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