Verify a text in the dropdown - selenium

I am trying to verify if the text is present in the dropdown menu. My assertion shows all the items, but with an error...expected[]but found[]. Please find below my script and the test failure message. Thanks in advance for the help!
My Script:
driver.findElement(By.cssSelector("#s2id_autogen4 > a.select2-choice > span")).click();;
ArrayList<String> expectedDropDownItems = new ArrayList<String>();
expectedDropDownItems.add("keysearch");
expectedDropDownItems.add("short");
expectedDropDownItems.add("standard");
expectedDropDownItems.add("to-date");
Assert.assertEquals(expectedDropDownItems, driver.findElement(By.xpath(".//*[#id='select2-drop']/ul")).getText());
ERROR MESSAGE:
java.lang.AssertionError: expected [keysearch
short
standard
to-date] but found [[keysearch, short, standard, to-date]]
HTML:
<div style="top: 1973px; left: 261px; width: 500px; display: block;" class="select2-drop select2-with-searchbox select2-drop-active" id="select2-drop">
<div class="select2-search">
<input type="text" class="select2-input" autocomplete="off" tabindex="0">
</div>
<ul class="select2-results" style="">
<li class="select2-results-dept-0 select2-result select2-result-selectable">
<div class="select2-result-label">
<span class="select2-match"></span>keysearch</div></li>
<li class="select2-results-dept-0 select2-result select2-result-selectable">
<div class="select2-result-label">
<span class="select2-match"></span>short</div></li>
<li class="select2-results-dept-0 select2-result select2-result-selectable">
<div class="select2-result-label">
<span class="select2-match"></span>standard</div></li>
<li class="select2-results-dept-0 select2-result select2-result-selectable" style="">
<div class="select2-result-label">
<span class="select2-match"></span>to-date</div></li></ul>
</div>

What you can do is,
1- First get all the elements of the dropdown.
2- Put it in a List
3- Iterate over the list, get texts of each element and then put it in a new ArrayList of Strings.
4- Assert using this ArrayList and the Original ArrayList of items.
Below code will help you out:
//Putting actual items in the Arraylist of expectedDropDownItems
ArrayList<String> expectedDropDownItems = new ArrayList<String>();
expectedDropDownItems.add("keysearch");
expectedDropDownItems.add("short");
expectedDropDownItems.add("standard");
expectedDropDownItems.add("to-date");
//Iterating over expected items and printing
System.out.println("\n--- Expected Items");
for(int i=0;i<expectedDropDownItems.size();i++)
System.out.println(expectedDropDownItems.get(i));
System.out.println("\n");
ArrayList<String> actualDropDownItems = new ArrayList<String>();
//Getting the list of all items in dropdown
List<WebElement> elements = driver.findElements(By.xpath("//div[#class='select2-result-label']"));
//Iterating over the list of dropdown, getting text of each element and adding the text to the Arraylist of actualDropDownItems
for(WebElement element : elements){
System.out.println("Adding element: "+ element.getText());
actualDropDownItems.add(element.getText());
}
//Iterating over actual items and printing
System.out.println("\n--- Actual Items");
for(int i=0;i<actualDropDownItems.size();i++)
System.out.println(actualDropDownItems.get(i));
//Asserting the ArrayLists if they are equal or not
Assert.assertEquals(expectedDropDownItems, actualDropDownItems);
System.out.println("Asserted text match");

According to assertion i can suppose and suggest to do next on attempt to fix your problem (p.s. i'm not good at java, but according my exp in C#):
1. Try to print data returned from driver.findElement(By.xpath(".//*[#id='select2-drop']/ul")).getText() code and make sure that this data really equals to your data from arrayList.
2. If data seem equal, try another assertion methods (such as Assert.That(object, matcher) (e.g. in C# in could be Assert.That(new[]{1}, Is.EquivalentTo(new[]{1}));), Assert.arrayEquals etc)
If both arrays are equal and asserts not help, please provide sample of html and we will try to solve that problem in other way.

Related

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());
}

How to deal with checkbox using selenium webdriver?

i want to scrape a page with checkboxes with no id, they have the same name and just the values are differents.
<div class="mvNavLk">
<form class="jsExpSCCategories" method="post" name="ExpressSCCategories" action="actionTest.html">
<ul class="mvSrcLk">
<li>
<label class="mvNavSel mvNavLvl1">
First
<input type="checkbox" value="firstValue" name="selectedNavigationCategoryPath">
</label>
</li>
<li>
<label class="mvNavSel mvNavLvl1">
Second
<input type="checkbox" value="secondValue" name="selectedNavigationCategoryPath">
</label>
</li>
</ul>
</form>
</div>
use below code:
driver.find_element_by_css_selector(".mvSrcLk>li:nth-child(1)>label.mvNavSel.mvNavLvl1").click();
hope this will work.
Hope this works-
driver.FindElement(By.XPath(".//label[contains(text(),'First')]/input")).SendKeys("test");
Hi please do it like below Note this example is in java
// take check boxes with same name inside the list
List<WebElement> myCheckBox = driver.findElements(By.name("selectedNavigationCategoryPath"));
// now on the basis of index call click
myCheckBox.get(0).click(); // for the first check box
Thread.sleep(2000);
myCheckBox.get(1).click(); // for the second check box
or if you want to select on the basis of value then
driver.findElement(By.xpath("//*[#value='firstValue']")).click(); // for the 1st one
Thread.sleep(2000);
driver.findElement(By.xpath("//*[#value='secondValue']")).click(); // for the 2st one
UPDATE
WebDriverWait wait = new WebDriverWait(driver,30);
wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath("//*[#value='firstValue']")));
driver.findElement(By.xpath("//*[#value='firstValue']")).click(); // for the 1st one
Hope this helps you
driver.findElement(By.name("selectedNavigationCategoryPath")).click();
Below Code is in C#, Collects all the Checkboxes with the name specified. Then Iterates through each ckeckbox, gets the value attribute, if the attribute is equal to your specified check box, then clicks it and comes out of the loop. Hope this should work.
IList<IWebElement> myCheckBoxs = driver.FindElements(By.name("selectedNavigationCategoryPath"));
Foreach(IWebElement chkBx in myCheckBoxs)
{
if(chkBx.GetAttribute("Value")=="Your Desired value")
{
chkBx.Click();
break;
}
}
`
Use this CSS locator.
[name='selectedNavigationCategoryPath'][value='firstValue']

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());
}