├── README.md
├── pom.xml
├── src
├── main
│ └── java
│ │ └── components
│ │ └── DatePicker.java
└── test
│ └── java
│ ├── base
│ └── BaseTests.java
│ └── datepicker
│ └── DatePickerTests.java
└── web
└── datepicker.html
/README.md:
--------------------------------------------------------------------------------
1 | # Automation Coding Recipe for Date Pickers
2 |
3 | This creates a model class to automate the interaction with a Date Picker component. Useful for automating UI tests.
4 |
5 | This projet uses Selenium WebDriver and Java.
6 |
7 | [Accompanying Blog Post](https://wp.me/p9CQEV-1oe) | [Live Stream Video](https://youtu.be/C72DOoI0fwk)
8 |
--------------------------------------------------------------------------------
/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 4.0.0
6 |
7 | org.example
8 | recipes
9 | 1.0-SNAPSHOT
10 |
11 |
12 | 1.14
13 | 1.14
14 |
15 |
16 |
17 |
18 | org.seleniumhq.selenium
19 | selenium-chrome-driver
20 | 4.0.0-alpha-2
21 |
22 |
23 |
24 | org.seleniumhq.selenium
25 | selenium-support
26 | 4.0.0-alpha-2
27 |
28 |
29 |
30 | org.seleniumhq.selenium
31 | selenium-server
32 | 4.0.0-alpha-2
33 |
34 |
35 |
36 | org.junit.jupiter
37 | junit-jupiter-api
38 | RELEASE
39 | test
40 |
41 |
42 |
43 | io.github.bonigarcia
44 | webdrivermanager
45 | RELEASE
46 | test
47 |
48 |
49 |
50 |
51 |
--------------------------------------------------------------------------------
/src/main/java/components/DatePicker.java:
--------------------------------------------------------------------------------
1 | package components;
2 |
3 | import org.openqa.selenium.By;
4 | import org.openqa.selenium.WebDriver;
5 |
6 | import java.time.LocalDate;
7 | import java.time.Month;
8 | import java.time.temporal.ChronoUnit;
9 |
10 | import static java.lang.String.format;
11 |
12 | public class DatePicker {
13 |
14 | private WebDriver driver;
15 |
16 | private By openCalendarButton = By.cssSelector("#datepicker ~ span button");
17 | private By calendar = By.cssSelector("div[role='calendar']");
18 | private By period = By.cssSelector("div[role='period']");
19 | private By leftArrow = By.cssSelector("div[role='navigator'] i.chevron-left");
20 | private By rightArrow = By.cssSelector("div[role='navigator'] i.chevron-right");
21 | private String day_FORMAT = "//td[@day='%d' and contains(@class, 'current-month')]";
22 |
23 | public DatePicker(WebDriver driver){
24 | this.driver = driver;
25 | }
26 |
27 | public LocalDate chooseDate(LocalDate date){
28 | open();
29 | chooseMonth(date);
30 | chooseDay(date.getDayOfMonth());
31 | return getSelectedDate();
32 | }
33 |
34 | public LocalDate getSelectedDate(){
35 | var fields = driver.findElement(calendar).getAttribute("selectedday").split("-");
36 | return LocalDate.of(
37 | Integer.parseInt(fields[0]),
38 | Integer.parseInt(fields[1]) + 1,
39 | Integer.parseInt(fields[2]));
40 | }
41 |
42 | public void chooseDay(int dayOfMonth) {
43 | By locator = By.xpath(format(day_FORMAT, dayOfMonth));
44 | driver.findElement(locator).click();
45 | }
46 |
47 | public void chooseMonth(LocalDate date) {
48 | var currentPeriod = getCurrentPeriod();
49 | long monthsAway = ChronoUnit.MONTHS.between(currentPeriod, date.withDayOfMonth(1));
50 |
51 | By arrow = monthsAway < 0 ? leftArrow : rightArrow;
52 |
53 | for(int i = 0; i < Math.abs(monthsAway); i++){
54 | driver.findElement(arrow).click();
55 | }
56 | }
57 |
58 | public LocalDate getCurrentPeriod(){
59 | var currentPeriod = driver.findElement(period).getText().split(" ");
60 | return LocalDate.of(
61 | Integer.parseInt(currentPeriod[1]),
62 | Month.valueOf(currentPeriod[0].toUpperCase()),
63 | 1);
64 | }
65 |
66 | public void open(){
67 | if(!isCalendarOpen()){
68 | driver.findElement(openCalendarButton).click();
69 | }
70 | }
71 |
72 | public boolean isCalendarOpen(){
73 | return driver.findElement(calendar).isDisplayed();
74 | }
75 | }
76 |
--------------------------------------------------------------------------------
/src/test/java/base/BaseTests.java:
--------------------------------------------------------------------------------
1 | package base;
2 |
3 | import io.github.bonigarcia.wdm.WebDriverManager;
4 | import org.junit.jupiter.api.AfterAll;
5 | import org.junit.jupiter.api.BeforeAll;
6 | import org.openqa.selenium.WebDriver;
7 | import org.openqa.selenium.chrome.ChromeDriver;
8 |
9 | public class BaseTests {
10 |
11 | protected static WebDriver driver;
12 |
13 | @BeforeAll
14 | public static void setUp() {
15 | WebDriverManager.chromedriver().setup();
16 | driver = new ChromeDriver();
17 | }
18 |
19 | @AfterAll
20 | public static void tearDown() {
21 | driver.quit();
22 | }
23 | }
--------------------------------------------------------------------------------
/src/test/java/datepicker/DatePickerTests.java:
--------------------------------------------------------------------------------
1 | package datepicker;
2 |
3 | import base.BaseTests;
4 | import components.DatePicker;
5 | import org.junit.jupiter.api.BeforeAll;
6 | import org.junit.jupiter.api.BeforeEach;
7 | import org.junit.jupiter.api.Test;
8 |
9 | import java.time.LocalDate;
10 | import java.time.Month;
11 |
12 | import static org.junit.jupiter.api.Assertions.assertEquals;
13 |
14 | public class DatePickerTests extends BaseTests {
15 |
16 | private DatePicker datePicker;
17 |
18 | @BeforeAll
19 | public static void launchApp(){
20 | //TODO: change this to your local URL
21 | driver.get("file:///Users/angie/workspace/blogs/recipes/web/datepicker.html");
22 | }
23 |
24 | @BeforeEach
25 | public void refreshCalendar(){
26 | driver.navigate().refresh();
27 | datePicker = new DatePicker(driver);
28 | }
29 |
30 | @Test
31 | public void pastDate(){
32 | var dateToSelect = LocalDate.of(1989, Month.DECEMBER, 20);
33 | var selectedDate = datePicker.chooseDate(dateToSelect);
34 | assertEquals(dateToSelect, selectedDate);
35 | }
36 |
37 | @Test
38 | public void trickyDate(){
39 | var dateToSelect = LocalDate.of(2020, Month.MARCH, 31);
40 | var selectedDate = datePicker.chooseDate(dateToSelect);
41 | assertEquals(dateToSelect, selectedDate);
42 | }
43 |
44 | @Test
45 | public void futureDate(){
46 | var dateToSelect = LocalDate.now().plusMonths(7);
47 | var selectedDate = datePicker.chooseDate(dateToSelect);
48 | assertEquals(dateToSelect, selectedDate);
49 | }
50 |
51 | @Test
52 | public void currentMonth(){
53 | var dateToSelect = LocalDate.now().withDayOfMonth(15);
54 | var selectedDate = datePicker.chooseDate(dateToSelect);
55 | assertEquals(dateToSelect, selectedDate);
56 | }
57 | }
--------------------------------------------------------------------------------
/web/datepicker.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Automation Cookbook: DatePicker Recipe
6 |
7 |
8 |
9 |
10 |
11 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------