简体   繁体   English

使用Selenium webdriver从日期选择器中选择日期

[英]Select a date from date picker using Selenium webdriver

I have a webpage with a textbox field. 我有一个带有文本框字段的网页。 A calender icon near it. 靠近它的日历图标。 When i click on the calender icon a calender view is displayed. 当我点击日历图标时,会显示日历视图。 I think its not a jquery calender. 我认为它不是一个jquery日历。 Can anyone provide an example to automate this type of date pickers. 任何人都可以提供一个示例来自动化这种类型的日期选择器。

I tried this code, it may work for you also: 我试过这段代码,它也适用于你:

            DateFormat dateFormat2 = new SimpleDateFormat("dd"); 
            Date date2 = new Date();

            String today = dateFormat2.format(date2); 

            //find the calendar
            WebElement dateWidget = driver.findElement(By.id("dp-calendar"));  
            List<WebElement> columns=dateWidget.findElements(By.tagName("td"));  

            //comparing the text of cell with today's date and clicking it.
            for (WebElement cell : columns)
            {
               if (cell.getText().equals(today))
               {
                  cell.click();
                  break;
               }
            }

You can handle in many ways in Selenium. 你可以在Selenium中以多种方式处理。

You can use direct click operation to Select values 您可以使用直接单击操作来选择值

or 要么

you can write general xpath to match all values from calender and click on specific date as per requirement. 您可以编写通用xpath来匹配日历中的所有值,并根据需要单击特定日期。

I have written detailed post on it. 我已经写了详细的帖子。

Hope it will help 希望它会有所帮助

http://learn-automation.com/handle-calender-in-selenium-webdriver/ http://learn-automation.com/handle-calender-in-selenium-webdriver/

It really depends on how it is coded but something like this may work: 这实际上取决于它是如何编码的,但这样的事情可能有效:

driver.findElement(By.id("datepicker")).click(); //click field
driver.findElement(By.linkText("Next")).click(); //click next month
driver.findElement(By.linkText("28")).click(); //click day

This one worked like a charm for me where the date picker just has previous and next buttons and Month and year as texts. 这个对我来说就像一个魅力,日期选择器只有前一个和下一个按钮,月和年作为文本。

Page objects are as follows 页面对象如下

    [FindsBy(How =How.ClassName, Using = "ui-datepicker-calendar")]
    public IWebElement tblCalendar;

    [FindsBy(How = How.XPath, Using = "//a[@title=\"Prev\"]")]
    public IWebElement btnPrevious;

    [FindsBy(How = How.XPath, Using = "//a[@title=\"Next\"]")]
    public IWebElement btnNext;

    [FindsBy(How = How.ClassName, Using = "ui-datepicker-year")]
    public IWebElement lblYear;

    [FindsBy(How = How.ClassName, Using = "ui-datepicker-month")]
    public IWebElement lblMonth;



    public void SelectDateFromDatePicker(string year, string month, string date)
    {

        while (year != lblYear.Text)
        {
            if (int.Parse(year) < int.Parse(lblYear.Text))
            {
                btnPrevious.Clicks();
            }
            else
            {
                btnNext.Clicks();
            }
        }

        while (lblMonth.Text != "January")
        {
            btnPrevious.Clicks();
        }

        while (month != lblMonth.Text)
        {
               btnNext.Clicks();
        }

        IWebElement dateField = PropertiesCollection.driver.FindElement(By.XPath("//a[text()=\""+ date+"\"]"));
        dateField.Clicks();
    }

Please use this code for selecting date from Two Jquery calendar like Flight Booking site. 请使用此代码从两个Jquery日历中选择日期,如航班预订网站。

    Hashtable h=new Hashtable();
    h.put("January",0 );
    h.put("February",1);
    h.put("March",2);
    h.put("April",3);
    h.put("May",4);
    h.put("June",5);
    h.put("July",6);
    h.put("August",7);
    h.put("September",8);
    h.put("October",9);
    h.put("November",10);
    h.put("December",11);


    int expMonth;
    int expYear;

    // Calendar Month and Year
    String calMonth = null;
    String calYear = null;
    boolean dateNotFound;
    dateNotFound = true;
    expMonth= 5;
    expYear = 2014;

    while(dateNotFound)
    {

        calMonth = driver.findElement(By.className("ui-datepicker-month")).getText(); // get the text of month
        calYear = driver.findElement(By.className("ui-datepicker-year")).getText();




        if(((Integer)h.get(calMonth))+1 == expMonth && (expYear == Integer.parseInt(calYear)))
        {
            String block="//div[@class='monthBlock first']/table/tbody/tr/td";  // THIS IS FIRST CALENDAR
            selectDate(expDate,block); 
            dateNotFound = false; 
        }
        // parseInt - Converts String to integer and indexof( It will return the index position of String)
        else if(((Integer)h.get(calMonth))+1 < expMonth && (expYear == Integer.parseInt(calYear)) || expYear > Integer.parseInt(calYear))
        {
            String block="//div[@class='monthBlock last']/table/tbody/tr/td"; // THIS IS SECOND CALENDAR


                            selectDate(expDate,block); // PASSING DATE AND CALENDAR
                            dateNotFound = false; // Otherwise it will rotate continuously 
        }
        else if((Integer)h.get(calMonth)+1 > expMonth && (expYear == Integer.parseInt(calYear)) || expYear < Integer.parseInt(calYear))
        {
            System.out.println(" Please enter the date greater than Current date");
            dateNotFound = false;

        }
    }

    }
    //Thread.sleep(3000);


    public static void selectDate(String date,String block) throws IOException
    {

                    String monthblock=block;

        List<WebElement> dateWidget = driver.findElements(By.xpath(monthblock));    

        for (WebElement cell: dateWidget)
        {
            //Selects Date
            if (cell.getText().equals(date))
            {
                cell.findElement(By.linkText(date)).click();
                break;
            }

        }

        //Doubt : How to verify the expected results and how to sort the program



        driver.findElement(By.id("SearchBtn")).submit();

        //driver.quit();
    }

try this, 尝试这个,

http://seleniumcapsules.blogspot.com/2012/10/design-of-datepicker.html http://seleniumcapsules.blogspot.com/2012/10/design-of-datepicker.html

  1. an icon used as a trigger; 用作触发器的图标;
  2. display a calendar when the icon is clicked; 单击图标时显示日历;
  3. Previous Year button(<<), optional; 上一年按钮(<<),可选;
  4. Next Year Button(>>), optional; 明年按钮(>>),可选;
  5. Previous Month button(<); 上个月按钮(<);
  6. Next Month button(>); 下个月按钮(>);
  7. day buttons; 日按钮;
  8. Weekday indicators; 平日指标;
  9. Calendar title ie "September, 2011" which representing current month and current year. 日历标题即“2011年9月”,代表当前月份和当前年份。

I think there will be different ways to select a Date for different Date picker formats. 我认为有不同的方法为不同的日期选择器格式选择日期。 For a Date Picker where you need to select a year and month from a dropdown and then pick/click a Date, I wrote the following code. 对于日期选择器,您需要从下拉列表中选择年份和月份,然后选择/单击日期,我编写了以下代码。

private void setupDate(WebDriver driver, String csvRow) throws Exception {
    String date[] = (csvRow).split("-");
    driver.findElement(By.id("flddateanchor")).click();
    new Select(driver.findElement(By
            .cssSelector("select.ui-datepicker-year")))
            .selectByVisibleText(date[0]);
    Thread.sleep(1000);
    new Select(driver.findElement(By
            .cssSelector("select.ui-datepicker-month")))
            .selectByVisibleText(date[1]);
    Thread.sleep(1000);
    driver.findElement(By.linkText(date[2])).click();
    Thread.sleep(1000);
}

I got the cssSelector part by the Selenium Firefox IDE. 我通过Selenium Firefox IDE获得了cssSelector部分。 Also, my Date(csvRow) is in (2015-03-31) format. 另外,我的日期(csvRow)是(2015-03-31)格式。

Hope it helps. 希望能帮助到你。

Here's a tidy solution where you provide the target date as a Calendar object. 这是一个整洁的解决方案,您可以将目标日期作为Calendar对象提供。

// Used to translate the Month value of a JQuery calendar to the month value expected by a Calendar.
private static final Map<String,Integer> MONTH_TO_CALENDAR_INDEX = new HashMap<String,Integer>();
static {
    MONTH_TO_CALENDAR_INDEX.put("January",  0);
    MONTH_TO_CALENDAR_INDEX.put("February",1);
    MONTH_TO_CALENDAR_INDEX.put("March",2);
    MONTH_TO_CALENDAR_INDEX.put("April",3);
    MONTH_TO_CALENDAR_INDEX.put("May",4);
    MONTH_TO_CALENDAR_INDEX.put("June",5);
    MONTH_TO_CALENDAR_INDEX.put("July",6);
    MONTH_TO_CALENDAR_INDEX.put("August",7);
    MONTH_TO_CALENDAR_INDEX.put("September",8);
    MONTH_TO_CALENDAR_INDEX.put("October",9);
    MONTH_TO_CALENDAR_INDEX.put("November",10);
    MONTH_TO_CALENDAR_INDEX.put("December",11);
}

        // ====================================================================================================
        // setCalendarPicker
        // ====================================================================================================

        /**
         * Sets the value of specified web element while assuming the element is a JQuery calendar.
         * @param byOpen The By phrase that locates the control that opens the JQuery calendar when clicked.
         * @param byPicker The By phrase that locates the JQuery calendar.
         * @param targetDate The target date that you want set.
         * @throws AssertionError if the method is unable to set the date.
         */

        public void setCalendarPicker(By byOpen, By byPicker, Calendar targetDate) {

            // Open the JQuery calendar.
            WebElement opener = driver.findElement(byOpen);
            opener.click();

            // Locate the JQuery calendar.
            WebElement picker = driver.findElement(byPicker);

            // Calculate the target and current year-and-month as an integer where value = year*12+month.
            // The difference between the two is the number of months we have to move ahead or backward.
            int targetYearMonth = targetDate.get(Calendar.YEAR) * 12 + targetDate.get(Calendar.MONTH);
            int currentYearMonth = Integer.valueOf(picker.findElement(By.className("ui-datepicker-year")).getText()) * 12
                    + Integer.valueOf(MONTH_TO_CALENDAR_INDEX.get(picker.findElement(By.className("ui-datepicker-month")).getText()));
            // Calculate the number of months we need to move the JQuery calendar.
            int delta = targetYearMonth - currentYearMonth;
            // As a sanity check, let's not allow more than 10 years so that we don't inadvertently spin in a loop for zillions of months.
            if (Math.abs(delta) > 120) throw new AssertionError("Target date is more than 10 years away");

            // Push the JQuery calendar forward or backward as appropriate.
            if (delta > 0) {
                while (delta-- > 0) picker.findElement(By.className("ui-icon-circle-triangle-e")).click();
            } else if (delta < 0 ){
                while (delta++ < 0) picker.findElement(By.className("ui-icon-circle-triangle-w")).click();
            }

            // Select the day within the month.
            String dayOfMonth = String.valueOf(targetDate.get(Calendar.DAY_OF_MONTH));
            WebElement tableOfDays = picker.findElement(By.cssSelector("tbody:nth-child(2)"));
            for (WebElement we : tableOfDays.findElements(By.tagName("td"))) {
                if (dayOfMonth.equals(we.getText())) {
                    we.click();

                    // Send a tab to completely leave this control.  If the next control the user will access is another CalendarPicker,
                    // the picker might not get selected properly if we stay on the current control.
                    opener.sendKeys("\t");

                    return;
                }
            }

            throw new AssertionError(String.format("Unable to select specified day"));
        }

here i show you my orignal code for automating jqueryui calender from its official site " https://jqueryui.com/resources/demos/datepicker/default.html ". 在这里,我向您展示我的orignal代码,用于从其官方网站“ https://jqueryui.com/resources/demos/datepicker/default.html ”自动化jqueryui日历。

copy paste the code and see it working like charm :) 复制粘贴代码,看它像魅力一样工作:)

vote up if you like it :) regards Avadh Goyal 如果你愿意,请投票赞成:)问候Avadh Goyal


public class JQueryDatePicker2 {
static int targetDay = 0, targetMonth = 0, targetYear = 0;

static int currenttDate = 0, currenttMonth = 0, currenttYear = 0;

static int jumMonthBy = 0;

static boolean increment = true;

public static void main(String[] args) throws InterruptedException {
    // TODO Auto-generated method stub
    String dateToSet = "16/12/2016";

    getCurrentDayMonth();
    System.out.println(currenttDate);
    System.out.println(currenttMonth);
    System.out.println(currenttYear);

    getTargetDayMonthYear(dateToSet);
    System.out.println(targetDay);
    System.out.println(targetMonth);
    System.out.println(targetYear);

    calculateToHowManyMonthToJump();
    System.out.println(jumMonthBy);
    System.out.println(increment);

    System.setProperty("webdriver.chrome.driver",
            "C:\\Users\\avadh.goyal\\Desktop\\selenium-2.52.0\\web driver\\chromedriver.exe");
    WebDriver driver = new ChromeDriver();
    driver.navigate().to(
            "https://jqueryui.com/resources/demos/datepicker/default.html");
    driver.manage().window().maximize();
    Thread.sleep(3000);

    driver.findElement(By.xpath("//*[@id='datepicker']")).click();

    for (int i = 0; i < jumMonthBy; i++) {
        if (increment) {
            driver.findElement(
                    By.xpath("//*[@id='ui-datepicker-div']/div/a[2]/span"))
                    .click();
        } else {
            driver.findElement(
                    By.xpath("//*[@id='ui-datepicker-div']/div/a[1]/span"))
                    .click();
        }
        Thread.sleep(1000);

    }

    driver.findElement(By.linkText(Integer.toString(targetDay))).click();

}

public static void getCurrentDayMonth() {

    Calendar cal = Calendar.getInstance();
    currenttDate = cal.get(Calendar.DAY_OF_MONTH);
    currenttMonth = cal.get(Calendar.MONTH) + 1;
    currenttYear = cal.get(Calendar.YEAR);
}

public static void getTargetDayMonthYear(String dateString) {
    int firstIndex = dateString.indexOf("/");
    int lastIndex = dateString.lastIndexOf("/");

    String day = dateString.substring(0, firstIndex);
    targetDay = Integer.parseInt(day);

    String month = dateString.substring(firstIndex + 1, lastIndex);
    targetMonth = Integer.parseInt(month);

    String year = dateString.substring(lastIndex + 1, dateString.length());
    targetYear = Integer.parseInt(year);

}

public static void calculateToHowManyMonthToJump() {

    if ((targetMonth - currenttMonth) > 0) {
        jumMonthBy = targetMonth - currenttMonth;

    } else {
        jumMonthBy = currenttMonth - targetMonth;
        increment = false;
    }
}

} }

This code should work properly to get the current date from the calendar. 此代码应该可以正常工作以从日历中获取当前日期。

String today=getCurrentDay(); //function 
driver.findElement(By.xpath("here xpath of textbox")).click();
Thread.sleep(5000);
WebElement dateWidgetForm= driver.findElement(By.xpath("here xpath of calender"));
List<WebElement> columns = dateWidgetForm.findElements(By.tagName("td"));

    for (WebElement cell: columns) {
      String z=cell.getAttribute("class").toString();
      if(z.equalsIgnoreCase("day")){
      if (cell.getText().equals(today)) {
        cell.click();
        break;
      }
    }

private String getCurrentDay() {
 Calendar calendar = Calendar.getInstance(TimeZone.getDefault());
 //Get Current Day as a number
 int todayInt = calendar.get(Calendar.DAY_OF_MONTH);
 System.out.println("Today Int: " + todayInt +"\n");

 //Integer to String Conversion
 String todayStr = Integer.toString(todayInt);
 return todayStr;
}
WebDriver driver;

public void launch(){

    driver = new FirefoxDriver();
    driver.get("http://www.cleartrip.com/");
    driver.manage().window().maximize();
    System.out.println("The browser launched successfully");
    }
public void clickdate(String inputDate){
    WebElement ele =driver.findElement(By.id("DepartDate"));
    ele.click();
    String month = driver.findElement(By.xpath("//div[@class='monthBlock first']/div[1]//span[1]")).getText();
    String year = driver.findElement(By.xpath("//div[@class='monthBlock first']/div[1]//span[2]")).getText();
    System.out.println("Application month : "+month + " Year :"+year);
    int monthNum = getMonthNum(month);
    System.out.println("Enum Num : "+monthNum);
    String[] parts = inputDate.split("/");
    int noOfHits = ((Integer.parseInt(parts[2])-Integer.parseInt(year))*12)+(Integer.parseInt(parts[1])-monthNum);
    System.out.println("No OF Hits "+noOfHits);
    for(int i=0; i< noOfHits;i++){
    driver.findElement(By.className("nextMonth ")).click();
    }
    List<WebElement> cals=driver.findElements(By.xpath("//div[@class='monthBlock first']//tr"));
    System.out.println(cals.size());
    for( WebElement daterow : cals){
    List<WebElement> datenums = daterow.findElements(By.xpath("//td"));
    /*iterating the "td" list*/
    for(WebElement date : datenums ){
    /* Checking The our input Date(if it match go inside and click*/
    if(date.getText().equalsIgnoreCase(parts[0])){
    date.click();
    break;
                          }
                     }
                 }
}

public  int getMonthNum(String month){
    for (Month mName : Month.values()) {
    if(mName.name().equalsIgnoreCase(month))
    return mName.value;
    }
    return -1;
    }

public enum Month{
    January(1), February(2), March(3), April(4), May(5), June(6) , July(7), August(8), September(9), October(10), November(11),December(12);
    private int value;

    private Month(int value) {
    this.value = value;
    }

    }


public static void main(String[] args)  {
    // TODO Auto-generated method stub
    Cleartrip cl=new Cleartrip();
    cl.launch();
    cl.clickdate("24/11/2015");
    }
}

There is an argument for keeping it simple and stupid if the date picker comes from a simple html5 input and the goal is to test whatever events were added to the test. 如果日期选择器来自简单的html5输入,并且目标是测试添加到测试中的任何事件,那么就有一个参数可以保持简单和愚蠢。 Consider for example: 考虑例如:

<input type=date name=mydate /> 

and one wants to set a test where 'mydate' is hardcoded to 02/22/2017, a solution with python is to use the following code, which is simple enough to debug to observe what it does: 并且想要设置一个测试,其中'mydate'被硬编码到02/22/2017,使用python的解决方案是使用以下代码,这很简单,可以调试以观察它的作用:

def setdate(elem_name, date_str):
    elem = driver.find_element_by_name('mydate')
    elem.click()
    elem.send_keys(Keys.ARROW_LEFT)
    elem.send_keys(Keys.ARROW_LEFT)
    elem.send_keys(date_str)

setdate('mydate'', '02222017')

Just do 做就是了

  JavascriptExecutor js = (JavascriptExecutor)driver;
  js.executeScript("document.getElementById('id').value='1988-01-01'");

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM