From 43a97878ce14b72f0981164f87f2e35e14151312 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 7 Apr 2024 11:22:09 +0200 Subject: Adding upstream version 110.0.1. Signed-off-by: Daniel Baumann --- .../tests/browser/browser_datetime_datepicker.js | 439 +++++++++++++++++++++ 1 file changed, 439 insertions(+) create mode 100644 toolkit/content/tests/browser/browser_datetime_datepicker.js (limited to 'toolkit/content/tests/browser/browser_datetime_datepicker.js') diff --git a/toolkit/content/tests/browser/browser_datetime_datepicker.js b/toolkit/content/tests/browser/browser_datetime_datepicker.js new file mode 100644 index 0000000000..df92813ea0 --- /dev/null +++ b/toolkit/content/tests/browser/browser_datetime_datepicker.js @@ -0,0 +1,439 @@ +/* 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 MONTH_YEAR = ".month-year", + DAYS_VIEW = ".days-view", + BTN_NEXT_MONTH = ".next", + DAY_TODAY = ".today", + DAY_SELECTED = ".selection"; +const DATE_FORMAT = new Intl.DateTimeFormat("en-US", { + year: "numeric", + month: "long", + timeZone: "UTC", +}).format; +const DATE_FORMAT_LOCAL = new Intl.DateTimeFormat("en-US", { + year: "numeric", + month: "long", +}).format; + +// Create a list of abbreviations for calendar class names +const W = "weekend", + O = "outside", + S = "selection", + R = "out-of-range", + T = "today", + P = "off-step"; + +// Calendar classlist for 2016-12. Used to verify the classNames are correct. +const calendarClasslist_201612 = [ + [W, O], + [O], + [O], + [O], + [], + [], + [W], + [W], + [], + [], + [], + [], + [], + [W], + [W], + [], + [], + [], + [S], + [], + [W], + [W], + [], + [], + [], + [], + [], + [W], + [W], + [], + [], + [], + [], + [], + [W], + [W, O], + [O], + [O], + [O], + [O], + [O], + [W, O], +]; + +function getCalendarText() { + let calendarCells = []; + for (const tr of helper.getChildren(DAYS_VIEW)) { + for (const td of tr.children) { + calendarCells.push(td.textContent); + } + } + return calendarCells; +} + +function getCalendarClassList() { + let calendarCellsClasses = []; + for (const tr of helper.getChildren(DAYS_VIEW)) { + for (const td of tr.children) { + calendarCellsClasses.push(td.classList); + } + } + return calendarCellsClasses; +} + +function mergeArrays(a, b) { + return a.map((classlist, index) => classlist.concat(b[index])); +} + +async function verifyPickerPosition(browsingContext, inputId) { + let inputRect = await SpecialPowers.spawn( + browsingContext, + [inputId], + async function(inputIdChild) { + let rect = content.document + .getElementById(inputIdChild) + .getBoundingClientRect(); + return { + left: content.mozInnerScreenX + rect.left, + bottom: content.mozInnerScreenY + rect.bottom, + }; + } + ); + + function is_close(got, exp, msg) { + // on some platforms we see differences of a fraction of a pixel - so + // allow any difference of < 1 pixels as being OK. + Assert.ok( + Math.abs(got - exp) < 1, + msg + ": " + got + " should be equal(-ish) to " + exp + ); + } + const marginLeft = parseFloat(getComputedStyle(helper.panel).marginLeft); + const marginTop = parseFloat(getComputedStyle(helper.panel).marginTop); + is_close( + helper.panel.screenX - marginLeft, + inputRect.left, + "datepicker x position" + ); + is_close( + helper.panel.screenY - marginTop, + inputRect.bottom, + "datepicker y position" + ); +} + +let helper = new DateTimeTestHelper(); + +registerCleanupFunction(() => { + helper.cleanup(); +}); + +/** + * Test that date picker opens to today's date when input field is blank + */ +add_task(async function test_datepicker_today() { + info("Test that date picker opens to today's date when input field is blank"); + + const date = new Date(); + + await helper.openPicker("data:text/html, "); + + if (date.getMonth() === new Date().getMonth()) { + Assert.equal( + helper.getElement(MONTH_YEAR).textContent, + DATE_FORMAT_LOCAL(date), + "Today's date is opened" + ); + Assert.equal( + helper.getElement(DAY_TODAY).getAttribute("aria-current"), + "date", + "Today's date is programmatically current" + ); + Assert.equal( + helper.getElement(DAY_TODAY).getAttribute("tabindex"), + "0", + "Today's date is included in the focus order, when nothing is selected" + ); + } else { + Assert.ok( + true, + "Skipping datepicker today test if month changes when opening picker." + ); + } + + await helper.tearDown(); +}); + +/** + * Test that date picker opens to the correct month, with calendar days + * displayed correctly, given a date value is set. + */ +add_task(async function test_datepicker_open() { + info("Test the date picker markup with a set input date value"); + + const inputValue = "2016-12-15"; + + await helper.openPicker( + `data:text/html, ` + ); + + Assert.equal( + helper.getElement(MONTH_YEAR).textContent, + DATE_FORMAT(new Date(inputValue)), + "2016-12-15 date is opened" + ); + + Assert.deepEqual( + getCalendarText(), + [ + "27", + "28", + "29", + "30", + "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", + "5", + "6", + "7", + ], + "Calendar text for 2016-12 is correct" + ); + Assert.deepEqual( + getCalendarClassList(), + calendarClasslist_201612, + "2016-12 classNames of the picker are correct" + ); + Assert.equal( + helper.getElement(DAY_SELECTED).getAttribute("aria-selected"), + "true", + "Chosen date is programmatically selected" + ); + Assert.equal( + helper.getElement(DAY_SELECTED).getAttribute("tabindex"), + "0", + "Selected date is included in the focus order" + ); + + await helper.tearDown(); +}); + +/** + * Ensure that the datepicker popup appears correctly positioned when + * the input field has been transformed. + */ +add_task(async function test_datepicker_transformed_position() { + const inputValue = "2016-12-15"; + + const style = + "transform: translateX(7px) translateY(13px); border-top: 2px; border-left: 5px; margin: 30px;"; + const iframeContent = ``; + await helper.openPicker( + "data:text/html,