How to handle year and month drop-downs using Selenium? - java

Can anyone guide me, how to select a year and month drop-down using Java in Selenium?
Had used the code mentioned below, But it didn't work.
Java Code:
{
List<WebElement> NomDOBYear = driver.findElements(By.className("ui-datepicker-year"));
Select selectYear= new Select((WebElement) NomDOBYear);
selectYear.selectByVisibleText("1991");
WebElement NomDOBMonth = (WebElement) driver.findElements(By.className("ui-datepicker-year"));
Select selectMonth= new Select(NomDOBMonth);
selectMonth.selectByVisibleText("Nov");
}

Use
driver.findElement(By.className("ui-datepicker-year"));
instead of
driver.findElements(By.className("ui-datepicker-year"));
When you use driver.findElements(By.className("ui-datepicker-year")) you are storing return elements in a list(I am expecting that there are 2 or more elements with the same className as "ui-datepicker-year").
So, if that is the case then you should note that the constructor "Select" class of selenium takes a 'WebElement' as a parameter which can be the first or any element stored inside the list.
Then your code should be written like -
List<WebElement> NomDOBYear = driver.findElements(By.className("ui-datepicker-
year"));
Select selectYear= new Select(NomDOBYear.get(0));//first element of the list
selectYear.selectByVisibleText("1991");
WebElement NomDOBMonth = driver.findElement(By.className("ui-
datepicker-month"));// you got the class name wrong here
Select selectMonth= new Select(NomDOBMonth);
selectMonth.selectByVisibleText("Nov");
Otherwise if there is only 1 element with className "ui-datepicker-year" or "ui-datepicker-month" in the entire DOM then your code should be written like -
WebElement NomDOBYear = driver.findElement(By.className("ui-datepicker-year"));
Select selectYear= new Select(NomDOBYear);
selectYear.selectByVisibleText("1991");
WebElement NomDOBMonth = driver.findElement(By.className("ui-datepicker-month"));
Select selectMonth= new Select(NomDOBMonth);
selectMonth.selectByVisibleText("Nov");
I would still recommend using XPath for finding elements.

Related

Difference WebElements Vs WebElement in selenium

I am fetching date webelements from facebook and I am looping it by using the below code.
public class select_facebook {
public static void main(String[] args) throws Exception {
WebDriver driver = new FirefoxDriver();
driver.get("http://www.facebook.com");
List<WebElement> days = driver.findElements(By.xpath("//select[#id='day']"));
System.out.println(days.size());
for (int i=0;i<days.size();i++) {
System.out.println(days.get(i));
}
}
}
But I get output as
1
[[FirefoxDriver: firefox on XP (58765a0e-31a0-40bc-8565-3418ae54682c)] -> xpath: //select[#id='day']]
But same code in for loop if I use System.out.println(days.get(i).gettext());
It list all the dates 1 to 31.
My question is then why should I call this as
List<WebElement> days = driver.findElements(By.xpath("//select[#id='day']"));
Because even the size of the webElements is just :1
System.out.println(days.size());
instead I could have called it as
WebElement days = driver.findElement(By.xpath("//select[#id='day']"));
You will get list of Elements in return of
List<WebElement> days = driver.findElements(By.xpath("//select[#id='day']"));
because there could be more than 1 element by same id ('day').
You should have to focus on what you exactly need. If you want more elements use FindElements() and when you are interested in only one element then use FindElement().
If there are more number of elements and if you use FindElement() it returns you very first element and rest others are get neglected. So make sure about your requirement.
This is because an id value can be given to only one HTML element. In other words, multiple elements cannot have the same id value on the same page in valid HTML DOM only.
FindElement() it returns you WebElement:
WebElement SINGLEELEMENT= driver.findElement(By.SELECTOR("//TAGNAME[#ATTRIBUTENAME='ATTRIBUTEVALUE']"));
FindElements() it returns you WebElements i.e List<WebElement> of multiple elements. It return 1 if only one element present in it or multiple if presents more:
List<WebElement> LISTOFELEMENTS= driver.findElements(By.SELECTOR("//TAGNAME[#ATTRIBUTENAME='ATTRIBUTEVALUE']"));
You can put looping on it to get each one element and work on each individually.

Selenium select each div separately that have the same class

I am trying to select all the divs withclass tile-consultation in (http://raspored.finki.ukim.mk/Home/Consultations), click each of them and extract some data from each div, I tried using:
List<WebElement> professors = driver.findElements(By.className("tile-consultation"));
ListIterator<WebElement> theListOfProfessors = professors.listIterator();
Thread.sleep(1000);
int i = 1;
while(theListOfProfessors.hasNext()) {
WebElement professorI = driver.findElement(By.cssSelector(".tile-consultation:nth-of-type(2)"));
professorI.click();
Thread.sleep(1000);
close = driver.findElement(By.cssSelector("button.btn-close"));
close.click();
Thread.sleep(1000);
}
but how can I change 1 to the 2nd, 3d and so on in a while loop?
You've already got the work done. You've already found the web elements and made a listiterator here:
List<WebElement> professors = driver.findElements(By.className("tile-consultation"));
ListIterator<WebElement> theListOfProfessors = professors.listIterator();
The findElements method will return a collection of elements matching the selector. There's no need for you to retrieve the elements again like you're trying to with driver.findElement(By.cssSelector(".tile-consultation:nth-of-type(x)" inside that loop. You merely need to iterate over the listiterator theListOfProfessors that you already created. E.g. something to the effect of
while(theListOfProfessors.hasNext()) {
WebElement elem = theListOfProfessors.next()
// do something with elem
}

Return all Select web elements as List in Selenium

Not a duplicate: I am not asking for the <option> within a <select>. I would like to return the <select> web elements themselves as a List. When achieved, the list should have a size of 2.
I have only found driver.findElements() that returns a List<WebElement>.
How do I return a List<Select> by ng-model="income.frequency"?
(Note: I have ngWebDriver so I can use ByAngular.model("income.frequency") as locator.)
HTML:
In order to match elements by their attribute, you can use the CSS selector:
By.cssSelector("<tag>[<attribute>='<value>']")
And in context:
List<WebElement> elements = driver.findElements(By.cssSelector("select[ng-model='income.frequency']"));
Edit: According to Selenium documentation, you can create a Select with a very straight-forward constructor. Hence, if you want a list of Select objects, just construct a new list:
List<Select> selectList = new ArrayList<>();
List<WebElement> elements = driver.findElements(By.cssSelector("select[ng-model='income.frequency']"));
for(WebElement element : elements) {
selectList.add(new Select(element);
}

Selenium IDE locator doesn't work in Selenium 3.3.1 Java

I have a web page which contains 2 links with the same classnames but with different div classes. The first one is invisible (it's in a dropdown menu) and the other one that I want is visible.
So, I'm trying to locate the visible element.
His HTML :
<div class="mainActionPanel">
<a css="create"></a>
</div>
The link has a dynamic ID. When I do a XPath search with the ID, I find rightly the element but it's deprecated because the button hasn't the same ID on each page.
I tried to locate the element with Selenium IDE, the following locator worked : css=div.mainActionPanel > a.create
The problem is with the locator that I showed above.
When I try to find the element, I always have this exception :
NoSuchElementException : Element By.cssSelector: css=div.mainActionPanel > a.create (first) (LazyElement) is not present.
He doesn't find it. I tried several syntax like an example in the FluentLenium documentation ($("form > input[data-custom=selenium]") but it doesn't worked.
Moreover, the el(".create").click() is throwing an ElementNotVisibleException because he selects the dropdown link.
How can I find the right element ?
Try using below:
WebElement elem = driver.findElement(By.cssSelector("div.mainActionPanel > a"));
WebDriverWait wait= new WebDriverWait(driver, 20);
wait.until(ExpectedConditions.visibilityOf(elem));
elem.click();
May be this should help you..
// this will provide you list of web elements based on class name
List<WebElement> webElements = driver.findElements(By.className("mainActionPanel"));
Then you have to find out the required element by iterating through the list, like below.
WebElement tempElement = null;
for (WebElement element : webElements) {
if (element.getAttribute("css").equals("create")) {
tempElement = element;
}
}
Full code as follow,
List<WebElement> webElements = driver.findElements(By.className("mainActionPanel"));
WebElement tempElement = null;
for (WebElement element : webElements) {
if (element.getAttribute("css").equals("create")) {
tempElement = element;
}
}
//then you can perform that you want
tempElement.click();
Changed from css search to xpath using :
xpath = (//a[contains(#href, '#')])[5]
Because it's the 4th "a" element with an href attribute which contains the text "#". No more trouble.
Look at this :
http://www.guru99.com/locators-in-selenium-ide.html

Selenium - Only able to select the first element in a list whereas able to print all elements

I am trying to loop through a drop-down menu, I am able to get each and every listed element but when I use the .click() and .submit() commands, it selects the first one and does not continue any further. I am aware for it to continue any further, I need to reselect the drop-down arrow so the list becomes visible to selenium after every submit. I tried commenting to make it readable. ANY help is greatly appreciated.
I wrote down the following,
WebElement search = driver.findElement(By.id("search-form"));
WebElement arrowDownButton = search.findElement(By.className("dropdown-toggle"));
arrowDownButton.click();
WebElement menu = search.findElement(By.className("dropdown-menu"));
List <WebElement> listOptions = menu.findElements(By.tagName(LI)); //selecting the listed elements , LI is "li" (declared previously)
int numberOfCountries = listOptions.size();
log("We have " + numberOfCountries + " entires");
int i=0; //for looping
//store into an array because web elements disappear
WebElement []listOfCountries = new WebElement[listOptions.size()]; //making an array of size listed elements
for (WebElement aOption : listOptions)
{
listOfCountries[i] = aOption; //saving the value into an array
String dataValue = aOption.getAttribute("data-value"); // what country am I wanting click
i++;
}
for(WebElement country : listOfCountries)
{
log(country.getText()); //log is a another function executing System.out.println
country.click(); //clicking on the web element
country.submit(); // submitting the element
arrowDownButton.click(); //reselecting the drop-down menu -> Why isn't this working?
}
}
Here are some methods I have already tried:
Instead of creating, saving and iterating through an array, I just directly tried to click the element. However, it also just clicks the first element.
Here is the error I am receiving:
Exception in thread "main" org.openqa.selenium.ElementNotVisibleException: Element is not currently visible and so may not be interacted with arrowDownButton.click(); but I cannot figure out WHY it fails to RESELECT.
for(WebElement country : listOfCountries)
{
log(country.getText()); //log is a another function executing System.out.println
country.click(); //clicking on the web element
Thread.Sleep(500);
country.submit(); // submitting the element
// You have to reselect this element. Because doesn't make sense anymore.
// Try reselect next element
arrowDownButton.click(); //reselecting the drop-down menu -> Why isn't this working?
}
see if ur drop down menu is not in a select list, probably it is, in that case ur current code wont work. It will be helpful if you could post the Html code of the webelement ur trying to interact with.

Categories