summaryrefslogtreecommitdiffstats
path: root/browser/components/extensions/test/browser/browser_ext_devtools_network.js
diff options
context:
space:
mode:
Diffstat (limited to 'browser/components/extensions/test/browser/browser_ext_devtools_network.js')
-rw-r--r--browser/components/extensions/test/browser/browser_ext_devtools_network.js298
1 files changed, 298 insertions, 0 deletions
diff --git a/browser/components/extensions/test/browser/browser_ext_devtools_network.js b/browser/components/extensions/test/browser/browser_ext_devtools_network.js
new file mode 100644
index 0000000000..0ca455444e
--- /dev/null
+++ b/browser/components/extensions/test/browser/browser_ext_devtools_network.js
@@ -0,0 +1,298 @@
+/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
+/* vim: set sts=2 sw=2 et tw=80: */
+"use strict";
+
+loadTestSubscript("head_devtools.js");
+
+// Allow rejections related to closing the devtools toolbox too soon after the test
+// has already verified the details that were relevant for that test case.
+PromiseTestUtils.allowMatchingRejectionsGlobally(
+ /can't be sent as the connection just closed/
+);
+
+function background() {
+ browser.test.onMessage.addListener(msg => {
+ let code;
+ if (msg === "navigate") {
+ code = "window.wrappedJSObject.location.href = 'http://example.com/';";
+ browser.tabs.executeScript({ code });
+ } else if (msg === "reload") {
+ code = "window.wrappedJSObject.location.reload(true);";
+ browser.tabs.executeScript({ code });
+ }
+ });
+ browser.tabs.onUpdated.addListener((tabId, changeInfo, tab) => {
+ if (changeInfo.status === "complete" && tab.url === "http://example.com/") {
+ browser.test.sendMessage("tabUpdated");
+ }
+ });
+ browser.test.sendMessage("ready");
+}
+
+function devtools_page() {
+ let eventCount = 0;
+ let listener = url => {
+ eventCount++;
+ browser.test.assertEq(
+ "http://example.com/",
+ url,
+ "onNavigated received the expected url."
+ );
+ browser.test.sendMessage("onNavigatedFired", eventCount);
+
+ if (eventCount === 2) {
+ eventCount = 0;
+ browser.devtools.network.onNavigated.removeListener(listener);
+ }
+ };
+ browser.devtools.network.onNavigated.addListener(listener);
+
+ let harLogCount = 0;
+ let harListener = async msg => {
+ if (msg !== "getHAR") {
+ return;
+ }
+
+ harLogCount++;
+
+ const harLog = await browser.devtools.network.getHAR();
+ browser.test.sendMessage("getHAR-result", harLog);
+
+ if (harLogCount === 3) {
+ harLogCount = 0;
+ browser.test.onMessage.removeListener(harListener);
+ }
+ };
+ browser.test.onMessage.addListener(harListener);
+
+ let requestFinishedListener = async request => {
+ browser.test.assertTrue(request.request, "Request entry must exist");
+ browser.test.assertTrue(request.response, "Response entry must exist");
+
+ browser.test.sendMessage("onRequestFinished");
+
+ // Get response content using callback
+ request.getContent((content, encoding) => {
+ browser.test.sendMessage("onRequestFinished-callbackExecuted", [
+ content,
+ encoding,
+ ]);
+ });
+
+ // Get response content using returned promise
+ request.getContent().then(([content, encoding]) => {
+ browser.test.sendMessage("onRequestFinished-promiseResolved", [
+ content,
+ encoding,
+ ]);
+ });
+
+ browser.devtools.network.onRequestFinished.removeListener(
+ requestFinishedListener
+ );
+ };
+
+ browser.test.onMessage.addListener(msg => {
+ if (msg === "addOnRequestFinishedListener") {
+ browser.devtools.network.onRequestFinished.addListener(
+ requestFinishedListener
+ );
+ }
+ });
+ browser.test.sendMessage("devtools-page-loaded");
+}
+
+let extData = {
+ background,
+ manifest: {
+ permissions: ["tabs", "http://mochi.test/", "http://example.com/"],
+ devtools_page: "devtools_page.html",
+ },
+ files: {
+ "devtools_page.html": `<!DOCTYPE html>
+ <html>
+ <head>
+ <meta charset="utf-8">
+ <script src="devtools_page.js"></script>
+ </head>
+ <body>
+ </body>
+ </html>`,
+ "devtools_page.js": devtools_page,
+ },
+};
+
+async function waitForRequestAdded(toolbox) {
+ let netPanel = await toolbox.getNetMonitorAPI();
+ return new Promise(resolve => {
+ netPanel.once("NetMonitor:RequestAdded", () => {
+ resolve();
+ });
+ });
+}
+
+async function navigateToolboxTarget(extension, toolbox) {
+ extension.sendMessage("navigate");
+
+ // Wait till the navigation is complete.
+ await Promise.all([
+ extension.awaitMessage("tabUpdated"),
+ extension.awaitMessage("onNavigatedFired"),
+ waitForRequestAdded(toolbox),
+ ]);
+}
+
+/**
+ * Test for `chrome.devtools.network.onNavigate()` API
+ */
+add_task(async function test_devtools_network_on_navigated() {
+ let tab = await BrowserTestUtils.openNewForegroundTab(
+ gBrowser,
+ "http://mochi.test:8888/"
+ );
+ let extension = ExtensionTestUtils.loadExtension(extData);
+
+ await extension.startup();
+ await extension.awaitMessage("ready");
+
+ await openToolboxForTab(tab);
+
+ info("Wait the devtools page load");
+ await extension.awaitMessage("devtools-page-loaded");
+
+ extension.sendMessage("navigate");
+ await extension.awaitMessage("tabUpdated");
+ let eventCount = await extension.awaitMessage("onNavigatedFired");
+ is(eventCount, 1, "The expected number of events were fired.");
+
+ extension.sendMessage("reload");
+ await extension.awaitMessage("tabUpdated");
+ eventCount = await extension.awaitMessage("onNavigatedFired");
+ is(eventCount, 2, "The expected number of events were fired.");
+
+ // do a reload after the listener has been removed, do not expect a message to be sent
+ extension.sendMessage("reload");
+ await extension.awaitMessage("tabUpdated");
+
+ await closeToolboxForTab(tab);
+
+ await extension.unload();
+
+ BrowserTestUtils.removeTab(tab);
+});
+
+/**
+ * Test for `chrome.devtools.network.getHAR()` API
+ */
+add_task(async function test_devtools_network_get_har() {
+ let tab = await BrowserTestUtils.openNewForegroundTab(
+ gBrowser,
+ "http://mochi.test:8888/"
+ );
+ let extension = ExtensionTestUtils.loadExtension(extData);
+
+ await extension.startup();
+ await extension.awaitMessage("ready");
+
+ // Open the Toolbox
+ const toolbox = await openToolboxForTab(tab);
+
+ info("Wait the devtools page load");
+ await extension.awaitMessage("devtools-page-loaded");
+
+ // Get HAR, it should be empty since no data collected yet.
+ const getHAREmptyPromise = extension.awaitMessage("getHAR-result");
+ extension.sendMessage("getHAR");
+ const getHAREmptyResult = await getHAREmptyPromise;
+ is(getHAREmptyResult.entries.length, 0, "HAR log should be empty");
+
+ // Reload the page to collect some HTTP requests.
+ await navigateToolboxTarget(extension, toolbox);
+
+ // Get HAR, it should not be empty now.
+ const getHARPromise = extension.awaitMessage("getHAR-result");
+ extension.sendMessage("getHAR");
+ const getHARResult = await getHARPromise;
+ is(getHARResult.entries.length, 1, "HAR log should not be empty");
+
+ // Select the Net panel and reload page again.
+ await toolbox.selectTool("netmonitor");
+ await navigateToolboxTarget(extension, toolbox);
+
+ // Get HAR again, it should not be empty even if
+ // the Network panel is selected now.
+ const getHAREmptyPromiseWithPanel = extension.awaitMessage("getHAR-result");
+ extension.sendMessage("getHAR");
+ const emptyResultWithPanel = await getHAREmptyPromiseWithPanel;
+ is(emptyResultWithPanel.entries.length, 1, "HAR log should not be empty");
+
+ // Shutdown
+ await closeToolboxForTab(tab);
+
+ await extension.unload();
+
+ BrowserTestUtils.removeTab(tab);
+});
+
+/**
+ * Test for `chrome.devtools.network.onRequestFinished()` API
+ */
+add_task(async function test_devtools_network_on_request_finished() {
+ let tab = await BrowserTestUtils.openNewForegroundTab(
+ gBrowser,
+ "http://mochi.test:8888/"
+ );
+ let extension = ExtensionTestUtils.loadExtension(extData);
+
+ await extension.startup();
+ await extension.awaitMessage("ready");
+
+ // Open the Toolbox
+ const toolbox = await openToolboxForTab(tab);
+
+ info("Wait the devtools page load");
+ await extension.awaitMessage("devtools-page-loaded");
+
+ // Wait the extension to subscribe the onRequestFinished listener.
+ await extension.sendMessage("addOnRequestFinishedListener");
+
+ // Reload the page
+ await navigateToolboxTarget(extension, toolbox);
+
+ info("Wait for an onRequestFinished event");
+ await extension.awaitMessage("onRequestFinished");
+
+ // Wait for response content being fetched.
+ info("Wait for request.getBody results");
+ let [callbackRes, promiseRes] = await Promise.all([
+ extension.awaitMessage("onRequestFinished-callbackExecuted"),
+ extension.awaitMessage("onRequestFinished-promiseResolved"),
+ ]);
+
+ ok(
+ callbackRes[0].startsWith("<html>"),
+ "The expected content has been retrieved."
+ );
+ is(
+ callbackRes[1],
+ "text/html; charset=utf-8",
+ "The expected content has been retrieved."
+ );
+ is(
+ promiseRes[0],
+ callbackRes[0],
+ "The resolved value is equal to the one received in the callback API mode"
+ );
+ is(
+ promiseRes[1],
+ callbackRes[1],
+ "The resolved value is equal to the one received in the callback API mode"
+ );
+
+ // Shutdown
+ await closeToolboxForTab(tab);
+
+ await extension.unload();
+
+ BrowserTestUtils.removeTab(tab);
+});