/* 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"; /** * Ensure navigating through Datepicker using keyboard after a date * has already been selected will keep the keyboard focus * when reaching a different month (bug 1804466). */ add_task(async function test_focus_after_selection() { info( `Ensure navigating through Datepicker using keyboard after a date has already been selected will not lose keyboard focus when reaching a different month.` ); // 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" ); const inputValue = "2022-12-12"; const prevMonth = "2022-10-01"; const nextYear = "2023-11-01"; const nextYearAfter = "2024-01-01"; await helper.openPicker( `data:text/html, ` ); let browser = helper.tab.linkedBrowser; info("Test behavior when selection is done on the calendar grid"); // Move focus from 2022-12-12 to 2022-10-24 by week // Changing 2 month views along the way: EventUtils.synthesizeKey("KEY_ArrowUp", { repeat: 7 }); Assert.equal( helper.getElement(MONTH_YEAR).textContent, DATE_FORMAT(new Date(prevMonth)), "The calendar is updated to show the second previous month (2022-10)." ); // 2022-10-24: const focusedDayEl = getDayEl(24); Assert.ok( focusedDayEl.matches(":focus"), "An expected focusable day within a calendar grid is focused" ); let closed = helper.promisePickerClosed(); // Make a selection and close the picker EventUtils.synthesizeKey(" ", {}); // Check the focus is returned to main browser window when a panel is closed await SpecialPowers.spawn(browser, [], async () => { const body = content.document.body; // Testing the focus position within content: Assert.deepEqual( body, content.document.activeElement, `The main content's received programmatic focus` ); }); await closed; Assert.equal( helper.panel.state, "closed", "Panel is closed when the selection is made" ); let ready = helper.waitForPickerReady(); // Move the keyboard focus to the input field to reopen the picker EventUtils.synthesizeKey("KEY_Tab", {}); // Check the focus is returned to the Calendar button await SpecialPowers.spawn(browser, [], async () => { const input = content.document.querySelector("input"); // Testing the focus position within content: Assert.deepEqual( input, content.document.activeElement, `The input field includes programmatic focus` ); }); // Reopen the picker EventUtils.synthesizeKey(" ", {}); await ready; Assert.equal(helper.panel.state, "open", "Panel is reopened"); // Move focus from 2022-10-24 to 2022-12-12 by week // Changing 2 month views along the way: EventUtils.synthesizeKey("KEY_ArrowDown", { repeat: 7 }); // 2022-12-12: const focusedDay = getDayEl(12); const monthYearEl = helper.getElement(MONTH_YEAR); 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( focusedDay, helper.getElement(DAYS_VIEW).querySelector('[tabindex="0"]'), "There is a focusable day within a calendar grid" ); Assert.ok( focusedDay.matches(":focus"), "The focusable day within a calendar grid is focused" ); info("Test behavior when selection is done on the month-year panel"); // Move focus to the month-year toggle button and open it: EventUtils.synthesizeKey("KEY_Tab", { repeat: 3 }); EventUtils.synthesizeKey(" "); // Move focus to the month spin button and change its value // from December to November: EventUtils.synthesizeKey("KEY_Tab"); EventUtils.synthesizeKey("KEY_ArrowUp"); // Move focus to the year spin button and change its value // from 2022 to 2023: EventUtils.synthesizeKey("KEY_Tab"); EventUtils.synthesizeKey("KEY_ArrowDown"); await BrowserTestUtils.waitForMutationCondition( monthYearEl, { childList: true }, () => { return monthYearEl.textContent == DATE_FORMAT(new Date(nextYear)); }, `Should change to November 2023, instead got ${ helper.getElement(MONTH_YEAR).textContent }` ); // Make a selection, close the month picker EventUtils.synthesizeKey(" ", {}); Assert.ok( BrowserTestUtils.is_hidden(helper.getElement(MONTH_YEAR_VIEW)), "Month-year selection panel is not visible" ); // Move focus from 2023-11-12 to 2024-01-07 by week // Changing 2 month views along the way: EventUtils.synthesizeKey("KEY_ArrowDown", { repeat: 8 }); // 2024-01-07: const newFocusedDay = getDayEl(7); Assert.equal( helper.getElement(MONTH_YEAR).textContent, DATE_FORMAT(new Date(nextYearAfter)), "The calendar is updated to show another month (2024-01)." ); Assert.equal( newFocusedDay, helper.getElement(DAYS_VIEW).querySelector('[tabindex="0"]'), "There is a focusable day within a calendar grid" ); Assert.ok( newFocusedDay.matches(":focus"), "The focusable day within a calendar grid is focused" ); await helper.tearDown(); await SpecialPowers.popPrefEnv(); });