/* Any copyright is dedicated to the Public Domain. * http://creativecommons.org/publicdomain/zero/1.0/ */ "use strict"; async function withBackgroundTab(url, fn) { let backgroundTab = await BrowserTestUtils.openNewForegroundTab( gBrowser, url ); let foregroundTab = await BrowserTestUtils.openNewForegroundTab( gBrowser, url ); try { await fn(backgroundTab.linkedBrowser, foregroundTab.linkedBrowser); } finally { BrowserTestUtils.removeTab(foregroundTab); BrowserTestUtils.removeTab(backgroundTab); } } async function testPicker(cb, { shouldOpen }) { let shownTarget = null; let onShown = e => (shownTarget = e.target); document.addEventListener("popupshowing", onShown); await cb(); // For the current subtests, no timeout is needed. The IPC roundtrip in cb() // and microtask checkpoint from awaiting cb is enough for the popup to show. document.removeEventListener("popupshowing", onShown); shownTarget?.hidePopup(); if (shouldOpen) { ok(shownTarget, "Expected picker to show"); } else { ok(!shownTarget, "Expected picker not to be shown"); } } function showPicker(browser, selector) { return SpecialPowers.spawn(browser, [selector], sel => { content.document.notifyUserGestureActivation(); content.document.querySelector(sel).showPicker(); }); } add_task(async function test_select_picker_blocked_in_background_tab() { const url = "data:text/html,"; await withBackgroundTab(url, async (bgBrowser, fgBrowser) => { await testPicker(() => showPicker(fgBrowser, "select"), { shouldOpen: true, }); await testPicker(() => showPicker(bgBrowser, "select"), { shouldOpen: false, }); }); }); add_task(async function test_date_picker_blocked_in_background_tab() { const url = "data:text/html,"; await withBackgroundTab(url, async (bgBrowser, fgBrowser) => { await testPicker(() => showPicker(fgBrowser, "input"), { shouldOpen: true, }); await testPicker(() => showPicker(bgBrowser, "input"), { shouldOpen: false, }); }); // Need to remove the iframe to prevent a leak, see DateTimeTestHelper.cleanup() // in toolkit/content/tests/browser/datetime/head.js. document.getElementById("DateTimePickerPanelPopupFrame")?.remove(); }); add_task(async function test_datalist_picker_blocked_in_background_tab() { // The datalist picker uses form fill code, which has two sources of delays // - If autocomplete != 'off', FormHistory will do a sql query // - nsFormFillController::mTimeout delays the form fill popup // See bug 2035124. async function clearFormfillDelay(browser) { await SpecialPowers.spawn(browser, [], () => { Cc["@mozilla.org/satchel/form-fill-controller;1"] .getService(Ci.nsIFormFillController) .QueryInterface(Ci.nsIAutoCompleteInput).timeout = 0; }); } const url = "data:text/html,"; await withBackgroundTab(url, async (bgBrowser, fgBrowser) => { await clearFormfillDelay(bgBrowser); await clearFormfillDelay(fgBrowser); await testPicker(() => showPicker(fgBrowser, "input"), { shouldOpen: true, }); await testPicker(() => showPicker(bgBrowser, "input"), { shouldOpen: false, }); }); });