summaryrefslogtreecommitdiffstats
path: root/mobile/android/components/extensions/test/mochitest/test_ext_tabs_events.html
diff options
context:
space:
mode:
Diffstat (limited to 'mobile/android/components/extensions/test/mochitest/test_ext_tabs_events.html')
-rw-r--r--mobile/android/components/extensions/test/mochitest/test_ext_tabs_events.html302
1 files changed, 302 insertions, 0 deletions
diff --git a/mobile/android/components/extensions/test/mochitest/test_ext_tabs_events.html b/mobile/android/components/extensions/test/mochitest/test_ext_tabs_events.html
new file mode 100644
index 0000000000..cd708d942a
--- /dev/null
+++ b/mobile/android/components/extensions/test/mochitest/test_ext_tabs_events.html
@@ -0,0 +1,302 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <meta charset="utf-8">
+ <title>Tabs Events Test</title>
+ <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="text/javascript" src="/tests/SimpleTest/ExtensionTestUtils.js"></script>
+ <script type="text/javascript" src="head.js"></script>
+ <link rel="stylesheet" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+
+<script type="text/javascript">
+"use strict";
+
+add_task(async function testTabEvents() {
+ async function background() {
+ const events = [];
+ let eventPromise;
+ const checkEvents = () => {
+ if (eventPromise && events.length >= eventPromise.names.length) {
+ eventPromise.resolve();
+ }
+ };
+
+ browser.tabs.onCreated.addListener(tab => {
+ events.push({type: "onCreated", tab});
+ checkEvents();
+ });
+
+ browser.tabs.onAttached.addListener((tabId, info) => {
+ events.push(Object.assign({type: "onAttached", tabId}, info));
+ checkEvents();
+ });
+
+ browser.tabs.onDetached.addListener((tabId, info) => {
+ events.push(Object.assign({type: "onDetached", tabId}, info));
+ checkEvents();
+ });
+
+ browser.tabs.onRemoved.addListener((tabId, info) => {
+ events.push(Object.assign({type: "onRemoved", tabId}, info));
+ checkEvents();
+ });
+
+ browser.tabs.onMoved.addListener((tabId, info) => {
+ events.push(Object.assign({type: "onMoved", tabId}, info));
+ checkEvents();
+ });
+
+ async function expectEvents(names) {
+ browser.test.log(`Expecting events: ${names.join(", ")}`);
+
+ await new Promise(resolve => {
+ eventPromise = {names, resolve};
+ checkEvents();
+ });
+
+ browser.test.assertEq(names.length, events.length, "Got expected number of events");
+ for (const [i, name] of names.entries()) {
+ browser.test.assertEq(name, i in events && events[i].type,
+ `Got expected ${name} event`);
+ }
+ return events.splice(0);
+ }
+
+ try {
+ browser.test.log("Create tab");
+ const tab = await browser.tabs.create({url: "about:blank"});
+ const oldIndex = tab.index;
+
+ const [created] = await expectEvents(["onCreated"]);
+ browser.test.assertEq(tab.id, created.tab.id, "Got expected tab ID");
+ browser.test.assertEq(oldIndex, created.tab.index, "Got expected tab index");
+
+
+ browser.test.log("Remove tab");
+ await browser.tabs.remove(tab.id);
+ const [removed] = await expectEvents(["onRemoved"]);
+
+ browser.test.assertEq(tab.id, removed.tabId, "Expected removed tab ID");
+ browser.test.assertEq(tab.windowId, removed.windowId, "Expected removed tab window ID");
+ // Note: We want to test for the actual boolean value false here.
+ browser.test.assertEq(false, removed.isWindowClosing, "Expected isWindowClosing value");
+
+ browser.test.notifyPass("tabs-events");
+ } catch (e) {
+ browser.test.fail(`${e} :: ${e.stack}`);
+ browser.test.notifyFail("tabs-events");
+ }
+ }
+
+ const extension = ExtensionTestUtils.loadExtension({
+ manifest: {
+ "permissions": ["tabs"],
+ },
+ background,
+ });
+
+ await extension.startup();
+ await extension.awaitFinish("tabs-events");
+ await extension.unload();
+});
+
+add_task(async function testTabRemovalEvent() {
+ async function background() {
+ function awaitLoad(tabId) {
+ return new Promise(resolve => {
+ browser.tabs.onUpdated.addListener(function listener(tabId_, changed, tab) {
+ if (tabId == tabId_ && changed.status == "complete") {
+ browser.tabs.onUpdated.removeListener(listener);
+ resolve();
+ }
+ });
+ });
+ }
+
+ chrome.tabs.onRemoved.addListener((tabId, info) => {
+ browser.test.log("Make sure the removed tab is not available in the tabs.query callback.");
+ chrome.tabs.query({}, tabs => {
+ for (const tab of tabs) {
+ browser.test.assertTrue(tab.id != tabId, "Tab query should not include removed tabId");
+ }
+ browser.test.notifyPass("tabs-events");
+ });
+ });
+
+ try {
+ const url = "http://example.com/mochitest/mobile/android/components/extensions/test/mochitest/context.html";
+ const tab = await browser.tabs.create({url: url});
+ await awaitLoad(tab.id);
+
+ await browser.tabs.remove(tab.id);
+ } catch (e) {
+ browser.test.fail(`${e} :: ${e.stack}`);
+ browser.test.notifyFail("tabs-events");
+ }
+ }
+
+ const extension = ExtensionTestUtils.loadExtension({
+ manifest: {
+ "permissions": ["tabs"],
+ },
+ background,
+ });
+
+ await extension.startup();
+ await extension.awaitFinish("tabs-events");
+ await extension.unload();
+});
+
+add_task(async function testTabActivationEvent() {
+ // TODO bug 1565536: tabs.onActivated is not supported in GeckoView.
+ if (true) {
+ todo(false, "skipping testTabActivationEvent");
+ return;
+ }
+ async function background() {
+ function makeExpectable() {
+ let expectation = null, resolver = null;
+ const expectable = param => {
+ if (expectation === null) {
+ browser.test.fail("unexpected call to expectable");
+ } else {
+ try {
+ resolver(expectation(param));
+ } catch (e) {
+ resolver(Promise.reject(e));
+ } finally {
+ expectation = null;
+ }
+ }
+ };
+ expectable.expect = e => {
+ expectation = e;
+ return new Promise(r => { resolver = r; });
+ };
+ return expectable;
+ }
+ try {
+ const listener = makeExpectable();
+ browser.tabs.onActivated.addListener(listener);
+
+ const [tab0] = await browser.tabs.query({active: true});
+ const [, tab1] = await Promise.all([
+ listener.expect(info => {
+ browser.test.assertEq(tab0.id, info.previousTabId, "Got expected previousTabId");
+ }),
+ browser.tabs.create({url: "about:blank"}),
+ ]);
+ const [, tab2] = await Promise.all([
+ listener.expect(info => {
+ browser.test.assertEq(tab1.id, info.previousTabId, "Got expected previousTabId");
+ }),
+ browser.tabs.create({url: "about:blank"}),
+ ]);
+
+ await Promise.all([
+ listener.expect(info => {
+ browser.test.assertEq(tab1.id, info.tabId, "Got expected tabId");
+ browser.test.assertEq(tab2.id, info.previousTabId, "Got expected previousTabId");
+ }),
+ browser.tabs.update(tab1.id, {active: true}),
+ ]);
+
+ await Promise.all([
+ listener.expect(info => {
+ browser.test.assertEq(tab2.id, info.tabId, "Got expected tabId");
+ browser.test.assertEq(undefined, info.previousTabId, "previousTabId should not be defined when previous tab was closed");
+ }),
+ browser.tabs.remove(tab1.id),
+ ]);
+
+ browser.tabs.onActivated.removeListener(listener);
+ await browser.tabs.remove(tab2.id);
+
+ browser.test.notifyPass("tabs-events");
+ } catch (e) {
+ browser.test.fail(`${e} :: ${e.stack}`);
+ browser.test.notifyFail("tabs-events");
+ }
+ }
+
+ const extension = ExtensionTestUtils.loadExtension({
+ manifest: {
+ "permissions": ["tabs"],
+ },
+
+ background,
+ });
+
+ await extension.startup();
+ await extension.awaitFinish("tabs-events");
+ await extension.unload();
+});
+
+add_task(async function test_tabs_event_page() {
+ function background() {
+ const EVENTS = [
+ "onActivated",
+ "onRemoved",
+ "onUpdated",
+ ];
+ browser.tabs.onCreated.addListener(() => {
+ browser.test.sendMessage("onCreated");
+ });
+ for (const event of EVENTS) {
+ browser.tabs[event].addListener(() => {
+ });
+ }
+ browser.test.onMessage.addListener(async msg => {
+ if (msg === "createTab") {
+ await browser.tabs.create({url: "about:blank"});
+ }
+ });
+ browser.test.sendMessage("ready");
+ }
+
+ const apiEvents = ["onActivated", "onCreated", "onRemoved", "onUpdated"];
+ const apiNs = "tabs";
+ const extension = ExtensionTestUtils.loadExtension({
+ manifest: {
+ browser_specific_settings: { gecko: { id: "eventpage@tabs" } },
+ "permissions": ["tabs"],
+ background: { persistent: false },
+ },
+ background,
+ });
+
+ await extension.startup();
+ info("Wait for event page to be started");
+ await extension.awaitMessage("ready");
+ // Sanity check
+ info("Wait for tabs.onCreated listener call");
+ extension.sendMessage("createTab");
+ await extension.awaitMessage("onCreated");
+
+ // on startup, all event listeners should not be primed
+ await assertPersistentListeners(extension, apiNs, apiEvents, { primed: false });
+
+ // when the extension is killed, all event listeners should be primed
+ info("Terminate event page");
+ await extension.terminateBackground({ disableResetIdleForTest: true });
+ await assertPersistentListeners(extension, apiNs, apiEvents, { primed: true });
+
+ // on start up again, all event listeners should not be primed
+ info("Wake up event page on a new tabs.onCreated event");
+ const newWin = window.open();
+ info("Wait for event page to be restarted");
+ await extension.awaitMessage("ready");
+ info("Wait for the primed tabs.onCreated to be received by the event page");
+ await extension.awaitMessage("onCreated");
+ await assertPersistentListeners(extension, apiNs, apiEvents, { primed: false });
+
+ await extension.unload();
+ newWin.close();
+});
+
+</script>
+
+</body>
+</html>