Datepickers and Date Object | Bondar Academy
Course: Cypress UI Testing with JavaScript
Module: Automation of User Interfaces
Instructor: Artem Bondar
Lesson Summary
This lesson focuses on automating the DatePicker component, which presents challenges due to its design and the dynamic nature of time. Specifically, selecting dates can be problematic if hard-coded, as the date will change when the test is run on a different day. Key Concepts DatePicker Design: The DatePicker consists of individual cells organized in rows, with some cells displaying dates from the previous month, known as bounding month dates. Automation Strategy: To automate date selection, we can filter out bounding month cells and select only the active dates. Automation Steps Use a locator to access the DatePicker input field. Expand the DatePicker to reveal the calendar. Select all day cells while excluding those with the boundingMonth class. Use the contains method to select the desired date. Dynamic Date Selection To avoid hard-coded values, utilize the JavaScript Date object to dynamically select dates: let date = new Date(); date.setDate(date.getDate() + 5); // Example: Select a date 5 days from today Extract the necessary values using methods like getDate() and getFullYear() to construct dynamic assertions for your tests. Conclusion In summary, when automating DatePickers, ensure you handle the active month correctly, filter out bounding month dates, and leverage the JavaScript Date object for dynamic date selection. This approach will enhance the reliability of your automated tests.
Video Transcript
All right, guys, let's talk about DatePicker and how to automate those. So DatePicker is also quite a tricky component to automate for two reasons. First of all, the design of the component, and second is time, which is continuously moving. And let's say you want to select the tomorrow's date in the calendar, and when you run the test tomorrow, then it will be today's date in the calendar, if you hard code this date, of course. And in this lesson, we will talk about how to automate these kind of flows, pick the right date, and how to handle date selection in the calendar. Let's jump into it. So for this lesson, we will use a different page under Forms, DatePicker. And we will automate this common DatePicker. Click on this, pick different dates, and so on. So let's look at the DatePicker design first. Right-click, Inspect, and look. The DatePicker consists of individual cells. You see I'm highlighting the cells. Then it's sliced by the rows, and then we have the entire DatePicker section with the numbers. And this particular DatePicker also have a tricky part. Look, it has a boundary month. You see the previous month numbers are also showed up in the list of available dates, why it is a problem sometimes to automate. Let's say you want to select the date 28, and instead of picking this 28 of the current month, the script may pick the previous month, and so the July 28 will be selected. But this, we can handle through the script, and let's automate selection of the date in the DatePicker. So going back to our script, I created a new test, it only DatePickers under the UI components. And first of all, let's pick the input field and expand this DatePicker. So let me refresh the page. And we can use the form picker placeholder to navigate to this input field and pick it up. So I grab this locator and typing sci.get, then square braces, placeholder, then input. So I can use this input field later. First of all, we need to click on this sci.get, no, sci.wrap, and then input field, and then click to expand it. The next step after it is expanded, we need to select the date within this DatePicker. So let's check it out how we can do it. Let's say we pick the 12, so inspect. And the class that we have is a day cell, or we can use cell content. So whatever works for us. But what I am more interested is about this bounding month and look. So this is the difference in the DOM. So look, the 1st of August has today day cell and G star inserted. But the previous month has the bounding month. So what we can do, we can select all day cells in the calendar, but we can exclude those that have bounding month. So this is the trick, how you can filter the output of the cells that you're gonna work with. And this is what I'm gonna do. So I take this day cell class, going back, sci.get. And I pick all day cells. But I want to exclude, and I will use method not. But I don't want to include those that have bounding month. I'm looking for this class, like this.boundingMonth. And after this expression, we will have only the active cells for the current active calendar excluding bounding month. And then selecting the date, you can use method contains, and then pick the date that we need. Let's say 12, and after that, click. That's it, and let's make the validation. After that, that selection was successful. So it should, and this is the input field. So it have to have.value. And the value should be in the format. Let's select this date in August 12, 2025, like this. So I believe that's it. Let's try to run this test. So UI components, and running the test, and here we go. The test passed successfully. So let's quickly take a look how it works. So look, we first found 42 cells of the active calendar. Then we excluded bounding month, so we selected only the active calendar area. Then we selected 12, then we clicked, and then made the validation. So pretty straightforward. But remember I mentioned earlier in the beginning of the lesson that the problem is this hard-coded value 12. How can we avoid? How can we, for example, configure the script, select tomorrow's date always. When we run the script every day, it will select tomorrow's date, or five days from today, or next week, something like this. How can we do this? With that, we can use a JavaScript date object to automatically handle the date selection based on the current system date and time. Let me show you how to do this. So let's create a new variable. I call it date, and I will call a new date object. This is a built-in JavaScript object. So what it has, going back to the browser, and I will type jsDate. And the first developer, Mozilla Org, is the documentation how to use this date object. So you have different methods, getDate, getDay, and it shows you when you call, for example, getDate, is return the current date, for example, 19. If it will be August 19, if I call getDate, it will return 19. Or getFullYear will return me a full year, and so on. So using different methods, you see it has a bunch of those. Using different methods from the date object, we can extract different values from the date that we need for our test. Now let's do this. So if I call just the empty date object, it will get current date and time. And from this object, I can extract the data that I need. So I want to call date, getDate, it will give me the current date. And let's say I want to add plus five days to the current date. So today is August 1st, so it should be August 6th. And then I need to set back this value to the date object, so then I can extract the updated date from the date object later on. And I will call date, setDate, and I put the argument of this expression as the argument. So date, getDate plus five will be a set date. So this date will now have updated date of current date plus five days. And now from this updated date, we can get any values that we need. So for example, I will create a new variable and say futureDay equals, and it will be date.getDate, this one, getDate. This will return me a value of the date that have to be picked, currentDate plus five. And I'll take this guy and replacing it right here, and let's try to run this test. It should fail because we didn't update the assertion yet, but at least it should work. Yeah, you see, August 6th was selected, but the assertion failed because our assertion expects August 12th. We're gonna fix it as well. And let's fix it with dynamic value as well. And I will create new variable, and let's say dateToAssert, I call it like this. And I create a custom string, it will be like this, August. Then concatenation or interpolation with the future date like this. Then I put comma, and then I put 2025. And this will be a string that we're going to assert, but the future date variable will be dynamic value inside of it. Then I take this guy and replace inside of the assertion. And let's run this test one more time. Running the test, and here we go right now, pass successfully. August 6th was selected. So now, if I change, for example, right now to, I don't know, 15 days and going back, and look, date dynamically was updated to August 16th. But if I will change something to more crazy number, like 50 days from today, going back, and August 20th was selected. But the actual value, you know, it have to be August, next month is September, right? So it should be somewhere in September. Well, this happened because we don't have a logic that handles the month selection inside of the calendar yet. We only handle the date. And this thing, we're gonna make in the next lesson. All right, so for this lesson is done, and let's quickly summarize what we did in this lesson. When you automate date selectors, make sure that you properly handle the current active month of the calendar that you're going to pick. If you have sometimes bounder month, you can filter it by method, not excluding the bounding month for the active calendar. And then to pick the date, just use method contains to pick the date by text. You can dynamically select dates in the calendar using JavaScript date object. And this object will return you current date and time. From this object, then you can add or subtract the number of days that you want to select. And then use this dynamic value in your calendar. So let me do just one thing to refactor. I will move it outside of this function because it can live independently. We'll make it like this, and everything is all set. And I'll see you in the next lesson.