-
Adding a Global Function to Cypress for a Date {num} Months Ago
I’m working on a COVID-19 booster shot registration form. On this form I ask the user when they received their last COVID-19 vaccine shot. This is three simple fields (the month values are 01, 02, 03, etc.):
Each vaccine brand (Pfizer, Moderna, J&J) has different eligibility criteria as it relates to the time since the individual received their original vaccine series. Pfizer, for example, is 6 months. My form needs to reject a user who says they received Pfizer less than 6 months ago.
Using Cypress I wanted some test coverage of this functionality. Original I had hard-coded a date value of 5 months ago:
123cy.get('select[name="datelastvax_month"]').select('08');cy.get('select[name="datelastvax_day"]').select('01');cy.get('select[name="datelastvax_year"]').select('2021');As you can imagine this would work well for a while. Fast-forward a few months from now… the time ago will eventually be more than 6 months ago. I don’t want to have to keep updating this code with a recent date. The obvious solution is to dynamically choose the dates based on the current date. A global helper function would be ideal as I need to use this in many tests. Here’s a simple solution:
Step 1: Define the Function in index.js
TheĀ support/index.js file is loaded before each Cypress run. Creating a global function here is a quick way to introduce a reusable piece of code.
12345678910111213141516171819202122/*** Returns a simple object for {num} months ago, containing YYYY, MM, DD.** @param {number} num* Number of months to subtract from current date.** @return object* Object containing three properties (year:YYYY, month:MM, day:DD)*/cy.getDateMonthsAgo = (num) => {const dateObj = new Date(new Date().getFullYear(),new Date().getMonth() - num,new Date().getDate());return {year: dateObj.getFullYear().toString(),month: ('0' + (dateObj.getMonth() + 1)).slice(-2),day: ('0' + dateObj.getDate()).slice(-2),}}There are many solutions to handle getting a date from {num} months ago. If you start looking around for “What is a month, really?” you will find many different opinions. The code I’m using above responds like most humans do: give the same day of the month from {num} months ago. With a {num} of 5 (five months ago), on October 25, 2021 the result would be May 25, 2021.
WARNING: Please note the following:
12345new Date(2021, 1, 28) ==> February 28, 2021new Date(2021, 1, 29) ==> March 1, 2021new Date(2021, 1, 30) ==> March 2, 2021new Date(2021, 1, 31) ==> March 3, 2021new Date(2021, 1, 32) ==> March 4, 2021Step 2: Use the Function
1234const fiveMonthsAgo = cy.getDateMonthsAgo(5);cy.get('select[name="datelastvax_month"]').select(fiveMonthsAgo.month);cy.get('select[name="datelastvax_day"]').select(fiveMonthsAgo.day);cy.get('select[name="datelastvax_year"]').select(fiveMonthsAgo.year);