summaryrefslogtreecommitdiffstats
path: root/browser/components/extensions/test/browser/browser_ext_webNavigation_getFrames.js
diff options
context:
space:
mode:
Diffstat (limited to 'browser/components/extensions/test/browser/browser_ext_webNavigation_getFrames.js')
-rw-r--r--browser/components/extensions/test/browser/browser_ext_webNavigation_getFrames.js319
1 files changed, 319 insertions, 0 deletions
diff --git a/browser/components/extensions/test/browser/browser_ext_webNavigation_getFrames.js b/browser/components/extensions/test/browser/browser_ext_webNavigation_getFrames.js
new file mode 100644
index 0000000000..f72713d8fc
--- /dev/null
+++ b/browser/components/extensions/test/browser/browser_ext_webNavigation_getFrames.js
@@ -0,0 +1,319 @@
+/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
+/* vim: set sts=2 sw=2 et tw=80: */
+"use strict";
+
+add_task(async function testWebNavigationGetNonExistentTab() {
+ let extension = ExtensionTestUtils.loadExtension({
+ background: async function () {
+ // There is no "tabId = 0" because the id assigned by tabTracker (defined in ext-browser.js)
+ // starts from 1.
+ await browser.test.assertRejects(
+ browser.webNavigation.getAllFrames({ tabId: 0 }),
+ "Invalid tab ID: 0",
+ "getAllFrames rejected Promise should pass the expected error"
+ );
+
+ // There is no "tabId = 0" because the id assigned by tabTracker (defined in ext-browser.js)
+ // starts from 1, processId is currently marked as optional and it is ignored.
+ await browser.test.assertRejects(
+ browser.webNavigation.getFrame({
+ tabId: 0,
+ frameId: 15,
+ processId: 20,
+ }),
+ "Invalid tab ID: 0",
+ "getFrame rejected Promise should pass the expected error"
+ );
+
+ browser.test.sendMessage("getNonExistentTab.done");
+ },
+ manifest: {
+ permissions: ["webNavigation"],
+ },
+ });
+
+ await extension.startup();
+
+ await extension.awaitMessage("getNonExistentTab.done");
+
+ await extension.unload();
+});
+
+add_task(async function testWebNavigationFrames() {
+ let extension = ExtensionTestUtils.loadExtension({
+ background: async function () {
+ let tabId;
+ let collectedDetails = [];
+
+ browser.webNavigation.onCompleted.addListener(async details => {
+ collectedDetails.push(details);
+
+ if (details.frameId !== 0) {
+ // wait for the top level iframe to be complete
+ return;
+ }
+
+ let getAllFramesDetails = await browser.webNavigation.getAllFrames({
+ tabId,
+ });
+
+ let getFramePromises = getAllFramesDetails.map(({ frameId }) => {
+ // processId is currently marked as optional and it is ignored.
+ return browser.webNavigation.getFrame({
+ tabId,
+ frameId,
+ processId: 0,
+ });
+ });
+
+ let getFrameResults = await Promise.all(getFramePromises);
+ browser.test.sendMessage("webNavigationFrames.done", {
+ collectedDetails,
+ getAllFramesDetails,
+ getFrameResults,
+ });
+
+ // Pick a random frameId.
+ let nonExistentFrameId = Math.floor(Math.random() * 10000);
+
+ // Increment the picked random nonExistentFrameId until it doesn't exists.
+ while (
+ getAllFramesDetails.filter(
+ details => details.frameId == nonExistentFrameId
+ ).length
+ ) {
+ nonExistentFrameId += 1;
+ }
+
+ // Check that getFrame Promise is rejected with the expected error message on nonexistent frameId.
+ await browser.test.assertRejects(
+ browser.webNavigation.getFrame({
+ tabId,
+ frameId: nonExistentFrameId,
+ processId: 20,
+ }),
+ `No frame found with frameId: ${nonExistentFrameId}`,
+ "getFrame promise should be rejected with the expected error message on unexistent frameId"
+ );
+
+ await browser.tabs.remove(tabId);
+ browser.test.sendMessage("webNavigationFrames.done");
+ });
+
+ let tab = await browser.tabs.create({ url: "tab.html" });
+ tabId = tab.id;
+ },
+ manifest: {
+ permissions: ["webNavigation", "tabs"],
+ },
+ files: {
+ "tab.html": `
+ <!DOCTYPE html>
+ <html>
+ <head>
+ <meta charset="utf-8">
+ </head>
+ <body>
+ <iframe src="subframe.html"></iframe>
+ <iframe src="subframe.html"></iframe>
+ </body>
+ </html>
+ `,
+ "subframe.html": `
+ <!DOCTYPE html>
+ <html>
+ <head>
+ <meta charset="utf-8">
+ </head>
+ </html>
+ `,
+ },
+ });
+
+ await extension.startup();
+
+ let { collectedDetails, getAllFramesDetails, getFrameResults } =
+ await extension.awaitMessage("webNavigationFrames.done");
+
+ is(getAllFramesDetails.length, 3, "expected number of frames found");
+ is(
+ getAllFramesDetails.length,
+ collectedDetails.length,
+ "number of frames found should equal the number onCompleted events collected"
+ );
+
+ is(
+ getAllFramesDetails[0].frameId,
+ 0,
+ "the root frame has the expected frameId"
+ );
+ is(
+ getAllFramesDetails[0].parentFrameId,
+ -1,
+ "the root frame has the expected parentFrameId"
+ );
+
+ // ordered by frameId
+ let sortByFrameId = (el1, el2) => {
+ let val1 = el1 ? el1.frameId : -1;
+ let val2 = el2 ? el2.frameId : -1;
+ return val1 - val2;
+ };
+
+ collectedDetails = collectedDetails.sort(sortByFrameId);
+ getAllFramesDetails = getAllFramesDetails.sort(sortByFrameId);
+ getFrameResults = getFrameResults.sort(sortByFrameId);
+
+ info("check frame details content");
+
+ is(
+ getFrameResults.length,
+ getAllFramesDetails.length,
+ "getFrame and getAllFrames should return the same number of results"
+ );
+
+ Assert.deepEqual(
+ getFrameResults,
+ getAllFramesDetails,
+ "getFrame and getAllFrames should return the same results"
+ );
+
+ info(`check frame details collected and retrieved with getAllFrames`);
+
+ for (let [i, collected] of collectedDetails.entries()) {
+ let getAllFramesDetail = getAllFramesDetails[i];
+
+ is(getAllFramesDetail.frameId, collected.frameId, "frameId");
+ is(
+ getAllFramesDetail.parentFrameId,
+ collected.parentFrameId,
+ "parentFrameId"
+ );
+ is(getAllFramesDetail.tabId, collected.tabId, "tabId");
+
+ // This can be uncommented once Bug 1246125 has been fixed
+ // is(getAllFramesDetail.url, collected.url, "url");
+ }
+
+ info("frame details content checked");
+
+ await extension.awaitMessage("webNavigationFrames.done");
+
+ await extension.unload();
+});
+
+add_task(async function testWebNavigationGetFrameOnDiscardedTab() {
+ const extension = ExtensionTestUtils.loadExtension({
+ manifest: {
+ permissions: ["tabs", "webNavigation"],
+ },
+ async background() {
+ let tabs = await browser.tabs.query({ currentWindow: true });
+ browser.test.assertEq(2, tabs.length, "Expect 2 tabs open");
+
+ const tabId = tabs[1].id;
+
+ await browser.tabs.discard(tabId);
+ let tab = await browser.tabs.get(tabId);
+ browser.test.assertEq(true, tab.discarded, "Expect a discarded tab");
+
+ const allFrames = await browser.webNavigation.getAllFrames({ tabId });
+ browser.test.assertEq(
+ null,
+ allFrames,
+ "Expect null from calling getAllFrames on discarded tab"
+ );
+
+ tab = await browser.tabs.get(tabId);
+ browser.test.assertEq(
+ true,
+ tab.discarded,
+ "Expect tab to stay discarded"
+ );
+
+ const topFrame = await browser.webNavigation.getFrame({
+ tabId,
+ frameId: 0,
+ });
+ browser.test.assertEq(
+ null,
+ topFrame,
+ "Expect null from calling getFrame on discarded tab"
+ );
+
+ tab = await browser.tabs.get(tabId);
+ browser.test.assertEq(
+ true,
+ tab.discarded,
+ "Expect tab to stay discarded"
+ );
+
+ browser.test.sendMessage("get-frames-done");
+ },
+ });
+
+ const initialTab = gBrowser.selectedTab;
+ const tab = await BrowserTestUtils.openNewForegroundTab(
+ gBrowser,
+ "http://mochi.test:8888/?toBeDiscarded=true"
+ );
+ // Switch back to the initial tab to allow the new tab
+ // to be discarded.
+ await BrowserTestUtils.switchTab(gBrowser, initialTab);
+
+ ok(!!tab.linkedPanel, "Tab not initially discarded");
+
+ await extension.startup();
+ await extension.awaitMessage("get-frames-done");
+
+ ok(!tab.linkedPanel, "Tab should be discarded");
+
+ BrowserTestUtils.removeTab(tab);
+
+ await extension.unload();
+});
+
+add_task(async function testWebNavigationCrossOriginFrames() {
+ let extension = ExtensionTestUtils.loadExtension({
+ manifest: {
+ permissions: ["webNavigation"],
+ },
+ async background() {
+ let url =
+ "http://mochi.test:8888/tests/toolkit/components/extensions/test/mochitest/file_contains_iframe.html";
+ let tab = await browser.tabs.create({ url });
+
+ await new Promise(resolve => {
+ browser.webNavigation.onCompleted.addListener(details => {
+ if (details.tabId === tab.id && details.frameId === 0) {
+ resolve();
+ }
+ });
+ });
+
+ let frames = await browser.webNavigation.getAllFrames({ tabId: tab.id });
+ browser.test.assertEq(frames[0].url, url, "Top is from mochi.test");
+
+ await browser.tabs.remove(tab.id);
+ browser.test.sendMessage("webNavigation.CrossOriginFrames", frames);
+ },
+ });
+
+ await extension.startup();
+
+ let frames = await extension.awaitMessage("webNavigation.CrossOriginFrames");
+ is(frames.length, 2, "getAllFrames() returns both frames.");
+
+ is(frames[0].frameId, 0, "Top frame has correct frameId.");
+ is(frames[0].parentFrameId, -1, "Top parentFrameId is correct.");
+
+ ok(frames[1].frameId > 0, "Cross-origin iframe has non-zero frameId.");
+ is(frames[1].parentFrameId, 0, "Iframe parentFrameId is correct.");
+ is(
+ frames[1].url,
+ "http://example.org/tests/toolkit/components/extensions/test/mochitest/file_contains_img.html",
+ "Irame is from example.org"
+ );
+
+ await extension.unload();
+});