Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore(ui5-datetime-picker): migrate tests to cypress #10845

Draft
wants to merge 3 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
335 changes: 335 additions & 0 deletions packages/main/cypress/specs/DateTimePicker.cy.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,335 @@
import DateTimePicker from "../../src/DateTimePicker.js";

function DefaultDateTimePicker() {
return (
<DateTimePicker id="dt" />
);
}

function DateTimePickerWithMinutes() {
return <DateTimePicker
id="dtMinutes"
formatPattern="dd/MM/yyyy, hh:mm a"
value="13/04/2020, 09:16 AM"/>;
}

function DateTimePickerWithSeconds({ initialValue }: { initialValue?: string }) {
return (
<DateTimePicker
id="dtSeconds"
formatPattern="dd/MM/yyyy, hh:mm:ss a"
value={initialValue || "13/04/2020, 03:16:16 AM"}
/>
);
}
describe("DateTimePicker general interaction", () => {
it("tests picker opens/closes programmatically", () => {
cy.mount(<DefaultDateTimePicker />);

cy.ui5DateTimePickerOpen("#dt");
cy.ui5DateTimePickerIsOpen("#dt").should("equal", true);
cy.ui5DateTimePickerClose("#dt");
cy.ui5DateTimePickerIsOpen("#dt").should("equal", false);
});

// Unstable but valid test, needs to be individually observed
// it("tests selection of new date/time", () => {
// const PREVIOUS_VALUE = "13/04/2020, 03:16:16 AM";

// cy.mount(<DateTimePicker id="dtSeconds" formatPattern="dd/MM/yyyy, hh:mm:ss a" value={PREVIOUS_VALUE} />);

// cy.ui5DateTimePickerOpen("#dtSeconds");

// cy.get("#dtSeconds")
// .shadow()
// .find("ui5-input")
// .should("have.value", PREVIOUS_VALUE);

// cy.ui5DateTimePickerGetPopover("#dtSeconds").within(() => {
// // Select the next day (click on the currently selected day, then ArrowRight and Space).
// cy.get("ui5-calendar")
// .shadow()
// .find("ui5-daypicker")
// .shadow()
// .find(".ui5-dp-item--selected")
// .realClick();

// cy.get("ui5-calendar")
// .shadow()
// .find("ui5-daypicker")
// .shadow()
// .find(".ui5-dp-item--selected")
// .should("exist");

// cy.realPress("ArrowRight");
// cy.realPress("Space");

// cy.get("ui5-time-selection-clocks")
// .shadow()
// .find(`ui5-toggle-spin-button[data-ui5-clock="hours"]`)
// .realClick();
// cy.realPress("ArrowDown");
// cy.realPress("Space");

// // Adjust minutes.
// cy.realPress("ArrowDown");
// cy.realPress("ArrowDown");
// cy.realPress("Space");

// // Adjust seconds.
// cy.realPress("ArrowUp");
// cy.realPress("ArrowUp");
// cy.realPress("ArrowUp");
// cy.realType("p");

// // Confirm.
// cy.get("#ok").realClick();
// });

// cy.get("#dtSeconds")
// .shadow()
// .find("ui5-input")
// .invoke("prop", "value")
// .should("equal", "14/04/2020, 02:14:19 PM");
// });

it("tests selection of new date without changing the time section", () => {
const PREVIOUS_VALUE = "14/04/2020, 02:14:19 PM";
cy.mount(<DateTimePickerWithSeconds initialValue={PREVIOUS_VALUE} />);

cy.get("#dtSeconds")
.shadow()
.find("ui5-input")
.should("have.value", PREVIOUS_VALUE);

// Simulate keyboard interactions
cy.realPress("Tab");
cy.realPress(["Shift", "Tab"]);
cy.realPress("Backspace");
cy.get("#dtSeconds")
.shadow()
.find("ui5-input")
.realClick();
cy.realType("wrongtext");
cy.realPress("Tab");

cy.ui5DateTimePickerOpen("#dtSeconds");

// Act
let selectedDate: string;
cy.ui5DateTimePickerGetPopover("#dtSeconds").within(() => {
cy.get("ui5-calendar")
.shadow()
.find("ui5-daypicker")
.shadow()
.find(".ui5-dp-item--now")
.then($el => {
const timestamp = $el.attr("data-sap-timestamp") || "";
const date = new Date(parseInt(timestamp) * 1000);
selectedDate = `${String(date.getDate()).padStart(2, "0")}/${String(date.getMonth() + 1).padStart(2, "0")}/${date.getFullYear()}`;
})
.realClick();

cy.get("#ok").realClick();
});

cy.get("#dtSeconds")
.shadow()
.find("ui5-input")
.invoke("prop", "value")
.should(val => {
expect(val).to.include(selectedDate);
});
});

it("tests time controls for dtSeconds picker", () => {
const expectedClocksCount = 3;
const expectedPeriodCount = 1;

cy.mount(<DateTimePickerWithSeconds />);

cy.ui5DateTimePickerOpen("#dtSeconds");

cy.ui5DateTimePickerTimeSelectionClocksCount("#dtSeconds").then(clocksCount => {
expect(clocksCount).to.equal(expectedClocksCount,
"The picker should display 3 clocks for hours, minutes and seconds.");
});

cy.ui5DateTimePickerPeriodSegmentedButtonCount("#dtSeconds").then(periodCount => {
expect(periodCount).to.equal(expectedPeriodCount,
"The picker should display 1 period selector.");
});

cy.ui5DateTimePickerClose("#dtSeconds");
});

it("tests time controls for dtMinutes picker", () => {
const expectedClocksCount = 2;
const expectedPeriodCount = 1;

cy.mount(<DateTimePickerWithMinutes />);

cy.ui5DateTimePickerOpen("#dtMinutes");

cy.ui5DateTimePickerTimeSelectionClocksCount("#dtMinutes").then(clocksCount => {
expect(clocksCount).to.equal(expectedClocksCount,
"The picker should display 2 clocks for hours and minutes.");
});

cy.ui5DateTimePickerPeriodSegmentedButtonCount("#dtMinutes").then(periodCount => {
expect(periodCount).to.equal(expectedPeriodCount,
"The picker should display 1 period selector.");
});

cy.ui5DateTimePickerClose("#dtMinutes");
});

it("tests hours clock is active on picker open", () => {
cy.mount(<DefaultDateTimePicker />);
cy.ui5DateTimePickerOpen("#dt");

cy.ui5DateTimePickerGetPopover("#dt").within(() => {
cy.get("ui5-time-selection-clocks")
.shadow()
.find(`ui5-time-picker-clock[data-ui5-clock="hours"]`)
.invoke("prop", "active")
.should("equal", true);
});
});

it("tests selection of 12:34:56 AM", () => {
cy.mount(<DateTimePickerWithSeconds />);

cy.ui5DateTimePickerOpen("#dtSeconds");

cy.ui5DateTimePickerGetPopover("#dtSeconds").within(() => {
cy.get("ui5-time-selection-clocks")
.shadow()
.find(`ui5-toggle-spin-button[data-ui5-clock="hours"]`)
.realClick();
cy.realType("12");
cy.get("ui5-time-selection-clocks")
.shadow()
.find(`ui5-toggle-spin-button[data-ui5-clock="minutes"]`)
.realClick();
cy.realType("34");
cy.get("ui5-time-selection-clocks")
.shadow()
.find(`ui5-toggle-spin-button[data-ui5-clock="seconds"]`)
.realClick();
cy.realType("56");
cy.get("#ok").realClick();
});

cy.get("#dtSeconds")
.shadow()
.find("ui5-input")
.invoke("prop", "value")
.should("equal", "13/04/2020, 12:34:56 AM");
});

it("tests change event is prevented on submit when prevent default is called", () => {
cy.mount(<DefaultDateTimePicker />);

// Prevent default behavior of ui5-change event.
cy.get("#dt").then($el => {
$el[0].addEventListener("ui5-change", (ev: Event) => {
ev.preventDefault();
});
});

cy.ui5DateTimePickerOpen("#dt");

cy.ui5DateTimePickerGetPopover("#dt").within(() => {
// Click the focused day and confirm the selection.
cy.get("ui5-calendar")
.shadow()
.find("ui5-daypicker")
.shadow()
.find("[data-sap-focus-ref]")
.realClick();
cy.get("#ok").realClick();
});

cy.get("#dt")
.shadow()
.find("ui5-input")
.invoke("prop", "value")
.should("equal", "");
});

it("Min and max dates are set, with no format pattern provided, using valid ISO format", () => {
cy.mount(
<DateTimePicker
id="dtMinMaxDatesISO"
minDate="2023-05-01"
maxDate="2023-05-31"
></DateTimePicker>
);

cy.ui5DateTimePickerOpen("#dtMinMaxDatesISO");

cy.ui5DateTimePickerGetPopover("#dtMinMaxDatesISO").within(() => {
cy.get("ui5-calendar")
.shadow()
.find(".ui5-calheader")
.find("div[data-ui5-cal-header-btn-prev]")
.should("have.class", "ui5-calheader-arrowbtn-disabled");

cy.get("ui5-calendar")
.shadow()
.find(".ui5-calheader")
.find("div[data-ui5-cal-header-btn-next]")
.should("have.class", "ui5-calheader-arrowbtn-disabled");
});
});

it("picker popover should have accessible name", () => {
cy.mount(<DefaultDateTimePicker />);
cy.ui5DateTimePickerOpen("#dt");

cy.ui5DateTimePickerGetPopover("#dt")
.invoke("attr", "accessible-name")
.should("equal", "Choose Date and Time");
});

it("tests change event is fired on submit", () => {
cy.mount(<DefaultDateTimePicker />);

const changeStub = cy.stub();
cy.get("#dt").then($el => {
$el[0].addEventListener("ui5-change", changeStub);
});

// Open the picker and select a date to enable the OK button
cy.ui5DateTimePickerOpen("#dt");
cy.ui5DateTimePickerGetPopover("#dt").within(() => {
cy.get("ui5-calendar")
.shadow()
.find("ui5-daypicker")
.shadow()
.find("[data-sap-focus-ref]")
.realClick();
cy.get("#ok").realClick();
});

// Assert that the change event was fired once
cy.wrap(null).then(() => {
expect(changeStub).to.have.callCount(1);
});

// Re-open the picker and submit without any change
cy.ui5DateTimePickerOpen("#dt");
cy.ui5DateTimePickerGetPopover("#dt").within(() => {
cy.get("#ok").realClick();
});

// The change event should not be fired again
cy.wrap(null).then(() => {
expect(changeStub).to.have.callCount(1);
});

// Verify the picker is closed
cy.ui5DateTimePickerIsOpen("#dt").should("equal", false);
});
});
9 changes: 9 additions & 0 deletions packages/main/cypress/support/commands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ import { internals, isPhone } from "@ui5/webcomponents-base/dist/Device.js";
import "./commands/Calendar.commands.js";
import "./commands/ColorPalette.commands.js";
import "./commands/ColorPicker.commands.js";
import "./commands/DateTimePicker.commands.js";
import "./commands/Menu.commands.js";

type SimulationDevices = "phone"
Expand All @@ -61,6 +62,14 @@ declare global {
ui5ColorPickerUpdateInput(name: string, value: string): Chainable<void>
ui5ColorPaletteCheckSelectedColor(colorPaletteItem: string, values: {r: string, g: string, b: string, a: string}): Chainable<void>
ui5ColorPaletteNavigateAndCheckSelectedColor(colorPalette: string, startIndex: number, key: string, expectedValue: string): Chainable<void>
ui5DateTimePickerOpen(selector: string): Chainable<void>;
ui5DateTimePickerClose(selector: string): Chainable<void>;
ui5DateTimePickerIsOpen(selector: string): Chainable<boolean>;
ui5DateTimePickerGetSubmitButton(selector: string): Chainable<JQuery<HTMLElement>>;
ui5DateTimePickerGetCancelButton(selector: string): Chainable<JQuery<HTMLElement>>;
ui5DateTimePickerTimeSelectionClocksCount(selector: string): Chainable<number>;
ui5DateTimePickerPeriodSegmentedButtonCount(selector: string): Chainable<number>;
ui5DateTimePickerGetPopover(selector: string): Chainable<JQuery<HTMLElement>>;
}
}
}
Expand Down
Loading