tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

commit bc2a7bec5bab70e5e95db2ab04c443553b7d0ef2
parent bc28ca1f46e39e71d041386a78e0845e97c4b236
Author: Timothy Nikkel <tnikkel@gmail.com>
Date:   Wed,  5 Nov 2025 01:24:09 +0000

Bug 1995207. Add test. r=hiro

Differential Revision: https://phabricator.services.mozilla.com/D270963

Diffstat:
Mgfx/layers/apz/test/mochitest/browser.toml | 6++++++
Agfx/layers/apz/test/mochitest/browser_test_popup_menu_in_parent_process_content.js | 163+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Agfx/layers/apz/test/mochitest/helper_popup_menu_in_parent_process_content.html | 6++++++
3 files changed, 175 insertions(+), 0 deletions(-)

diff --git a/gfx/layers/apz/test/mochitest/browser.toml b/gfx/layers/apz/test/mochitest/browser.toml @@ -52,6 +52,12 @@ support-files = [ "helper_popup_menu_in_parent_process-2.html" ] +["browser_test_popup_menu_in_parent_process_content.js"] +support-files = [ + "helper_popup_menu_in_parent_process_content.html" +] +run-if = ["os != 'mac'"] # On Mac popup windows having no remote content doesn't have the compositor + ["browser_test_popup_menu_in_position_fixed.js"] support-files = ["helper_popup_menu_in_parent_process-1.html"] run-if = ["os != 'mac'"] # On Mac popup windows having no remote content doesn't have the compositor diff --git a/gfx/layers/apz/test/mochitest/browser_test_popup_menu_in_parent_process_content.js b/gfx/layers/apz/test/mochitest/browser_test_popup_menu_in_parent_process_content.js @@ -0,0 +1,163 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +Services.scriptloader.loadSubScript( + "chrome://mochikit/content/tests/SimpleTest/paint_listener.js", + this +); + +Services.scriptloader.loadSubScript( + new URL("apz_test_utils.js", gTestPath).href, + this +); + +Services.scriptloader.loadSubScript( + new URL("apz_test_native_event_utils.js", gTestPath).href, + this +); + +/* import-globals-from helper_browser_test_utils.js */ +// For openSelectPopup. +Services.scriptloader.loadSubScript( + new URL("helper_browser_test_utils.js", gTestPath).href, + this +); + +// Cleanup for paint_listener.js. +add_task(() => { + registerCleanupFunction(() => { + delete window.waitForAllPaintsFlushed; + delete window.waitForAllPaints; + delete window.promiseAllPaintsDone; + }); +}); + +// Setup preferences. +add_task(async () => { + await SpecialPowers.pushPrefEnv({ + set: [ + ["apz.popups.enabled", true], + ["apz.popups_without_remote.enabled", true], + ], + }); +}); + +async function twoRafsInContent(browser) { + await SpecialPowers.spawn(browser, [], async function () { + await new Promise(r => + content.requestAnimationFrame(() => content.requestAnimationFrame(r)) + ); + }); +} + +async function runTest(aTestFile) { + // To test this scenario we need to create a content document (so that + // isTopLevelContentDocShell and it can zoom) but that lives in the parent + // process. This is not done very often in tests, but is used by for example + // about:preferences. To do that we load about:blank and use + // forceNotRemote: true to put it in the parent process and then + // triggeringPrincipal: nullPrincipal to make sure it doesn't gain chrome + // privileges. We then get that tab to navigate itself to a chrome uri so + // that it stays in that same process but it doesn't gain chrome privileges. + const nullPrincipal = Services.scriptSecurityManager.createNullPrincipal({}); + const tab = gBrowser.addTab("about:blank", { + forceNotRemote: true, + triggeringPrincipal: nullPrincipal, + }); + gBrowser.selectedTab = tab; + const browser = tab.linkedBrowser; + + // Can't wait for about:blank to load, so do this to make sure everything is + // settled and ready. + await TestUtils.waitForCondition(() => browser.isConnected); + await promiseApzFlushedRepaints(); + await waitUntilApzStable(); + + const url_of_test_file = getRootDirectory(gTestPath) + aTestFile; + await SpecialPowers.spawn( + browser, + [url_of_test_file], + async function (_url_of_test_file) { + content.location = _url_of_test_file; + } + ); + + await BrowserTestUtils.browserLoaded(browser); + + // Make sure the document gets loaded in the parent process and is a top + // level content document. + await SpecialPowers.spawn(tab.linkedBrowser, [], () => { + Assert.ok(SpecialPowers.isMainProcess()); + Assert.ok(SpecialPowers.wrap(content).docShell.isTopLevelContentDocShell); + }); + + await promiseApzFlushedRepaints(); + await waitUntilApzStable(); + + let contentWin = browser.contentWindow; + + // Create a popup menu that is inside a transform dynamically and set + // `position:fixed` on the menu. + const adiv = contentWin.document.createElement("div"); + adiv.style.transform = "translateX(1px)"; + contentWin.document.body.appendChild(adiv); + const popupset = contentWin.document.createXULElement("popupset"); + adiv.appendChild(popupset); + const popup = contentWin.document.createXULElement("menupopup"); + popup.style.position = "fixed"; + popup.style.background = "blue"; + popup.setAttribute("noautohide", true); + + const scroller = contentWin.document.createElement("div"); + scroller.style = + "width: 100px; height: 100px; overflow: auto; background-color: white;"; + popup.appendChild(scroller); + const spacer = contentWin.document.createElement("div"); + spacer.style = "width: 200px; height: 200px; background-color: green;"; + scroller.appendChild(spacer); + popupset.appendChild(popup); + + // Open the popup. + const popupshownPromise = new Promise(resolve => { + popup.addEventListener("popupshown", resolve()); + }); + popup.openPopupAtScreen( + contentWin.mozInnerScreenX, + contentWin.mozInnerScreenY, + true + ); + await popupshownPromise; + + // Make sure APZ is ready for the popup. + await ensureApzReadyForPopup(popup, contentWin); + await promiseApzFlushedRepaints(popup); + + // Do a mouse click in the popup. + const popupRect = popup.getBoundingClientRect(); + ok(popupRect.width > 10, "non-zero popup width"); + ok(popupRect.height > 10, "non-zero popup height"); + await synthesizeNativeMouseEventWithAPZ({ + type: "click", + target: popup, + offsetX: 10, + offsetY: 10, + }); + + // Just wait to make sure that's processed without hitting an assert. + await twoRafsInContent(browser); + + // Close the popup. + const popuphiddenPromise = new Promise(resolve => { + popup.addEventListener("popuphidden", resolve()); + }); + popup.hidePopup(); + await popuphiddenPromise; + + BrowserTestUtils.removeTab(tab); +} + +add_task(async () => { + await runTest("helper_popup_menu_in_parent_process_content.html"); +}); diff --git a/gfx/layers/apz/test/mochitest/helper_popup_menu_in_parent_process_content.html b/gfx/layers/apz/test/mochitest/helper_popup_menu_in_parent_process_content.html @@ -0,0 +1,6 @@ +<!DOCTYPE html> +<html> +<div style="overflow: auto; height: 100px;"> + <div style="height: 400px;"></div> +</div> +</html>