0

In this code i want to navigate to the year 2022 and select July and print that result in the console but the issue is that in the else if condition when checking when this particular condition is encounted where the year is 2022 and the month is december it is passing and it is navigating to next Button which is January 2023 so the loop keeps on running and i cannot get my desired result

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;

import java.time.Duration;

public class DatePicker {
    public static void main(String[] args) {
        WebDriver driver = new ChromeDriver();
        WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(5000));

        driver.get("https://seleniumpractise.blogspot.com/2016/08/how-to-handle-calendar-in-selenium.html");

        driver.findElement(By.id("datepicker")).click();

        String desiredMonth = "July";
        String desiredYear = "2022";

        while (true) {
            String year1 = driver.findElement(By.className("ui-datepicker-year")).getText();
            String month1 = driver.findElement(By.className("ui-datepicker-month")).getText();

            if (year1.equals(desiredYear) && month1.equalsIgnoreCase(desiredMonth)) {
                System.out.println("Desired date reached: the year is " + year1 + " and the month is " + month1);
                break;
            } else if (year1.equals(desiredYear) && month1.compareTo(desiredMonth) < 0) {
                driver.findElement(By.className("ui-icon-circle-triangle-e")).click();
            } else {
                driver.findElement(By.className("ui-icon-circle-triangle-w")).click();
            }

            // Wait for the changes to take effect
            wait.until(ExpectedConditions.presenceOfElementLocated(By.className("ui-datepicker-year")));
        }

        driver.quit();
    }
}

2 Answers 2

0

Is there a reason why you want to traverse and not select the date using text input? I'm asking because the loop is not necessary in selecting dates here.

You should instead first add text like "07/16/2022" to input field datepicker

<input type="text" id="datepicker" class="hasDatepicker">

After that do a click to the same datepicker, you will have July 2022 as predefined month/year and you can then select and print out to console.

If you have another reason for traversing, then of course this does not apply, and your condition above is bad. By looking at the code, your getText for month and year at the begining of your loop will always run over values and kill your loop.

0

Your issue is your month comparator, the line that says

month1.compareTo(desiredMonth) < 0)

desiredMonth is a string, not a number. You need to use Java's date compareTo class, not its string compareTo.

If your date picker only needs to go backwards in time, it is sufficient to get your code to run to just change the compareTo statement to month1.equals(desiredMonth). This keeps it from going into the second else condition when only one item matches.

If you need the date picker to be able to intelligently find a desired date in either direction, you will need to make sure it can tell what month names are before which other month names, ideally using a datetime utility. You can do this comparison manually, without datetime, as well, like so:

  1. add an array of months near your desiredMonth/desiredYear variables

String[] monthsOrder = {"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"};

  1. write a method that returns the index of a month's string from that date list

     public static int findMonthIndex(String[] months, String targetMonth) {
     for (int i = 0; i < months.length; i++) {
         if (months[i].equals(targetMonth)) {
             return i;
         }
     }
     //If month not in list just crash
     throw new IllegalArgumentException("Bad month");
     }
    
  2. instead of checking if the difference between two month strings is zero, compare the results of two calls to your month conversion function:

findMonthIndex(monthsOrder, month1) < findMonthIndex(monthsOrder, desiredMonth))

  1. Your year comparison will have the same problem. You need to compare the years as numbers rather than as strings, and have cases handling each combination of year and month being greater or less than the desired month.

There is still a lot of room for simplification and exception catching but here is what a finished and working code looks like:

        String[] monthsOrder = {"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"};
    while (true) {
        String year1 = driver.findElement(By.className("ui-datepicker-year")).getText();
        String month1 = driver.findElement(By.className("ui-datepicker-month")).getText();
        if (year1.equals(desiredYear) && month1.equalsIgnoreCase(desiredMonth)) {
            System.out.println("Desired date reached: the year is " + year1 + " and the month is " + month1);
            break;
        } else if (Integer.parseInt(year1) > Integer.parseInt(desiredYear)){
            driver.findElement(By.className("ui-icon-circle-triangle-w")).click();
        } else if (Integer.parseInt(year1) == Integer.parseInt(desiredYear) && findMonthIndex(monthsOrder, month1) < findMonthIndex(monthsOrder, desiredMonth)) {
            driver.findElement(By.className("ui-icon-circle-triangle-e")).click();
        } else if (Integer.parseInt(year1) == Integer.parseInt(desiredYear) && findMonthIndex(monthsOrder, month1) > findMonthIndex(monthsOrder, desiredMonth)) {
            driver.findElement(By.className("ui-icon-circle-triangle-w")).click();
        } else {
            driver.findElement(By.className("ui-icon-circle-triangle-e")).click();
        }
    }

    driver.quit();
}
public static int findMonthIndex(String[] months, String targetMonth) {
    for (int i = 0; i < months.length; i++) {
        if (months[i].equals(targetMonth)) {
            return i;
        }
    }
    //If month not in list just crash
    throw new IllegalArgumentException("Bad month");
}

Not the answer you're looking for? Browse other questions tagged or ask your own question.