diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 19:33:14 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 19:33:14 +0000 |
commit | 36d22d82aa202bb199967e9512281e9a53db42c9 (patch) | |
tree | 105e8c98ddea1c1e4784a60a5a6410fa416be2de /browser/components/firefoxview/tests/chrome | |
parent | Initial commit. (diff) | |
download | firefox-esr-36d22d82aa202bb199967e9512281e9a53db42c9.tar.xz firefox-esr-36d22d82aa202bb199967e9512281e9a53db42c9.zip |
Adding upstream version 115.7.0esr.upstream/115.7.0esrupstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to '')
4 files changed, 914 insertions, 0 deletions
diff --git a/browser/components/firefoxview/tests/chrome/chrome.ini b/browser/components/firefoxview/tests/chrome/chrome.ini new file mode 100644 index 0000000000..a6a1475190 --- /dev/null +++ b/browser/components/firefoxview/tests/chrome/chrome.ini @@ -0,0 +1,5 @@ +[DEFAULT] + +[test_card_container.html] +[test_fxview_category_navigation.html] +[test_fxview_tab_list.html] diff --git a/browser/components/firefoxview/tests/chrome/test_card_container.html b/browser/components/firefoxview/tests/chrome/test_card_container.html new file mode 100644 index 0000000000..c76c6ec222 --- /dev/null +++ b/browser/components/firefoxview/tests/chrome/test_card_container.html @@ -0,0 +1,122 @@ +<!DOCTYPE HTML> +<html> +<head> + <meta charset="utf-8"> + <title>CardContainer Tests</title> + <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> + <script src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"></script> + <link rel="stylesheet" href="chrome://mochikit/content/tests/SimpleTest/test.css"/> + <link rel="stylesheet" href="chrome://global/skin/in-content/common.css"> + <link rel="localization" href="browser/firefoxView.ftl"/> + <script type="module" src="chrome://browser/content/firefoxview/card-container.mjs"></script> +</head> +<body> + <style> + </style> +<p id="display"></p> +<div id="content"> + <card-container viewAllPage="history"> + <h2 slot="header" data-l10n-id="history-header"></h2> + <ul slot="main"> + <li>History Row 1</li> + <li>History Row 2</li> + <li>History Row 3</li> + <li>History Row 4</li> + <li>History Row 5</li> + </ul> + </card-container> +</div> +<pre id="test"> +<script class="testbody" type="application/javascript"> + const cardContainer = document.querySelector("card-container"); + + /** + * Tests that the card-container can expand and collapse when the summary element is clicked + */ + add_task(async function test_open_close_card() { + is( + cardContainer.isExpanded, + true, + "The card-container is expanded initially" + ); + + // Click the summary to collapse the details disclosure + cardContainer.summaryEl.click(); + is( + cardContainer.detailsEl.hasAttribute("open"), + false, + "The card-container is collapsed" + ); + + // Click on the summary again to expand the details disclosure + cardContainer.summaryEl.click(); + is( + cardContainer.detailsEl.hasAttribute("open"), + true, + "The card-container is expanded" + ); + }); + + /** + * Tests keyboard navigation of the card-container component + */ + add_task(async function test_keyboard_navigation() { + const tab = async shiftKey => { + info(`Tab${shiftKey ? ' + Shift' : ''}`); + synthesizeKey("KEY_Tab", { shiftKey }); + }; + const enter = async () => { + info("Enter"); + synthesizeKey("KEY_Enter", {}); + }; + + // Setting this pref allows the test to run as expected with a keyboard on MacOS + await SpecialPowers.pushPrefEnv({ + set: [["accessibility.tabfocus", 7]], + }); + + cardContainer.summaryEl.focus(); + is( + cardContainer.shadowRoot.activeElement, + cardContainer.summaryEl, + "Focus should be on the summary element within card-container" + ); + + // Tab to the 'View all' link + await tab(); + is( + cardContainer.shadowRoot.activeElement, + cardContainer.viewAllLink, + "Focus should be on the 'View all' link within card-container" + ); + + // Shift + Tab back to the summary element + await tab(true); + is( + cardContainer.shadowRoot.activeElement, + cardContainer.summaryEl, + "Focus should be back on the summary element within card-container" + ); + + // Select the summary to collapse the details disclosure + await enter(); + is( + cardContainer.detailsEl.hasAttribute("open"), + false, + "The card-container is collapsed" + ); + + // Select the summary again to expand the details disclosure + await enter(); + is( + cardContainer.detailsEl.hasAttribute("open"), + true, + "The card-container is expanded" + ); + + await SpecialPowers.popPrefEnv(); + }); +</script> +</pre> +</body> +</html> diff --git a/browser/components/firefoxview/tests/chrome/test_fxview_category_navigation.html b/browser/components/firefoxview/tests/chrome/test_fxview_category_navigation.html new file mode 100644 index 0000000000..d074d96740 --- /dev/null +++ b/browser/components/firefoxview/tests/chrome/test_fxview_category_navigation.html @@ -0,0 +1,322 @@ +<!DOCTYPE HTML> +<html> +<head> + <meta charset="utf-8"> + <title>FxviewCategoryNavigation Tests</title> + <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> + <script src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"></script> + <link rel="stylesheet" href="chrome://mochikit/content/tests/SimpleTest/test.css"/> + <link rel="stylesheet" href="chrome://global/skin/in-content/common.css"> + <script type="module" src="chrome://browser/content/firefoxview/fxview-category-navigation.mjs"></script> +</head> +<style> +body { + display: flex; +} +#navigation { + width: var(--in-content-sidebar-width); +} +fxview-category-button[name="category-one"]::part(icon) { + background-image: url("chrome://mozapps/skin/extensions/category-discover.svg"); +} +fxview-category-button[name="category-two"]::part(icon) { + background-image: url("chrome://mozapps/skin/extensions/category-discover.svg"); +} +fxview-category-button[name="category-three"]::part(icon) { + background-image: url("chrome://mozapps/skin/extensions/category-discover.svg"); +} +fxview-category-button[name="category-four"]::part(icon) { + background-image: url("chrome://mozapps/skin/extensions/category-discover.svg"); +} +fxview-category-button[name="category-five"]::part(icon) { + background-image: url("chrome://mozapps/skin/extensions/category-discover.svg"); +} +</style> +<body> + <p id="display"></p> + <div id="content"> + <div id="navigation"> + <fxview-category-navigation> + <h2 slot="category-nav-header">Header</h2> + <fxview-category-button class="category" slot="category-button" name="category-one"> + <span class="category-name">Category 1</span> + </fxview-category-button> + <fxview-category-button class="category" slot="category-button" name="category-two"> + <span class="category-name">Category 2</span> + </fxview-category-button> + <fxview-category-button class="category" slot="category-button" name="category-three"> + <span class="category-name">Category 3</span> + </fxview-category-button> + <fxview-category-button class="category" slot="category-button" name="category-four"> + <span class="category-name">Category 4</span> + </fxview-category-button> + <fxview-category-button class="category" slot="category-button" name="category-five"> + <span class="category-name">Category 5</span> + </fxview-category-button> + </fxview-category-navigation> + </div> + </div> +<pre id="test"></pre> +<script> + Services.scriptloader.loadSubScript( + "chrome://browser/content/utilityOverlay.js", + this + ); + const { BrowserTestUtils } = ChromeUtils.import( + "resource://testing-common/BrowserTestUtils.jsm" + ); + +const fxviewCategoryNav = document.querySelector("fxview-category-navigation"); + +function isActiveElement(expectedActiveEl) { + return expectedActiveEl.getRootNode().activeElement == expectedActiveEl; + } + + /** + * Tests that the first category is selected by default + */ + add_task(async function test_first_item_selected_by_default() { + is( + fxviewCategoryNav.categoryButtons.length, + 5, + "Five category buttons are in the navigation" + ); + + ok( + fxviewCategoryNav.categoryButtons[0].name === fxviewCategoryNav.currentCategory, + "The first category button is selected by default" + ) + }); + + /** + * Tests that categories are selected when clicked + */ + add_task(async function test_select_category() { + let gBrowser = BrowserWindowTracker.getTopWindow().top.gBrowser; + let secondCategory = fxviewCategoryNav.categoryButtons[1]; + let categoryChanged = BrowserTestUtils.waitForEvent( + gBrowser, + "change-category" + ); + + secondCategory.buttonEl.click(); + await categoryChanged; + + ok( + secondCategory.name === fxviewCategoryNav.currentCategory, + "The second category button is selected" + ) + + let thirdCategory = fxviewCategoryNav.categoryButtons[2]; + categoryChanged = BrowserTestUtils.waitForEvent( + gBrowser, + "change-category" + ); + + thirdCategory.buttonEl.click(); + await categoryChanged; + + ok( + thirdCategory.name === fxviewCategoryNav.currentCategory, + "The third category button is selected" + ) + + let firstCategory = fxviewCategoryNav.categoryButtons[0]; + categoryChanged = BrowserTestUtils.waitForEvent( + gBrowser, + "change-category" + ); + + firstCategory.buttonEl.click(); + await categoryChanged; + + ok( + firstCategory.name === fxviewCategoryNav.currentCategory, + "The first category button is selected" + ) + }); + + /** + * Tests that categories are keyboard-navigable + */ + add_task(async function test_keyboard_navigation() { + const arrowDown = async () => { + info("Arrow down"); + synthesizeKey("KEY_ArrowDown", {}); + await fxviewCategoryNav.getUpdateComplete(); + }; + const arrowUp = async () => { + info("Arrow up"); + synthesizeKey("KEY_ArrowUp", {}); + await fxviewCategoryNav.getUpdateComplete(); + }; + const arrowLeft = async () => { + info("Arrow left"); + synthesizeKey("KEY_ArrowLeft", {}); + await fxviewCategoryNav.getUpdateComplete(); + }; + const arrowRight = async () => { + info("Arrow right"); + synthesizeKey("KEY_ArrowRight", {}); + await fxviewCategoryNav.getUpdateComplete(); + }; + + // Setting this pref allows the test to run as expected with a keyboard on MacOS + await SpecialPowers.pushPrefEnv({ + set: [["accessibility.tabfocus", 7]], + }); + + let firstCategory = fxviewCategoryNav.categoryButtons[0]; + let secondCategory = fxviewCategoryNav.categoryButtons[1]; + let thirdCategory = fxviewCategoryNav.categoryButtons[2]; + let fourthCategory = fxviewCategoryNav.categoryButtons[3]; + let fifthCategory = fxviewCategoryNav.categoryButtons[4]; + + is( + firstCategory.name, + fxviewCategoryNav.currentCategory, + "The first category button is selected" + ) + firstCategory.focus(); + await arrowDown(); + ok( + isActiveElement(secondCategory), + "The second category button is the active element after first arrow down" + ); + is( + secondCategory.name, + fxviewCategoryNav.currentCategory, + "The second category button is selected" + ) + await arrowDown(); + is( + thirdCategory.name, + fxviewCategoryNav.currentCategory, + "The third category button is selected" + ) + await arrowDown(); + is( + fourthCategory.name, + fxviewCategoryNav.currentCategory, + "The fourth category button is selected" + ) + await arrowDown(); + is( + fifthCategory.name, + fxviewCategoryNav.currentCategory, + "The fifth category button is selected" + ) + await arrowDown(); + is( + fifthCategory.name, + fxviewCategoryNav.currentCategory, + "The fifth category button is still selected" + ) + await arrowUp(); + is( + fourthCategory.name, + fxviewCategoryNav.currentCategory, + "The fourth category button is selected" + ) + await arrowUp(); + is( + thirdCategory.name, + fxviewCategoryNav.currentCategory, + "The third category button is selected" + ) + await arrowUp(); + is( + secondCategory.name, + fxviewCategoryNav.currentCategory, + "The second category button is selected" + ) + await arrowUp(); + is( + firstCategory.name, + fxviewCategoryNav.currentCategory, + "The first category button is selected" + ) + await arrowUp(); + is( + firstCategory.name, + fxviewCategoryNav.currentCategory, + "The first category button is still selected" + ) + + // Test navigation with arrow left/right keys + is( + firstCategory.name, + fxviewCategoryNav.currentCategory, + "The first category button is selected" + ) + firstCategory.focus(); + await arrowRight(); + ok( + isActiveElement(secondCategory), + "The second category button is the active element after first arrow right" + ); + is( + secondCategory.name, + fxviewCategoryNav.currentCategory, + "The second category button is selected" + ) + await arrowRight(); + is( + thirdCategory.name, + fxviewCategoryNav.currentCategory, + "The third category button is selected" + ) + await arrowRight(); + is( + fourthCategory.name, + fxviewCategoryNav.currentCategory, + "The fourth category button is selected" + ) + await arrowRight(); + is( + fifthCategory.name, + fxviewCategoryNav.currentCategory, + "The fifth category button is selected" + ) + await arrowRight(); + is( + fifthCategory.name, + fxviewCategoryNav.currentCategory, + "The fifth category button is still selected" + ) + await arrowLeft(); + is( + fourthCategory.name, + fxviewCategoryNav.currentCategory, + "The fourth category button is selected" + ) + await arrowLeft(); + is( + thirdCategory.name, + fxviewCategoryNav.currentCategory, + "The third category button is selected" + ) + await arrowLeft(); + is( + secondCategory.name, + fxviewCategoryNav.currentCategory, + "The second category button is selected" + ) + await arrowLeft(); + is( + firstCategory.name, + fxviewCategoryNav.currentCategory, + "The first category button is selected" + ) + await arrowLeft(); + is( + firstCategory.name, + fxviewCategoryNav.currentCategory, + "The first category button is still selected" + ) + + await SpecialPowers.popPrefEnv(); + }); +</script> +</body> +</html> diff --git a/browser/components/firefoxview/tests/chrome/test_fxview_tab_list.html b/browser/components/firefoxview/tests/chrome/test_fxview_tab_list.html new file mode 100644 index 0000000000..92a645c431 --- /dev/null +++ b/browser/components/firefoxview/tests/chrome/test_fxview_tab_list.html @@ -0,0 +1,465 @@ +<!DOCTYPE HTML> +<html> +<head> + <meta charset="utf-8"> + <title>FxviewTabList Tests</title> + <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> + <script src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"></script> + <link rel="localization" href="browser/places.ftl"> + <link rel="stylesheet" href="chrome://mochikit/content/tests/SimpleTest/test.css"/> + <link rel="stylesheet" href="chrome://global/skin/in-content/common.css"> + <script type="module" src="chrome://browser/content/firefoxview/fxview-tab-list.mjs"></script> +</head> +<body> + <style> + fxview-tab-list.history::part(secondary-button) { + background-image: url("chrome://global/skin/icons/more.svg"); + } + </style> +<p id="display"></p> +<div id="content" style="max-width: 750px"> + <fxview-tab-list class="history" .dateTimeFormat="relative" .hasPopup="menu"> + <panel-list slot="menu"> + <panel-item data-l10n-id="fxviewtabrow-delete"></panel-item> + <panel-item data-l10n-id="fxviewtabrow-forget-about-this-site"></panel-item> + <hr /> + <panel-item data-l10n-id="fxviewtabrow-open-in-window"></panel-item> + <panel-item data-l10n-id="fxviewtabrow-open-in-private-window"></panel-item> + <hr /> + <panel-item data-l10n-id="fxviewtabrow-add-bookmark"></panel-item> + <panel-item data-l10n-id="fxviewtabrow-save-to-pocket"></panel-item> + <panel-item data-l10n-id="fxviewtabrow-copy-link"></panel-item> + </panel-list> + </fxview-tab-list> +</div> +<pre id="test"> +<script class="testbody" type="application/javascript"> + Services.scriptloader.loadSubScript( + "chrome://browser/content/utilityOverlay.js", + this + ); + + const { BrowserTestUtils } = ChromeUtils.import( + "resource://testing-common/BrowserTestUtils.jsm" + ); + const { PlacesQuery } = ChromeUtils.importESModule( + "resource://gre/modules/PlacesQuery.sys.mjs" + ); + const { PromiseUtils } = ChromeUtils.importESModule( + "resource://gre/modules/PromiseUtils.sys.mjs" + ); + const { PlacesUtils } = ChromeUtils.importESModule( + "resource://gre/modules/PlacesUtils.sys.mjs" + ); + const { PlacesUIUtils } = ChromeUtils.importESModule( + "resource:///modules/PlacesUIUtils.sys.mjs" + ); + const { PlacesTestUtils } = ChromeUtils.importESModule( + "resource://testing-common/PlacesTestUtils.sys.mjs" + ); + const { TestUtils } = ChromeUtils.import( + "resource://testing-common/TestUtils.jsm" + ); + + const fxviewTabList = document.querySelector("fxview-tab-list"); + let tabItems = []; + const placesQuery = new PlacesQuery(); + + const URLs = [ + "http://mochi.test:8888/browser/", + "https://www.example.com/", + "https://example.net/", + "https://example.org/", + "https://www.mozilla.org/" + ]; + + async function addHistoryItems() { + await PlacesUtils.history.clear(); + let history = await placesQuery.getHistory(); + + const now = new Date(); + await PlacesUtils.history.insert({ + url: URLs[0], + title: "Example Domain 1", + visits: [{ date: now }], + }); + let historyUpdated = PromiseUtils.defer(); + placesQuery.observeHistory(newHistory => { + history = newHistory; + historyUpdated.resolve(); + }); + await PlacesUtils.history.insert({ + url: URLs[1], + title: "Example Domain 2", + visits: [{ date: now }], + }); + await historyUpdated.promise; + historyUpdated = PromiseUtils.defer(); + placesQuery.observeHistory(newHistory => { + history = newHistory; + historyUpdated.resolve(); + }); + await PlacesUtils.history.insert({ + url: URLs[2], + title: "Example Domain 3", + visits: [{ date: now }], + }); + await historyUpdated.promise; + historyUpdated = PromiseUtils.defer(); + placesQuery.observeHistory(newHistory => { + history = newHistory; + historyUpdated.resolve(); + }); + await PlacesUtils.history.insert({ + url: URLs[3], + title: "Example Domain 4", + visits: [{ date: now }], + }); + await historyUpdated.promise; + + let normalized = normalizeHistoryData(history); + fxviewTabList.tabItems = normalized; + + await fxviewTabList.getUpdateComplete(); + tabItems = Array.from(fxviewTabList.rowEls); + } + + function normalizeHistoryData(history) { + history.forEach(historyItem => { + historyItem.time = historyItem.date.getTime(); + historyItem.icon = `page-icon:${historyItem.url}`; + historyItem.primaryL10nId = "fxviewtabrow-tabs-list-tab"; + historyItem.primaryL10nArgs = JSON.stringify({ targetURI: historyItem.url }); + historyItem.secondaryL10nId = "fxviewtabrow-open-menu-button"; + }); + return history; + } + + function getCurrentDisplayDate() { + let lastItemMainEl = tabItems[tabItems.length - 1].mainEl; + return lastItemMainEl.querySelector("#fxview-tab-row-date span:not([hidden])")?.textContent.trim() ?? ""; + } + + function getCurrentDisplayTime() { + let lastItemMainEl = tabItems[tabItems.length - 1].mainEl; + return lastItemMainEl.querySelector("#fxview-tab-row-time")?.textContent.trim() ?? ""; + } + + function isActiveElement(expectedLinkEl) { + return expectedLinkEl.getRootNode().activeElement == expectedLinkEl; + } + + function onPrimaryAction(e) { + let gBrowser = BrowserWindowTracker.getTopWindow().top.gBrowser; + gBrowser.addTrustedTab(e.originalTarget.url); + } + + function onSecondaryAction(e) { + e.target.querySelector("panel-list").toggle(e.detail.originalEvent); + } + + add_setup(function setup() { + fxviewTabList.addEventListener("fxview-tab-list-primary-action", onPrimaryAction); + fxviewTabList.addEventListener("fxview-tab-list-secondary-action", onSecondaryAction); + }); + + /** + * Tests that history items are loaded in the expected order + */ + add_task(async function test_list_ordering() { + await addHistoryItems(); + is( + tabItems.length, + 4, + "Four history items are shown in the list." + ); + + // Check ordering + ok( + tabItems[0].title === "Example Domain 4", + "First history item in fxview-tab-list is in the correct order." + ) + + ok( + tabItems[3].title === "Example Domain 1", + "Last history item in fxview-tab-list is in the correct order." + ) + }); + + /** + * Tests the primary action function is triggered when selecting the main row element + */ + add_task(async function test_primary_action(){ + await addHistoryItems(); + let gBrowser = BrowserWindowTracker.getTopWindow().top.gBrowser; + let newTabPromise = BrowserTestUtils.waitForNewTab(gBrowser, tabItems[0].url); + tabItems[0].mainEl.click(); + await newTabPromise; + + is( + tabItems.length, + 4, + "Four history items are still shown in the list." + ); + + await BrowserTestUtils.removeTab(gBrowser.tabs[gBrowser.tabs.length - 1]); + }); + + /** + * Tests that a max tabs length value can be given to fxview-tab-list + */ + add_task(async function test_max_list_items() { + const mockMaxTabsLength = 3; + + // override this value for testing purposes + fxviewTabList.maxTabsLength = mockMaxTabsLength; + await addHistoryItems(); + + is( + tabItems.length, + mockMaxTabsLength, + `fxview-tabs-list should have ${mockMaxTabsLength} list items` + ); + + // Add new history items + let history = await placesQuery.getHistory(); + + const now = new Date(); + await PlacesUtils.history.insert({ + url: URLs[4], + title: "Internet for people, not profits - Mozilla", + visits: [{ date: now }], + }); + let historyUpdated = PromiseUtils.defer(); + placesQuery.observeHistory(newHistory => { + history = newHistory; + historyUpdated.resolve(); + }); + await historyUpdated.promise; + + ok( + history.length === 5, + "Five total history items after inserting another node" + ); + + // Update fxview-tab-list component with latest history data + let normalized = normalizeHistoryData(history); + fxviewTabList.tabItems = normalized; + await fxviewTabList.getUpdateComplete(); + tabItems = Array.from(fxviewTabList.rowEls); + + is( + tabItems.length, + mockMaxTabsLength, + `fxview-tabs-list should have ${mockMaxTabsLength} list items` + ); + + ok( + tabItems[0].title === "Internet for people, not profits - Mozilla", + "History list has been updated with the expected maxTabsLength." + ) + fxviewTabList.maxTabsLength = 25; + }); + + /** + * Tests keyboard navigation of the fxview-tab-list component + */ + add_task(async function test_keyboard_navigation() { + const arrowDown = async () => { + info("Arrow down"); + synthesizeKey("KEY_ArrowDown", {}); + await fxviewTabList.getUpdateComplete(); + }; + const arrowUp = async () => { + info("Arrow up"); + synthesizeKey("KEY_ArrowUp", {}); + await fxviewTabList.getUpdateComplete(); + }; + const arrowRight = async () => { + info("Arrow right"); + synthesizeKey("KEY_ArrowRight", {}); + await fxviewTabList.getUpdateComplete(); + }; + const arrowLeft = async () => { + info("Arrow left"); + synthesizeKey("KEY_ArrowLeft", {}); + await fxviewTabList.getUpdateComplete(); + }; + + await addHistoryItems(); + tabItems[0].mainEl.focus(); + ok( + isActiveElement(tabItems[0].mainEl), + "Focus should be on the first main element of the list" + ); + + // Arrow down/up the list + await arrowDown(); + ok( + isActiveElement(tabItems[1].mainEl), + "Focus should be on the second main element of the list" + ); + await arrowDown(); + ok( + isActiveElement(tabItems[2].mainEl), + "Focus should be on the third main element of the list" + ); + await arrowDown(); + ok( + isActiveElement(tabItems[3].mainEl), + "Focus should be on the fourth main element of the list" + ); + await arrowUp(); + ok( + isActiveElement(tabItems[2].mainEl), + "Focus should be on the third main element of the list" + ); + await arrowUp(); + ok( + isActiveElement(tabItems[1].mainEl), + "Focus should be on the second main element of the list" + ); + await arrowUp(); + ok( + isActiveElement(tabItems[0].mainEl), + "Focus should be on the first main element of the list" + ); + await arrowRight(); + ok( + isActiveElement(tabItems[0].buttonEl), + "Focus should be on the first row's context menu button element of the list" + ); + await arrowDown(); + ok( + isActiveElement(tabItems[1].buttonEl), + "Focus should be on the second row's context menu button element of the list" + ); + await arrowLeft(); + ok( + isActiveElement(tabItems[1].mainEl), + "Focus should be on the second main element of the list" + ); + await arrowUp(); + ok( + isActiveElement(tabItems[0].mainEl), + "Focus should be on the first main element of the list" + ); + }); + + /** + * Tests relative time format for the fxview-tab-list component + */ + add_task(async function test_relative_format() { + await addHistoryItems(); + ok( + getCurrentDisplayDate().includes("Just now"), + "Current dateTime format is 'relative' and date displays 'Just now' initially" + ); + ok( + !getCurrentDisplayTime().length, + "Current dateTime format is 'relative' and time displays an empty string" + ); + }); + + /** + * Tests date only format for the fxview-tab-list component + */ + add_task(async function test_date_only_format() { + await addHistoryItems(); + + // Check date only format + fxviewTabList.dateTimeFormat = "date"; + await fxviewTabList.getUpdateComplete(); + await BrowserTestUtils.waitForCondition(() => { + return getCurrentDisplayDate().includes("/"); + }); + ok( + getCurrentDisplayDate().includes("/"), + "Current dateTime format is 'date' and displays the current date" + ); + ok( + !getCurrentDisplayTime().length, + "Current dateTime format is 'date' and time displays an empty string" + ); + }); + + /** + * Tests time only format for the fxview-tab-list component + */ + add_task(async function test_time_only_format() { + await addHistoryItems(); + + // Check time only format + fxviewTabList.dateTimeFormat = "time"; + await fxviewTabList.getUpdateComplete(); + await BrowserTestUtils.waitForCondition(() => { + return getCurrentDisplayTime().includes("AM") || getCurrentDisplayTime().includes("PM"); + }); + ok( + !getCurrentDisplayDate().length, + "Current dateTime format is 'time' and date displays an empty string" + ); + ok( + getCurrentDisplayTime().includes("AM") || getCurrentDisplayTime().includes("PM"), + "Current dateTime format is 'time' and displays the current time" + ); + }); + + /** + * Tests date and time format for the fxview-tab-list component + */ + add_task(async function test_date_and_time_format() { + await addHistoryItems(); + + // Check date and time format + fxviewTabList.dateTimeFormat = "dateTime"; + await fxviewTabList.getUpdateComplete(); + await BrowserTestUtils.waitForCondition(() => { + return getCurrentDisplayDate().includes("/") && + (getCurrentDisplayTime().includes("AM") || getCurrentDisplayTime().includes("PM")); + }); + ok( + getCurrentDisplayDate().includes("/"), + "Current dateTime format is 'dateTime' and date displays the current date" + ); + ok( + getCurrentDisplayTime().includes("AM") || getCurrentDisplayTime().includes("PM"), + "Current dateTime format is 'dateTime' and displays the current time" + ); + + // Reset dateTimeFormat to relative before next test + fxviewTabList.dateTimeFormat = "relative"; + await fxviewTabList.getUpdateComplete(); + }); + + /** + * Tests that relative time updates properly for the fxview-tab-list component + */ + add_task(async function test_relative_time_updates() { + await addHistoryItems(); + + await BrowserTestUtils.waitForCondition(() => { + return getCurrentDisplayDate().includes("Just now"); + }); + + ok( + getCurrentDisplayDate().includes("Just now"), + "Current date element displays 'Just now' initially" + ); + + // Set the updateTimeMs pref to something low to check that relative time updates properly + const TAB_UPDATE_TIME_MS = 500; + await SpecialPowers.pushPrefEnv({ + set: [["browser.tabs.firefox-view.updateTimeMs", TAB_UPDATE_TIME_MS]], + }); + await BrowserTestUtils.waitForCondition(() => { + return !getCurrentDisplayDate().includes("now"); + }); + info("Currently displayed date is something other than 'Just now'"); + + await SpecialPowers.popPrefEnv(); + }); +</script> +</pre> +</body> +</html> |