Getting empty dropdown in JSP - java

Here is the code. When I click the dropdown icon, it is empty. I want it to be loaded as soon as the page loads
ArrayList<Notifications> notifications = (ArrayList<Notifications>) session.getAttribute("notif");
<ul class="nav navbar-nav navbar-right">
<li class="dropdown" data-toggle="tooltip" data-placement="bottom" title="Friend Requests">
<a href="#" class="dropdown-toggle" data-toggle="dropdown">
<i class="fa fa-user"></i>
</a>
<ul class="dropdown-menu" role="menu">
<%
for(int i=0; i<notifications .size(); i++){
%>
<li>
<%= notifications .get(i).getSender() %>
</li>
<% } %>
</ul>
</li>
</ul>

Look at this simple sample :
<%
ArrayList<String> notifications = new ArrayList<String>();
notifications.add("One");
notifications.add("Two");
notifications.add("Three");
for(int i=0; i<notifications.size(); i++){
%>
<li>
<%= notifications.get(i).toString() %>
</li>
<%}%>
It works and print the Three letters. As I don't know your Notification object, I used an Array of String. Compare this with your code (May be you do not get complete array from session, or may be the getSender method does not return correct data.

Related

how to wait for list of elements to be loaded in dynamic

i have a search box, when i do search a value, say a bank name, it displays the results matching the text given on the search box. But the catch here is it may not an exact result, and also it takes some seconds to load in a complete list, by refreshing intellectually within the search results. so even if i wait for some results to load, it gets the values immediately whatever came at that moment, but actually it refreshes the list even after couple more seconds. So how can i wait for complete load and then take out the results. any help on this please.
code snippet
<ul class="DropDown__options DropDown__options--small--focused DropDown__options--focused" id="searchTopBank-listbox" role="listbox" aria-activedescendant="searchTopBank-options-4">
<li aria-selected="true" class="DropDown__option TypeAhead__option DropDown__option--focused DropDown__option--small" id="searchTopBank-options-0" role="option">
<img alt="" class="dropdown-logo" src="data">
<span>
<span class="DropDown__matched-option-chars">Bank of America</span>
</span>
</li>
<li aria-selected="false" class="DropDown__option TypeAhead__option DropDown__option--focused DropDown__option--small" id="searchTopBank-options-1" role="option">
<img alt="" class="dropdown-logo" src="data">
<span>First National
<span class="DropDown__matched-option-chars">Bank of America</span>
</span>
</li>
<li aria-selected="false" class="DropDown__option TypeAhead__option DropDown__option--focused DropDown__option--small" id="searchTopBank-options-2" role="option">
<img alt="" class="dropdown-logo" src="data:image/png;base64, null">
<span>Second National Farmer's
<span class="DropDown__matched-option-chars">Bank of America</span>
</span>
</li>
<li aria-selected="false" class="DropDown__option TypeAhead__option DropDown__option--focused DropDown__option--small" id="searchTopBank-options-3" role="option">
<img alt="" class="dropdown-logo" src="data:image/png;base64, null">
<span>
<span class="DropDown__matched-option-chars">Altabank</span>
</span>
</li>
<li aria-selected="false" class="DropDown__option TypeAhead__option DropDown__option--focused DropDown__option--hover DropDown__option--small" id="searchTopBank-options-4" role="option">
<img alt="" class="dropdown-logo" src="data:image/png;base64, null">
<span>Freedom
<span class="DropDown__matched-option-chars">Bank of America</span>
</span>
</li>
</ul>
I would suggest doing something like this:
WebDriverWait wait = new WebDriverWait(driver, 20);
public void wait(int delay){
try {
Thread.sleep(delay);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
String searchResult = "//li[contains(#id,'searchTopBank-options')]";
wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath(searchResult)));
int initialAmount = driver.findElements(By.xpath(searchResult)).size();
while(true){
wait(200);
int newAmount = driver.findElements(By.xpath(searchResult)).size();
if(newAmount > initialAmount){
initialAmount = newAmount;
}else{
break;
}
}
The wait amount depends on the slowest actual speed of bringing the new search results.
Why not mix worst ExplicitWait - (Thread.sleep(5000)) and Mix it with a reliable ExplicitWait - visibilityOfAllElements and give a list using - driver.findElements:
I believe this css represent all the elements :
span.DropDown__matched-option-chars
code :
Thread.sleep(5000);
new WebDriverWait(driver, 10).until(ExpectedConditions.visibilityOfAllElements(driver.findElements(By.cssSelector("span.DropDown__matched-option-chars"))));

Can't get text from dropdown options

driver.findElement(By.xpath("//*[#id=\"_desktop_currency_selector\"]/div")).click();
List<WebElement> list = driver.findElements(By.xpath("//*[#id=\"_desktop_currency_selector\"]/div/ul//li"));
System.out.println(list.size());
for (int i=0; i<list.size(); i++){
System.out.println(list.get(i).getText());
}
Output:
3
EUR €
I'm need to get the text from items in dropdown, my code can find all li elements and print number of them, but when I'm trying to print the visible text from them but I'm getting only text from the first option :(
I would be very grateful for a hint...
Part of page source:
<div id="_desktop_currency_selector">
<div class="currency-selector dropdown js-dropdown">
<span>Currency:</span>
<span class="expand-more _gray-darker hidden-sm-down" data-toggle="dropdown">UAH ₴</span>
<a data-target="#" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" class="hidden-sm-down">
<i class="material-icons expand-more"></i>
</a>
<ul class="dropdown-menu hidden-sm-down" aria-labelledby="dLabel">
<li >
<a title="European EURO" rel="nofollow" href="http://wasd.com.ua/ru/search?order=product.price.desc&s=dress&SubmitCurrency=1&id_currency=2" class="dropdown-item">EUR €</a>
</li>
<li class="current" >
<a title="Ukrainian UAH" rel="nofollow" href="http://wasd.com.ua/ru/search?order=product.price.desc&s=dress&SubmitCurrency=1&id_currency=1" class="dropdown-item">UAH ₴</a>
</li>
<li >
<a title="Dollar USA" rel="nofollow" href="http://wasd.com.ua/ru/search?order=product.price.desc&s=dress&SubmitCurrency=1&id_currency=3" class="dropdown-item">USD $</a>
</li>
</ul>
<select class="link hidden-md-up">
<option value="http://wasd.com.ua/ru/search?order=product.price.desc&s=dress&SubmitCurrency=1&id_currency=2">EUR €</option>
<option value="http://wasd.com.ua/ru/search?order=product.price.desc&s=dress&SubmitCurrency=1&id_currency=1" selected="selected">UAH ₴</option>
<option value="http://wasd.com.ua/ru/search?order=product.price.desc&s=dress&SubmitCurrency=1&id_currency=3">USD $</option>
</select>
</div>
I've added a tag at the end which seems working.
List<WebElement> list = driver.findElements(By.xpath("//*[#id=\"_desktop_currency_selector\"]/div/ul/li/a"));
Also if you just want to print the text inside <option> tag use this:
List<WebElement> list = driver.findElements(By.xpath("//*[#id=\"_desktop_currency_selector\"]/div/select/option"));
Both of this produce same result.
Output:
3
EUR €
UAH ₴
USD $
// preprare emtpy list
List<String> texts = new ArrayList<String>();
// get the dropdown element
WebElement dropDown = driver.findElement(By.className("link hidden-md-up"));
// get dropdown options
List<WebElement> options = dropDown.findElements(By.tagName("option"));
// collect texts
for (WebElement option: options) {
texts.add(option.getText());
}

How to check when an element changes its state from enable to disable in Selenium

I have a view of items. There are total 29 pages and in one page there are 20 items are displayed. I'm trying to get the count of total items (including all pages) via selenium.
Here is the HTML for the first page :
<div class="pagination pagination-toolbar clearfix">
<nav role="navigation" aria-label="Pagination">
<ul class="pagination-list">
<li class="disabled">
<span >
<span class="icon-backward icon-first" aria-hidden="true"></span> </span>
</li>
<li class="disabled">
<span >
<span class="icon-step-backward icon-previous" aria-hidden="true"></span> </span>
</li>
<li class="active">
<span aria-current="true" aria-label="Page 1">
1 </span>
</li>
<li class="hidden-phone">
<a aria-label="Go to page 2" href="#" onclick="document.adminForm.limitstart.value=20; submitform();return false;">
2 </a>
</li>
<li class="hidden-phone">
<a aria-label="Go to page 3" href="#" onclick="document.adminForm.limitstart.value=40; submitform();return false;">
3 </a>
</li>
<li class="hidden-phone">
<a aria-label="Go to page 4" href="#" onclick="document.adminForm.limitstart.value=60; submitform();return false;">
4 </a>
</li>
<li class="hidden-phone">
<a aria-label="Go to page 5" href="#" onclick="document.adminForm.limitstart.value=80; submitform();return false;">
5 </a>
</li>
<li class="hidden-phone">
<a aria-label="Go to page 6" href="#" onclick="document.adminForm.limitstart.value=100; submitform();return false;">
6 </a>
</li>
<li class="hidden-phone">
<a aria-label="Go to page 7" href="#" onclick="document.adminForm.limitstart.value=120; submitform();return false;">
7 </a>
</li>
<li class="hidden-phone">
<a aria-label="Go to page 8" href="#" onclick="document.adminForm.limitstart.value=140; submitform();return false;">
8 </a>
</li>
<li class="hidden-phone">
<a aria-label="Go to page 9" href="#" onclick="document.adminForm.limitstart.value=160; submitform();return false;">
9 </a>
</li>
<li class="hidden-phone">
<a aria-label="Go to page 10" href="#" onclick="document.adminForm.limitstart.value=180; submitform();return false;">
10 </a>
</li>
<li>
<a aria-label="Go to next page" class="hasTooltip" title="Next" href="#" onclick="document.adminForm.limitstart.value=20; submitform();return false;">
<span class="icon-step-forward icon-next" aria-hidden="true"></span> </a>
</li>
<li>
<a aria-label="Go to end page" class="hasTooltip" title="End (Page 29 of 29)" href="#" onclick="document.adminForm.limitstart.value=560; submitform();return false;">
<span class="icon-forward icon-last" aria-hidden="true"></span> </a>
</li>
</ul>
</nav>
<input type="hidden" name="limitstart" value="0" />
</div>
Here is the HTML of last page:
<div class="pagination pagination-toolbar clearfix">
<nav role="navigation" aria-label="Pagination">
<ul class="pagination-list">
<li>
<a aria-label="Go to start page" class="hasTooltip" title="Start (Page 1 of 29)" href="#" onclick="document.adminForm.limitstart.value=0; submitform();return false;">
<span class="icon-backward icon-first" aria-hidden="true"></span> </a>
</li>
<li>
<a aria-label="Go to previous page" class="hasTooltip" title="Previous" href="#" onclick="document.adminForm.limitstart.value=540; submitform();return false;">
<span class="icon-step-backward icon-previous" aria-hidden="true"></span> </a>
</li>
<li class="hidden-phone">
<a aria-label="Go to page 20" href="#" onclick="document.adminForm.limitstart.value=380; submitform();return false;">
20 </a>
</li>
<li class="hidden-phone">
<a aria-label="Go to page 21" href="#" onclick="document.adminForm.limitstart.value=400; submitform();return false;">
21 </a>
</li>
<li class="hidden-phone">
<a aria-label="Go to page 22" href="#" onclick="document.adminForm.limitstart.value=420; submitform();return false;">
22 </a>
</li>
<li class="hidden-phone">
<a aria-label="Go to page 23" href="#" onclick="document.adminForm.limitstart.value=440; submitform();return false;">
23 </a>
</li>
<li class="hidden-phone">
<a aria-label="Go to page 24" href="#" onclick="document.adminForm.limitstart.value=460; submitform();return false;">
24 </a>
</li>
<li class="hidden-phone">
<a aria-label="Go to page 25" href="#" onclick="document.adminForm.limitstart.value=480; submitform();return false;">
25 </a>
</li>
<li class="hidden-phone">
<a aria-label="Go to page 26" href="#" onclick="document.adminForm.limitstart.value=500; submitform();return false;">
26 </a>
</li>
<li class="hidden-phone">
<a aria-label="Go to page 27" href="#" onclick="document.adminForm.limitstart.value=520; submitform();return false;">
27 </a>
</li>
<li class="hidden-phone">
<a aria-label="Go to page 28" href="#" onclick="document.adminForm.limitstart.value=540; submitform();return false;">
28 </a>
</li>
<li class="active">
<span aria-current="true" aria-label="Page 29">
29 </span>
</li>
<li class="disabled">
<span >
<span class="icon-step-forward icon-next" aria-hidden="true"></span> </span>
</li>
<li class="disabled">
<span >
<span class="icon-forward icon-last" aria-hidden="true"></span> </span>
</li>
</ul>
</nav>
<input type="hidden" name="limitstart" value="560" />
</div>
I'm able to reach till the last page. But on reaching the last page, it continues to find the element to click which is no longer active.
Here is my Selenium Code:
WebElement pag = driver.findElement(By.xpath("//li[not(contains(#class, 'disabled'))]/a/span[(contains(#class, 'icon-next'))]"));
while(pag!= null)
{
((JavascriptExecutor)driver).executeScript("window.scrollTo(0, document.body.scrollHeight)");
driver.findElement(By.className("icon-next")).click();
List <WebElement> itemlist = driver.findElements(By.xpath("//div[#class='tjlms-tbl']/table/tbody/tr"));
total = total + itemlist.size();
}
The loop is getting infinite. How can I stop once the last page is reached and the state of element changes to disabled.
Here, the Next Page button is enabled /disabled based on the below section in HTML and If the button is disabled, then class='disabled' is added in HTML. So, we can iterate the while loop until the above disabled element found . Please check the below solution code
First Page HTML:
<li class="hidden-phone">
<a aria-label="Go to page 10" href="#" onclick="document.adminForm.limitstart.value=180; submitform();return false;">
10 </a>
</li>
<li>
<a aria-label="Go to next page" class="hasTooltip" title="Next" href="#" onclick="document.adminForm.limitstart.value=20; submitform();return false;">
<span class="icon-step-forward icon-next" aria-hidden="true"></span>
</a>
</li>
<li>
<a aria-label="Go to end page" class="hasTooltip" title="End (Page 29 of 29)" href="#" onclick="document.adminForm.limitstart.value=560; submitform();return false;">
<span class="icon-forward icon-last" aria-hidden="true"></span>
</a>
</li>
</ul>
Last Page HTML:
<li class="active">
<span aria-current="true" aria-label="Page 29">
29 </span>
</li>
<li class="disabled">
<span >
<span class="icon-step-forward icon-next" aria-hidden="true"></span>
</span>
</li>
<li class="disabled">
<span >
<span class="icon-forward icon-last" aria-hidden="true"></span>
</span>
</li>
</ul>
</nav>
<input type="hidden" name="limitstart" value="560" />
Solution Code:
List <WebElement> fistPagelist = driver.findElements(By.xpath("//div[#class='tjlms-tbl']/table/tbody/tr"));
total = fistPagelist .size();
boolean hasNextPage=true;
while(hasNextPage)
{
((JavascriptExecutor)driver).executeScript("window.scrollTo(0, document.body.scrollHeight)");
List <WebElement> disabledButtonList = driver.findElements(By.xpath("//li[#class='disabled']//span[#class='icon-forward icon-last']"));
//If the page is lastpage, then only above disabledButtonList webElement will be found and it's size will be 1. Otherwise, it's size will be 0.
if(disabledButtonList.size()==0){
driver.findElement(By.className("icon-next")).click();
List <WebElement> itemlist = driver.findElements(By.xpath("//div[#class='tjlms-tbl']/table/tbody/tr"));
total = total + itemlist.size();
//Inorder to iterate the while loop, hasNextPage flag value is set it as true
hasNextPage=true;
}
else{
List <WebElement> itemlist = driver.findElements(By.xpath("//div[#class='tjlms-tbl']/table/tbody/tr"));
total = total + itemlist.size();
//If the LastPage found, then we need to stop the while loop and hence hasNextPage flag value is set it as false;
hasNextPage=false;
System.out.println("You have reached the last page");
}
}
You can check if element is enabled like this:
if (element.isEnabled()) {
// do stuff
}else {
break;
}
in your code it could be like this:
WebElement pag = driver.findElement(By.xpath("//li[not(contains(#class, 'disabled'))]/a/span[(contains(#class, 'icon-next'))]"));
while(pag!= null)
{
((JavascriptExecutor)driver).executeScript("window.scrollTo(0, document.body.scrollHeight)");
WebElement next = driver.findElement(By.className("icon-next"));
if (next.isEnabled()){
next.click(); // click only if enabled
List <WebElement> itemlist = driver.findElements(By.xpath("//div[#class='tjlms-tbl']/table/tbody/tr"));
total = total + itemlist.size();
}else { // break the loop if not enabled
System.out.println("You have reached the last page");
break;
}
}
or you can try also this way:
List<WebElement> pag = driver.findElements(By.xpath("//li[not(contains(#class, 'disabled'))]/a/span[(contains(#class, 'icon-next'))]"));
while(pag.size() > 0)
{
pag = driver.findElements(By.xpath("//li[not(contains(#class, 'disabled'))]/a/span[(contains(#class, 'icon-next'))]"));
((JavascriptExecutor)driver).executeScript("window.scrollTo(0, document.body.scrollHeight)");
driver.findElement(By.className("icon-next")).click();
List <WebElement> itemlist = driver.findElements(By.xpath("//div[#class='tjlms-tbl']/table/tbody/tr"));
total = total + itemlist.size();
}
Here every time you locate the list of elements and if the list size becomes 0, then you have reached the last page.

Button ng drop down- how to choose the item using webdriver with java

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

Build <ul> list recursively

So, I have this site structure
Page 1
Page 1.1
Page 2
Page 2.1
Page 2.1.1
Page 2.2
Page 3
Page 3.1
Page 3.2
Page 4
and I want to build <ul> list using recursive function. My function looks like this
public String getMenu(Page rootPage, boolean base){
final Logger log = LoggerFactory.getLogger(this.getClass());
Iterator<Page> subPages = rootPage.listChildren();
StringBuilder output = new StringBuilder("<ul");
output.append(" id=\"drop-menu\"");
output.append(" class=\"popup-menu\">");
if(!base){
output.append("<li><a href=\"").append(rootPage.getPath()).append(".html\" class=\"showSubPage\" rel=\"").append(rootPage.getPath()).append("\">");
String title = rootPage.getPageTitle() == null ? rootPage.getTitle() : rootPage.getPageTitle();
output.append(title);
output.append("</a>");
output.append("</li>");
output.append("</ul>");
}
while(subPages.hasNext()){
output.append("<ul>");
log.info("som subpages here!");
Page curPage = subPages.next();
output.append("<li><a href=\"").append(curPage.getPath()).append(".html\" class=\"showSubPage\" rel=\"").append(curPage.getPath()).append("\">");
String title = curPage.getPageTitle() == null ? curPage.getTitle() : curPage.getPageTitle();
output.append(title);
output.append("</a>");
Iterator<Page> subSub = curPage.listChildren();
int tmpCtr = 0;
while(subSub.hasNext()){
tmpCtr++;
output.append(getMenu(subSub.next(), false));
}
output.append("</li>");
output.append("</ul>");
}
return output.toString();
}
and the output looks like this
<ul id="drop-menu" class="popup-menu">
<ul>
<li><a href="/menu-hier/afsafa.html" class="showSubPage" >Page 1</a>
<ul id="drop-menu" class="popup-menu">
<li>Page 1.1
</li>
</ul>
</li>
</ul>
<ul>
<li>Page 2
<ul id="drop-menu" class="popup-menu">
<li>Page 2.1
</li>
</ul>
<ul>
<li>Page 2.1.1
</li>
</ul>
<ul id="drop-menu" class="popup-menu">
<li>Page 2.2
</li>
</ul>
</li>
</ul>
<ul>
<li>Page 3
<ul id="drop-menu" class="popup-menu">
<li>Page 3.1
</li>
</ul>
<ul id="drop-menu" class="popup-menu">
<li>Page 3.2
</li>
</ul>
<ul id="drop-menu" class="popup-menu">
<li>Page 3.3
</li>
</ul>
</li>
</ul>
<ul>
<li>Page 4
</li>
</ul>
So the problem is, that the level 3 pages aren't placed properly. For example the Page 2.1.1 isn't under the Page 2.1 section.
Thanks for any help!
Not sure, how you want your HTML to look like, but:
1) From your code, the <ul> tag is inserted twice for sub-pages (once in the while loop, then in the recursive called getMenu() again)
2) I think, you are missing the <li> tags below the <ul> tags.
3) Your code looks quite redundant and complex, can't it be done easier like so (not tested):
public String getMenu(Page page, boolean isRoot) {
StringBuilder output = new StringBuilder();
if (isRoot) {
output.append("<ul id=\"drop-menu\"");
output.append(" class=\"popup-menu\">");
}
else {
output.append("<ul>");
}
output.append("<li><a href=\"")
.append(page.getPath())
.append(".html\" class=\"showSubPage\" rel=\"")
.append(rootPage.getPath()).append("\">");
String title = page.getPageTitle() == null ? page.getTitle() : page.getPageTitle();
output.append(title);
output.append("</a>");
Iterator<Page> subPages = page.listChildren();
while(subPages.hasNext()){
output.append(getMenu(subPages.next(), false));
}
output.append("</li>");
output.append("</ul>");
return output.toString();
}

Categories