Line 0
Link Here
|
0 |
- |
1 |
// flatpickrHelpers.js - Cypress helper methods for interacting with flatpickr date pickers |
|
|
2 |
|
3 |
/** |
4 |
* Gets the visible flatpickr input element using the ID of the original hidden input |
5 |
* @param {string} originalInputSelector - The CSS selector for the original hidden input |
6 |
* @returns {Cypress.Chainable} - The visible flatpickr input element |
7 |
*/ |
8 |
Cypress.Commands.add("getFlatpickr", originalInputSelector => { |
9 |
return cy |
10 |
.get(originalInputSelector) |
11 |
.parents() |
12 |
.find(".flatpickr_wrapper input.flatpickr-input"); |
13 |
}); |
14 |
|
15 |
/** |
16 |
* Opens a flatpickr calendar by clicking on its visible input element |
17 |
* @param {string} originalInputSelector - The CSS selector for the original hidden input |
18 |
* @returns {Cypress.Chainable} - The Cypress chainable object for additional commands |
19 |
*/ |
20 |
Cypress.Commands.add("openFlatpickr", originalInputSelector => { |
21 |
cy.getFlatpickr(originalInputSelector).click(); |
22 |
// Ensure the calendar is open by checking for the flatpickr container |
23 |
cy.get(".flatpickr-calendar.open").should("be.visible"); |
24 |
|
25 |
// Return the originalInputSelector to enable chaining |
26 |
return cy.wrap(originalInputSelector); |
27 |
}); |
28 |
|
29 |
/** |
30 |
* Closes an open flatpickr calendar by clicking outside of it |
31 |
*/ |
32 |
Cypress.Commands.add("closeFlatpickr", () => { |
33 |
// Click on the body element, but not on the calendar |
34 |
cy.get("body").click(0, 0); |
35 |
// Ensure the calendar is closed |
36 |
cy.get(".flatpickr-calendar.open").should("not.exist"); |
37 |
}); |
38 |
|
39 |
/** |
40 |
* Clears a flatpickr input by clicking the clear button |
41 |
* @param {string} originalInputSelector - The CSS selector for the original hidden input |
42 |
*/ |
43 |
Cypress.Commands.add("clearFlatpickr", originalInputSelector => { |
44 |
// Click the clear button (the .clear_date element) |
45 |
cy.get(originalInputSelector).parents().find(".clear_date").click(); |
46 |
|
47 |
// Verify both the visible and hidden inputs are cleared |
48 |
cy.get(originalInputSelector).should("have.value", ""); |
49 |
cy.getFlatpickr(originalInputSelector).should("have.value", ""); |
50 |
}); |
51 |
|
52 |
/** |
53 |
* Sets a date in a flatpickr by selecting it from the calendar |
54 |
* @param {string} originalInputSelector - The CSS selector for the original hidden input |
55 |
* @param {Date|string} date - The date to select (Date object or YYYY-MM-DD string) |
56 |
*/ |
57 |
Cypress.Commands.add("selectFlatpickrDate", (originalInputSelector, date) => { |
58 |
// Convert to Date object if string was provided |
59 |
const dateObj = typeof date === "string" ? new Date(date) : date; |
60 |
const year = dateObj.getFullYear(); |
61 |
const month = dateObj.getMonth(); // 0-based index |
62 |
const day = dateObj.getDate(); |
63 |
|
64 |
// Open the flatpickr calendar |
65 |
cy.openFlatpickr(originalInputSelector); |
66 |
|
67 |
// Navigate to the correct month and year |
68 |
cy.get(".flatpickr-current-month .cur-month").then($currentMonth => { |
69 |
cy.get(".flatpickr-current-month .numInput.cur-year").then( |
70 |
$currentYear => { |
71 |
const currentMonth = new Date( |
72 |
$currentMonth.text() + " 1, " + $currentYear.val() |
73 |
).getMonth(); |
74 |
const currentYear = parseInt($currentYear.val()); |
75 |
|
76 |
// Navigate to the correct year |
77 |
const yearDiff = year - currentYear; |
78 |
if (yearDiff !== 0) { |
79 |
const arrowSelector = |
80 |
yearDiff > 0 |
81 |
? ".flatpickr-next-month" |
82 |
: ".flatpickr-prev-month"; |
83 |
for (let i = 0; i < Math.abs(yearDiff) * 12; i++) { |
84 |
cy.get(arrowSelector).click(); |
85 |
cy.wait(100); // Give time for the calendar to update |
86 |
} |
87 |
} |
88 |
|
89 |
// Navigate to the correct month |
90 |
const monthDiff = month - currentMonth; |
91 |
if (monthDiff !== 0) { |
92 |
const arrowSelector = |
93 |
monthDiff > 0 |
94 |
? ".flatpickr-next-month" |
95 |
: ".flatpickr-prev-month"; |
96 |
for (let i = 0; i < Math.abs(monthDiff); i++) { |
97 |
cy.get(arrowSelector).click(); |
98 |
cy.wait(100); // Give time for the calendar to update |
99 |
} |
100 |
} |
101 |
} |
102 |
); |
103 |
}); |
104 |
|
105 |
// Select the day |
106 |
cy.get(".flatpickr-day") |
107 |
.not(".prevMonthDay") |
108 |
.not(".nextMonthDay") |
109 |
.contains(day) |
110 |
.click(); |
111 |
|
112 |
// Verify the hidden input has been updated |
113 |
const formattedDate = `${year}-${(month + 1).toString().padStart(2, "0")}-${day.toString().padStart(2, "0")}`; |
114 |
cy.get(originalInputSelector).should("have.value", formattedDate); |
115 |
|
116 |
// Return the originalInputSelector to enable chaining |
117 |
return cy.wrap(originalInputSelector); |
118 |
}); |
119 |
|
120 |
/** |
121 |
* Sets a date in a flatpickr by typing directly into the visible input |
122 |
* @param {string} originalInputSelector - The CSS selector for the original hidden input |
123 |
* @param {string} dateString - The date string to type in the format expected by flatpickr |
124 |
*/ |
125 |
Cypress.Commands.add( |
126 |
"typeFlatpickrDate", |
127 |
(originalInputSelector, dateString) => { |
128 |
// Clear the input and type the new date |
129 |
cy.getFlatpickr(originalInputSelector).clear().type(dateString); |
130 |
|
131 |
// Click away to ensure the date is applied |
132 |
cy.get("body").click(0, 0); |
133 |
|
134 |
// Verify both inputs have been updated |
135 |
cy.get(originalInputSelector).should("have.value", dateString); |
136 |
|
137 |
// Return the originalInputSelector to enable chaining |
138 |
return cy.wrap(originalInputSelector); |
139 |
} |
140 |
); |
141 |
|
142 |
/** |
143 |
* Sets a date range in a flatpickr range picker |
144 |
* @param {string} originalInputSelector - The CSS selector for the original hidden input |
145 |
* @param {string|Date} startDate - The start date to select |
146 |
* @param {string|Date} endDate - The end date to select |
147 |
*/ |
148 |
Cypress.Commands.add( |
149 |
"selectFlatpickrDateRange", |
150 |
(originalInputSelector, startDate, endDate) => { |
151 |
// Open the flatpickr calendar |
152 |
cy.openFlatpickr(originalInputSelector); |
153 |
|
154 |
// Convert to Date objects if strings were provided |
155 |
const startDateObj = |
156 |
typeof startDate === "string" ? new Date(startDate) : startDate; |
157 |
const endDateObj = |
158 |
typeof endDate === "string" ? new Date(endDate) : endDate; |
159 |
|
160 |
// Select start date |
161 |
const startDay = startDateObj.getDate(); |
162 |
cy.get(".flatpickr-day") |
163 |
.not(".prevMonthDay") |
164 |
.not(".nextMonthDay") |
165 |
.contains(startDay) |
166 |
.click(); |
167 |
|
168 |
// Select end date |
169 |
const endDay = endDateObj.getDate(); |
170 |
cy.get(".flatpickr-day") |
171 |
.not(".prevMonthDay") |
172 |
.not(".nextMonthDay") |
173 |
.contains(endDay) |
174 |
.click(); |
175 |
|
176 |
// Verify the hidden input has been updated (format depends on your flatpickr configuration) |
177 |
cy.get(originalInputSelector).should("not.have.value", ""); |
178 |
|
179 |
// Return the originalInputSelector to enable chaining |
180 |
return cy.wrap(originalInputSelector); |
181 |
} |
182 |
); |
183 |
|
184 |
/** |
185 |
* Gets the current date from a flatpickr input |
186 |
* @param {string} originalInputSelector - The CSS selector for the original hidden input |
187 |
* @returns {string} The date value in the input |
188 |
*/ |
189 |
Cypress.Commands.add("getFlatpickrValue", originalInputSelector => { |
190 |
return cy.get(originalInputSelector).invoke("val"); |
191 |
}); |
192 |
|
193 |
/** |
194 |
* Asserts that a flatpickr input has a specific date value |
195 |
* @param {string} originalInputSelector - The CSS selector for the original hidden input |
196 |
* @param {string} expectedDate - The expected date value in the input |
197 |
*/ |
198 |
Cypress.Commands.add( |
199 |
"flatpickrShouldHaveValue", |
200 |
(originalInputSelector, expectedDate) => { |
201 |
cy.get(originalInputSelector).should("have.value", expectedDate); |
202 |
} |
203 |
); |
204 |
|
205 |
/** |
206 |
* Navigates to a specific month/year in an already open flatpickr calendar |
207 |
* @param {Date|string} date - The date to navigate to (only month/year are used) |
208 |
* @returns {Cypress.Chainable} - Chainable |
209 |
*/ |
210 |
Cypress.Commands.add("navigateToMonth", date => { |
211 |
// Convert to Date object if string was provided |
212 |
const dateObj = typeof date === "string" ? new Date(date) : date; |
213 |
const year = dateObj.getFullYear(); |
214 |
const month = dateObj.getMonth(); // 0-based index |
215 |
|
216 |
// Navigate to the correct month and year |
217 |
cy.get(".flatpickr-current-month .cur-month").then($currentMonth => { |
218 |
cy.get(".flatpickr-current-month .numInput.cur-year").then( |
219 |
$currentYear => { |
220 |
const currentMonth = new Date( |
221 |
$currentMonth.text() + " 1, " + $currentYear.val() |
222 |
).getMonth(); |
223 |
const currentYear = parseInt($currentYear.val()); |
224 |
|
225 |
// Navigate to the correct year |
226 |
const yearDiff = year - currentYear; |
227 |
if (yearDiff !== 0) { |
228 |
const arrowSelector = |
229 |
yearDiff > 0 |
230 |
? ".flatpickr-next-month" |
231 |
: ".flatpickr-prev-month"; |
232 |
for (let i = 0; i < Math.abs(yearDiff) * 12; i++) { |
233 |
cy.get(arrowSelector).click(); |
234 |
cy.wait(100); // Give time for the calendar to update |
235 |
} |
236 |
} |
237 |
|
238 |
// Navigate to the correct month |
239 |
const monthDiff = month - currentMonth; |
240 |
if (monthDiff !== 0) { |
241 |
const arrowSelector = |
242 |
monthDiff > 0 |
243 |
? ".flatpickr-next-month" |
244 |
: ".flatpickr-prev-month"; |
245 |
for (let i = 0; i < Math.abs(monthDiff); i++) { |
246 |
cy.get(arrowSelector).click(); |
247 |
cy.wait(100); // Give time for the calendar to update |
248 |
} |
249 |
} |
250 |
} |
251 |
); |
252 |
}); |
253 |
|
254 |
return cy.wrap(date); |
255 |
}); |
256 |
|
257 |
/** |
258 |
* Selects a day from the currently displayed month in an open flatpickr |
259 |
* @param {number|string} day - The day of the month to select |
260 |
* @param {string} [originalInputSelector] - Optional selector to verify the input value |
261 |
* @returns {Cypress.Chainable} - The originalInputSelector (if provided) for chaining |
262 |
*/ |
263 |
Cypress.Commands.add("selectDay", (day, originalInputSelector = null) => { |
264 |
// Convert to number if string was provided |
265 |
const dayNum = parseInt(day, 10); |
266 |
|
267 |
// Select the day |
268 |
cy.get(".flatpickr-day") |
269 |
.not(".prevMonthDay") |
270 |
.not(".nextMonthDay") |
271 |
.contains(dayNum) |
272 |
.click(); |
273 |
|
274 |
// If originalInputSelector is provided, verify it has a non-empty value |
275 |
if (originalInputSelector) { |
276 |
cy.get(originalInputSelector).should("not.have.value", ""); |
277 |
return cy.wrap(originalInputSelector); |
278 |
} |
279 |
|
280 |
return cy.wrap(dayNum); |
281 |
}); |
282 |
|
283 |
/** |
284 |
* Goes to the next month in an open flatpickr calendar |
285 |
* @returns {Cypress.Chainable} - Chainable |
286 |
*/ |
287 |
Cypress.Commands.add("nextMonth", () => { |
288 |
cy.get(".flatpickr-next-month").click(); |
289 |
cy.wait(100); // Give time for the calendar to update |
290 |
return cy.wrap("next"); |
291 |
}); |
292 |
|
293 |
/** |
294 |
* Goes to the previous month in an open flatpickr calendar |
295 |
* @returns {Cypress.Chainable} - Chainable |
296 |
*/ |
297 |
Cypress.Commands.add("prevMonth", () => { |
298 |
cy.get(".flatpickr-prev-month").click(); |
299 |
cy.wait(100); // Give time for the calendar to update |
300 |
return cy.wrap("prev"); |
301 |
}); |
302 |
|
303 |
/** |
304 |
* Sets the current year in an open flatpickr calendar |
305 |
* @param {number|string} year - The year to set |
306 |
* @returns {Cypress.Chainable} - Chainable |
307 |
*/ |
308 |
Cypress.Commands.add("setYear", year => { |
309 |
const yearNum = parseInt(year, 10); |
310 |
cy.get(".flatpickr-current-month .numInput.cur-year") |
311 |
.clear() |
312 |
.type(yearNum.toString(), { force: true }) |
313 |
.type("{enter}"); |
314 |
cy.wait(100); // Give time for the calendar to update |
315 |
return cy.wrap(yearNum); |
316 |
}); |
317 |
|
318 |
/** |
319 |
* Selects today's date in an open flatpickr calendar |
320 |
* @param {string} [originalInputSelector] - Optional selector to verify the input value |
321 |
* @returns {Cypress.Chainable} - The originalInputSelector (if provided) for chaining |
322 |
*/ |
323 |
Cypress.Commands.add("selectToday", (originalInputSelector = null) => { |
324 |
cy.get(".flatpickr-day.today").click(); |
325 |
|
326 |
// If originalInputSelector is provided, verify it has a non-empty value |
327 |
if (originalInputSelector) { |
328 |
cy.get(originalInputSelector).should("not.have.value", ""); |
329 |
return cy.wrap(originalInputSelector); |
330 |
} |
331 |
|
332 |
return cy.wrap("today"); |
333 |
}); |