From 26a029d407be480d791972afb5975cf62c9360a6 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Fri, 19 Apr 2024 02:47:55 +0200 Subject: Adding upstream version 124.0.1. Signed-off-by: Daniel Baumann --- .../test/general/browser_contentAreaClick.js | 329 +++++++++++++++++++++ 1 file changed, 329 insertions(+) create mode 100644 browser/base/content/test/general/browser_contentAreaClick.js (limited to 'browser/base/content/test/general/browser_contentAreaClick.js') diff --git a/browser/base/content/test/general/browser_contentAreaClick.js b/browser/base/content/test/general/browser_contentAreaClick.js new file mode 100644 index 0000000000..1a788e823f --- /dev/null +++ b/browser/base/content/test/general/browser_contentAreaClick.js @@ -0,0 +1,329 @@ +/* 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/. */ + +/** + * Test for bug 549340. + * Test for browser.js::contentAreaClick() util. + * + * The test opens a new browser window, then replaces browser.js methods invoked + * by contentAreaClick with a mock function that tracks which methods have been + * called. + * Each sub-test synthesizes a mouse click event on links injected in content, + * the event is collected by a click handler that ensures that contentAreaClick + * correctly prevent default events, and follows the correct code path. + */ + +const { sinon } = ChromeUtils.importESModule( + "resource://testing-common/Sinon.sys.mjs" +); + +var gTests = [ + { + desc: "Simple left click", + setup() {}, + clean() {}, + event: {}, + targets: ["commonlink", "mathlink", "svgxlink", "maplink"], + expectedInvokedMethods: [], + preventDefault: false, + }, + + { + desc: "Ctrl/Cmd left click", + setup() {}, + clean() {}, + event: { ctrlKey: true, metaKey: true }, + targets: ["commonlink", "mathlink", "svgxlink", "maplink"], + expectedInvokedMethods: ["urlSecurityCheck", "openLinkIn"], + preventDefault: true, + }, + + // The next test should just be like Alt click. + { + desc: "Shift+Alt left click", + setup() { + Services.prefs.setBoolPref("browser.altClickSave", true); + }, + clean() { + Services.prefs.clearUserPref("browser.altClickSave"); + }, + event: { shiftKey: true, altKey: true }, + targets: ["commonlink", "maplink"], + expectedInvokedMethods: ["gatherTextUnder", "saveURL"], + preventDefault: true, + }, + + { + desc: "Shift+Alt left click on XLinks", + setup() { + Services.prefs.setBoolPref("browser.altClickSave", true); + }, + clean() { + Services.prefs.clearUserPref("browser.altClickSave"); + }, + event: { shiftKey: true, altKey: true }, + targets: ["mathlink", "svgxlink"], + expectedInvokedMethods: ["saveURL"], + preventDefault: true, + }, + + { + desc: "Shift click", + setup() {}, + clean() {}, + event: { shiftKey: true }, + targets: ["commonlink", "mathlink", "svgxlink", "maplink"], + expectedInvokedMethods: ["urlSecurityCheck", "openLinkIn"], + preventDefault: true, + }, + + { + desc: "Alt click", + setup() { + Services.prefs.setBoolPref("browser.altClickSave", true); + }, + clean() { + Services.prefs.clearUserPref("browser.altClickSave"); + }, + event: { altKey: true }, + targets: ["commonlink", "maplink"], + expectedInvokedMethods: ["gatherTextUnder", "saveURL"], + preventDefault: true, + }, + + { + desc: "Alt click on XLinks", + setup() { + Services.prefs.setBoolPref("browser.altClickSave", true); + }, + clean() { + Services.prefs.clearUserPref("browser.altClickSave"); + }, + event: { altKey: true }, + targets: ["mathlink", "svgxlink"], + expectedInvokedMethods: ["saveURL"], + preventDefault: true, + }, + + { + desc: "Panel click", + setup() {}, + clean() {}, + event: {}, + targets: ["panellink"], + expectedInvokedMethods: ["urlSecurityCheck", "loadURI"], + preventDefault: true, + }, + + { + desc: "Simple middle click opentab", + setup() {}, + clean() {}, + event: { button: 1 }, + wantedEvent: "auxclick", + targets: ["commonlink", "mathlink", "svgxlink", "maplink"], + expectedInvokedMethods: ["urlSecurityCheck", "openLinkIn"], + preventDefault: true, + }, + + { + desc: "Simple middle click openwin", + setup() { + Services.prefs.setBoolPref("browser.tabs.opentabfor.middleclick", false); + }, + clean() { + Services.prefs.clearUserPref("browser.tabs.opentabfor.middleclick"); + }, + event: { button: 1 }, + wantedEvent: "auxclick", + targets: ["commonlink", "mathlink", "svgxlink", "maplink"], + expectedInvokedMethods: ["urlSecurityCheck", "openLinkIn"], + preventDefault: true, + }, + + { + desc: "Middle mouse paste", + setup() { + Services.prefs.setBoolPref("middlemouse.contentLoadURL", true); + Services.prefs.setBoolPref("general.autoScroll", false); + }, + clean() { + Services.prefs.clearUserPref("middlemouse.contentLoadURL"); + Services.prefs.clearUserPref("general.autoScroll"); + }, + event: { button: 1 }, + wantedEvent: "auxclick", + targets: ["emptylink"], + expectedInvokedMethods: ["middleMousePaste"], + preventDefault: true, + }, +]; + +// Array of method names that will be replaced in the new window. +var gReplacedMethods = [ + "middleMousePaste", + "urlSecurityCheck", + "loadURI", + "gatherTextUnder", + "saveURL", + "openLinkIn", + "getShortcutOrURIAndPostData", +]; + +// Returns the target object for the replaced method. +function getStub(replacedMethod) { + let targetObj = + replacedMethod == "getShortcutOrURIAndPostData" ? UrlbarUtils : gTestWin; + return targetObj[replacedMethod]; +} + +// Reference to the new window. +var gTestWin = null; + +// The test currently running. +var gCurrentTest = null; + +function test() { + waitForExplicitFinish(); + + registerCleanupFunction(function () { + sinon.restore(); + }); + + gTestWin = openDialog(location, "", "chrome,all,dialog=no", "about:blank"); + whenDelayedStartupFinished(gTestWin, function () { + info("Browser window opened"); + waitForFocus(function () { + info("Browser window focused"); + waitForFocus( + function () { + info("Setting up browser..."); + setupTestBrowserWindow(); + info("Running tests..."); + executeSoon(runNextTest); + }, + gTestWin.content, + true + ); + }, gTestWin); + }); +} + +// Click handler used to steal click events. +var gClickHandler = { + handleEvent(event) { + if (event.type == "click" && event.button != 0) { + return; + } + let linkId = event.target.id || event.target.localName; + let wantedEvent = gCurrentTest.wantedEvent || "click"; + is( + event.type, + wantedEvent, + `${gCurrentTest.desc}:Handler received a ${wantedEvent} event on ${linkId}` + ); + + let isPanelClick = linkId == "panellink"; + gTestWin.contentAreaClick(event, isPanelClick); + let prevent = event.defaultPrevented; + is( + prevent, + gCurrentTest.preventDefault, + gCurrentTest.desc + + ": event.defaultPrevented is correct (" + + prevent + + ")" + ); + + // Check that all required methods have been called. + for (let expectedMethod of gCurrentTest.expectedInvokedMethods) { + ok( + getStub(expectedMethod).called, + `${gCurrentTest.desc}:${expectedMethod} should have been invoked` + ); + } + + for (let method of gReplacedMethods) { + if ( + getStub(method).called && + !gCurrentTest.expectedInvokedMethods.includes(method) + ) { + ok(false, `Should have not called ${method}`); + } + } + + event.preventDefault(); + event.stopPropagation(); + + executeSoon(runNextTest); + }, +}; + +function setupTestBrowserWindow() { + // Steal click events and don't propagate them. + gTestWin.addEventListener("click", gClickHandler, true); + gTestWin.addEventListener("auxclick", gClickHandler, true); + + // Replace methods. + gReplacedMethods.forEach(function (methodName) { + let targetObj = + methodName == "getShortcutOrURIAndPostData" ? UrlbarUtils : gTestWin; + sinon.stub(targetObj, methodName).returnsArg(0); + }); + + // Inject links in content. + let doc = gTestWin.content.document; + let mainDiv = doc.createElement("div"); + mainDiv.innerHTML = + '

Common link

' + + '

Panel link

' + + '

Empty link

' + + '

MathML XLink

' + + '

SVG XLink

' + + '

'; + doc.body.appendChild(mainDiv); +} + +function runNextTest() { + if (!gCurrentTest) { + gCurrentTest = gTests.shift(); + gCurrentTest.setup(); + } + + if (!gCurrentTest.targets.length) { + info(gCurrentTest.desc + ": cleaning up..."); + gCurrentTest.clean(); + + if (gTests.length) { + gCurrentTest = gTests.shift(); + gCurrentTest.setup(); + } else { + finishTest(); + return; + } + } + + // Move to next target. + sinon.resetHistory(); + let target = gCurrentTest.targets.shift(); + + info(gCurrentTest.desc + ": testing " + target); + + // Fire (aux)click event. + let targetElt = gTestWin.content.document.getElementById(target); + ok(targetElt, gCurrentTest.desc + ": target is valid (" + targetElt.id + ")"); + EventUtils.synthesizeMouseAtCenter( + targetElt, + gCurrentTest.event, + gTestWin.content + ); +} + +function finishTest() { + info("Restoring browser..."); + gTestWin.removeEventListener("click", gClickHandler, true); + gTestWin.removeEventListener("auxclick", gClickHandler, true); + gTestWin.close(); + finish(); +} -- cgit v1.2.3