Selenium Framework(finding the field name) - selenium

I am trying to find the field name "SavePLButton". The Html code behind this page is:
<ul class="button-bar">
<li class="first">
<a href="#" id="SavePLButton" type="button" name="SavePLButton" value="Save" onclick="formSubmit('SAVEEXIT');">
<i class="icon-save"/>
Save
</a>
</li>
The C# code that I am using is:
var Submit = Driver.Instance.FindElement(By.CssSelector("i.icon-save"));
Submit.Click();
I have also tried:
var Submit = Driver.Instance.FindElement(By.Id("SavePLButton"));
Submit.Click();
It is unable to find the fieldname. Can someone please help. Thank you.

Try using WebDriverWait to wait until element visible as below :-
var wait = new WebDriverWait(driver, TimeSpan.FromSeconds(10));
var Submit = wait.Until(ExpectedConditions.ElementIsVisible(By.Id("SavePLButton")));
Submit.Click();
Note :- make sure before try this element is not inside any frame
Hope it helps.....:)

Related

Selenium Webdriver C# Unable to locate an element on the "active" dropdown class list

I am on the beginner level if it goes for the selenium Webdriver in C#. I can locate elements, write simple scripts in order to input some value, withdraw it, compare and etc. I can also get values from the dropdown list by SelectElement class and so far I have not had any issues.
Recently one of our systems was refactored to React JS and most of my automation tests have stopped working.
Right now I have been struggling with a simple logout operation. I will please my issue below, and I would be grateful for any tips or suggestions.
The hard thing is that I can not locate the logout link which is located in the dropdown list, however, the code for it looks as below. Before you click on the link which acts as an action for the drop-down list it looks like this:
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">
<span class="glyphicon glyphicon-user" aria-hidden="true"></span>
UserName UserLast
<span class="caret"></span>
</a>
<ul class="dropdown-menu">
<li>Logout</li>
</ul>
<div id="user-login" class="hidden">UserName.UserLast</div>
<div id="user-email" class="hidden">UserName.UserLast#companyname.com</div>
</li>
When a User clicks on the the code changes to this one below:
<li class="dropdown open">
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="true">
<span class="glyphicon glyphicon-user" aria-hidden="true"></span>
UserName UserLast
<span class="caret"></span>
</a>
<ul class="dropdown-menu">
<li>Logout</li>
</ul>
<div id="user-login" class="hidden">UserName.UserLast</div>
<div id="user-email" class="hidden">UserName.UserLast#companyname.com</div>
</li>
My test is quite simple, locate the Logout "button/link", click on it and perform the logout operation. Now I have started of location the action link which looks like this:
[FindsBy(How = How.XPath, Using = "/html/body/div[1]/div/div[2]/ul[2]/li[2]/a")]
private IWebElement userDropdown;
And my logout method looks like that's,
public void LogOut()
{
userDropdown.Click();
var userDropDownList = Browser.WebDriver.FindElement(By.XPath("/html/body/div[1]/div/div[2]/ul[2]/li[2]/ul"));
var logoutButton = userDropDownList.FindElement(By.LinkText("Logout"));
logoutButton.Click();
}
I perform the click operation on the link, look for the list with the Logout, use the click operation. Still my test does not work and I am not getting any errors at all but the logout operation is not done. I think that the issue here is not the drop-down list is not visible by selenium. I have not tried the SelectElement class because this example is not a select element or maybe I am wrong...
You will need to perform click() on 2 elements to logout:
Identify the dropdown:
[FindsBy(How = How.XPath, Using = "//li[#class='dropdown']/a[#class='dropdown-toggle']/span[#class='glyphicon glyphicon-user']")]
private IWebElement userDropdown;
logOut method:
public void logOut()
{
userDropdown.Click();
var logoutButton = Browser.WebDriver.FindElement(By.XPath("//li[#class='dropdown']//ul[#class='dropdown-menu']/li/a[#href='/Account/Logout']"));
logoutButton.Click();
}
so first things first make sure you've scrolled the item to view
var js = (IJavascriptExecutor)driver;
string idOfLinkToMakeDropDownOpen = "whatever the id is"
IWebElement obj = driver.FindElement(By.XPath("//input[#id='idOfLinkToMakeDropDownOpen']"));
js.ExecuteScript("arguments[0].scrollIntoView(true);", obj);
obj.Click();
Now the drop down should be open so click it
driver.FindElement(By.Xpath("descendant::a[text() = 'Logout']")).Click();
That should click it. You'll probably want to watch it to see if opens the drop down. You also may need to wait a second after the dom to change after having opened the drop down. That would work something like this:
IWebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(15));
after obj.Click(); you do this line:
wait.Until(ExpectedConditions.ElementIsVisible(By.Xpath("descendant::li[#class = 'dropdown open']"));

How to select specific element form list by using Selenium WebDriver?

Can anyone guide me how to select specific element from list view
from using below code.
<div id="menu" class="tabalign k-widget k-reset k-header k-menu k-menu-horizontal" data-role="menu" tabindex="0" role="menubar" aria-activedescendant="menu_mn_active">
<li class="k-item k-state-default k-first mainMenu2" role="menuitem" id="menu_mn_active"><span class="k-link"><img class="k-image" alt="" src="/Images/Common/Module_2.png"><span id="2">Profiles</span></span></li>
<li class="k-item k-state-default mainMenu3" role="menuitem"><span class="k-link"><img class="k-image" alt="" src="/Images/Common/Module_3.png"><span id="3">Contacts</span></span></li>
And I have tried below code but it is not worked for me:
WebElement element = driver.findElements(By.xpath("//*[#id=\"menu_mn_active\"]"));
element.click();
Try this code in Java (it selects first element from dropdown):
driver.findElement(By. id("menu")).click();
List<WebElement> options = driver.findElements(By. cssSelector(".k-item.k-state-default"));
for (WebElement opt : options) {
if (opt.getText().equals("Profiles")) {
opt.click();
}
}
You can use like this:
First get location of all elements:
List<WebElement> element = driver.findElements(By.xpath("//*[#id=\"menu_mn_active\"]"));
For the first element:
element.get(0).click(); // for first element
For the second element:
element.get(1).click(); // for second element

trouble making in xpath for "ul" html code in selenium webdriver

HTML code:
<div id="routingPanel" class="">
<div id="routingPanelRight">
<ul id="routingList" class="ui-sortable">
<li class="ui-menu-item ui-draggable" style="display: list-item;" role="presentation" data-type="srl" data-id="15">
<a class="ui-corner-all" tabindex="-1">AS-HTTS-US-LAN-SW</a>
<span class="fa fa-trash"/>
<span class="type">[srl]</span>
</li>
<li class="ui-menu-item ui-draggable" style="display: list-item;" role="presentation" data-type="queue" data-id="119">
<a class="ui-corner-all" tabindex="-1">AS-EMEA-NORTH</a>
<span class="fa fa-trash"/>
<span class="type">[queue]</span>
</li></ul></div></div>
I need to click on a button which is having the span class"fa fa-trash" but it is inside li class. And i have list on buttons on the page with li class changing.
I am giving testdata from excel file so i can't use the direct value.
i tried to use this xpath
.//*[#id='routingList']/li[5]/span[1] //testdata1
.//*[#id='routingList']/li[2]/span[1] //testdata2
where li value changes everytime from excel file.
WebDriverWait wait = new WebDriverWait(driver, 15);
wait.until(ExpectedConditions.visibilityOfElementLocated((By.xpath("//ul[#id='routingList']/li/span[1]")))).click();
List<WebElement> options = driver.findElements(By.xpath("//ul[#id='routingList']/li/span[1]"));
for (WebElement option : options) {
if(testData.equals(option.getText()))
option.click();
Tried above code but it is deleting only one from the list ,where i have passed two more testdata that needs to be deleted.
Need suggestions Please
According to the information you gave me in comments, I think the problem is that you are trying to get a text from an element that doesn't contain text.
Let's say your testData is AS-HTTS-US-LAN-SW. In the HTML you provided and the xpath you mentioned, you are selecting an autoclosing tag <span class="fa fa-trash"/>. Once this tag is selected, you are trying to get the text inside of it, and there is none.
<ul id="routingList" class="ui-sortable">
<li class="ui-menu-item ui-draggable" style="display: list-item;" role="presentation" data-type="srl" data-id="15">
===========================
<a class="ui-corner-all" tabindex="-1">AS-HTTS-US-LAN-SW</a> ----> The text is contained here
<span class="fa fa-trash"/> ---> No text in that tag
===========================
<span class="type">[srl]</span>
</li>
</ul>
So, basically, you have to modify a little bit your xpath from : //ul[#id='routingList']/li/span[1] to : //ul[#id='routingList']/li/a to get the text, and then go back to the parent node to find your button with : ../span[contains(#class, 'fa fa-trash')]
WebDriverWait wait = new WebDriverWait(driver, 15);
wait.until(ExpectedConditions.visibilityOfElementLocated((By.xpath("//ul[#id='routingList']/li/span[1]")))) // removed the click here because you were clicking on the first element of the list
List<WebElement> options = driver.findElements(By.xpath("//ul[#id='routingList']/li/a"));
for (WebElement option : options) {
if(testData.equals(option.getText()))
option.findElement(By.xpath("../span[contains(#class, 'fa fa-trash')]")).click();
Tell me if it helped
I know you already accepted an answer but there's a more efficient way to do this. You can specify the text you are looking for as part of the XPath. So, you do a single search instead of looping through all the options which can be a performance hit if there are many options. Also, with something like this you are likely to use it more than once so put it in a function.
In this case, the function would take in the string you are looking for and then click the appropriate element.
public void selectRegion(String regionName)
{
driver.findElement(By.xpath("//a[.='" + regionName + "']/following-sibling::span[#class='fa fa-trash']")).click();
}
and you would call it like
selectRegion(testData);
The function looks for an A tag that contains the desired text and then clicks the sibling SPAN with class fa fa-trash.

No such element Exception. class name with double__

I am trying to get the text under the tag. That is Arduus, Gstaad, Switzerland. I tried with the classname and also with xpath.
driver.findElement(By.className("chalet-details__title"));
String chaletTitle = driver.findElement(By.xpath("//div/h1[#class='chalet-details_title']")).getText();
But its giving NoSuchElementException. The classname has double underscore(__) .Is it because of that not working? Can anyone help me with this?
<div class="col-md-12 col-sm-12 col-xs-12">
<h1 class="chalet-details__title">
<span class="chalet-details__title-property">Arduus</span>,
<a class="chalet-details__title-resort" href="/ski- resorts/switzerland/gstaad">Gstaad</a>,
<a class="chalet-details__title-country" href="/ski- resorts/switzerland">Switzerland</a>
</h1>
<div class="chalet-details__rating">
<div class="chalet-details__wrapper">
<span class="chalet-details__star" style="width: 108px;"></span>
<span class="chalet-details__mask"></span>
</div>
</div>
</div>
You can try something like:
driver.findElement(by.cssSelector("h1.chalet-details__title"))
I just tried this and it worked fine with the provided html, if this still fails for you, can you verify that there aren't any iframes on the page.
Both your locators are OK, but you might need to wait for your element to be present in DOM:
WebDriverWait wait= new WebDriverWait(driver,20 );
String chaletTitle = wait.until(ExpectedConditions.presenceOfElementLocated(By.className("chalet-details__title"))).getText();
Another reason for NoSuchElementException: your element could be located inside an iframe, so you need to switch to that frame before handling target element:
driver.switchTo().frame("iframeNameOrId");
If it has no attributes as id or name:
WebElement someFrame = driver.findElement(By.xpath("//iframe[#someAttr='someValue']"));
driver.switchTo().frame(someFrame);
To get all the text under h1 tag find all elements using locator as follows:
List<WebElement> items = driver.findElements(By.cssSelector("h1.chalet-details__title > *")); //it will find all elements immediately under the h1 tag
Now, iterate over the elements.
Complete code:
List<WebElement> items = driver.findElements(By.cssSelector("h1.chalet-details__title > *"));
for(WebElement item : items){
System.out.println(item.getText());
}

Identifying the Web element with same class name in Selenium

I have tried to get the number of tweets(tweet count) through selenium
Here is the page source:
<li class="DashboardProfileCard-stat Arrange-sizeFit">
<a class="DashboardProfileCard-statLink u-textUserColor u-linkClean u-block"
title="1 Tweet"
href="/saisiva14"
data-element-term="tweet_stats">
<span class="DashboardProfileCard-statLabel u-block">Tweets</span>
<span class="DashboardProfileCard-statValue" data-is-compact="false">1</span>
</a>
</li>
<li class="DashboardProfileCard-stat Arrange-sizeFit">
<a class="DashboardProfileCard-statLink u-textUserColor u-linkClean u-block"
title="38 Following"
href="/following"
data-element-term="follower_stats">
<span class="DashboardProfileCard-statLabel u-block">Following</span>
<span class="DashboardProfileCard-statValue" data-is-compact="false">38</span>
</a>
</li>
<li class="DashboardProfileCard-stat Arrange-sizeFit">
<a class="DashboardProfileCard-statLink u-textUserColor u-linkClean u-block"
title="4 Followers"
href="/followers"
data-element-term="following_stats">
<span class="DashboardProfileCard-statLabel u-block">Followers</span>
<span class="DashboardProfileCard-statValue" data-is-compact="false">4</span>
</a>
</li>
I could not able to locate the web element for getting Tweets,Followers & following. The reason is span class names are common for all these elements.Please help me .
To get number of Tweets/ Following/ Followers, You can try the below statements:
System.out.println(driver.findElement(By.xpath("//a[contains(#title, 'Tweet')]/span[2]")).getText());
System.out.println(driver.findElement(By.xpath("//a[contains(#title, 'Following')]/span[2]")).getText());
System.out.println(driver.findElement(By.xpath("//a[contains(#title, 'Followers')]/span[2]")).getText());
To click on the Tweets/ Following/ Followers links, You can try the below statements:
driver.findElement(By.xpath("//a[contains(#title, 'Tweet')]")).click();
driver.findElement(By.xpath("//a[contains(#title, 'Following')]")).click();
driver.findElement(By.xpath("//a[contains(#title, 'Followers')]")).click();
or
driver.findElement(By.xpath("//a[./span[text()='Tweets']]")).click();
driver.findElement(By.xpath("//a[./span[text()='Following']]")).click();
driver.findElement(By.xpath("//a[./span[text()='Followers']]")).click();
The above statements are working fine for me.
try this
IList<IWebElement> elements = driver.FindElements(By.ClassName("DashboardProfileCard-stat"));
foreach (IWebElement element in elements)
{
IWebElement ele = element.FindElement(By.ClassName("DashboardProfileCard-statLabel"));
if (ele.Text == "Tweets")
{
return element.FindElement(By.ClassName("DashboardProfileCard-statValue")).Text;
}
}
this is using C#, you can modify accordingly if anyother language is used.
The selector .DashboardProfileCard-stat span:nth-child(2) should give you the collection of web elements pointing to the count. For example in Java:
ArrayList<WebElement> elements = driver.findElements(By.cssSelector(".DashboardProfileCard-stat span:nth-child(2)"))
Then you can use elements.get(0).getText() for tweets. elements.get(1).getText() for following. elements.get(2).getText() for followers. So:
ArrayList<WebElement> elements = driver.findElements(By.cssSelector(".DashboardProfileCard-stat span:nth-child(2)"));
int tweets = elements.get(0).getText();
int following = elements.get(1).getText();
int followers = elements.get(2).getText();
Of course, do your appropriate safety checks, etc. Check the length of the array before access.
This code is in Java :)
capture all the parents of the "SPAN" into a collection item.
Iterate on the collection to find the span elements (which are child of <a> tag) and capture text based on the class name variation statLabel / statValue".
List<WebElement> webElement = driver.findElements(By.xpath("//li[#class='DashboardProfileCard-stat Arrange-sizeFit']//a"));
for (WebElement element : webElement) {
System.out.println(element.findElement(By.xpath("//span[contains(#class,'statLabel')]")).getText());
System.out.println(element.findElement(By.xpath("//span[contains(#class,'statValue')]")).getText());
}