UNPKG

@shopware-ag/meteor-component-library

Version:

The meteor component library is a Vue component library developed by Shopware. It is based on the [Meteor Design System](https://shopware.design/).

441 lines (348 loc) 15.5 kB
import { within, userEvent, screen } from "@storybook/test"; import { expect } from "@storybook/test"; import meta, { type MtDatepickerMeta, type MtDatepickerStory } from "./mt-datepicker.stories"; import { waitUntil } from "../../../_internal/test-helper"; export default { ...meta, title: "Interaction Tests/Form/mt-datepicker", } as MtDatepickerMeta; export const VisualTestDatepickerDefault: MtDatepickerStory = { name: "Render datepicker", args: { label: "Datepicker", }, }; export const TestDatepickerShouldOpen: MtDatepickerStory = { name: "Should open datepicker", args: { modelValue: new Date(Date.UTC(2012, 1, 21)).toISOString(), }, play: async ({ canvasElement }) => { const canvas = within(canvasElement); // Open datepicker by clicking the input wrapper await userEvent.click(canvas.getByRole("textbox")); // Wait until the datepicker's dropdown menu appears in the DOM await waitUntil(() => document.getElementsByClassName("dp__menu").length > 0); // Once the datepicker menu is detected, look for it within the document const calendar = within(document.getElementsByClassName("dp__menu")[0] as HTMLElement); // Expect input event is triggered expect(calendar).toBeDefined(); }, }; export const VisualTestDateInputValue: MtDatepickerStory = { name: "Should input date value", args: { label: "Date value", dateType: "date", locale: "en-US", }, play: async ({ canvasElement, args }) => { const canvas = within(canvasElement); // Open datepicker by clicking the input wrapper await userEvent.click(canvas.getByRole("textbox")); await waitUntil(() => document.getElementsByClassName("dp__menu").length > 0); await userEvent.click( document.querySelector('[data-test-id="year-toggle-overlay-0"]') as HTMLInputElement, ); await userEvent.click(document.querySelector('[data-test-id="2024"]') as HTMLInputElement); await userEvent.click( document.querySelector('[data-test-id="month-toggle-overlay-0"]') as HTMLInputElement, ); await userEvent.click(document.querySelector('[data-test-id="Nov"]') as HTMLInputElement); // Access the calendar and click the date await userEvent.click(document.getElementById("2024-11-13") as HTMLInputElement); // Check that the input value matches the date chosen const input = document.querySelector('[data-test-id="dp-input"]') as HTMLInputElement; expect(input.value).toContain("2024/11/13"); // Expect updatemodelvalue to have been called with date expect(args.updateModelValue).toHaveBeenCalledWith( expect.stringMatching(/^2024-11-13T\d{2}:\d{2}:\d{2}.\d{3}Z$/), ); }, }; export const VisualTestDateTimeInputValue: MtDatepickerStory = { name: "Should input datetime value", args: { label: "Date value", dateType: "datetime", locale: "en-US", }, play: async ({ canvasElement, args }) => { const canvas = within(canvasElement); // Open datepicker by clicking the input wrapper await userEvent.click(canvas.getByRole("textbox")); await waitUntil(() => document.getElementsByClassName("dp__menu").length > 0); await userEvent.click( document.querySelector('[data-test-id="year-toggle-overlay-0"]') as HTMLInputElement, ); await userEvent.click(document.querySelector('[data-test-id="2024"]') as HTMLInputElement); await userEvent.click( document.querySelector('[data-test-id="month-toggle-overlay-0"]') as HTMLInputElement, ); await userEvent.click(document.querySelector('[data-test-id="Nov"]') as HTMLInputElement); // Open the hours panel await userEvent.click( document.querySelector('[data-test-id="hours-toggle-overlay-btn-0"]') as HTMLInputElement, ); await waitUntil(() => !document.querySelector(".calendar-header")); // Select an hour await userEvent.click(document.querySelector('[data-test-id="12"]') as HTMLInputElement); // Open the minutes panel await userEvent.click( document.querySelector('[data-test-id="minutes-toggle-overlay-btn-0"]') as HTMLInputElement, ); // Wait 500ms, element checking is not always reliable await new Promise((resolve) => setTimeout(resolve, 500)); // Select minute const selectedMin = document.querySelector('[data-test-id="40"]') as HTMLInputElement; await userEvent.click(selectedMin); // Click date within calendar await userEvent.click(document.getElementById("2024-11-13") as HTMLInputElement); // Check that the input value matches the date chosen const input = document.querySelector('[data-test-id="dp-input"]') as HTMLInputElement; expect(input.value).toEqual("2024/11/13, 12:40"); // Expect updatemodelvalue to have been called with date expect(args.updateModelValue).toHaveBeenCalledWith("2024-11-13T12:40:00.000Z"); }, }; export const VisualTestDateRangeValue: MtDatepickerStory = { name: "Should input date range", args: { label: "Date value", dateType: "date", range: true, locale: "en-US", }, play: async ({ canvasElement }) => { const canvas = within(canvasElement); // Open datepicker by clicking the input wrapper await userEvent.click(canvas.getByRole("textbox")); await waitUntil(() => document.getElementsByClassName("dp__menu").length > 0); await userEvent.click( document.querySelector('[data-test-id="year-toggle-overlay-0"]') as HTMLInputElement, ); await userEvent.click(document.querySelector('[data-test-id="2024"]') as HTMLInputElement); await userEvent.click( document.querySelector('[data-test-id="month-toggle-overlay-0"]') as HTMLInputElement, ); await userEvent.click(document.querySelector('[data-test-id="Nov"]') as HTMLInputElement); // Click first date on calendar await userEvent.click(document.getElementById("2024-11-13") as HTMLInputElement); // Click second date on calendar await userEvent.click(document.getElementById("2024-11-16") as HTMLInputElement); // Check that the input value matches the dates chosen const input = document.querySelector('[data-test-id="dp-input"]') as HTMLInputElement; const dateRange = input.value.split(" - ").map((date) => date.split(",")[0].trim()); expect(dateRange).toEqual(["2024/11/13", "2024/11/16"]); }, }; export const VisualTestDateTimeRangeValue: MtDatepickerStory = { name: "Should input datetime range", args: { label: "Date value", dateType: "datetime", range: true, timeZone: "UTC", locale: "en-US", }, play: async ({ canvasElement, args }) => { const canvas = within(canvasElement); // Open datepicker by clicking the input wrapper await userEvent.click(canvas.getByRole("textbox")); await waitUntil(() => document.getElementsByClassName("dp__menu").length > 0); await userEvent.click( document.querySelector('[data-test-id="year-toggle-overlay-0"]') as HTMLInputElement, ); await userEvent.click(document.querySelector('[data-test-id="2024"]') as HTMLInputElement); await userEvent.click( document.querySelector('[data-test-id="month-toggle-overlay-0"]') as HTMLInputElement, ); await userEvent.click(document.querySelector('[data-test-id="Nov"]') as HTMLInputElement); // Set hours for first date await userEvent.click( document.querySelector('[data-test-id="hours-toggle-overlay-btn-0"]') as HTMLInputElement, ); const selectedHour1 = document.querySelector('[data-test-id="12"]') as HTMLInputElement; await waitUntil(() => selectedHour1 !== null); await userEvent.click(selectedHour1); // Set minutes for first date const minuteButton1 = document.querySelector( '[data-test-id="minutes-toggle-overlay-btn-0"]', ) as HTMLInputElement; await userEvent.click(minuteButton1); const selectedMinute1 = document.querySelector('[data-test-id="40"]') as HTMLInputElement; await waitUntil(() => selectedMinute1 !== null); await userEvent.click(selectedMinute1); // Set hours for second date await userEvent.click( document.querySelector('[data-test-id="hours-toggle-overlay-btn-1"]') as HTMLInputElement, ); // Wait until dialog with "hours overlay" is open await expect(document.querySelector('[aria-label="hours overlay"]')).toBeInTheDocument(); await expect(document.querySelector('[data-test-id="11"]')).toBeInTheDocument(); await expect(document.querySelector('[aria-label="Toggle overlay"]')).toBeInTheDocument(); // await new Promise((resolve) => setTimeout(resolve, 500000)); await waitUntil(() => !document.querySelector(".dp-slide-down-enter-active")); await waitUntil(() => document.querySelector('[aria-label="Toggle overlay"]')); await userEvent.click(document.querySelector('[data-test-id="11"]') as HTMLInputElement); // Set minutes for second date const minuteButton2 = document.querySelector( '[data-test-id="minutes-toggle-overlay-btn-1"]', ) as HTMLInputElement; await userEvent.click(minuteButton2); await waitUntil( () => (document.querySelector('[data-test-id="30"]') as HTMLInputElement) !== null, ); await expect(document.querySelector('[data-test-id="30"]')).toBeInTheDocument(); await userEvent.click(document.querySelector('[data-test-id="30"]') as HTMLInputElement); // Click first date on calendar const firstDate = document.getElementById("2024-11-13") as HTMLInputElement; await userEvent.click(firstDate); // Click second date on calendar const secondDate = document.getElementById("2024-11-16") as HTMLInputElement; await userEvent.click(secondDate); // Check that the input value matches the dates and times chosen const input = document.querySelector('[data-test-id="dp-input"]') as HTMLInputElement; expect(input.value).toEqual("2024/11/13, 12:40 - 2024/11/16, 11:30"); // Expect updatemodelvalue to have been called with array of ISO formatted dates expect(args.updateModelValue).toHaveBeenCalledWith([ "2024-11-13T12:40:00.000Z", "2024-11-16T11:30:00.000Z", ]); }, }; export const TestDisabledDoesNotOpenDatepicker: MtDatepickerStory = { name: "Should not open datepicker when disabled", args: { label: "Disabled", disabled: true, }, play: async ({ canvasElement }) => { const canvas = within(canvasElement); // Try to open datepicker await userEvent.click(canvas.getByRole("textbox")); // Expect the datepciker input to be disabled expect((canvas.getByRole("textbox") as HTMLInputElement).disabled).toBe(true); }, }; export const VisualTestTestCustomFormat: MtDatepickerStory = { name: "Should use custom format", args: { // Render it as "Year: 2024, Month: 11, Day: 13" format: (date: any) => { const year = date.getFullYear(); const month = date.getMonth() + 1; const day = date.getDate(); return `Year: ${year}, Month: ${month}, Day: ${day}`; }, }, play: async ({ canvasElement }) => { const canvas = within(canvasElement); // Open datepicker by clicking the input wrapper await userEvent.click(canvas.getByRole("textbox")); await waitUntil(() => document.getElementsByClassName("dp__menu").length > 0); await userEvent.click( document.querySelector('[data-test-id="year-toggle-overlay-0"]') as HTMLInputElement, ); await userEvent.click(document.querySelector('[data-test-id="2024"]') as HTMLInputElement); await userEvent.click( document.querySelector('[data-test-id="month-toggle-overlay-0"]') as HTMLInputElement, ); await userEvent.click(document.querySelector('[data-test-id="Nov"]') as HTMLInputElement); // Access the calendar and click the date await userEvent.click(document.getElementById("2024-11-13") as HTMLInputElement); // Check that the input value matches the date chosen const input = document.querySelector('[data-test-id="dp-input"]') as HTMLInputElement; expect(input.value).toContain("Year: 2024, Month: 11, Day: 13"); }, }; export const VisualTestTimeType: MtDatepickerStory = { name: "Should render just the time", args: { dateType: "time", placeholder: "Select time", modelValue: "07:15", }, play: async ({ canvasElement, args }) => { const canvas = within(canvasElement); // Open datepicker by clicking the input wrapper await userEvent.click(canvas.getByRole("textbox")); await waitUntil(() => document.getElementsByClassName("dp__menu").length > 0); await userEvent.click( document.querySelector('[data-test-id="hours-time-inc-btn-0"]') as HTMLInputElement, ); await userEvent.click( document.querySelector('[data-test-id="minutes-time-inc-btn-0"]') as HTMLInputElement, ); await userEvent.click(canvas.getByRole("textbox")); // Check that the input value matches the date chosen const input = document.querySelector('[data-test-id="dp-input"]') as HTMLInputElement; expect(input.value).toBe("08:16"); // Check that the modelvalue is the correct time string expect(args.updateModelValue).toHaveBeenCalledWith("08:16"); }, }; export const VisualTestClearButton: MtDatepickerStory = { name: "Shows clear button when the value is set", args: { modelValue: "07:15", dateType: "time", }, play: async ({ canvasElement }) => { const canvas = within(canvasElement); expect(canvas.getByRole("button", { name: "Clear value" })).toBeVisible(); }, }; export const VisualTestErrorStateRendering: MtDatepickerStory = { name: "Should display error", args: { error: { code: 500, detail: "Error while saving!", }, }, play: async ({ canvasElement }) => { const canvas = within(canvasElement); const errorMessage = canvas.getByText("Error while saving!"); expect(errorMessage).toBeInTheDocument(); const errorIcon = document.querySelector("#meteor-icon-kit__solid-exclamation-circle"); expect(errorIcon).toBeInTheDocument(); expect(canvasElement.firstElementChild).toHaveClass("has-error"); }, }; export const VisualTestMinDateDisabledDays: MtDatepickerStory = { name: "Should disable days before a fixed min-date", args: { label: "Date value", modelValue: "2025-06-15T12:00:00.000Z", minDate: "2025-06-15T00:00:00.000Z", locale: "en-US", }, play: async ({ canvasElement }) => { const canvas = within(canvasElement); await userEvent.click(canvas.getByRole("textbox")); const menu = await screen.findByRole("dialog"); await within(menu).findByText("Jun"); await within(menu).findByText("2025"); const calendarGrid = within(menu).getByRole("grid"); const dayCells = within(calendarGrid) .getAllByRole("gridcell") .filter((cell) => !cell.classList.contains("dp__cell_offset")); const day14 = dayCells.find((d) => d.textContent === "14"); expect(day14).toHaveAttribute("aria-disabled", "true"); const day15 = dayCells.find((d) => d.textContent === "15"); expect(day15).toBeDefined(); }, }; export const VisualTestHelpText: MtDatepickerStory = { name: "Should display help text", args: { label: "Datepicker", helpText: "This is a help text", }, play: async () => { const canvas = within(document.body); await userEvent.tab(); expect(canvas.getByRole("tooltip")).toBeInTheDocument(); }, };