/* Any copyright is dedicated to the Public Domain. http://creativecommons.org/publicdomain/zero/1.0/ */ "use strict"; /** * Test that the network monitor displays all requests in an HTTP authentication * flow. */ const { PromptTestUtils } = ChromeUtils.importESModule( "resource://testing-common/PromptTestUtils.sys.mjs" ); const AUTH_SJS = EXAMPLE_URL + "sjs_auth-test-server.sjs"; const USERNAME = "guest"; const PASSWORD = "guest"; /** * Return a unique URL for the auth server to avoid cached auth responses * causing a different number of network events across test runs. */ function getUniqueAuthURL() { const uuid = Services.uuid.generateUUID().number.slice(1, -1); return AUTH_SJS + "?" + uuid; } function cleanupAuthManager() { const authManager = SpecialPowers.Cc[ "@mozilla.org/network/http-auth-manager;1" ].getService(SpecialPowers.Ci.nsIHttpAuthManager); authManager.clearAll(); } add_task(async function testAuthRequestsDisplayedSeparately() { cleanupAuthManager(); // Bug 2038321: At the moment devtools only displays distinct requests for // each authentication attempt when the following pref is true. await pushPref("network.auth.use_redirect_for_retries", true); const { monitor, tab } = await initNetMonitor(SIMPLE_URL, { requestCount: 1, }); info("Starting test..."); const { store, windowRequire } = monitor.panelWin; const Actions = windowRequire("devtools/client/netmonitor/src/actions/index"); store.dispatch(Actions.batchEnable(false)); const authURL = getUniqueAuthURL(); // Set up the auth dialog handler before triggering the fetch so we don't // miss the prompt. const onAuthHandled = PromptTestUtils.handleNextPrompt( tab.linkedBrowser, { promptType: "promptUserAndPass", modalType: Services.prompt.MODAL_TYPE_TAB, }, { buttonNumClick: 0, loginInput: USERNAME, passwordInput: PASSWORD } ); info("Fetching auth-protected URL to trigger the authentication flow"); await SpecialPowers.spawn(tab.linkedBrowser, [authURL], url => { content.wrappedJSObject.fetch(url); }); info("Waiting for the auth dialog to be handled"); await onAuthHandled; info("Waiting for the 200 response to appear in the network monitor"); await waitUntil(() => store.getState().requests.requests.some(r => r.status === "200") ); await waitForAllNetworkUpdateEvents(); is( store.getState().requests.requests.length, 2, "Both the 401 and the 200 auth requests should be visible in the network monitor" ); const requests = getSortedRequests(store.getState()); is(requests[0].status, "401", "The first request should have status 401"); is(requests[1].status, "200", "The second request should have status 200"); await teardown(monitor); });