summaryrefslogtreecommitdiffstats
path: root/devtools/client/netmonitor/test/browser_net_frame.js
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--devtools/client/netmonitor/test/browser_net_frame.js272
1 files changed, 272 insertions, 0 deletions
diff --git a/devtools/client/netmonitor/test/browser_net_frame.js b/devtools/client/netmonitor/test/browser_net_frame.js
new file mode 100644
index 0000000000..4827a8fbc4
--- /dev/null
+++ b/devtools/client/netmonitor/test/browser_net_frame.js
@@ -0,0 +1,272 @@
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+/**
+ * Tests for all expected requests when an iframe is loading a subdocument.
+ */
+
+const TOP_FILE_NAME = "html_frame-test-page.html";
+const SUB_FILE_NAME = "html_frame-subdocument.html";
+const TOP_URL = EXAMPLE_URL + TOP_FILE_NAME;
+const SUB_URL = EXAMPLE_URL + SUB_FILE_NAME;
+
+const EXPECTED_REQUESTS_TOP = [
+ {
+ method: "GET",
+ url: TOP_URL,
+ causeType: "document",
+ causeUri: null,
+ stack: true,
+ },
+ {
+ method: "GET",
+ url: EXAMPLE_URL + "stylesheet_request",
+ causeType: "stylesheet",
+ causeUri: TOP_URL,
+ stack: false,
+ },
+ {
+ method: "GET",
+ url: EXAMPLE_URL + "img_request",
+ causeType: "img",
+ causeUri: TOP_URL,
+ stack: false,
+ },
+ {
+ method: "GET",
+ url: EXAMPLE_URL + "xhr_request",
+ causeType: "xhr",
+ causeUri: TOP_URL,
+ stack: [{ fn: "performXhrRequest", file: TOP_FILE_NAME, line: 25 }],
+ },
+ {
+ method: "GET",
+ url: EXAMPLE_URL + "fetch_request",
+ causeType: "fetch",
+ causeUri: TOP_URL,
+ stack: [{ fn: "performFetchRequest", file: TOP_FILE_NAME, line: 29 }],
+ },
+ {
+ method: "GET",
+ url: EXAMPLE_URL + "promise_fetch_request",
+ causeType: "fetch",
+ causeUri: TOP_URL,
+ stack: [
+ { fn: "performPromiseFetchRequest", file: TOP_FILE_NAME, line: 41 },
+ {
+ fn: null,
+ file: TOP_FILE_NAME,
+ line: 40,
+ asyncCause: "promise callback",
+ },
+ ],
+ },
+ {
+ method: "GET",
+ url: EXAMPLE_URL + "timeout_fetch_request",
+ causeType: "fetch",
+ causeUri: TOP_URL,
+ stack: [
+ { fn: "performTimeoutFetchRequest", file: TOP_FILE_NAME, line: 43 },
+ {
+ fn: "performPromiseFetchRequest",
+ file: TOP_FILE_NAME,
+ line: 42,
+ asyncCause: "setTimeout handler",
+ },
+ ],
+ },
+ {
+ method: "POST",
+ url: EXAMPLE_URL + "beacon_request",
+ causeType: "beacon",
+ causeUri: TOP_URL,
+ stack: [{ fn: "performBeaconRequest", file: TOP_FILE_NAME, line: 33 }],
+ },
+];
+
+const EXPECTED_REQUESTS_SUB = [
+ {
+ method: "GET",
+ url: SUB_URL,
+ causeType: "subdocument",
+ causeUri: TOP_URL,
+ stack: false,
+ },
+ {
+ method: "GET",
+ url: EXAMPLE_URL + "stylesheet_request",
+ causeType: "stylesheet",
+ causeUri: SUB_URL,
+ stack: false,
+ },
+ {
+ method: "GET",
+ url: EXAMPLE_URL + "img_request",
+ causeType: "img",
+ causeUri: SUB_URL,
+ stack: false,
+ },
+ {
+ method: "GET",
+ url: EXAMPLE_URL + "xhr_request",
+ causeType: "xhr",
+ causeUri: SUB_URL,
+ stack: [{ fn: "performXhrRequest", file: SUB_FILE_NAME, line: 24 }],
+ },
+ {
+ method: "GET",
+ url: EXAMPLE_URL + "fetch_request",
+ causeType: "fetch",
+ causeUri: SUB_URL,
+ stack: [{ fn: "performFetchRequest", file: SUB_FILE_NAME, line: 28 }],
+ },
+ {
+ method: "GET",
+ url: EXAMPLE_URL + "promise_fetch_request",
+ causeType: "fetch",
+ causeUri: SUB_URL,
+ stack: [
+ { fn: "performPromiseFetchRequest", file: SUB_FILE_NAME, line: 40 },
+ {
+ fn: null,
+ file: SUB_FILE_NAME,
+ line: 39,
+ asyncCause: "promise callback",
+ },
+ ],
+ },
+ {
+ method: "GET",
+ url: EXAMPLE_URL + "timeout_fetch_request",
+ causeType: "fetch",
+ causeUri: SUB_URL,
+ stack: [
+ { fn: "performTimeoutFetchRequest", file: SUB_FILE_NAME, line: 42 },
+ {
+ fn: "performPromiseFetchRequest",
+ file: SUB_FILE_NAME,
+ line: 41,
+ asyncCause: "setTimeout handler",
+ },
+ ],
+ },
+ {
+ method: "POST",
+ url: EXAMPLE_URL + "beacon_request",
+ causeType: "beacon",
+ causeUri: SUB_URL,
+ stack: [{ fn: "performBeaconRequest", file: SUB_FILE_NAME, line: 32 }],
+ },
+];
+
+const REQUEST_COUNT =
+ EXPECTED_REQUESTS_TOP.length + EXPECTED_REQUESTS_SUB.length;
+
+add_task(async function () {
+ // the initNetMonitor function clears the network request list after the
+ // page is loaded. That's why we first load a bogus page from SIMPLE_URL,
+ // and only then load the real thing from TOP_URL - we want to catch
+ // all the requests the page is making, not only the XHRs.
+ // We can't use about:blank here, because initNetMonitor checks that the
+ // page has actually made at least one request.
+ const { monitor } = await initNetMonitor(SIMPLE_URL, { requestCount: 1 });
+
+ const { document, store, windowRequire, connector } = monitor.panelWin;
+ const Actions = windowRequire("devtools/client/netmonitor/src/actions/index");
+ const { getDisplayedRequests, getSortedRequests } = windowRequire(
+ "devtools/client/netmonitor/src/selectors/index"
+ );
+
+ store.dispatch(Actions.batchEnable(false));
+
+ await navigateTo(TOP_URL);
+
+ await waitForNetworkEvents(monitor, REQUEST_COUNT);
+
+ is(
+ store.getState().requests.requests.length,
+ REQUEST_COUNT,
+ "All the page events should be recorded."
+ );
+
+ // Fetch stack-trace data from the backend and wait till
+ // all packets are received.
+ const requests = getSortedRequests(store.getState());
+ await Promise.all(
+ requests.map(requestItem =>
+ connector.requestData(requestItem.id, "stackTrace")
+ )
+ );
+
+ // While there is a defined order for requests in each document separately, the requests
+ // from different documents may interleave in various ways that change per test run, so
+ // there is not a single order when considering all the requests together.
+ let currentTop = 0;
+ let currentSub = 0;
+ for (let i = 0; i < REQUEST_COUNT; i++) {
+ const requestItem = getSortedRequests(store.getState())[i];
+
+ const itemUrl = requestItem.url;
+ const itemCauseUri = requestItem.cause.loadingDocumentUri;
+ let spec;
+ if (itemUrl == SUB_URL || itemCauseUri == SUB_URL) {
+ spec = EXPECTED_REQUESTS_SUB[currentSub++];
+ } else {
+ spec = EXPECTED_REQUESTS_TOP[currentTop++];
+ }
+ const { method, url, causeType, causeUri, stack } = spec;
+
+ verifyRequestItemTarget(
+ document,
+ getDisplayedRequests(store.getState()),
+ requestItem,
+ method,
+ url,
+ { cause: { type: causeType, loadingDocumentUri: causeUri } }
+ );
+
+ const { stacktrace } = requestItem;
+ const stackLen = stacktrace ? stacktrace.length : 0;
+
+ if (stack) {
+ ok(stacktrace, `Request #${i} has a stacktrace`);
+ ok(
+ stackLen > 0,
+ `Request #${i} (${causeType}) has a stacktrace with ${stackLen} items`
+ );
+
+ // if "stack" is array, check the details about the top stack frames
+ if (Array.isArray(stack)) {
+ stack.forEach((frame, j) => {
+ is(
+ stacktrace[j].functionName,
+ frame.fn,
+ `Request #${i} has the correct function on JS stack frame #${j}`
+ );
+ is(
+ stacktrace[j].filename.split("/").pop(),
+ frame.file,
+ `Request #${i} has the correct file on JS stack frame #${j}`
+ );
+ is(
+ stacktrace[j].lineNumber,
+ frame.line,
+ `Request #${i} has the correct line number on JS stack frame #${j}`
+ );
+ is(
+ stacktrace[j].asyncCause,
+ frame.asyncCause,
+ `Request #${i} has the correct async cause on JS stack frame #${j}`
+ );
+ });
+ }
+ } else {
+ is(stackLen, 0, `Request #${i} (${causeType}) has an empty stacktrace`);
+ }
+ }
+
+ await teardown(monitor);
+});