summaryrefslogtreecommitdiffstats
path: root/toolkit/content/tests/browser/datetime/browser_datetime_datepicker_prev_next_month.js
diff options
context:
space:
mode:
Diffstat (limited to 'toolkit/content/tests/browser/datetime/browser_datetime_datepicker_prev_next_month.js')
-rw-r--r--toolkit/content/tests/browser/datetime/browser_datetime_datepicker_prev_next_month.js534
1 files changed, 534 insertions, 0 deletions
diff --git a/toolkit/content/tests/browser/datetime/browser_datetime_datepicker_prev_next_month.js b/toolkit/content/tests/browser/datetime/browser_datetime_datepicker_prev_next_month.js
new file mode 100644
index 0000000000..1734e6fdc0
--- /dev/null
+++ b/toolkit/content/tests/browser/datetime/browser_datetime_datepicker_prev_next_month.js
@@ -0,0 +1,534 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+"use strict";
+
+/**
+ * When the Previous Month button is pressed, calendar should display
+ * the dates for the previous month.
+ */
+add_task(async function test_datepicker_prev_month_btn() {
+ const inputValue = "2016-12-15";
+ const prevMonth = "2016-11-01";
+
+ await helper.openPicker(
+ `data:text/html, <input type="date" value="${inputValue}">`
+ );
+
+ // Move focus from the selected date to the Previous Month button:
+ EventUtils.synthesizeKey("KEY_Tab", { repeat: 2 });
+ EventUtils.synthesizeKey(" ", {});
+
+ // 2016-11-15:
+ const focusableDay = getDayEl(15);
+
+ Assert.equal(
+ helper.getElement(MONTH_YEAR).textContent,
+ DATE_FORMAT(new Date(prevMonth))
+ );
+ Assert.deepEqual(
+ getCalendarText(),
+ [
+ "30",
+ "31",
+ "1",
+ "2",
+ "3",
+ "4",
+ "5",
+ "6",
+ "7",
+ "8",
+ "9",
+ "10",
+ "11",
+ "12",
+ "13",
+ "14",
+ "15",
+ "16",
+ "17",
+ "18",
+ "19",
+ "20",
+ "21",
+ "22",
+ "23",
+ "24",
+ "25",
+ "26",
+ "27",
+ "28",
+ "29",
+ "30",
+ "1",
+ "2",
+ "3",
+ "4",
+ "5",
+ "6",
+ "7",
+ "8",
+ "9",
+ "10",
+ ],
+ "The calendar is updated to show the previous month (2016-11)"
+ );
+ Assert.ok(
+ helper.getElement(BTN_PREV_MONTH).matches(":focus"),
+ "Focus stays on a Previous Month button after it's pressed"
+ );
+ Assert.equal(
+ focusableDay.textContent,
+ "15",
+ "The same day of the month is present within a calendar grid"
+ );
+ Assert.equal(
+ focusableDay,
+ helper.getElement(DAYS_VIEW).querySelector('[tabindex="0"]'),
+ "The same day of the month is focusable within a calendar grid"
+ );
+
+ // Move focus from the Previous Month button to the same day of the month (2016-11-15):
+ EventUtils.synthesizeKey("KEY_Tab", { repeat: 3 });
+
+ Assert.ok(
+ focusableDay.matches(":focus"),
+ "The same day of the previous month can be focused with a keyboard"
+ );
+
+ await helper.tearDown();
+});
+
+/**
+ * When the Next Month button is clicked, calendar should display the dates for
+ * the next month.
+ */
+add_task(async function test_datepicker_next_month_btn() {
+ const inputValue = "2016-12-15";
+ const nextMonth = "2017-01-01";
+
+ await helper.openPicker(
+ `data:text/html, <input type="date" value="${inputValue}">`
+ );
+
+ // Move focus from the selected date to the Next Month button:
+ EventUtils.synthesizeKey("KEY_Tab", { repeat: 4 });
+ EventUtils.synthesizeKey(" ", {});
+
+ // 2017-01-15:
+ const focusableDay = getDayEl(15);
+
+ Assert.equal(
+ helper.getElement(MONTH_YEAR).textContent,
+ DATE_FORMAT(new Date(nextMonth))
+ );
+ Assert.deepEqual(
+ getCalendarText(),
+ [
+ "25",
+ "26",
+ "27",
+ "28",
+ "29",
+ "30",
+ "31",
+ "1",
+ "2",
+ "3",
+ "4",
+ "5",
+ "6",
+ "7",
+ "8",
+ "9",
+ "10",
+ "11",
+ "12",
+ "13",
+ "14",
+ "15",
+ "16",
+ "17",
+ "18",
+ "19",
+ "20",
+ "21",
+ "22",
+ "23",
+ "24",
+ "25",
+ "26",
+ "27",
+ "28",
+ "29",
+ "30",
+ "31",
+ "1",
+ "2",
+ "3",
+ "4",
+ ],
+ "The calendar is updated to show the next month (2017-01)."
+ );
+ Assert.ok(
+ helper.getElement(BTN_NEXT_MONTH).matches(":focus"),
+ "Focus stays on a Next Month button after it's pressed"
+ );
+ Assert.equal(
+ focusableDay.textContent,
+ "15",
+ "The same day of the month is present within a calendar grid"
+ );
+ Assert.equal(
+ focusableDay,
+ helper.getElement(DAYS_VIEW).querySelector('[tabindex="0"]'),
+ "The same day of the month is focusable within a calendar grid"
+ );
+
+ // Move focus from the Next Month button to the same day of the month (2017-01-15):
+ EventUtils.synthesizeKey("KEY_Tab", {});
+
+ Assert.ok(
+ focusableDay.matches(":focus"),
+ "The same day of the next month can be focused with a keyboard"
+ );
+
+ await helper.tearDown();
+});
+
+/**
+ * When the Previous Month button is pressed, calendar should display
+ * the dates for the previous month on RTL build (bug 1806823).
+ */
+add_task(async function test_datepicker_prev_month_btn_rtl() {
+ const inputValue = "2016-12-15";
+ const prevMonth = "2016-11-01";
+
+ await SpecialPowers.pushPrefEnv({ set: [["intl.l10n.pseudo", "bidi"]] });
+
+ await helper.openPicker(
+ `data:text/html, <input type="date" value="${inputValue}">`
+ );
+
+ // Move focus from the selected date to the Previous Month button:
+ EventUtils.synthesizeKey("KEY_Tab", { repeat: 2 });
+ EventUtils.synthesizeKey(" ", {});
+
+ // 2016-11-15:
+ const focusableDay = getDayEl(15);
+
+ Assert.equal(
+ helper.getElement(MONTH_YEAR).textContent,
+ DATE_FORMAT(new Date(prevMonth)),
+ "The calendar is updated to show the previous month (2016-11)"
+ );
+ Assert.ok(
+ helper.getElement(BTN_PREV_MONTH).matches(":focus"),
+ "Focus stays on a Previous Month button after it's pressed"
+ );
+ Assert.equal(
+ focusableDay.textContent,
+ "15",
+ "The same day of the month is present within a calendar grid"
+ );
+ Assert.equal(
+ focusableDay,
+ helper.getElement(DAYS_VIEW).querySelector('[tabindex="0"]'),
+ "The same day of the month is focusable within a calendar grid"
+ );
+
+ // Move focus from the Previous Month button to the same day of the month (2016-11-15):
+ EventUtils.synthesizeKey("KEY_Tab", { repeat: 3 });
+
+ Assert.ok(
+ focusableDay.matches(":focus"),
+ "The same day of the previous month can be focused with a keyboard"
+ );
+
+ await helper.tearDown();
+ await SpecialPowers.popPrefEnv();
+});
+
+/**
+ * When the Next Month button is clicked, calendar should display the dates for
+ * the next month on RTL build (bug 1806823).
+ */
+add_task(async function test_datepicker_next_month_btn_rtl() {
+ const inputValue = "2016-12-15";
+ const nextMonth = "2017-01-01";
+
+ await SpecialPowers.pushPrefEnv({ set: [["intl.l10n.pseudo", "bidi"]] });
+
+ await helper.openPicker(
+ `data:text/html, <input type="date" value="${inputValue}">`
+ );
+
+ // Move focus from the selected date to the Next Month button:
+ EventUtils.synthesizeKey("KEY_Tab", { repeat: 4 });
+ EventUtils.synthesizeKey(" ", {});
+
+ // 2017-01-15:
+ const focusableDay = getDayEl(15);
+
+ Assert.equal(
+ helper.getElement(MONTH_YEAR).textContent,
+ DATE_FORMAT(new Date(nextMonth)),
+ "The calendar is updated to show the next month (2017-01)."
+ );
+ Assert.ok(
+ helper.getElement(BTN_NEXT_MONTH).matches(":focus"),
+ "Focus stays on a Next Month button after it's pressed"
+ );
+ Assert.equal(
+ focusableDay.textContent,
+ "15",
+ "The same day of the month is present within a calendar grid"
+ );
+ Assert.equal(
+ focusableDay,
+ helper.getElement(DAYS_VIEW).querySelector('[tabindex="0"]'),
+ "The same day of the month is focusable within a calendar grid"
+ );
+
+ // Move focus from the Next Month button to the same day of the month (2017-01-15):
+ EventUtils.synthesizeKey("KEY_Tab", {});
+
+ Assert.ok(
+ focusableDay.matches(":focus"),
+ "The same day of the next month can be focused with a keyboard"
+ );
+
+ await helper.tearDown();
+ await SpecialPowers.popPrefEnv();
+});
+
+/**
+ * When Previous/Next Month buttons or arrow keys are used to change a month view
+ * when a time value is incomplete for datetime-local inputs,
+ * calendar should update the month (bug 1817785).
+ */
+add_task(async function test_datepicker_reopened_prev_next_month_btn() {
+ info("Setup a datetime-local datepicker to its reopened state for testing");
+
+ let inputValueDT = "2023-05-02T01:01";
+ let prevMonth = new Date("2023-04-02");
+
+ await helper.openPicker(
+ `data:text/html, <input type="datetime-local" value="${inputValueDT}">`
+ );
+
+ let closed = helper.promisePickerClosed();
+ EventUtils.synthesizeKey("KEY_Escape", {});
+ await closed;
+
+ Assert.equal(
+ helper.panel.state,
+ "closed",
+ "Date picker panel should be closed"
+ );
+
+ await SpecialPowers.spawn(gBrowser.selectedBrowser, [], () => {
+ const input = content.document.querySelector("input");
+ const shadowRoot = SpecialPowers.wrap(input).openOrClosedShadowRoot;
+ const editFields = shadowRoot.querySelectorAll(".datetime-edit-field");
+ const amPm = editFields[5];
+ amPm.focus();
+
+ Assert.ok(
+ amPm.matches(":focus"),
+ "Period of the day within the input is focused"
+ );
+ });
+
+ // Use Backspace key to clear the value of the AM/PM section of the input
+ // and wait for input.value to change to null (bug 1833988):
+ await SpecialPowers.spawn(gBrowser.selectedBrowser, [], async () => {
+ const input = content.document.querySelector("input");
+
+ const EventUtils = ContentTaskUtils.getEventUtils(content);
+ EventUtils.synthesizeKey("KEY_Backspace", {}, content);
+
+ await ContentTaskUtils.waitForMutationCondition(
+ input,
+ { attributeFilter: ["value"] },
+ () => input.value == ""
+ );
+
+ Assert.ok(
+ !input.value,
+ `Expected an input value to be changed to 'null' when a time value became incomplete, instead got ${input.value}`
+ );
+ });
+
+ let ready = helper.waitForPickerReady();
+
+ // Move focus to a day section of the input and open a picker:
+ EventUtils.synthesizeKey("KEY_Tab", {});
+ EventUtils.synthesizeKey(" ", {});
+
+ await ready;
+
+ Assert.equal(
+ helper.panel.querySelector("#dateTimePopupFrame").contentDocument
+ .activeElement.textContent,
+ "2",
+ "Picker is opened with a focus set to the currently selected date"
+ );
+
+ info("Test the Previous Month button behavior");
+
+ // Move focus from the selected date to the Previous Month button,
+ // and activate it to move calendar from 2023-05-02 to 2023-04-02:
+ EventUtils.synthesizeKey("KEY_Tab", {
+ repeat: 2,
+ });
+ EventUtils.synthesizeKey(" ", {});
+
+ // Same date of the previous month should be visible and focusable
+ // (2023-04-02) but the focus should remain on the Previous Month button:
+ const focusableDayPrevMonth = getDayEl(2);
+ const monthYearEl = helper.getElement(MONTH_YEAR);
+ await BrowserTestUtils.waitForMutationCondition(
+ monthYearEl,
+ {
+ childList: true,
+ },
+ () => {
+ return monthYearEl.textContent == DATE_FORMAT(new Date(prevMonth));
+ },
+ `Should change to the previous month (April 2023), instead got ${
+ helper.getElement(MONTH_YEAR).textContent
+ }`
+ );
+ Assert.ok(
+ true,
+ `The date on both the Calendar and Month-Year button was updated
+ when Previous Month button was used`
+ );
+ Assert.ok(
+ helper.getElement(BTN_PREV_MONTH).matches(":focus"),
+ "Focus stays on a Previous Month button after it's pressed"
+ );
+ Assert.equal(
+ focusableDayPrevMonth,
+ helper.getElement(DAYS_VIEW).querySelector('[tabindex="0"]'),
+ "The same day of the month is focusable within a calendar grid"
+ );
+ Assert.equal(
+ focusableDayPrevMonth.textContent,
+ "2",
+ "The same day of the month is present within a calendar grid"
+ );
+
+ // Move focus from the Previous Month button to the same day of the month (2023-04-02):
+ EventUtils.synthesizeKey("KEY_Tab", {
+ repeat: 3,
+ });
+
+ Assert.ok(
+ focusableDayPrevMonth.matches(":focus"),
+ "The same day of the previous month can be focused with a keyboard"
+ );
+
+ info("Test the Next Month button behavior");
+
+ // Move focus from the focused date to the Next Month button and activate it,
+ // (from 2023-04-02 to 2023-05-02):
+ EventUtils.synthesizeKey("KEY_Tab", {
+ repeat: 4,
+ });
+ EventUtils.synthesizeKey(" ", {});
+
+ // Same date of the next month should be visible and focusable
+ // (2023-05-02) but the focus should remain on the Next Month button:
+ const focusableDayNextMonth = getDayEl(2);
+ await BrowserTestUtils.waitForMutationCondition(
+ monthYearEl,
+ {
+ childList: true,
+ },
+ () => {
+ return monthYearEl.textContent == DATE_FORMAT(new Date(inputValueDT));
+ },
+ `Should change to May 2023, instead got ${
+ helper.getElement(MONTH_YEAR).textContent
+ }`
+ );
+ Assert.ok(
+ true,
+ `The date on both the Calendar and Month-Year button was updated
+ when Next Month button was used`
+ );
+ Assert.ok(
+ helper.getElement(BTN_NEXT_MONTH).matches(":focus"),
+ "Focus stays on a Next Month button after it's pressed"
+ );
+ Assert.equal(
+ focusableDayNextMonth,
+ helper.getElement(DAYS_VIEW).querySelector('[tabindex="0"]'),
+ "The same day of the month is focusable within a calendar grid"
+ );
+ Assert.equal(
+ focusableDayNextMonth.textContent,
+ "2",
+ "The same day of the month is present within a calendar grid"
+ );
+
+ // Move focus from the Next Month button to the focusable day of the month (2023-05-02):
+ EventUtils.synthesizeKey("KEY_Tab", {});
+
+ Assert.ok(
+ focusableDayNextMonth.matches(":focus"),
+ "The same day of the month can be focused with a keyboard"
+ );
+
+ info("Test the arrow navigation behavior");
+
+ // Move focus from the focused date to the same weekday of the previous month,
+ // (From 2023-05-02 to 2023-04-25):
+ EventUtils.synthesizeKey("KEY_ArrowUp", {});
+
+ await BrowserTestUtils.waitForMutationCondition(
+ monthYearEl,
+ {
+ childList: true,
+ },
+ () => {
+ return monthYearEl.textContent == DATE_FORMAT(new Date(prevMonth));
+ },
+ `Should change to the previous month, instead got ${
+ helper.getElement(MONTH_YEAR).textContent
+ }`
+ );
+ Assert.ok(
+ true,
+ `The date on both the Calendar and Month-Year button was updated
+ when an Up Arrow key was used`
+ );
+
+ // Move focus from the focused date to the same weekday of the next month,
+ // (from 2023-04-25 to 2023-05-02):
+ EventUtils.synthesizeKey("KEY_ArrowDown", {});
+
+ await BrowserTestUtils.waitForMutationCondition(
+ monthYearEl,
+ {
+ childList: true,
+ },
+ () => {
+ return monthYearEl.textContent == DATE_FORMAT(new Date(inputValueDT));
+ },
+ `Should change to the previous month, instead got ${
+ helper.getElement(MONTH_YEAR).textContent
+ }`
+ );
+ Assert.ok(
+ true,
+ `The date on both the Calendar and Month-Year button was updated
+ when a Down Arrow key was used`
+ );
+
+ await helper.tearDown();
+});