-1

How to display all the values in auto drop down list using selenium web driver when it is developed using <div> tag.

My code

driver.get("https://www.yatra.com/");// URl of yatra
String origin ="(//input[@name='flight_origin_city'])[1]";// text box for entering origin
driver.findElement(By.xpath(origin)).sendKeys("Bangalore");
String destination = "(//input[@name='flight_destination_city'])[1]";// text for entering destination
driver.findElement(By.xpath(destination)).sendKeys("M");
List<WebElement> lists= driver.findElements(By.xpath("(//div[@class='viewport'])[2]")); // this is the div where all the values are present.

for (int i=0; i<lists.size();++i){
    System.out.println(lists.get(i).getText());// getting the text for all the values.
}
Guy
  • 46,488
  • 10
  • 44
  • 88

2 Answers2

0

The xpath "(//div[@class='viewport'])[2]" gives you a single element, not list. This is also not where the options are stored, its the parent of the container where they are stored. Try

 List<WebElement> lists= driver.findElements(By.xpath("(//div[@class='overview'])[3]//li"));
Guy
  • 46,488
  • 10
  • 44
  • 88
0

Your case is a bit difficult, but that's what makes it worth exploring. Here's a step wise dissection of the problem:

Desktop notification dialog

First of all, when I tried to run your test in Chrome, the "Do you want to allow Desktop notifications?" dialog interfered with the test (it popped up some time after the second sendKeys which is why the text box lost its focus and one of the entries got accepted which made it impossible to find the other suggestions).

I worked around that using this tip: Disable Chrome notifications (Selenium)

Finding the right container

You got pretty far already by identifying that you can locate the container of the suggestions as By.xpath("(//div[@class='viewport'])[2]"). From there though, you need to look more specifically for the right child elements. Also as this is dynamic content, it is advisable to use an explicit wait statement to make sure the test doesn't fail prematurely in case the element takes longer to load.

I changed your test so that it would look the <li> elements which are children of the <div> elements with the viewport class. Those elements have children which format the city, airport and country names accordingly. To get the text of those, you have to drill down a bit more into the DOM structure. Here's the solution for that:

WebElement list = new WebDriverWait(driver, 2000).until(ExpectedConditions.visibilityOfElementLocated(By.xpath("(//div[@class='viewport'])[2]")));

List<WebElement> elements = list.findElements(By.tagName("li"));

for (WebElement element : elements) {    
        String city = element.findElement(By.className("ac_cityname")).getText();
        String airport = element.findElement(By.className("ac_airportname")).getText();
        String country = element.findElement(By.className("ac_country")).getText();

        System.out.println(city + " " + airport + " (" + country + ")");
}

So far, so good. But note that this solution gives you the followiing output:

Mumbai (BOM) Chatrapati Shivaji (India)
Madras (MAA) Chennai (India)
Chennai (MAA) Chennai (India)
Madurai (IXM)  (India)
  ()
  ()
  ()
  ()
  ()
  ()

Scrolling

This is because of another speciality of your page: It only renders the text for the elements that are actually in view. So in addition to the code above, apply this trick to make sure all elements are being scrolled to before retrieving their text: Scroll Element into View with Selenium

Long story short: Here's my final version:

driver.get("https://www.yatra.com/");// URl of yatra
String origin ="(//input[@name='flight_origin_city'])[1]";// text box for entering origin
driver.findElement(By.xpath(origin)).sendKeys("Bangalore");
String destination = "(//input[@name='flight_destination_city'])[1]";// text for entering destination
driver.findElement(By.xpath(destination)).sendKeys("M");

WebElement list = new WebDriverWait(driver, 2000).until(ExpectedConditions.visibilityOfElementLocated(By.xpath("(//div[@class='viewport'])[2]")));

List<WebElement> elements = list.findElements(By.tagName("li"));

for (WebElement element : elements) {
        ((JavascriptExecutor) driver).executeScript("arguments[0].scrollIntoView(true);", element);

        String city = element.findElement(By.className("ac_cityname")).getText();
        String airport = element.findElement(By.className("ac_airportname")).getText();
        String country = element.findElement(By.className("ac_country")).getText();

        System.out.println(city + " " + airport + " (" + country + ")");
}

That should give you the following output when running in Google Chrome:

Mumbai (BOM) Chatrapati Shivaji (India)
Madras (MAA) Chennai (India)
Chennai (MAA) Chennai (India)
Madurai (IXM) Madurai (India)
Mangalore (IXE) Bajpe (India)
Mysore (MYQ) Mysore (India)
Coorg (MYQ) (nearest airport Mysore) (India)
Male (MLE) Male (Maldives)
Melbourne (MEL) Tullamarine (Australia)
Mauritius (MRU) Plaisancet (Mauritius)
Community
  • 1
  • 1
ralph.mayr
  • 1,320
  • 8
  • 12