Select a date from date picker using Selenium webdriver


656
656 points
select a date from date picker
select a date from date picker

Select a date from date picker using Selenium webdriver

The problem that many of the QA face when they have to select a date from date picker is that they don’t know exactly how to tell to the picker in which month it should be and on that specific month which day should I select. All this is because time never stops , it’s a dynamic mechanism and we need to deal with that.

Prerequisites to select a date from date picker:

We need not to think about selenium in the first instance , we need to find a way to provide the write information to selenium in order to be able to deal with the date picker :

Calculate the difference between two dates :

To be able to how many months we flip over the date picker months we need to know how many months are between 2 dates , this includes how many months in the future from today based on the number of days ahead , or how many months in the past based on number of days in the past provided.


    ##
    # Calculates the difference in years and month between two dates
    # Returns an array [year, month]
    # we care more about months ,
    # based on the number of months we will know how to loop through
    # the date picker and choose the right date
     ##
    # Calculates the difference in years and month between two dates
    # Returns an array [year, month]
    # we care more about months ,
    # based on the number of months we will know how to loop through
    # the date picker and choose the right date
    def date_diff(days)
      if days.to_i < 0
        # .abs will return the absolute value for the nr_of_days , removing the
        # negation sign
        nr_of_days = days.to_i.abs
        # caculate the number of months in the past
        start_date = Date.today
        start_date.to_s
        end_date = (start_date-nr_of_days).to_s
        date_to_start = start_date.strftime("%Y-%m-%d")
      else
        # caculate the number of months in the future
        start_date = Date.today.strftime("%Y-%m-%d")
        date_to_start = start_date
        end_date = Date.today.next_day(days).strftime("%Y-%m-%d")
      end
      # Parses the given representation of date and time with the given template
      date1_parse = Date::strptime(date_to_start, "%Y-%m-%d")
      date2_parse = Date::strptime(end_date, "%Y-%m-%d")
      # we ignore day differences here
      # and then calculate the number of years by dividing that number by
      if days.to_i < 0
        month = (date1_parse.year * 12 + date1_parse.month) -
            (date2_parse.year * 12 + date2_parse.month)
      else
        month = (date2_parse.year * 12 + date2_parse.month) -
            (date1_parse.year * 12 + date1_parse.month)
      end
      # month.divmod(12) is a shorthand for [month / 12,month % 12]
      # we care of returning just months as will not be necessary
      # to know the nr of years in this case
      month.divmod(12)[1]
    end

Im using date library from Ruby so you should consider to require ‘date’ in top of your class/module.

Now we need to get the target date for the date picker. Now my date picker had the date format Month day, year eg :

August 25, 2017

So the method will return the date in my format but you can change this method according with your date picker.

    ## get target date
    # target date will be used inside the date picker to
    # choose the date from the calendar
    def date_picker_target_date(days)
      if days.to_i < 0
        # .abs will return the absolute value for the nr_of_days , removing the
        # negation sign
        nr_of_days = days.to_i.abs
        # calculate the target date in the past
        end_date = Date.today.prev_day(nr_of_days).strftime("%Y-%m-%d")
      else
        # return a date in the past
        end_date = Date.today.next_day(days.to_i).strftime("%Y-%m-%d")
      end
      # get target day
      day = Date::strptime(end_date, "%Y-%m-%d").strftime("%d")
      # get target month
      month = Date::strptime(end_date, "%Y-%m-%d").strftime("%B")
      # get target year
      year = Date::strptime(end_date, "%Y-%m-%d").strftime("%Y")
      # convert the date into date picker format
      # so we can use this format on web to pass it inside an xpath
      # as a query string eg : August 25, 2017
      full_picker_date_format = "#{month} #{day.to_i}, #{year}"
      return full_picker_date_format
    end

 

Navigate through the date picker:

Using the informations that we have so far we can basically start thinking how we can navigate through the date picker .

  ## flip through the date picker to select the target date
      def flip_date_picker(element, nr_of_days)
        months = date_diff(nr_of_days.to_i)
        for i in 1..months do
          element.click
        end
      end
Define select date method:
 def select_date(days)
        date = date_picker_target_date(days).to_s
        find(:xpath, "//span[contains(@class, 'flatpickr-day') and @aria-label='#{date}']").click
      end

In this case I used the calculated date returned in a String format inside an xpath , and click on it.

Create select target date method:

Now we need to combine all methods from above in one method that will be used inside our step definition:

    ## select target date and flip through the calendar
      def select_target_date(days)
        months_ahead = date_diff(days.to_i)
        click_on_input_date
        # define next month selector used into flip date picker method
        if days.to_i < 0
          navigator = find(PREV_MONTH)
        else
          navigator = find(NEXT_MONTH)
        end
        # flip over the date picker to the target calculated month
        if months_ahead == 0
          select_date(days)
        else
          flip_date_picker(navigator, days)
          select_date(days)
        end
      end
Create your cucumber step:

And finally here is your cucumber step and your step definition:

When I select that I'm planning to move in <nr_of_days> days
When(/I select that I'm planning to move in (.*) days$/) do |nr_of_days|
  $web.moving.select_target_date(nr_of_days)
end

Happy Testing!


Like it? Share with your friends!

656
656 points
Test engineer

0 Comments

Your email address will not be published. Required fields are marked *

4 × 1 =