diff --git a/packages/main/cypress/specs/TimePicker.mobile.cy.tsx b/packages/main/cypress/specs/TimePicker.mobile.cy.tsx
new file mode 100644
index 000000000000..b5b6194e8c80
--- /dev/null
+++ b/packages/main/cypress/specs/TimePicker.mobile.cy.tsx
@@ -0,0 +1,231 @@
+import TimePicker from "../../src/TimePicker.js";
+import { setLanguage } from "@ui5/webcomponents-base/dist/config/Language.js";
+
+describe("TimePicker on phone - general interactions", () => {
+ beforeEach(() => {
+ cy.ui5SimulateDevice("phone");
+
+ // Set the language to Bulgarian for the tests
+ cy.wrap({ setLanguage })
+ .then(api => {
+ return api.setLanguage("bg")
+ })
+ });
+
+ it("opening of popover with numeric inputs", () => {
+ cy.mount();
+
+ cy.get("[ui5-time-picker]")
+ .as("timePicker")
+ .ui5TimePickerValueHelpIconPress();
+
+ cy.get("@timePicker")
+ .ui5TimePickerGetClock("hours")
+ .should("have.prop", "valueNow", 11);
+
+ cy.get("@timePicker")
+ .ui5TimePickerGetClock("minutes")
+ .should("have.prop", "valueNow", 12);
+
+ cy.get("@timePicker")
+ .ui5TimePickerGetClock("seconds")
+ .should("have.prop", "valueNow", 13);
+ });
+
+ it("value change with numeric inputs on OK and Cancel button press", () => {
+ cy.mount();
+
+ cy.get("[ui5-time-picker]")
+ .ui5TimePickerGetInnerInput()
+ .should("have.value", "10:20:30 AM");
+
+ cy.get("[ui5-time-picker]")
+ .as("timePicker")
+ .ui5TimePickerValueHelpIconPress();
+
+ cy.get("@timePicker")
+ .shadow()
+ .find("[ui5-responsive-popover]")
+ .find("[ui5-time-selection-clocks]")
+ .shadow()
+ .find("[ui5-segmented-button-item]")
+ .last()
+ .realClick()
+ .should("be.focused");
+
+ cy.get("@timePicker")
+ .ui5TimePickerGetClock("hours")
+ .should("have.prop", "valueNow", 10);
+
+ cy.get("@timePicker")
+ .ui5TimePickerGetClock("minutes")
+ .should("have.prop", "valueNow", 20);
+
+ cy.get("@timePicker")
+ .ui5TimePickerGetClock("seconds")
+ .should("have.prop", "valueNow", 30);
+
+ cy.get("@timePicker")
+ .ui5TimePickerGetSubmitButton()
+ .realClick();
+
+ cy.get("@timePicker")
+ .ui5TimePickerGetInnerInput()
+ .should("have.value", "10:20:30 PM");
+ });
+
+ it("direct number typing", () => {
+ cy.mount();
+
+ cy.get("[ui5-time-picker]")
+ .as("timePicker")
+ .ui5TimePickerGetInnerInput()
+ .realClick();
+
+ cy.get("@timePicker")
+ .ui5TimePickerGetInputsMobile()
+ .first()
+ .should("be.focused");
+
+ cy.realType("082413")
+
+ cy.get("@timePicker")
+ .shadow()
+ .find("[ui5-popover]")
+ .find("[ui5-time-selection-inputs]")
+ .shadow()
+ .find("[ui5-segmented-button-item]")
+ .last()
+ .realClick()
+ .should("be.focused");
+
+ cy.get("@timePicker")
+ .shadow()
+ .find("[ui5-popover]")
+ .find("#submitInputs")
+ .realClick();
+
+ cy.get("@timePicker")
+ .ui5TimePickerGetInnerInput()
+ .should("have.value", "8:24:13 PM");
+
+ cy.get("[ui5-time-picker]")
+ .as("timePicker")
+ .ui5TimePickerValueHelpIconPress();
+
+ cy.get("@timePicker")
+ .ui5TimePickerGetClock("hours")
+ .should("have.prop", "valueNow", 8);
+
+ cy.get("@timePicker")
+ .ui5TimePickerGetClock("minutes")
+ .should("have.prop", "valueNow", 24);
+
+ cy.get("@timePicker")
+ .ui5TimePickerGetClock("seconds")
+ .should("have.prop", "valueNow", 13);
+
+ cy.realType("092233");
+
+ cy.get("@timePicker")
+ .ui5TimePickerGetSubmitButton()
+ .realClick();
+
+ cy.get("@timePicker")
+ .ui5TimePickerGetInnerInput()
+ .should("have.value", "9:22:33 PM");
+ });
+});
+describe("TimePicker on phone - accessibility and other input attributes", () => {
+ beforeEach(() => {
+ cy.ui5SimulateDevice("phone");
+
+ // Set the language to Bulgarian for the tests
+ cy.wrap({ setLanguage })
+ .then(api => {
+ return api.setLanguage("bg")
+ })
+ });
+
+ it("accessibility attributes of numeric inputs", () => {
+ cy.mount();
+
+ cy.get("[ui5-time-picker]")
+ .as("timePicker")
+ .ui5TimePickerGetInnerInput()
+ .realClick();
+
+ cy.get("@timePicker")
+ .ui5TimePickerGetInputsMobile()
+ .as("inputs")
+ .should("have.length", 3);
+
+ cy.get("@inputs")
+ .first()
+ .shadow()
+ .find("input")
+ .should("have.attr", "step", "1")
+ .and("have.attr", "min", "1")
+ .and("have.attr", "max", "12")
+ .and("have.attr", "aria-label", "Please enter hours");
+
+ cy.get("@inputs")
+ .eq(1)
+ .shadow()
+ .find("input")
+ .should("have.attr", "step", "1")
+ .and("have.attr", "min", "0")
+ .and("have.attr", "max", "59")
+ .and("have.attr", "aria-label", "Please enter minutes");
+
+ cy.get("@inputs")
+ .last()
+ .shadow()
+ .find("input")
+ .should("have.attr", "step", "1")
+ .and("have.attr", "min", "0")
+ .and("have.attr", "max", "59")
+ .and("have.attr", "aria-label", "Please enter seconds");
+ });
+
+ it("other important attributes of numeric inputs", () => {
+ cy.mount();
+
+ cy.get("[ui5-time-picker]")
+ .as("timePicker")
+ .ui5TimePickerGetInnerInput()
+ .realClick();
+
+ cy.get("@timePicker")
+ .ui5TimePickerGetInputsMobile()
+ .as("inputs")
+ .should("have.length", 3);
+
+ cy.get("@inputs")
+ .first()
+ .shadow()
+ .find("input")
+ .should("have.attr", "type", "number")
+ .and("have.attr", "autocomplete", "off")
+ .and("have.attr", "pattern", "[0-9]*")
+ .and("have.attr", "inputmode", "numeric");
+
+ cy.get("@inputs")
+ .eq(1)
+ .shadow()
+ .find("input")
+ .should("have.attr", "type", "number")
+ .and("have.attr", "autocomplete", "off")
+ .and("have.attr", "pattern", "[0-9]*")
+ .and("have.attr", "inputmode", "numeric");
+
+ cy.get("@inputs")
+ .last()
+ .shadow()
+ .find("input")
+ .should("have.attr", "type", "number")
+ .and("have.attr", "autocomplete", "off")
+ .and("have.attr", "pattern", "[0-9]*")
+ .and("have.attr", "inputmode", "numeric");
+ });
+});
\ No newline at end of file
diff --git a/packages/main/cypress/support/commands/TimePicker.commands.ts b/packages/main/cypress/support/commands/TimePicker.commands.ts
index fb341547115b..9d2ea1b24edc 100644
--- a/packages/main/cypress/support/commands/TimePicker.commands.ts
+++ b/packages/main/cypress/support/commands/TimePicker.commands.ts
@@ -41,6 +41,21 @@ Cypress.Commands.add("ui5TimePickerGetClock", { prevSubject: true }, (subject, c
.find(`ui5-toggle-spin-button[data-ui5-clock="${clockType}"]`);
});
+Cypress.Commands.add("ui5TimePickerGetInputsMobile", { prevSubject: true }, (subject) => {
+ cy.wrap(subject)
+ .as("timePicker");
+
+ cy.get("@timePicker")
+ .should("not.have.attr", "open");
+
+ return cy.get("@timePicker")
+ .shadow()
+ .find("[ui5-popover]")
+ .find("[ui5-time-selection-inputs]")
+ .shadow()
+ .find(`[ui5-input]`)
+});
+
Cypress.Commands.add("ui5TimePickerGetSubmitButton", { prevSubject: true }, subject => {
cy.wrap(subject)
.as("timePicker");
@@ -67,9 +82,12 @@ declare global {
this: Chainable>,
clockType: string
): Chainable>;
+ ui5TimePickerGetInputsMobile(
+ this: Chainable>,
+ ): Chainable>;
ui5TimePickerGetSubmitButton(
this: Chainable>
): Chainable>;
}
}
-}
\ No newline at end of file
+}
\ No newline at end of file
diff --git a/packages/main/test/specs/TimePicker.mobile.spec.js b/packages/main/test/specs/TimePicker.mobile.spec.js
deleted file mode 100644
index 4db6f07606f2..000000000000
--- a/packages/main/test/specs/TimePicker.mobile.spec.js
+++ /dev/null
@@ -1,239 +0,0 @@
-import { assert } from "chai";
-
-/**
- *
- * @param {Array} options.keys The bundle keys of the texts
- * @param {String} options.id ID of the component to get the texts from
- * @returns
- */
-async function getResourceBundleTexts(options) {
- return browser.executeAsync((options, done) => {
- const component = document.getElementById(options.id);
-
- const texts = options.keys.reduce((result, key) => {
- result[key] = component.constructor.i18nBundle.getText(window["sap-ui-webcomponents-bundle"].defaultTexts[key])
- return result;
- }, {});
- done(texts);
-
- }, options);
-}
-
-describe("TimePicker on phone - general interactions", () => {
- before(async () => {
- await browser.url(`test/pages/TimePicker.html?sap-ui-language=bg`);
- await browser.emulateDevice('iPhone X');
- });
-
- it("opening of popover with numeric inputs", async () => {
- const timePicker = await browser.$("#timepicker");
- const timePickerPopover = await timePicker.shadow$("ui5-popover");
- const timeSelectionInputs = await timePickerPopover.$('div.popover-content').$('ui5-time-selection-inputs');
- const components = await timeSelectionInputs.shadow$$('ui5-input');
- const hoursInnerInput = await components[0].shadow$("input");
- const minutesInnerInput = await components[1].shadow$("input");
- const secondsInnerInput = await components[2].shadow$("input");
-
- // act
- await timePicker.setProperty("value", "11:12:13");
- await timePicker.shadow$("ui5-datetime-input").click();
-
- // assert
- assert.ok(await timePickerPopover.getAttribute("open"), "Popover found");
- assert.ok(await timeSelectionInputs, "TimeSelectionInputs found");
- assert.strictEqual(await components.length, 3, "Found 3 Inputs");
- assert.strictEqual(await hoursInnerInput.getValue(), "11", "Correct hours value is set");
- assert.strictEqual(await minutesInnerInput.getValue(), "12", "Correct minutes value is set");
- assert.strictEqual(await secondsInnerInput.getValue(), "13", "Correct seconds value is set");
- });
-
- it("value change with numeric inputs on OK and Cancel button press", async () => {
- const timePicker = await browser.$("#timepicker3");
- const timePickerPopover = await timePicker.shadow$("ui5-popover");
- const timePickerPopoverButtons = await timePickerPopover.$('div.ui5-time-picker-footer').$$("ui5-button");
- const timeSelectionInputs = await timePickerPopover.$('div.popover-content').$('ui5-time-selection-inputs');
- const components = await timeSelectionInputs.shadow$$('ui5-input');
- const hoursInnerInput = await components[0].shadow$("input");
- const minutesInnerInput = await components[1].shadow$("input");
- const secondsInnerInput = await components[2].shadow$("input");
- const amPmButton = await timeSelectionInputs.shadow$('ui5-segmented-button');
- const amPmButtonItems = await amPmButton.$$("ui5-segmented-button-item");
-
- // act
- await timePicker.setProperty("value", "10:20:30 AM");
- await timePicker.shadow$("ui5-datetime-input").click();
-
- await hoursInnerInput.setValue("11");
- await minutesInnerInput.setValue("22");
- await secondsInnerInput.setValue("33");
- await amPmButtonItems[1].click(); // click on PM button
-
- // assert
- assert.strictEqual(await hoursInnerInput.getValue(), "11", "Correct new hours value is set");
- assert.strictEqual(await minutesInnerInput.getValue(), "22", "Correct new minutes value is set");
- assert.strictEqual(await secondsInnerInput.getValue(), "33", "Correct new seconds value is set");
-
- // act
- await timePickerPopoverButtons[0].click(); // click on OK button
-
- // assert
- assert.strictEqual((await timePicker.getAttribute("value")).toUpperCase(), "11:22:33 PM", "Correct new time is set to the TimePicker");
-
- // act
- await timePicker.shadow$("ui5-datetime-input").click();
- await hoursInnerInput.setValue("10");
- await minutesInnerInput.setValue("20");
- await secondsInnerInput.setValue("30");
-
- // assert
- assert.strictEqual(await hoursInnerInput.getValue(), "10", "Correct new hours value is set");
- assert.strictEqual(await minutesInnerInput.getValue(), "20", "Correct new minutes value is set");
- assert.strictEqual(await secondsInnerInput.getValue(), "30", "Correct new seconds value is set");
-
- // act
- await timePickerPopoverButtons[1].click(); // click on Cancel button
-
- // assert
- assert.strictEqual((await timePicker.getAttribute("value")).toUpperCase(), "11:22:33 PM", "New time is not set to the TimePicker");
- });
-
- it("direct number typing", async () => {
- const timePicker = await browser.$("#timepicker");
- const timePickerPopover = await timePicker.shadow$("ui5-popover");
- const timePickerPopoverButtons = await timePickerPopover.$('div.ui5-time-picker-footer').$$("ui5-button");
- const timeSelectionInputs = await timePickerPopover.$('div.popover-content').$('ui5-time-selection-inputs');
- const components = await timeSelectionInputs.shadow$$('ui5-input');
- const hoursInnerInput = await components[0].shadow$("input");
- const minutesInnerInput = await components[1].shadow$("input");
- const secondsInnerInput = await components[2].shadow$("input");
-
- // act
- await timePicker.setProperty("value", "10:20:30 AM");
- await timePicker.shadow$("ui5-datetime-input").click();
- await browser.keys(["0", "8", "2", "4", "1", "3"]);
-
- // assert
- assert.strictEqual(await hoursInnerInput.getValue(), "08", "Correct new hours value is set");
- assert.strictEqual(await minutesInnerInput.getValue(), "24", "Correct new minutes value is set");
- assert.strictEqual(await secondsInnerInput.getValue(), "13", "Correct new seconds value is set");
-
- // act
- await timePickerPopoverButtons[0].click(); // click on OK button
-
- // assert
- assert.strictEqual((await timePicker.getAttribute("value")).toUpperCase(), "08:24:13", "New time is not set to the TimePicker");
-
- // act
- await timePicker.shadow$("ui5-datetime-input").click();
- await browser.keys(["3", "6", "8"]);
-
- // assert
- assert.strictEqual(await hoursInnerInput.getValue(), "03", "Correct new hours value is set");
- assert.strictEqual(await minutesInnerInput.getValue(), "06", "Correct new minutes value is set");
- assert.strictEqual(await secondsInnerInput.getValue(), "08", "Correct new seconds value is set");
-
- // act
- await timePickerPopoverButtons[0].click(); // click on OK button
-
- // assert
- assert.strictEqual((await timePicker.getAttribute("value")).toUpperCase(), "03:06:08", "New time is not set to the TimePicker");
-
- // act
- await timePicker.shadow$("ui5-datetime-input").click();
- await browser.keys(["4", "5"]);
-
- // assert
- assert.strictEqual(await hoursInnerInput.getValue(), "04", "Correct new hours value is set");
- assert.strictEqual(await minutesInnerInput.getValue(), "05", "Correct new minutes value is set");
-
- // act
- await browser.pause(1500); // simulate cooldown
- await browser.keys(["3", "2", "1", "0"]);
-
- // assert
- assert.strictEqual(await hoursInnerInput.getValue(), "04", "Correct new hours value is set");
- assert.strictEqual(await minutesInnerInput.getValue(), "32", "Correct new minutes value is set");
- assert.strictEqual(await secondsInnerInput.getValue(), "10", "Correct new seconds value is set");
-
-
- // act
- await timePickerPopoverButtons[0].click(); // click on OK button
-
- // assert
- assert.strictEqual((await timePicker.getAttribute("value")).toUpperCase(), "04:32:10", "New time is not set to the TimePicker");
- });
-
-});
-
-describe("TimePicker on phone - accessibility and other input attributes", () => {
- before(async () => {
- await browser.url(`test/pages/TimePicker.html?sap-ui-language=bg`);
- await browser.emulateDevice('iPhone X');
- });
-
- it("accessibility attributes of numeric inputs", async () => {
- const timePicker = await browser.$("#timepicker");
- const timePickerPopover = await timePicker.shadow$("ui5-popover");
- const timeSelectionInputs = await timePickerPopover.$('div.popover-content').$('ui5-time-selection-inputs');
- const components = await timeSelectionInputs.shadow$$('ui5-input');
- const hoursInnerInput = await components[0].shadow$("input");
- const minutesInnerInput = await components[1].shadow$("input");
- const secondsInnerInput = await components[2].shadow$("input");
-
- const keys = [
- "TIMEPICKER_INPUTS_ENTER_HOURS",
- "TIMEPICKER_INPUTS_ENTER_MINUTES",
- "TIMEPICKER_INPUTS_ENTER_SECONDS",
- ];
- const texts = await getResourceBundleTexts({ keys, id: "timepicker" });
-
- // act
- await timePicker.shadow$("ui5-datetime-input").click();
-
- // assert
- assert.strictEqual(await hoursInnerInput.getAttribute("step"), "1", "Correct hours 'step' attribute");
- assert.strictEqual(await hoursInnerInput.getAttribute("min"), "0", "Correct hours 'min' attribute");
- assert.strictEqual(await hoursInnerInput.getAttribute("max"), "23", "Correct hours 'max' attribute");
- assert.strictEqual(await hoursInnerInput.getAttribute("aria-label"), texts.TIMEPICKER_INPUTS_ENTER_HOURS, "Correct hours 'aria-label' attribute");
-
- assert.strictEqual(await minutesInnerInput.getAttribute("step"), "1", "Correct minutes 'step' attribute");
- assert.strictEqual(await minutesInnerInput.getAttribute("min"), "0", "Correct minutes 'min' attribute");
- assert.strictEqual(await minutesInnerInput.getAttribute("max"), "59", "Correct minutes 'max' attribute");
- assert.strictEqual(await minutesInnerInput.getAttribute("aria-label"), texts.TIMEPICKER_INPUTS_ENTER_MINUTES, "Correct minutes 'aria-label' attribute");
-
- assert.strictEqual(await secondsInnerInput.getAttribute("step"), "1", "Correct seconds 'step' attribute");
- assert.strictEqual(await secondsInnerInput.getAttribute("min"), "0", "Correct seconds 'min' attribute");
- assert.strictEqual(await secondsInnerInput.getAttribute("max"), "59", "Correct seconds 'max' attribute");
- assert.strictEqual(await secondsInnerInput.getAttribute("aria-label"), texts.TIMEPICKER_INPUTS_ENTER_SECONDS, "Correct seconds 'aria-label' attribute");
- });
-
- it("other important attributes of numeric inputs", async () => {
- const timePicker = await browser.$("#timepicker");
- const timePickerPopover = await timePicker.shadow$("ui5-popover");
- const timeSelectionInputs = await timePickerPopover.$('div.popover-content').$('ui5-time-selection-inputs');
- const components = await timeSelectionInputs.shadow$$('ui5-input');
- const hoursInnerInput = await components[0].shadow$("input");
- const minutesInnerInput = await components[1].shadow$("input");
- const secondsInnerInput = await components[2].shadow$("input");
-
- // act
- await timePicker.shadow$("ui5-datetime-input").click();
-
- // assert
- assert.strictEqual(await hoursInnerInput.getAttribute("type"), "number", "Correct hours 'type' attribute");
- assert.strictEqual(await hoursInnerInput.getAttribute("autocomplete"), "off", "Correct hours 'autocomplete' attribute");
- assert.strictEqual(await hoursInnerInput.getAttribute("pattern"), "[0-9]*", "Correct hours 'pattern' attribute");
- assert.strictEqual(await hoursInnerInput.getAttribute("inputmode"), "numeric", "Correct hours 'inputmode' attribute");
-
- assert.strictEqual(await minutesInnerInput.getAttribute("type"), "number", "Correct minutes 'type' attribute");
- assert.strictEqual(await minutesInnerInput.getAttribute("autocomplete"), "off", "Correct minutes 'autocomplete' attribute");
- assert.strictEqual(await minutesInnerInput.getAttribute("pattern"), "[0-9]*", "Correct minutes 'pattern' attribute");
- assert.strictEqual(await minutesInnerInput.getAttribute("inputmode"), "numeric", "Correct minutes 'inputmode' attribute");
-
- assert.strictEqual(await secondsInnerInput.getAttribute("type"), "number", "Correct seconds 'type' attribute");
- assert.strictEqual(await secondsInnerInput.getAttribute("autocomplete"), "off", "Correct seconds 'autocomplete' attribute");
- assert.strictEqual(await secondsInnerInput.getAttribute("pattern"), "[0-9]*", "Correct seconds 'pattern' attribute");
- assert.strictEqual(await secondsInnerInput.getAttribute("inputmode"), "numeric", "Correct seconds 'inputmode' attribute");
- });
-
-});