summaryrefslogtreecommitdiffstats
path: root/toolkit/mozapps/extensions/test/xpinstall/browser_required_useractivation.js
diff options
context:
space:
mode:
Diffstat (limited to 'toolkit/mozapps/extensions/test/xpinstall/browser_required_useractivation.js')
-rw-r--r--toolkit/mozapps/extensions/test/xpinstall/browser_required_useractivation.js156
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..6c8894699d
--- /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.importESModule(
+ "resource://testing-common/AddonTestUtils.sys.mjs"
+);
+
+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 }
+ );
+});