Bugzilla – Attachment 182636 Details for
Bug 39916
The 'Place booking' modal should have cypress tests
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
Bug 39916: Add cypress helpers for flatpickr
Bug-39916-Add-cypress-helpers-for-flatpickr.patch (text/plain), 13.58 KB, created by
Martin Renvoize (ashimema)
on 2025-05-19 18:06:28 UTC
(
hide
)
Description:
Bug 39916: Add cypress helpers for flatpickr
Filename:
MIME Type:
Creator:
Martin Renvoize (ashimema)
Created:
2025-05-19 18:06:28 UTC
Size:
13.58 KB
patch
obsolete
>From 35f82b58cde0f0136974ca4b3510d47777e6ac2e Mon Sep 17 00:00:00 2001 >From: Martin Renvoize <martin.renvoize@openfifth.co.uk> >Date: Mon, 19 May 2025 13:29:49 +0100 >Subject: [PATCH] Bug 39916: Add cypress helpers for flatpickr > >--- > t/cypress/support/e2e.js | 1 + > t/cypress/support/flatpickr.js | 333 +++++++++++++++++++++++++++++++++ > 2 files changed, 334 insertions(+) > create mode 100644 t/cypress/support/flatpickr.js > >diff --git a/t/cypress/support/e2e.js b/t/cypress/support/e2e.js >index 96250ac2bbc..0777212dd42 100644 >--- a/t/cypress/support/e2e.js >+++ b/t/cypress/support/e2e.js >@@ -26,6 +26,7 @@ > > // Import Select2 helpers > import "./select2"; >+import "./flatpickr.js"; > > function get_fallback_login_value(param) { > var env_var = param == "username" ? "KOHA_USER" : "KOHA_PASS"; >diff --git a/t/cypress/support/flatpickr.js b/t/cypress/support/flatpickr.js >new file mode 100644 >index 00000000000..ea7f7b57184 >--- /dev/null >+++ b/t/cypress/support/flatpickr.js >@@ -0,0 +1,333 @@ >+// flatpickrHelpers.js - Cypress helper methods for interacting with flatpickr date pickers >+ >+/** >+ * Gets the visible flatpickr input element using the ID of the original hidden input >+ * @param {string} originalInputSelector - The CSS selector for the original hidden input >+ * @returns {Cypress.Chainable} - The visible flatpickr input element >+ */ >+Cypress.Commands.add("getFlatpickr", originalInputSelector => { >+ return cy >+ .get(originalInputSelector) >+ .parents() >+ .find(".flatpickr_wrapper input.flatpickr-input"); >+}); >+ >+/** >+ * Opens a flatpickr calendar by clicking on its visible input element >+ * @param {string} originalInputSelector - The CSS selector for the original hidden input >+ * @returns {Cypress.Chainable} - The Cypress chainable object for additional commands >+ */ >+Cypress.Commands.add("openFlatpickr", originalInputSelector => { >+ cy.getFlatpickr(originalInputSelector).click(); >+ // Ensure the calendar is open by checking for the flatpickr container >+ cy.get(".flatpickr-calendar.open").should("be.visible"); >+ >+ // Return the originalInputSelector to enable chaining >+ return cy.wrap(originalInputSelector); >+}); >+ >+/** >+ * Closes an open flatpickr calendar by clicking outside of it >+ */ >+Cypress.Commands.add("closeFlatpickr", () => { >+ // Click on the body element, but not on the calendar >+ cy.get("body").click(0, 0); >+ // Ensure the calendar is closed >+ cy.get(".flatpickr-calendar.open").should("not.exist"); >+}); >+ >+/** >+ * Clears a flatpickr input by clicking the clear button >+ * @param {string} originalInputSelector - The CSS selector for the original hidden input >+ */ >+Cypress.Commands.add("clearFlatpickr", originalInputSelector => { >+ // Click the clear button (the .clear_date element) >+ cy.get(originalInputSelector).parents().find(".clear_date").click(); >+ >+ // Verify both the visible and hidden inputs are cleared >+ cy.get(originalInputSelector).should("have.value", ""); >+ cy.getFlatpickr(originalInputSelector).should("have.value", ""); >+}); >+ >+/** >+ * Sets a date in a flatpickr by selecting it from the calendar >+ * @param {string} originalInputSelector - The CSS selector for the original hidden input >+ * @param {Date|string} date - The date to select (Date object or YYYY-MM-DD string) >+ */ >+Cypress.Commands.add("selectFlatpickrDate", (originalInputSelector, date) => { >+ // Convert to Date object if string was provided >+ const dateObj = typeof date === "string" ? new Date(date) : date; >+ const year = dateObj.getFullYear(); >+ const month = dateObj.getMonth(); // 0-based index >+ const day = dateObj.getDate(); >+ >+ // Open the flatpickr calendar >+ cy.openFlatpickr(originalInputSelector); >+ >+ // Navigate to the correct month and year >+ cy.get(".flatpickr-current-month .cur-month").then($currentMonth => { >+ cy.get(".flatpickr-current-month .numInput.cur-year").then( >+ $currentYear => { >+ const currentMonth = new Date( >+ $currentMonth.text() + " 1, " + $currentYear.val() >+ ).getMonth(); >+ const currentYear = parseInt($currentYear.val()); >+ >+ // Navigate to the correct year >+ const yearDiff = year - currentYear; >+ if (yearDiff !== 0) { >+ const arrowSelector = >+ yearDiff > 0 >+ ? ".flatpickr-next-month" >+ : ".flatpickr-prev-month"; >+ for (let i = 0; i < Math.abs(yearDiff) * 12; i++) { >+ cy.get(arrowSelector).click(); >+ cy.wait(100); // Give time for the calendar to update >+ } >+ } >+ >+ // Navigate to the correct month >+ const monthDiff = month - currentMonth; >+ if (monthDiff !== 0) { >+ const arrowSelector = >+ monthDiff > 0 >+ ? ".flatpickr-next-month" >+ : ".flatpickr-prev-month"; >+ for (let i = 0; i < Math.abs(monthDiff); i++) { >+ cy.get(arrowSelector).click(); >+ cy.wait(100); // Give time for the calendar to update >+ } >+ } >+ } >+ ); >+ }); >+ >+ // Select the day >+ cy.get(".flatpickr-day") >+ .not(".prevMonthDay") >+ .not(".nextMonthDay") >+ .contains(day) >+ .click(); >+ >+ // Verify the hidden input has been updated >+ const formattedDate = `${year}-${(month + 1).toString().padStart(2, "0")}-${day.toString().padStart(2, "0")}`; >+ cy.get(originalInputSelector).should("have.value", formattedDate); >+ >+ // Return the originalInputSelector to enable chaining >+ return cy.wrap(originalInputSelector); >+}); >+ >+/** >+ * Sets a date in a flatpickr by typing directly into the visible input >+ * @param {string} originalInputSelector - The CSS selector for the original hidden input >+ * @param {string} dateString - The date string to type in the format expected by flatpickr >+ */ >+Cypress.Commands.add( >+ "typeFlatpickrDate", >+ (originalInputSelector, dateString) => { >+ // Clear the input and type the new date >+ cy.getFlatpickr(originalInputSelector).clear().type(dateString); >+ >+ // Click away to ensure the date is applied >+ cy.get("body").click(0, 0); >+ >+ // Verify both inputs have been updated >+ cy.get(originalInputSelector).should("have.value", dateString); >+ >+ // Return the originalInputSelector to enable chaining >+ return cy.wrap(originalInputSelector); >+ } >+); >+ >+/** >+ * Sets a date range in a flatpickr range picker >+ * @param {string} originalInputSelector - The CSS selector for the original hidden input >+ * @param {string|Date} startDate - The start date to select >+ * @param {string|Date} endDate - The end date to select >+ */ >+Cypress.Commands.add( >+ "selectFlatpickrDateRange", >+ (originalInputSelector, startDate, endDate) => { >+ // Open the flatpickr calendar >+ cy.openFlatpickr(originalInputSelector); >+ >+ // Convert to Date objects if strings were provided >+ const startDateObj = >+ typeof startDate === "string" ? new Date(startDate) : startDate; >+ const endDateObj = >+ typeof endDate === "string" ? new Date(endDate) : endDate; >+ >+ // Select start date >+ const startDay = startDateObj.getDate(); >+ cy.get(".flatpickr-day") >+ .not(".prevMonthDay") >+ .not(".nextMonthDay") >+ .contains(startDay) >+ .click(); >+ >+ // Select end date >+ const endDay = endDateObj.getDate(); >+ cy.get(".flatpickr-day") >+ .not(".prevMonthDay") >+ .not(".nextMonthDay") >+ .contains(endDay) >+ .click(); >+ >+ // Verify the hidden input has been updated (format depends on your flatpickr configuration) >+ cy.get(originalInputSelector).should("not.have.value", ""); >+ >+ // Return the originalInputSelector to enable chaining >+ return cy.wrap(originalInputSelector); >+ } >+); >+ >+/** >+ * Gets the current date from a flatpickr input >+ * @param {string} originalInputSelector - The CSS selector for the original hidden input >+ * @returns {string} The date value in the input >+ */ >+Cypress.Commands.add("getFlatpickrValue", originalInputSelector => { >+ return cy.get(originalInputSelector).invoke("val"); >+}); >+ >+/** >+ * Asserts that a flatpickr input has a specific date value >+ * @param {string} originalInputSelector - The CSS selector for the original hidden input >+ * @param {string} expectedDate - The expected date value in the input >+ */ >+Cypress.Commands.add( >+ "flatpickrShouldHaveValue", >+ (originalInputSelector, expectedDate) => { >+ cy.get(originalInputSelector).should("have.value", expectedDate); >+ } >+); >+ >+/** >+ * Navigates to a specific month/year in an already open flatpickr calendar >+ * @param {Date|string} date - The date to navigate to (only month/year are used) >+ * @returns {Cypress.Chainable} - Chainable >+ */ >+Cypress.Commands.add("navigateToMonth", date => { >+ // Convert to Date object if string was provided >+ const dateObj = typeof date === "string" ? new Date(date) : date; >+ const year = dateObj.getFullYear(); >+ const month = dateObj.getMonth(); // 0-based index >+ >+ // Navigate to the correct month and year >+ cy.get(".flatpickr-current-month .cur-month").then($currentMonth => { >+ cy.get(".flatpickr-current-month .numInput.cur-year").then( >+ $currentYear => { >+ const currentMonth = new Date( >+ $currentMonth.text() + " 1, " + $currentYear.val() >+ ).getMonth(); >+ const currentYear = parseInt($currentYear.val()); >+ >+ // Navigate to the correct year >+ const yearDiff = year - currentYear; >+ if (yearDiff !== 0) { >+ const arrowSelector = >+ yearDiff > 0 >+ ? ".flatpickr-next-month" >+ : ".flatpickr-prev-month"; >+ for (let i = 0; i < Math.abs(yearDiff) * 12; i++) { >+ cy.get(arrowSelector).click(); >+ cy.wait(100); // Give time for the calendar to update >+ } >+ } >+ >+ // Navigate to the correct month >+ const monthDiff = month - currentMonth; >+ if (monthDiff !== 0) { >+ const arrowSelector = >+ monthDiff > 0 >+ ? ".flatpickr-next-month" >+ : ".flatpickr-prev-month"; >+ for (let i = 0; i < Math.abs(monthDiff); i++) { >+ cy.get(arrowSelector).click(); >+ cy.wait(100); // Give time for the calendar to update >+ } >+ } >+ } >+ ); >+ }); >+ >+ return cy.wrap(date); >+}); >+ >+/** >+ * Selects a day from the currently displayed month in an open flatpickr >+ * @param {number|string} day - The day of the month to select >+ * @param {string} [originalInputSelector] - Optional selector to verify the input value >+ * @returns {Cypress.Chainable} - The originalInputSelector (if provided) for chaining >+ */ >+Cypress.Commands.add("selectDay", (day, originalInputSelector = null) => { >+ // Convert to number if string was provided >+ const dayNum = parseInt(day, 10); >+ >+ // Select the day >+ cy.get(".flatpickr-day") >+ .not(".prevMonthDay") >+ .not(".nextMonthDay") >+ .contains(dayNum) >+ .click(); >+ >+ // If originalInputSelector is provided, verify it has a non-empty value >+ if (originalInputSelector) { >+ cy.get(originalInputSelector).should("not.have.value", ""); >+ return cy.wrap(originalInputSelector); >+ } >+ >+ return cy.wrap(dayNum); >+}); >+ >+/** >+ * Goes to the next month in an open flatpickr calendar >+ * @returns {Cypress.Chainable} - Chainable >+ */ >+Cypress.Commands.add("nextMonth", () => { >+ cy.get(".flatpickr-next-month").click(); >+ cy.wait(100); // Give time for the calendar to update >+ return cy.wrap("next"); >+}); >+ >+/** >+ * Goes to the previous month in an open flatpickr calendar >+ * @returns {Cypress.Chainable} - Chainable >+ */ >+Cypress.Commands.add("prevMonth", () => { >+ cy.get(".flatpickr-prev-month").click(); >+ cy.wait(100); // Give time for the calendar to update >+ return cy.wrap("prev"); >+}); >+ >+/** >+ * Sets the current year in an open flatpickr calendar >+ * @param {number|string} year - The year to set >+ * @returns {Cypress.Chainable} - Chainable >+ */ >+Cypress.Commands.add("setYear", year => { >+ const yearNum = parseInt(year, 10); >+ cy.get(".flatpickr-current-month .numInput.cur-year") >+ .clear() >+ .type(yearNum.toString(), { force: true }) >+ .type("{enter}"); >+ cy.wait(100); // Give time for the calendar to update >+ return cy.wrap(yearNum); >+}); >+ >+/** >+ * Selects today's date in an open flatpickr calendar >+ * @param {string} [originalInputSelector] - Optional selector to verify the input value >+ * @returns {Cypress.Chainable} - The originalInputSelector (if provided) for chaining >+ */ >+Cypress.Commands.add("selectToday", (originalInputSelector = null) => { >+ cy.get(".flatpickr-day.today").click(); >+ >+ // If originalInputSelector is provided, verify it has a non-empty value >+ if (originalInputSelector) { >+ cy.get(originalInputSelector).should("not.have.value", ""); >+ return cy.wrap(originalInputSelector); >+ } >+ >+ return cy.wrap("today"); >+}); >-- >2.49.0
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
|
Splinter Review
Attachments on
bug 39916
:
182515
|
182516
|
182545
|
182546
|
182635
|
182636
|
182637
|
182771
|
182772
|
182773
|
183206
|
183207
|
183208
|
183209
|
183210