diff options
Diffstat (limited to 'toolkit/mozapps/extensions/test/xpinstall/browser_required_useractivation.js')
-rw-r--r-- | toolkit/mozapps/extensions/test/xpinstall/browser_required_useractivation.js | 156 |
1 files changed, 156 insertions, 0 deletions
diff --git a/toolkit/mozapps/extensions/test/xpinstall/browser_required_useractivation.js b/toolkit/mozapps/extensions/test/xpinstall/browser_required_useractivation.js new file mode 100644 index 0000000000..064249f0cb --- /dev/null +++ b/toolkit/mozapps/extensions/test/xpinstall/browser_required_useractivation.js @@ -0,0 +1,156 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ + */ + +"use strict"; + +const { AddonTestUtils } = ChromeUtils.import( + "resource://testing-common/AddonTestUtils.jsm" +); + +AddonTestUtils.initMochitest(this); + +const XPI_URL = `${TESTROOT}amosigned.xpi`; + +async function runTestCase(spawnArgs, spawnFn, { expectInstall, clickLink }) { + await SpecialPowers.pushPrefEnv({ + set: [ + // Make use the user activation requirements is enabled while running this test. + ["xpinstall.userActivation.required", true], + ], + }); + await BrowserTestUtils.withNewTab(TESTROOT, async browser => { + const expectedError = `${XPI_URL} install cancelled because of missing user gesture activation`; + + let promiseDone; + + if (expectInstall) { + promiseDone = TestUtils.topicObserved("addon-install-blocked").then( + ([subject]) => { + // Cancel the pending installation flow. + subject.wrappedJSObject.cancel(); + } + ); + } else { + promiseDone = new Promise(resolve => { + function messageHandler(msgObj) { + if ( + msgObj instanceof Ci.nsIScriptError && + msgObj.message.includes(expectedError) + ) { + ok( + true, + "Expect error on triggering navigation to xpi without user gesture activation" + ); + cleanupListener(); + resolve(); + } + } + let listenerCleared = false; + function cleanupListener() { + if (!listenerCleared) { + Services.console.unregisterListener(messageHandler); + } + listenerCleared = true; + } + Services.console.registerListener(messageHandler); + registerCleanupFunction(cleanupListener); + }); + } + + await SpecialPowers.spawn(browser, spawnArgs, spawnFn); + + if (clickLink) { + info("Click link element"); + // Wait for the install to trigger the third party website doorhanger. + // Trigger the link by simulating a mouse click, and expect it to trigger the + // install flow instead (the window is still navigated to the xpi url from the + // webpage JS code, but doing it while handling a DOM event does make it pass + // the user activation check). + await BrowserTestUtils.synthesizeMouseAtCenter( + "#link-to-xpi-file", + {}, + browser + ); + } + + info("Wait test case to be completed"); + await promiseDone; + ok(true, "Test case run completed"); + }); +} + +add_task(async function testSuccessOnUserActivatedLink() { + await runTestCase( + [XPI_URL], + xpiURL => { + const { document } = this.content; + const link = document.createElement("a"); + link.id = "link-to-xpi-file"; + link.setAttribute("href", xpiURL); + link.textContent = "Link to XPI File"; + + // Empty the test case and add the link, if the link is not visible + // without scrolling, BrowserTestUtils.synthesizeMouseAtCenter may + // fail to trigger the mouse event. + document.body.innerHTML = ""; + document.body.appendChild(link); + }, + { expectInstall: true, clickLink: true } + ); +}); + +add_task(async function testSuccessOnJSWithUserActivation() { + await runTestCase( + [XPI_URL], + xpiURL => { + const { document } = this.content; + const link = document.createElement("a"); + link.id = "link-to-xpi-file"; + link.setAttribute("href", "#"); + link.textContent = "Link to XPI File"; + + // Empty the test case and add the link, if the link is not visible + // without scrolling, BrowserTestUtils.synthesizeMouseAtCenter may + // fail to trigger the mouse event. + document.body.innerHTML = ""; + document.body.appendChild(link); + + this.content.eval(` + const linkEl = document.querySelector("#link-to-xpi-file"); + linkEl.onclick = () => { + // This is expected to trigger the install flow successfully if handling + // a user gesture DOM event, but to fail when triggered outside of it (as + // done a few line below). + window.location = "${xpiURL}"; + }; + `); + }, + { expectInstall: true, clickLink: true } + ); +}); + +add_task(async function testFailureOnJSWithoutUserActivation() { + await runTestCase( + [XPI_URL], + xpiURL => { + this.content.eval(`window.location = "${xpiURL}";`); + }, + { expectInstall: false } + ); +}); + +add_task(async function testFailureOnJSWithoutUserActivation() { + await runTestCase( + [XPI_URL], + xpiURL => { + this.content.eval(` + const frame = document.createElement("iframe"); + frame.src = "${xpiURL}"; + document.body.innerHTML = ""; + document.body.appendChild(frame); + `); + }, + { expectInstall: false } + ); +}); |