summaryrefslogtreecommitdiffstats
path: root/browser/components/extensions/test/browser/browser_ext_tabs_onUpdated.js
diff options
context:
space:
mode:
Diffstat (limited to 'browser/components/extensions/test/browser/browser_ext_tabs_onUpdated.js')
-rw-r--r--browser/components/extensions/test/browser/browser_ext_tabs_onUpdated.js339
1 files changed, 339 insertions, 0 deletions
diff --git a/browser/components/extensions/test/browser/browser_ext_tabs_onUpdated.js b/browser/components/extensions/test/browser/browser_ext_tabs_onUpdated.js
new file mode 100644
index 0000000000..a59fa21f8a
--- /dev/null
+++ b/browser/components/extensions/test/browser/browser_ext_tabs_onUpdated.js
@@ -0,0 +1,339 @@
+/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
+/* vim: set sts=2 sw=2 et tw=80: */
+"use strict";
+
+requestLongerTimeout(2);
+
+add_task(async function () {
+ let win1 = await BrowserTestUtils.openNewBrowserWindow();
+
+ await focusWindow(win1);
+
+ let extension = ExtensionTestUtils.loadExtension({
+ manifest: {
+ permissions: ["tabs"],
+ content_scripts: [
+ {
+ matches: ["http://mochi.test/*/context_tabs_onUpdated_page.html"],
+ js: ["content-script.js"],
+ run_at: "document_start",
+ },
+ ],
+ },
+
+ background: function () {
+ let pageURL =
+ "http://mochi.test:8888/browser/browser/components/extensions/test/browser/context_tabs_onUpdated_page.html";
+
+ let expectedSequence = [
+ { status: "loading" },
+ { status: "loading", url: pageURL },
+ { status: "complete" },
+ ];
+ let collectedSequence = [];
+
+ browser.tabs.onUpdated.addListener(function (tabId, updatedInfo) {
+ // onUpdated also fires with updatedInfo.faviconUrl, so explicitly
+ // check for updatedInfo.status before recording the event.
+ if ("status" in updatedInfo) {
+ collectedSequence.push(updatedInfo);
+ }
+ });
+
+ browser.runtime.onMessage.addListener(function () {
+ if (collectedSequence.length !== expectedSequence.length) {
+ browser.test.assertEq(
+ JSON.stringify(expectedSequence),
+ JSON.stringify(collectedSequence),
+ "got unexpected number of updateInfo data"
+ );
+ } else {
+ for (let i = 0; i < expectedSequence.length; i++) {
+ browser.test.assertEq(
+ expectedSequence[i].status,
+ collectedSequence[i].status,
+ "check updatedInfo status"
+ );
+ if (expectedSequence[i].url || collectedSequence[i].url) {
+ browser.test.assertEq(
+ expectedSequence[i].url,
+ collectedSequence[i].url,
+ "check updatedInfo url"
+ );
+ }
+ }
+ }
+
+ browser.test.notifyPass("tabs.onUpdated");
+ });
+
+ browser.tabs.create({ url: pageURL });
+ },
+ files: {
+ "content-script.js": `
+ window.addEventListener("message", function(evt) {
+ if (evt.data == "frame-updated") {
+ browser.runtime.sendMessage("load-completed");
+ }
+ }, true);
+ `,
+ },
+ });
+
+ await Promise.all([
+ extension.startup(),
+ extension.awaitFinish("tabs.onUpdated"),
+ ]);
+
+ await extension.unload();
+
+ await BrowserTestUtils.closeWindow(win1);
+});
+
+async function do_test_update(background, withPermissions = true) {
+ let win1 = await BrowserTestUtils.openNewBrowserWindow();
+
+ await focusWindow(win1);
+
+ let manifest = {};
+ if (withPermissions) {
+ manifest.permissions = ["tabs", "http://mochi.test/"];
+ }
+ let extension = ExtensionTestUtils.loadExtension({ manifest, background });
+
+ await extension.startup();
+ await extension.awaitFinish("finish");
+
+ await extension.unload();
+
+ await BrowserTestUtils.closeWindow(win1);
+}
+
+add_task(async function test_pinned() {
+ await do_test_update(function background() {
+ // Create a new tab for testing update.
+ browser.tabs.create({}, function (tab) {
+ browser.tabs.onUpdated.addListener(function onUpdated(tabId, changeInfo) {
+ // Check callback
+ browser.test.assertEq(tabId, tab.id, "Check tab id");
+ browser.test.log("onUpdate: " + JSON.stringify(changeInfo));
+ if ("pinned" in changeInfo) {
+ browser.test.assertTrue(changeInfo.pinned, "Check changeInfo.pinned");
+ browser.tabs.onUpdated.removeListener(onUpdated);
+ // Remove created tab.
+ browser.tabs.remove(tabId);
+ browser.test.notifyPass("finish");
+ }
+ });
+ browser.tabs.update(tab.id, { pinned: true });
+ });
+ });
+});
+
+add_task(async function test_unpinned() {
+ await do_test_update(function background() {
+ // Create a new tab for testing update.
+ browser.tabs.create({ pinned: true }, function (tab) {
+ browser.tabs.onUpdated.addListener(function onUpdated(tabId, changeInfo) {
+ // Check callback
+ browser.test.assertEq(tabId, tab.id, "Check tab id");
+ browser.test.log("onUpdate: " + JSON.stringify(changeInfo));
+ if ("pinned" in changeInfo) {
+ browser.test.assertFalse(
+ changeInfo.pinned,
+ "Check changeInfo.pinned"
+ );
+ browser.tabs.onUpdated.removeListener(onUpdated);
+ // Remove created tab.
+ browser.tabs.remove(tabId);
+ browser.test.notifyPass("finish");
+ }
+ });
+ browser.tabs.update(tab.id, { pinned: false });
+ });
+ });
+});
+
+add_task(async function test_url() {
+ await do_test_update(function background() {
+ // Create a new tab for testing update.
+ browser.tabs.create({ url: "about:blank?initial_url=1" }, function (tab) {
+ const expectedUpdatedURL = "about:blank?updated_url=1";
+
+ browser.tabs.onUpdated.addListener(function onUpdated(tabId, changeInfo) {
+ // Wait for the tabs.onUpdated events related to the updated url (because
+ // there is a good chance that we may still be receiving events related to
+ // the browser.tabs.create API call above before we are able to start
+ // loading the new url from the browser.tabs.update API call below).
+ if ("url" in changeInfo && changeInfo.url === expectedUpdatedURL) {
+ browser.test.assertEq(
+ expectedUpdatedURL,
+ changeInfo.url,
+ "Got tabs.onUpdated event for the expected url"
+ );
+ browser.tabs.onUpdated.removeListener(onUpdated);
+ // Remove created tab.
+ browser.tabs.remove(tabId);
+ browser.test.notifyPass("finish");
+ }
+ // Check callback
+ browser.test.assertEq(tabId, tab.id, "Check tab id");
+ browser.test.log("onUpdate: " + JSON.stringify(changeInfo));
+ });
+
+ browser.tabs.update(tab.id, { url: expectedUpdatedURL });
+ });
+ });
+});
+
+add_task(async function test_title() {
+ await do_test_update(async function background() {
+ const url =
+ "http://mochi.test:8888/browser/browser/components/extensions/test/browser/context_tabs_onUpdated_page.html";
+ const tab = await browser.tabs.create({ url });
+
+ browser.tabs.onUpdated.addListener(function onUpdated(tabId, changeInfo) {
+ browser.test.assertEq(tabId, tab.id, "Check tab id");
+ browser.test.log(`onUpdated: ${JSON.stringify(changeInfo)}`);
+ if ("title" in changeInfo && changeInfo.title === "New Message (1)") {
+ browser.test.log("changeInfo.title is correct");
+ browser.tabs.onUpdated.removeListener(onUpdated);
+ browser.tabs.remove(tabId);
+ browser.test.notifyPass("finish");
+ }
+ });
+
+ browser.tabs.executeScript(tab.id, {
+ code: "document.title = 'New Message (1)'",
+ });
+ });
+});
+
+add_task(async function test_without_tabs_permission() {
+ await do_test_update(async function background() {
+ const url =
+ "http://mochi.test:8888/browser/browser/components/extensions/test/browser/context_tabs_onUpdated_page.html";
+ let tab = null;
+ let count = 0;
+
+ browser.tabs.onUpdated.addListener(function onUpdated(tabId, changeInfo) {
+ // An attention change can happen during tabs.create, so
+ // we can't compare against tab yet.
+ if (!("attention" in changeInfo)) {
+ browser.test.assertEq(tabId, tab.id, "Check tab id");
+ }
+ browser.test.log(`onUpdated: ${JSON.stringify(changeInfo)}`);
+
+ browser.test.assertFalse(
+ "url" in changeInfo,
+ "url should not be included without tabs permission"
+ );
+ browser.test.assertFalse(
+ "favIconUrl" in changeInfo,
+ "favIconUrl should not be included without tabs permission"
+ );
+ browser.test.assertFalse(
+ "title" in changeInfo,
+ "title should not be included without tabs permission"
+ );
+
+ if (changeInfo.status == "complete") {
+ count++;
+ if (count === 1) {
+ browser.tabs.reload(tabId);
+ } else {
+ browser.test.log("Reload complete");
+ browser.tabs.onUpdated.removeListener(onUpdated);
+ browser.tabs.remove(tabId);
+ browser.test.notifyPass("finish");
+ }
+ }
+ });
+
+ tab = await browser.tabs.create({ url });
+ }, false /* withPermissions */);
+});
+
+add_task(async function test_onUpdated_after_onRemoved() {
+ let extension = ExtensionTestUtils.loadExtension({
+ manifest: {
+ permissions: ["tabs"],
+ },
+ async background() {
+ const url =
+ "http://mochi.test:8888/browser/browser/components/extensions/test/browser/context_tabs_onUpdated_page.html";
+ let removed = false;
+ let tab;
+
+ // If remove happens fast and we never receive onUpdated, that is ok, but
+ // we never want to receive onUpdated after onRemoved.
+ browser.tabs.onUpdated.addListener(function onUpdated(tabId, changeInfo) {
+ if (!tab || tab.id !== tabId) {
+ return;
+ }
+ browser.test.assertFalse(
+ removed,
+ "tab has not been removed before onUpdated"
+ );
+ });
+
+ browser.tabs.onRemoved.addListener((tabId, removedInfo) => {
+ if (!tab || tab.id !== tabId) {
+ return;
+ }
+ removed = true;
+ browser.test.notifyPass("onRemoved");
+ });
+
+ tab = await browser.tabs.create({ url });
+ browser.tabs.remove(tab.id);
+ },
+ });
+ await extension.startup();
+ await extension.awaitFinish("onRemoved");
+ await extension.unload();
+});
+
+// Regression test for Bug 1852391.
+add_task(async function test_pin_discarded_tab() {
+ let extension = ExtensionTestUtils.loadExtension({
+ manifest: {
+ permissions: ["tabs"],
+ },
+ async background() {
+ const url = "http://mochi.test:8888";
+ const newTab = await browser.tabs.create({
+ url,
+ active: false,
+ discarded: true,
+ });
+ browser.tabs.onUpdated.addListener(
+ async (tabId, changeInfo) => {
+ browser.test.assertEq(
+ tabId,
+ newTab.id,
+ "Expect onUpdated to be fired for the expected tab"
+ );
+ browser.test.assertEq(
+ changeInfo.pinned,
+ true,
+ "Expect pinned to be set to true"
+ );
+ await browser.tabs.remove(newTab.id);
+ browser.test.notifyPass("onPinned");
+ },
+ { properties: ["pinned"] }
+ );
+ await browser.tabs.update(newTab.id, { pinned: true }).catch(err => {
+ browser.test.fail(`Got unexpected rejection from tabs.update: ${err}`);
+ browser.test.notifyFail("onPinned");
+ });
+ },
+ });
+
+ await extension.startup();
+ await extension.awaitFinish("onPinned");
+ await extension.unload();
+});
+
+add_task(forceGC);