From 6bf0a5cb5034a7e684dcc3500e841785237ce2dd Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 7 Apr 2024 19:32:43 +0200 Subject: Adding upstream version 1:115.7.0. Signed-off-by: Daniel Baumann --- .../netmonitor/test/browser_net_initiator.js | 291 +++++++++++++++++++++ 1 file changed, 291 insertions(+) create mode 100644 devtools/client/netmonitor/test/browser_net_initiator.js (limited to 'devtools/client/netmonitor/test/browser_net_initiator.js') diff --git a/devtools/client/netmonitor/test/browser_net_initiator.js b/devtools/client/netmonitor/test/browser_net_initiator.js new file mode 100644 index 0000000000..4082db6fa2 --- /dev/null +++ b/devtools/client/netmonitor/test/browser_net_initiator.js @@ -0,0 +1,291 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; +const { + getUrlBaseName, +} = require("resource://devtools/client/netmonitor/src/utils/request-utils.js"); +/** + * Tests if request initiator is reported correctly. + */ + +const INITIATOR_FILE_NAME = "html_cause-test-page.html"; +const INITIATOR_URL = HTTPS_EXAMPLE_URL + INITIATOR_FILE_NAME; + +const EXPECTED_REQUESTS = [ + { + method: "GET", + url: INITIATOR_URL, + causeType: "document", + causeUri: null, + stack: false, + }, + { + method: "GET", + url: HTTPS_EXAMPLE_URL + "stylesheet_request", + causeType: "stylesheet", + causeUri: INITIATOR_URL, + stack: false, + }, + { + method: "GET", + url: HTTPS_EXAMPLE_URL + "img_request", + causeType: "img", + causeUri: INITIATOR_URL, + stack: false, + }, + { + method: "GET", + url: HTTPS_EXAMPLE_URL + "img_srcset_request", + causeType: "imageset", + causeUri: INITIATOR_URL, + stack: false, + }, + { + method: "GET", + url: HTTPS_EXAMPLE_URL + "xhr_request", + causeType: "xhr", + causeUri: INITIATOR_URL, + stack: [{ fn: "performXhrRequestCallback", file: INITIATOR_URL, line: 32 }], + }, + { + method: "GET", + url: HTTPS_EXAMPLE_URL + "fetch_request", + causeType: "fetch", + causeUri: INITIATOR_URL, + stack: [{ fn: "performFetchRequest", file: INITIATOR_URL, line: 37 }], + }, + { + method: "GET", + url: HTTPS_EXAMPLE_URL + "promise_fetch_request", + causeType: "fetch", + causeUri: INITIATOR_URL, + stack: [ + { + fn: "performPromiseFetchRequestCallback", + file: INITIATOR_URL, + line: 43, + }, + { + fn: "performPromiseFetchRequest", + file: INITIATOR_URL, + line: 42, + asyncCause: "promise callback", + }, + ], + }, + { + method: "GET", + url: HTTPS_EXAMPLE_URL + "timeout_fetch_request", + causeType: "fetch", + causeUri: INITIATOR_URL, + stack: [ + { + fn: "performTimeoutFetchRequestCallback2", + file: INITIATOR_URL, + line: 50, + }, + { + fn: "performTimeoutFetchRequestCallback1", + file: INITIATOR_URL, + line: 49, + asyncCause: "setTimeout handler", + }, + ], + }, + { + method: "GET", + url: HTTPS_EXAMPLE_URL + "favicon_request", + causeType: "img", + causeUri: INITIATOR_URL, + // the favicon request is triggered in FaviconLoader.jsm module, it should + // NOT be shown in the stack (bug 1280266). For now we intentionally + // specify the file and the line number to be properly sorted. + // NOTE: The line number can be an arbitrary number greater than 0. + stack: [ + { + file: "resource:///modules/FaviconLoader.jsm", + line: Number.MAX_SAFE_INTEGER, + }, + ], + }, + { + method: "GET", + url: HTTPS_EXAMPLE_URL + "lazy_img_request", + causeType: "lazy-img", + causeUri: INITIATOR_URL, + stack: false, + }, + { + method: "GET", + url: HTTPS_EXAMPLE_URL + "lazy_img_srcset_request", + causeType: "lazy-imageset", + causeUri: INITIATOR_URL, + stack: false, + }, + { + method: "POST", + url: HTTPS_EXAMPLE_URL + "beacon_request", + causeType: "beacon", + causeUri: INITIATOR_URL, + stack: [{ fn: "performBeaconRequest", file: INITIATOR_URL, line: 82 }], + }, +]; + +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 INITIATOR_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 { tab, monitor } = await initNetMonitor(SIMPLE_URL, { + requestCount: 1, + }); + + const { document, store, windowRequire } = monitor.panelWin; + const Actions = windowRequire("devtools/client/netmonitor/src/actions/index"); + const { getSortedRequests } = windowRequire( + "devtools/client/netmonitor/src/selectors/index" + ); + + store.dispatch(Actions.batchEnable(false)); + + const wait = waitForNetworkEvents(monitor, EXPECTED_REQUESTS.length); + BrowserTestUtils.loadURIString(tab.linkedBrowser, INITIATOR_URL); + + registerFaviconNotifier(tab.linkedBrowser); + + await wait; + + // For all expected requests + for (const [index, { stack }] of EXPECTED_REQUESTS.entries()) { + if (!stack) { + continue; + } + + EventUtils.sendMouseEvent( + { type: "mousedown" }, + document.querySelectorAll( + ".request-list-item .requests-list-initiator-lastframe" + )[index] + ); + + // Clicking on the initiator column should open the Stack Trace panel + const onStackTraceRendered = waitUntil(() => + document.querySelector("#stack-trace-panel .stack-trace .frame-link") + ); + await onStackTraceRendered; + } + + is( + store.getState().requests.requests.length, + EXPECTED_REQUESTS.length, + "All the page events should be recorded." + ); + + validateRequests(EXPECTED_REQUESTS, monitor); + + // Sort the requests by initiator and check the order + EventUtils.sendMouseEvent( + { type: "click" }, + document.querySelector("#requests-list-initiator-button") + ); + + const expectedOrder = EXPECTED_REQUESTS.sort(initiatorSortPredicate).map( + r => { + let isChromeFrames = false; + const lastFrameExists = !!r.stack; + let initiator = ""; + let lineNumber = ""; + if (lastFrameExists) { + const { file, line: _lineNumber } = r.stack[0]; + initiator = getUrlBaseName(file); + lineNumber = ":" + _lineNumber; + isChromeFrames = file.startsWith("resource:///"); + } + const causeStr = lastFrameExists ? " (" + r.causeType + ")" : r.causeType; + return { + initiatorStr: initiator + lineNumber + causeStr, + isChromeFrames, + }; + } + ); + + expectedOrder.forEach((expectedInitiator, i) => { + const request = getSortedRequests(store.getState())[i]; + let initiator; + // In cases of chrome frames, we shouldn't have stack. + if ( + request.cause.stacktraceAvailable && + !expectedInitiator.isChromeFrames + ) { + const { filename, lineNumber } = request.cause.lastFrame; + initiator = + getUrlBaseName(filename) + + ":" + + lineNumber + + " (" + + request.cause.type + + ")"; + } else { + initiator = request.cause.type; + } + + if (expectedInitiator.isChromeFrames) { + todo_is( + initiator, + expectedInitiator.initiatorStr, + `The request #${i} has the expected initiator after sorting` + ); + } else { + is( + initiator, + expectedInitiator.initiatorStr, + `The request #${i} has the expected initiator after sorting` + ); + } + }); + + await teardown(monitor); +}); + +// derived from devtools/client/netmonitor/src/utils/sort-predicates.js +function initiatorSortPredicate(first, second) { + const firstLastFrame = first.stack ? first.stack[0] : null; + const secondLastFrame = second.stack ? second.stack[0] : null; + + let firstInitiator = ""; + let firstInitiatorLineNumber = 0; + + if (firstLastFrame) { + firstInitiator = getUrlBaseName(firstLastFrame.file); + firstInitiatorLineNumber = firstLastFrame.line; + } + + let secondInitiator = ""; + let secondInitiatorLineNumber = 0; + + if (secondLastFrame) { + secondInitiator = getUrlBaseName(secondLastFrame.file); + secondInitiatorLineNumber = secondLastFrame.line; + } + + let result; + // if both initiators don't have a stack trace, compare their causes + if (!firstInitiator && !secondInitiator) { + result = compareValues(first.causeType, second.causeType); + } else if (!firstInitiator || !secondInitiator) { + // if one initiator doesn't have a stack trace but the other does, former should precede the latter + result = compareValues(firstInitiatorLineNumber, secondInitiatorLineNumber); + } else { + result = compareValues(firstInitiator, secondInitiator); + if (result === 0) { + result = compareValues( + firstInitiatorLineNumber, + secondInitiatorLineNumber + ); + } + } + return result; +} -- cgit v1.2.3