Select a date in a DatePicker with Selenium WebDriver
How to use Selenium WebDriver to select a date in a date picker
Many modern websites use date pickers to select dates. This article will show you how to use Selenium WebDriver to select a date via a date picker in an automated test script. I will script using raw Selenium WebDriver in RSpec, using TestWise IDE.
For some date-pickers, we may be able to set the selected date (the hidden text field) directly, or use JavaScript. In this exercise, I will drive the data-picker UI (as a user would) using Selenium.
· Test Case 1: Select tomorrow’s date (Simple)
∘ Test Design
∘ Prepare
∘ Tasks
· Test Case 2: Select tomorrow’s date (edge cases)
∘ Complete Test Script
Test Case 1: Select tomorrow’s date (Simple)
Test Page URL: https://fengyuanchen.github.io/datepicker/
Test Design
Following typical test design, do it manually first to come up with a test design.
- Click the text control to show the date picker
- Select tomorrow’s date
- Close the date picker, if not auto-closed after the selection
- Verify the selected date
Then implement the above in an automated test script.
Prepare
From experience, picking a date involves date calculation, such as tomorrow and next week’s date. ActiveSupport (part of Rails) is very helpful on that.
require 'active_support/all'
Date.today
Date.today.advance(:days => 1) # tomorrow
Date.today.next_week
Also, formatting a date.
Date.today.strftime("%m/%d/%Y") #=> 12/17/2022 if today is 2022-12-17
Tasks
- Populate the date picker.
Right-click the “Pick a date” text box and inspect (in Chrome).
To get the date-picker to open up, click on the text-field.
driver.find_element(:name, "date").click
2. Select tomorrow’s date
Get the target date’s day (e.g 18 of 2022–12–18), and click the “18” in the date picker.
Inspecting the date-picker, there is a days
view (in a ul
). Inside that ul
, each day
corresponds to a date on the datepicker.
To select a date, just select the item with the date text matching your target date’s day.
# calculate the day tomorrow
date_tomorrow = Date.today.advance(:days => 1)
day_tomorrow = date_tomorrow.strftime("%d")
# click the day on the date picker
driver.find_element(:xpath, "//ul[@data-view='days']/li[text()=#{day_tomorrow}]").click
3. Close the date picker
Click anywhere else on the page (outside the date-picker) will close it. The safest place to click is just the body
element:
driver.find_element(:tag_name, "body").click
4. Verify the selected date
This is straightforward. Just assert that the value in the date-field matches the date you selected.
We can use strftime
to format it in the same way for comparison (mm/dd/yyyy):
result = driver.find_element(:name, "date")["value"]
expect(result).to eq(date_tomorrow.strftime("%m/%d/%Y"))
Test Case 2: Select tomorrow’s date (edge cases)
If today is the last day of the month, then tomorrow’s date will fall on the next month.
To handle this edge case, click the “next month” button to move month pages. Then, follow the same steps from Test Case 1 (select the day, close the date picker and verify the date).
# force tomorrow's date to be the first day of the month
date_tomorrow = Date.today.end_of_month.tomorrow
# edge case, end of the month
if date_tomorrow.month != Date.today.month
driver.find_element(:xpath, "//ul/li[@data-view='month next']").click
end
The above is to verify the edge case (the last day of the month). After verification, we need to change it back to handle both scenarios (see the complete test scripts below).
Complete Test Script
Please note that TestCase 1 and TestCase 2 were listed separately, this is to show the chain of thoughts. This in fact just one test case.
load File.dirname(__FILE__) + "/../test_helper.rb"
require "active_support/all"
describe "Date Picker" do
include TestHelper
before(:all) do
# browser_type, browser_options, site_url are defined in test_helper.rb
@driver = $driver = Selenium::WebDriver.for(browser_type, browser_options)
driver.manage().window().resize_to(1280, 720)
driver.get("https://fengyuanchen.github.io/datepicker/")
end
after(:all) do
driver.quit unless debugging?
end
it "Select tomorrow's date in datepicker" do
driver.find_element(:name, "date").click
date_tomorrow = Date.today.tomorrow
# if month changes
if date_tomorrow.month != Date.today.month
driver.find_element(:xpath, "//ul/li[@data-view='month next']").click
end
day_tomorrow = date_tomorrow.day
driver.find_element(:xpath, "//ul[@data-view='days']/li[text()=#{day_tomorrow}]").click
driver.find_element(:tag_name, "body").click
result = driver.find_element(:name, "date")["value"]
expect(result).to eq(date_tomorrow.strftime("%m/%d/%Y"))
end
end