TransWikia.com

Can't Select random months dates using jquery calender

Software Quality Assurance & Testing Asked by koushick on December 12, 2021

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;

                   }
                }
        }   

3 Answers

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

Answered by sushen on December 12, 2021

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.

Answered by anonygoose on December 12, 2021

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.

Answered by lauda on December 12, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP