├── 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 | --------------------------------------------------------------------------------