diff --git a/toolkit/mozapps/extensions/test/xpinstall/browser.ini b/toolkit/mozapps/extensions/test/xpinstall/browser.ini index cbf802f82842..f96e772a53e7 100644 --- a/toolkit/mozapps/extensions/test/xpinstall/browser.ini +++ b/toolkit/mozapps/extensions/test/xpinstall/browser.ini @@ -39,6 +39,7 @@ support-files = [browser_bug645699.js] [browser_bug672485.js] skip-if = true # disabled due to a leak. See bug 682410. +[browser_containers.js] [browser_cookies.js] [browser_cookies2.js] [browser_cookies3.js] @@ -66,6 +67,8 @@ skip-if = true # Bug 1449788 [browser_localfile3.js] [browser_localfile4.js] [browser_offline.js] +[browser_privatebrowsing.js] +skip-if = debug # Bug 1541577 - leaks on debug [browser_relative.js] [browser_softwareupdate.js] [browser_trigger_redirect.js] diff --git a/toolkit/mozapps/extensions/test/xpinstall/browser_containers.js b/toolkit/mozapps/extensions/test/xpinstall/browser_containers.js new file mode 100644 index 000000000000..b69deef31917 --- /dev/null +++ b/toolkit/mozapps/extensions/test/xpinstall/browser_containers.js @@ -0,0 +1,75 @@ +const MY_CONTEXT = 2; +let gDidSeeChannel = false; + +function check_channel(subject) { + if (!(subject instanceof Ci.nsIHttpChannel)) { + return; + } + let channel = subject.QueryInterface(Ci.nsIHttpChannel); + let uri = channel.URI; + if (!uri || !uri.spec.endsWith("amosigned.xpi")) { + return; + } + gDidSeeChannel = true; + ok(true, "Got request for " + uri.spec); + + let loadInfo = channel.loadInfo; + is(loadInfo.originAttributes.userContextId, MY_CONTEXT, "Got expected usercontextid"); +} +// ---------------------------------------------------------------------------- +// Tests we send the right cookies when installing through an InstallTrigger call +function test() { + Harness.installConfirmCallback = confirm_install; + Harness.installEndedCallback = install_ended; + Harness.installsCompletedCallback = finish_test; + Harness.finalContentEvent = "InstallComplete"; + Harness.setup(); + + var pm = Services.perms; + pm.add(makeURI("http://example.com/"), "install", pm.ALLOW_ACTION); + + var triggers = encodeURIComponent(JSON.stringify({ + "Unsigned XPI": { + URL: TESTROOT + "amosigned.xpi", + IconURL: TESTROOT + "icon.png", + toString() { return this.URL; }, + }, + })); + gBrowser.selectedTab = BrowserTestUtils.addTab(gBrowser, "", {userContextId: MY_CONTEXT}); + Services.obs.addObserver(check_channel, "http-on-before-connect"); + BrowserTestUtils.loadURI(gBrowser, TESTROOT + "installtrigger.html?" + triggers); +} + +function confirm_install(panel) { + is(panel.getAttribute("name"), "XPI Test", "Should have seen the name"); + return true; +} + +function install_ended(install, addon) { + Assert.deepEqual(install.installTelemetryInfo, {source: "test-host", method: "installTrigger"}, + "Got the expected install.installTelemetryInfo"); + install.cancel(); +} + +const finish_test = async function(count) { + ok(gDidSeeChannel, "Should have seen the request for the XPI and verified it was sent the right way."); + is(count, 1, "1 Add-on should have been successfully installed"); + + Services.obs.removeObserver(check_channel, "http-on-before-connect"); + + Services.perms.remove(makeURI("http://example.com"), "install"); + + const results = await ContentTask.spawn(gBrowser.selectedBrowser, null, () => { + return { + return: content.document.getElementById("return").textContent, + status: content.document.getElementById("status").textContent, + }; + }); + + is(results.return, "true", "installTrigger should have claimed success"); + is(results.status, "0", "Callback should have seen a success"); + + gBrowser.removeCurrentTab(); + Harness.finish(); +}; + diff --git a/toolkit/mozapps/extensions/test/xpinstall/browser_privatebrowsing.js b/toolkit/mozapps/extensions/test/xpinstall/browser_privatebrowsing.js new file mode 100644 index 000000000000..4119fac1e08c --- /dev/null +++ b/toolkit/mozapps/extensions/test/xpinstall/browser_privatebrowsing.js @@ -0,0 +1,85 @@ +let gDidSeeChannel = false; + +function check_channel(subject) { + if (!(subject instanceof Ci.nsIHttpChannel)) { + return; + } + let channel = subject.QueryInterface(Ci.nsIHttpChannel); + let uri = channel.URI; + if (!uri || !uri.spec.endsWith("amosigned.xpi")) { + return; + } + gDidSeeChannel = true; + ok(true, "Got request for " + uri.spec); + + let loadInfo = channel.loadInfo; + is(loadInfo.originAttributes.privateBrowsingId, 1, "Request should have happened using private browsing"); +} +// ---------------------------------------------------------------------------- +// Tests we send the right cookies when installing through an InstallTrigger call +let gPrivateWin; +async function test() { + waitForExplicitFinish(); // have to call this ourselves because we're async. + Harness.installConfirmCallback = confirm_install; + Harness.installEndedCallback = install_ended; + Harness.installsCompletedCallback = finish_test; + Harness.finalContentEvent = "InstallComplete"; + gPrivateWin = await BrowserTestUtils.openNewBrowserWindow({private: true}); + Harness.setup(gPrivateWin); + + var pm = Services.perms; + pm.add(makeURI("http://example.com/"), "install", pm.ALLOW_ACTION); + + var triggers = encodeURIComponent(JSON.stringify({ + "Unsigned XPI": { + URL: TESTROOT + "amosigned.xpi", + IconURL: TESTROOT + "icon.png", + toString() { return this.URL; }, + }, + })); + gPrivateWin.gBrowser.selectedTab = BrowserTestUtils.addTab(gPrivateWin.gBrowser); + Services.obs.addObserver(check_channel, "http-on-before-connect"); + BrowserTestUtils.loadURI(gPrivateWin.gBrowser, TESTROOT + "installtrigger.html?" + triggers); +} + +function confirm_install(panel) { + is(panel.getAttribute("name"), "XPI Test", "Should have seen the name"); + return true; +} + +function install_ended(install, addon) { + Assert.deepEqual(install.installTelemetryInfo, {source: "test-host", method: "installTrigger"}, + "Got the expected install.installTelemetryInfo"); + install.cancel(); +} + +const finish_test = async function(count) { + ok(gDidSeeChannel, "Should have seen the request for the XPI and verified it was sent the right way."); + is(count, 1, "1 Add-on should have been successfully installed"); + + Services.obs.removeObserver(check_channel, "http-on-before-connect"); + + Services.perms.remove(makeURI("http://example.com"), "install"); + + const results = await ContentTask.spawn(gPrivateWin.gBrowser.selectedBrowser, null, () => { + return { + return: content.document.getElementById("return").textContent, + status: content.document.getElementById("status").textContent, + }; + }); + + is(results.return, "true", "installTrigger should have claimed success"); + is(results.status, "0", "Callback should have seen a success"); + + // Explicitly click the "OK" button to avoid the panel reopening in the other window once this + // window closes (see also bug 1535069): + await BrowserTestUtils.waitForEvent(gPrivateWin.PanelUI.notificationPanel, "popupshown"); + gPrivateWin.PanelUI.notificationPanel.querySelector("popupnotification[popupid=addon-installed]").button.click(); + + // Now finish the test: + await BrowserTestUtils.closeWindow(gPrivateWin); + Harness.finish(gPrivateWin); + gPrivateWin = null; +}; + + diff --git a/toolkit/mozapps/extensions/test/xpinstall/head.js b/toolkit/mozapps/extensions/test/xpinstall/head.js index b9b3c0cc8ae9..b7185b0b7f84 100644 --- a/toolkit/mozapps/extensions/test/xpinstall/head.js +++ b/toolkit/mozapps/extensions/test/xpinstall/head.js @@ -91,7 +91,7 @@ var Harness = { leaveOpen: {}, // Setup and tear down functions - setup() { + setup(win = window) { if (!this.waitingForFinish) { waitForExplicitFinish(); this.waitingForFinish = true; @@ -109,12 +109,13 @@ var Harness = { Services.obs.addObserver(this, "addon-install-failed"); Services.obs.addObserver(this, "addon-install-complete"); + this._boundWin = Cu.getWeakReference(win); // need this so our addon manager listener knows which window to use. AddonManager.addInstallListener(this); Services.wm.addListener(this); - window.addEventListener("popupshown", this); - PanelUI.notificationPanel.addEventListener("popupshown", this); + win.addEventListener("popupshown", this); + win.PanelUI.notificationPanel.addEventListener("popupshown", this); var self = this; registerCleanupFunction(async function() { @@ -134,8 +135,9 @@ var Harness = { Services.wm.removeListener(self); - window.removeEventListener("popupshown", self); - PanelUI.notificationPanel.removeEventListener("popupshown", self); + win.removeEventListener("popupshown", self); + win.PanelUI.notificationPanel.removeEventListener("popupshown", self); + win = null; let aInstalls = await AddonManager.getAllInstalls(); is(aInstalls.length, 0, "Should be no active installs at the end of the test"); @@ -151,12 +153,13 @@ var Harness = { this.runningInstalls = []; }, - finish() { + finish(win = window) { // Some tests using this harness somehow finish leaving // the addon-installed panel open. hiding here addresses // that which fixes the rest of the tests. Since no test // here cares about this panel, we just need it to close. - PanelUI.notificationPanel.hidePopup(); + win.PanelUI.notificationPanel.hidePopup(); + delete this._boundWin; finish(); }, @@ -246,8 +249,8 @@ var Harness = { handleEvent(event) { if (event.type === "popupshown") { - if (event.target == PanelUI.notificationPanel) { - PanelUI.notificationPanel.hidePopup(); + if (event.target == event.view.PanelUI.notificationPanel) { + event.view.PanelUI.notificationPanel.hidePopup(); } else if (event.target.firstElementChild) { let popupId = event.target.firstElementChild.getAttribute("popupid"); if (popupId === "addon-webext-permissions") { @@ -323,7 +326,7 @@ var Harness = { if (this.finalContentEvent && !this.waitingForEvent) { this.waitingForEvent = true; info("Waiting for " + this.finalContentEvent); - let mm = gBrowser.selectedBrowser.messageManager; + let mm = this._boundWin.get().gBrowser.selectedBrowser.messageManager; mm.loadFrameScript(`data:,content.addEventListener("${this.finalContentEvent}", () => { sendAsyncMessage("Test:GotNewInstallEvent"); });`, false); let listener = () => { info("Saw " + this.finalContentEvent);