0

I have Jquery calender in my application. I have task to select dates from different months using Selenium, but I can do only previous month and forward month. Actually I need to select dates from random months by specifying the date and month as input. If there is a way to achieve it let me know.

**My code for Selecting Previous Month date.**

public static void Date_Picker(String datetoselect,String Xpath,String month) {
        // Click on the Given Calender Button
        driver.findElement(By.xpath(Xpath)).click();

        driver.findElement(By.xpath("//div[@id='ui-datepicker-div']/div/a[1]")).click();

        WebElement Month = driver.findElement(By.xpath("//div[@id='ui-datepicker-div']/div/div[@class='ui-datepicker-title']/span"));
        String Month_Message = Month.getText();

        if(Month_Message.contains(month))
        {
            WebElement dateWidget = driver.findElement(By.className("ui-datepicker-calendar"));

              List<WebElement> rows=dateWidget.findElements(By.tagName("tr"));

              List<WebElement> columns=dateWidget.findElements(By.tagName("td"));

              for (WebElement cell: columns){

                   if (cell.getText().equals(datetoselect)){

                   cell.findElement(By.linkText(datetoselect)).click();
                   break;

                   }
                }
        }   
  • can you share your web view of your datepicker and DOM too? – Upkar Singh May 28 '19 at 5:11
  • @UpkarSingh i can't share the HTML code. That's my problem. you can say with normal jquery calender and i will match with it. – koushick May 28 '19 at 5:29
  • 1
    Can you manually select a month outside the range of last month, this month, and next month? If you can, consider the following options: instead of aiming to click the date, enter the date into the text field then verify that the calendar is showing the correct date; if there's a month select dropdown, use that. If not, you need to work out how many clicks on the previous/next button you need in order to reach your target month. – Kate Paulk May 28 '19 at 12:28
  • @KatePaulk Their is no Target Month. My end users will filters the date randomly. if we give any date and month it should go to that month and click it. i was trying hard till now But Can't Achive it.My input should be date&Month&Year, then it should go to that date and click it – koushick May 31 '19 at 7:37
  • By "target month" I mean the month that you are trying to go to in this particular test. – Kate Paulk May 31 '19 at 12:32
0

I would use a script based on the jQuery datepicker api that can also handle different date formats with an execute script method.

The script should be something like:

jQuery('datepickerSelector').datepicker( 'setDate', '-1y' );

This will select the current date -1 year no matter the date format. You can adapt it for months and use a random generator and have from -1m to -12m.

|improve this answer|||||
  • My input should be date&Month&Year. if i give the date&Month&Year, it should go to that specific date and click it. if their is any way to achive like this means let me know. Thanks.:) – koushick May 31 '19 at 7:44
  • This is a fast work around to avoid clicking and waiting and related issues. This will set the entire date using the difference that you are passing in the datepicker method. – lauda Jun 5 '19 at 14:04
  • You can test it here jqueryui.com/datepicker by executing this script jQuery('#datepicker').datepicker( 'setDate', '-1y' ); in the console – lauda Jun 5 '19 at 14:05
0

Datepickers are really slow and tedious to interact with. As Kate Paulk and lauda suggest, it may be worth trying to bypass this by just filling text into the field instead of using the interface if you're not testing the datepicker itself.

If you really need to test the datepicker I would suggest a simple loop that figures out which direction it needs to move in based on the current month. Without seeing the actual datepicker you're trying to automate, this is just a vague suggestion rather than something you can just copy and paste in. This will be incredibly slow and should only ever be used sparingly.

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;

import java.time.LocalDate;
import java.time.Month;

public class DatePicker {
    private WebDriver driver;

    public DatePicker(WebDriver driver) {
        this.driver = driver;
    }

    public void selectDate(LocalDate date) throws InterruptedException {
        boolean monthFound = false;
        int maxAttempts = 100;
        int attempts = 0;
        int currentlySelectedMonth;
        int currentlySelectedYear;

        while (!monthFound && attempts++ < maxAttempts) {
            currentlySelectedMonth = getCurrentlySelectedMonth();
            currentlySelectedYear = getCurrentYear();

            // Make sure we move to the correct year first
            if(currentlySelectedYear != date.getYear()) {
                if(currentlySelectedYear > date.getYear()) {
                    clickPreviousMonth();
                } else {
                    clickNextMonth();
                }

                continue;
            }

            if (currentlySelectedMonth == date.getMonthValue()) {
                clickDay(date.getDayOfMonth());
                break;
            } else {

                // Which direction do we need to move?
                if (currentlySelectedMonth > date.getMonthValue()) {
                    clickPreviousMonth();
                } else {
                    clickNextMonth();
                    Thread.sleep(250); // Quick sleep to give the UI a chance to update, you probably want something smarter
                }
            }
        }
    }

    private void clickNextMonth() {
        driver.findElement(By.xpath("//a[@title='Next']")).click();
    }

    private void clickPreviousMonth() {
        driver.findElement(By.xpath("//a[@title='Prev']")).click();
    }

    private int getCurrentlySelectedMonth() {
        String monthName = driver.findElement(By.className("ui-datepicker-month")).getText();
        return Month.valueOf(monthName.toUpperCase()).getValue();
    }

    private int getCurrentYear() {
        return Integer.valueOf(
                driver.findElement(By.className("ui-datepicker-year")).getText()
        );
    }

    private void clickDay(int dayNumber) {
        driver.findElement(By.linkText(String.valueOf(dayNumber))).click();
    }

}

and a test case from a publicly available demo of jquery datepicker:

import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;

import java.time.LocalDate;

public class QuickTest {

    @Test
    public void datePickerTest() throws InterruptedException {
        System.setProperty("webdriver.chrome.driver", System.getProperty("user.home") + "/Downloads/chromedriver");
        WebDriver driver = new ChromeDriver();
        DatePicker datePicker = new DatePicker(driver);

        driver.get("https://jqueryui.com/datepicker/#default");
        WebElement frame = driver.findElement(By.className("demo-frame"));
        driver.switchTo().frame(frame);

        WebDriverWait wait = new WebDriverWait(driver, 30);

        wait.until(ExpectedConditions.presenceOfElementLocated(By.id("datepicker")));
        driver.findElement(By.id("datepicker")).click();

        datePicker.selectDate(LocalDate.now().plusMonths(24).minusDays(5));
    }

}

The testcase will sometimes stale reference on locating the field to click, but that's something you can easily fix on a real implementation of this. Not worth fixing for this demo.

Turns out it's not that slow, but still preferable to skip this if you're just wanting a date to be filled out.

|improve this answer|||||
  • i have two date boxes From and Too. i will give date randomly, so it will filter it out. but my dates are not fixed. i will any date.According to it i need to strech my code. Thanks :) – koushick May 31 '19 at 7:48
0
Here is the code to play with the multi-date calendar.

// Function to select the day of month in the date picker.
        public void SelectDayFromMultiDateCalendar(String day)
                        throws InterruptedException {

                // We are using a special XPath style to select the day of current
                // month.
                // It will ignore the previous or next month day and pick the correct
                // one.
                By calendarXpath = By
                                .xpath("//td[not(contains(@class,'ui-datepicker-other-month'))]/a[text()='"
                                                + day + "']");
                browser.findElement(calendarXpath).click();

                // Intentional pause for 2 seconds.
                Thread.sleep(2000);
        }
|improve this answer|||||

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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