/* 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";
const BTN_MONTH_YEAR = "#month-year-label",
SPINNER_MONTH = "#spinner-month",
SPINNER_YEAR = "#spinner-year",
MONTH_YEAR = ".month-year";
const DATE_FORMAT = new Intl.DateTimeFormat("en-US", {
year: "numeric",
month: "long",
timeZone: "UTC",
}).format;
let helper = new DateTimeTestHelper();
add_setup(async function setPrefsReducedMotion() {
// Set "prefers-reduced-motion" media to "reduce"
// to avoid intermittent scroll failures (1803612, 1803687)
await SpecialPowers.pushPrefEnv({
set: [["ui.prefersReducedMotion", 1]],
});
Assert.ok(
matchMedia("(prefers-reduced-motion: reduce)").matches,
"The reduce motion mode is active"
);
registerCleanupFunction(() => {
helper.cleanup();
});
});
/**
* Ensure the month spinner follows arrow key bindings appropriately.
*/
add_task(async function test_spinner_month_keyboard_arrows() {
info("Ensure the month spinner follows arrow key bindings appropriately.");
const inputValue = "2022-12-10";
const nextMonthValue = "2022-01-01";
await helper.openPicker(
`data:text/html, `
);
let pickerDoc = helper.panel.querySelector("#dateTimePopupFrame")
.contentDocument;
info("Testing general keyboard navigation");
Assert.equal(
helper.getElement(BTN_MONTH_YEAR).getAttribute("aria-expanded"),
"false",
"Month-year button is collapsed when a picker is opened (by default)"
);
// Move focus from the selection to the month-year toggle button:
EventUtils.synthesizeKey("KEY_Tab", { repeat: 2 });
// Open month-year selection panel with spinners:
EventUtils.synthesizeKey(" ", {});
const spinnerMonthBtn = helper.getElement(SPINNER_MONTH).children[1];
const spinnerYearBtn = helper.getElement(SPINNER_YEAR).children[1];
let monthYearEl = helper.getElement(MONTH_YEAR);
Assert.equal(
helper.getElement(BTN_MONTH_YEAR).getAttribute("aria-expanded"),
"true",
"Month-year button is expanded when the spinners are shown"
);
// December 2022 is an example:
Assert.equal(
pickerDoc.activeElement.textContent,
DATE_FORMAT(new Date(inputValue)),
"Month-year toggle button is focused"
);
Assert.equal(
spinnerMonthBtn.getAttribute("aria-valuenow"),
"11",
"Month Spinner control is ready"
);
Assert.equal(
spinnerYearBtn.getAttribute("aria-valuenow"),
"2022",
"Year Spinner control is ready"
);
// Move focus from the month-year toggle button to the month spinner:
EventUtils.synthesizeKey("KEY_Tab", {});
Assert.equal(
pickerDoc.activeElement.getAttribute("aria-valuenow"),
"11",
"Tab moves focus to the month spinner"
);
info("Testing Up/Down Arrow keys behavior of the Month Spinner");
// Change the month-year from December 2022 to January 2022:
EventUtils.synthesizeKey("KEY_ArrowDown", {});
await BrowserTestUtils.waitForMutationCondition(
monthYearEl,
{ childList: true },
() => {
return monthYearEl.textContent == DATE_FORMAT(new Date(nextMonthValue));
},
`Should change to January 2022, instead got ${
helper.getElement(MONTH_YEAR).textContent
}`
);
Assert.equal(
spinnerMonthBtn.getAttribute("aria-valuenow"),
"0",
"Down Arrow selects the next month"
);
Assert.equal(
spinnerYearBtn.getAttribute("aria-valuenow"),
"2022",
"Down Arrow on a month spinner does not update the year"
);
Assert.equal(
helper.getElement(BTN_MONTH_YEAR).textContent,
DATE_FORMAT(new Date(nextMonthValue)),
"Down Arrow updates the month-year button to the next month"
);
// Change the month-year from January 2022 to December 2022:
EventUtils.synthesizeKey("KEY_ArrowUp", {});
await BrowserTestUtils.waitForMutationCondition(
monthYearEl,
{ childList: true },
() => {
return monthYearEl.textContent == DATE_FORMAT(new Date(inputValue));
},
`Should change to December 2022, instead got ${
helper.getElement(MONTH_YEAR).textContent
}`
);
Assert.equal(
spinnerMonthBtn.getAttribute("aria-valuenow"),
"11",
"Up Arrow selects the previous month"
);
Assert.equal(
spinnerYearBtn.getAttribute("aria-valuenow"),
"2022",
"Up Arrow on a month spinner does not update the year"
);
Assert.equal(
helper.getElement(BTN_MONTH_YEAR).textContent,
DATE_FORMAT(new Date(inputValue)),
"Up Arrow updates the month-year button to the previous month"
);
await helper.tearDown();
});
/**
* Ensure the month spinner follows Page Up/Down key bindings appropriately.
*/
add_task(async function test_spinner_month_keyboard_pageup_pagedown() {
info(
"Ensure the month spinner follows Page Up/Down key bindings appropriately."
);
const inputValue = "2022-12-10";
const nextFifthMonthValue = "2022-05-10";
await helper.openPicker(
`data:text/html, `
);
// const browser = helper.tab.linkedBrowser;
// Move focus from the selection to the month-year toggle button:
EventUtils.synthesizeKey("KEY_Tab", { repeat: 2 });
// Open month-year selection panel with spinners:
EventUtils.synthesizeKey(" ", {});
const spinnerMonthBtn = helper.getElement(SPINNER_MONTH).children[1];
const spinnerYearBtn = helper.getElement(SPINNER_YEAR).children[1];
let monthYearEl = helper.getElement(MONTH_YEAR);
// Move focus from the month-year toggle button to the month spinner:
EventUtils.synthesizeKey("KEY_Tab", {});
// Change the month-year from December 2022 to May 2022:
EventUtils.synthesizeKey("KEY_PageDown", {});
await BrowserTestUtils.waitForMutationCondition(
monthYearEl,
{ childList: true },
() => {
return (
monthYearEl.textContent == DATE_FORMAT(new Date(nextFifthMonthValue))
);
},
`Should change to May 2022, instead got ${
helper.getElement(MONTH_YEAR).textContent
}`
);
Assert.equal(
spinnerMonthBtn.getAttribute("aria-valuenow"),
"4",
"Page Down selects the fifth later month"
);
Assert.equal(
spinnerYearBtn.getAttribute("aria-valuenow"),
"2022",
"Page Down on a month spinner does not update the year"
);
Assert.equal(
helper.getElement(BTN_MONTH_YEAR).textContent,
DATE_FORMAT(new Date(nextFifthMonthValue)),
"Page Down updates the month-year button to the fifth later month"
);
// Change the month-year from May 2022 to December 2022:
EventUtils.synthesizeKey("KEY_PageUp", {});
await BrowserTestUtils.waitForMutationCondition(
monthYearEl,
{ childList: true },
() => {
return monthYearEl.textContent == DATE_FORMAT(new Date(inputValue));
},
`Should change to December 2022, instead got ${
helper.getElement(MONTH_YEAR).textContent
}`
);
Assert.equal(
spinnerMonthBtn.getAttribute("aria-valuenow"),
"11",
"Page Up selects the fifth earlier month"
);
Assert.equal(
spinnerYearBtn.getAttribute("aria-valuenow"),
"2022",
"Page Up on a month spinner does not update the year"
);
Assert.equal(
helper.getElement(BTN_MONTH_YEAR).textContent,
DATE_FORMAT(new Date(inputValue)),
"Page Up updates the month-year button to the fifth earlier month"
);
await helper.tearDown();
});
/**
* Ensure the month spinner follows Home/End key bindings appropriately.
*/
add_task(async function test_spinner_month_keyboard_home_end() {
info("Ensure the month spinner follows Home/End key bindings appropriately.");
const inputValue = "2022-12-11";
const firstMonthValue = "2022-01-11";
await helper.openPicker(
`data:text/html, `
);
// const browser = helper.tab.linkedBrowser;
// Move focus from the selection to the month-year toggle button:
EventUtils.synthesizeKey("KEY_Tab", { repeat: 2 });
// Open month-year selection panel with spinners:
EventUtils.synthesizeKey(" ", {});
const spinnerMonthBtn = helper.getElement(SPINNER_MONTH).children[1];
const spinnerYearBtn = helper.getElement(SPINNER_YEAR).children[1];
let monthYearEl = helper.getElement(MONTH_YEAR);
// Move focus from the month-year toggle button to the month spinner:
EventUtils.synthesizeKey("KEY_Tab", {});
// Change the month-year from December 2022 to January 2022:
EventUtils.synthesizeKey("KEY_Home", {});
await BrowserTestUtils.waitForMutationCondition(
monthYearEl,
{ childList: true },
() => {
return monthYearEl.textContent == DATE_FORMAT(new Date(firstMonthValue));
},
`Should change to January 2022, instead got ${
helper.getElement(MONTH_YEAR).textContent
}`
);
Assert.equal(
spinnerMonthBtn.getAttribute("aria-valuenow"),
"0",
"Home key selects the first month of the year (min value)"
);
Assert.equal(
spinnerYearBtn.getAttribute("aria-valuenow"),
"2022",
"Home key does not update the year value"
);
Assert.equal(
helper.getElement(BTN_MONTH_YEAR).textContent,
DATE_FORMAT(new Date(firstMonthValue)),
"Home key updates the month-year button to the first month of the same year (min value)"
);
// Change the month-year from January 2022 to December 2022:
EventUtils.synthesizeKey("KEY_End", {});
await BrowserTestUtils.waitForMutationCondition(
monthYearEl,
{ childList: true },
() => {
return monthYearEl.textContent == DATE_FORMAT(new Date(inputValue));
},
`Should change to December 2022, instead got ${
helper.getElement(MONTH_YEAR).textContent
}`
);
Assert.equal(
spinnerMonthBtn.getAttribute("aria-valuenow"),
"11",
"End key selects the last month of the year (max value)"
);
Assert.equal(
spinnerYearBtn.getAttribute("aria-valuenow"),
"2022",
"End key does not update the year value"
);
Assert.equal(
helper.getElement(BTN_MONTH_YEAR).textContent,
DATE_FORMAT(new Date(inputValue)),
"End key updates the month-year button to the last month of the same year (max value)"
);
await helper.tearDown();
});
/**
* Ensure the year spinner follows arrow key bindings appropriately.
*/
add_task(async function test_spinner_year_keyboard_arrows() {
info("Ensure the year spinner follows arrow key bindings appropriately.");
const inputValue = "2022-12-10";
const nextYearValue = "2023-12-01";
await helper.openPicker(
`data:text/html, `
);
let pickerDoc = helper.panel.querySelector("#dateTimePopupFrame")
.contentDocument;
info("Testing general keyboard navigation");
// Move focus from the selection to the month-year toggle button:
EventUtils.synthesizeKey("KEY_Tab", { repeat: 2 });
// Open month-year selection panel with spinners:
EventUtils.synthesizeKey(" ", {});
const spinnerMonthBtn = helper.getElement(SPINNER_MONTH).children[1];
const spinnerYearBtn = helper.getElement(SPINNER_YEAR).children[1];
let monthYearEl = helper.getElement(MONTH_YEAR);
// December 2022 is an example:
Assert.equal(
spinnerYearBtn.getAttribute("aria-valuenow"),
"2022",
"Year Spinner control is ready"
);
// Move focus from the month-year toggle button to the year spinner:
EventUtils.synthesizeKey("KEY_Tab", { repeat: 2 });
Assert.equal(
pickerDoc.activeElement.getAttribute("aria-valuenow"),
"2022",
"Tab can move the focus to the year spinner"
);
info("Testing Up/Down Arrow keys behavior of the Year Spinner");
// Change the month-year from December 2022 to December 2023:
EventUtils.synthesizeKey("KEY_ArrowDown", {});
await BrowserTestUtils.waitForMutationCondition(
monthYearEl,
{ childList: true },
() => {
return monthYearEl.textContent == DATE_FORMAT(new Date(nextYearValue));
},
`Should change to December 2023, instead got ${
helper.getElement(MONTH_YEAR).textContent
}`
);
Assert.equal(
spinnerMonthBtn.getAttribute("aria-valuenow"),
"11",
"Down Arrow on the year spinner does not change the month"
);
Assert.equal(
spinnerYearBtn.getAttribute("aria-valuenow"),
"2023",
"Down Arrow updates the year to the next"
);
Assert.equal(
helper.getElement(BTN_MONTH_YEAR).textContent,
DATE_FORMAT(new Date(nextYearValue)),
"Down Arrow updates the month-year button to the next year"
);
// Change the month-year from December 2023 to December 2022:
EventUtils.synthesizeKey("KEY_ArrowUp", {});
await BrowserTestUtils.waitForMutationCondition(
monthYearEl,
{ childList: true },
() => {
return monthYearEl.textContent == DATE_FORMAT(new Date(inputValue));
},
`Should change to December 2022, instead got ${
helper.getElement(MONTH_YEAR).textContent
}`
);
Assert.equal(
spinnerMonthBtn.getAttribute("aria-valuenow"),
"11",
"Up Arrow on the year spinner does not change the month"
);
Assert.equal(
spinnerYearBtn.getAttribute("aria-valuenow"),
"2022",
"Up Arrow updates the year to the previous"
);
Assert.equal(
helper.getElement(BTN_MONTH_YEAR).textContent,
DATE_FORMAT(new Date(inputValue)),
"Up Arrow updates the month-year button to the previous year"
);
await helper.tearDown();
});
/**
* Ensure the year spinner follows Page Up/Down key bindings appropriately.
*/
add_task(async function test_spinner_year_keyboard_pageup_pagedown() {
info(
"Ensure the year spinner follows Page Up/Down key bindings appropriately."
);
const inputValue = "2022-12-10";
const nextFifthYearValue = "2027-12-10";
await helper.openPicker(
`data:text/html, `
);
// const browser = helper.tab.linkedBrowser;
// Move focus from the selection to the month-year toggle button:
EventUtils.synthesizeKey("KEY_Tab", { repeat: 2 });
// Open month-year selection panel with spinners:
EventUtils.synthesizeKey(" ", {});
const spinnerMonthBtn = helper.getElement(SPINNER_MONTH).children[1];
const spinnerYearBtn = helper.getElement(SPINNER_YEAR).children[1];
let monthYearEl = helper.getElement(MONTH_YEAR);
// Move focus from the month-year toggle button to the year spinner:
EventUtils.synthesizeKey("KEY_Tab", { repeat: 2 });
// Change the month-year from December 2022 to December 2027:
EventUtils.synthesizeKey("KEY_PageDown", {});
await BrowserTestUtils.waitForMutationCondition(
monthYearEl,
{ childList: true },
() => {
return (
monthYearEl.textContent == DATE_FORMAT(new Date(nextFifthYearValue))
);
},
`Should change to December 2027, instead got ${
helper.getElement(MONTH_YEAR).textContent
}`
);
Assert.equal(
spinnerMonthBtn.getAttribute("aria-valuenow"),
"11",
"Page Down on the year spinner does not change the month"
);
Assert.equal(
spinnerYearBtn.getAttribute("aria-valuenow"),
"2027",
"Page Down selects the fifth later year"
);
Assert.equal(
helper.getElement(BTN_MONTH_YEAR).textContent,
DATE_FORMAT(new Date(nextFifthYearValue)),
"Page Down updates the month-year button to the fifth later year"
);
// Change the month-year from December 2027 to December 2022:
EventUtils.synthesizeKey("KEY_PageUp", {});
await BrowserTestUtils.waitForMutationCondition(
monthYearEl,
{ childList: true },
() => {
return monthYearEl.textContent == DATE_FORMAT(new Date(inputValue));
},
`Should change to December 2022, instead got ${
helper.getElement(MONTH_YEAR).textContent
}`
);
Assert.equal(
spinnerMonthBtn.getAttribute("aria-valuenow"),
"11",
"Page Up on the year spinner does not change the month"
);
Assert.equal(
spinnerYearBtn.getAttribute("aria-valuenow"),
"2022",
"Page Up selects the fifth earlier year"
);
Assert.equal(
helper.getElement(BTN_MONTH_YEAR).textContent,
DATE_FORMAT(new Date(inputValue)),
"Page Up updates the month-year button to the fifth earlier year"
);
await helper.tearDown();
});
/**
* Ensure the year spinner follows Home/End key bindings appropriately.
*/
add_task(async function test_spinner_year_keyboard_home_end() {
info("Ensure the year spinner follows Home/End key bindings appropriately.");
const inputValue = "2022-12-10";
const minValue = "2020-10-10";
const maxValue = "2030-12-31";
const minYearValue = "2020-12-10";
const maxYearValue = "2030-12-10";
await helper.openPicker(
`data:text/html, `
);
// Move focus from the selection to the month-year toggle button:
EventUtils.synthesizeKey("KEY_Tab", { repeat: 2 });
// Open month-year selection panel with spinners:
EventUtils.synthesizeKey(" ", {});
const spinnerMonthBtn = helper.getElement(SPINNER_MONTH).children[1];
const spinnerYearBtn = helper.getElement(SPINNER_YEAR).children[1];
let monthYearEl = helper.getElement(MONTH_YEAR);
// Move focus from the month-year toggle button to the year spinner:
EventUtils.synthesizeKey("KEY_Tab", { repeat: 2 });
// Change the month-year from December 2022 to December 2020:
EventUtils.synthesizeKey("KEY_Home", {});
await BrowserTestUtils.waitForMutationCondition(
monthYearEl,
{ childList: true },
() => {
return monthYearEl.textContent == DATE_FORMAT(new Date(minYearValue));
},
`Should change to December 2020, instead got ${
helper.getElement(MONTH_YEAR).textContent
}`
);
Assert.equal(
spinnerMonthBtn.getAttribute("aria-valuenow"),
"11",
"Home key on the year spinner does not change the month"
);
Assert.equal(
spinnerYearBtn.getAttribute("aria-valuenow"),
"2020",
"Home key selects the min year value"
);
Assert.equal(
helper.getElement(BTN_MONTH_YEAR).textContent,
DATE_FORMAT(new Date(minYearValue)),
"Home key updates the month-year button to the min year value"
);
// Change the month-year from December 2022 to December 2030:
EventUtils.synthesizeKey("KEY_End", {});
await BrowserTestUtils.waitForMutationCondition(
monthYearEl,
{ childList: true },
() => {
return monthYearEl.textContent == DATE_FORMAT(new Date(maxYearValue));
},
`Should change to December 2030, instead got ${
helper.getElement(MONTH_YEAR).textContent
}`
);
Assert.equal(
spinnerMonthBtn.getAttribute("aria-valuenow"),
"11",
"End key on the year spinner does not change the month"
);
Assert.equal(
spinnerYearBtn.getAttribute("aria-valuenow"),
"2030",
"End key selects the max year value"
);
Assert.equal(
helper.getElement(BTN_MONTH_YEAR).textContent,
DATE_FORMAT(new Date(maxYearValue)),
"End key updates the month-year button to the max year value"
);
await helper.tearDown();
});