Bug 1419336 - Update tests; r=nchevobbe
MozReview-Commit-ID: 4EEUWLufth8
--- a/devtools/client/webconsole/new-console-output/test/mochitest/browser.ini
+++ b/devtools/client/webconsole/new-console-output/test/mochitest/browser.ini
@@ -2,16 +2,17 @@
tags = devtools
subsuite = devtools
support-files =
code_bundle_invalidmap.js
code_bundle_invalidmap.js.map
code_bundle_nosource.js
code_bundle_nosource.js.map
head.js
+ sjs_slow-response-test-server.sjs
source-mapped.css
source-mapped.css.map
source-mapped.scss
test_bug_1010953_cspro.html
test_bug_1010953_cspro.html^headers^
test_bug_1247459_violation.html
test_bug_770099_violation.html
test_bug_770099_violation.html^headers^
--- a/devtools/client/webconsole/new-console-output/test/mochitest/browser_webconsole_network_messages_expand.js
+++ b/devtools/client/webconsole/new-console-output/test/mochitest/browser_webconsole_network_messages_expand.js
@@ -12,92 +12,272 @@ const XHR_PREF = "devtools.webconsole.fi
Services.prefs.setBoolPref(NET_PREF, false);
Services.prefs.setBoolPref(XHR_PREF, true);
registerCleanupFunction(() => {
Services.prefs.clearUserPref(NET_PREF);
Services.prefs.clearUserPref(XHR_PREF);
});
+let tabs = [{
+ id: "headers",
+ testEmpty: testEmptyHeaders,
+ testContent: testHeaders,
+}, {
+ id: "cookies",
+ testEmpty: testEmptyCookies,
+ testContent: testCookies,
+}, {
+ id: "params",
+ testEmpty: testEmptyParams,
+ testContent: testParams,
+}, {
+ id: "response",
+ testEmpty: testEmptyResponse,
+ testContent: testResponse,
+}, {
+ id: "timings",
+ testEmpty: testEmptyTimings,
+ testContent: testTimings,
+}, {
+ id: "stack-trace",
+ testEmpty: testEmptyStackTrace,
+ testContent: testStackTrace,
+}];
+
+/**
+ * Main test for checking HTTP logs in the Console panel.
+ */
add_task(async function task() {
const hud = await openNewTabAndConsole(TEST_URI);
-
const currentTab = gBrowser.selectedTab;
let target = TargetFactory.forTab(currentTab);
+
+ // Execute XHR and expand it after all network
+ // update events are received. Consequently,
+ // check out content of all (HTTP details) tabs.
+ await openRequestAfterUpdates(target, hud);
+
+ // Test proper UI update when request is opened.
+ // For every tab (with HTTP details):
+ // 1. Execute long-time request
+ // 2. Expand the net log before the request finishes (set default tab)
+ // 3. Check the default tab empty content
+ // 4. Wait till the request finishes
+ // 5. Check content of all tabs
+ for (let tab of tabs) {
+ await openRequestBeforeUpdates(target, hud, tab);
+ }
+});
+
+async function openRequestAfterUpdates(target, hud) {
let toolbox = gDevTools.getToolbox(target);
+ let xhrUrl = TEST_PATH + "sjs_slow-response-test-server.sjs";
+ let message = waitForMessage(hud, xhrUrl);
+
// Fire an XHR POST request.
- await ContentTask.spawn(gBrowser.selectedBrowser, null, function () {
- content.wrappedJSObject.testXhrPost();
+ ContentTask.spawn(gBrowser.selectedBrowser, null, function () {
+ content.wrappedJSObject.testXhrPostSlowResponse();
});
- info("XHR executed");
+ let { node: messageNode } = await message;
+
+ info("Network message found.");
await waitForRequestUpdates(toolbox);
- let xhrUrl = TEST_PATH + "test-data.json";
- let messageNode = await waitFor(() => findMessage(hud, xhrUrl));
+ let payload = waitForPayloadReady(toolbox);
+
+ // Expand network log
let urlNode = messageNode.querySelector(".url");
+ urlNode.click();
+
+ await payload;
+ await testNetworkMessage(toolbox, messageNode);
+}
+
+async function openRequestBeforeUpdates(target, hud, tab) {
+ let toolbox = gDevTools.getToolbox(target);
+
+ hud.jsterm.clearOutput(true);
+
+ let xhrUrl = TEST_PATH + "sjs_slow-response-test-server.sjs";
+ let message = waitForMessage(hud, xhrUrl);
+
+ // Fire an XHR POST request.
+ ContentTask.spawn(gBrowser.selectedBrowser, null, function () {
+ content.wrappedJSObject.testXhrPostSlowResponse();
+ });
+
+ let { node: messageNode } = await message;
+
info("Network message found.");
- let updates = waitForPayloadReady(toolbox);
+ let updates = waitForRequestUpdates(toolbox);
+ let payload = waitForPayloadReady(toolbox);
+
+ // Set the default panel.
+ const state = hud.ui.newConsoleOutput.getStore().getState();
+ state.ui.networkMessageActiveTabId = tab.id;
// Expand network log
+ let urlNode = messageNode.querySelector(".url");
urlNode.click();
+ // Make sure the current tab is the expected one.
+ let currentTab = messageNode.querySelector(`#${tab.id}-tab`);
+ is(currentTab.getAttribute("aria-selected"), "true",
+ "The correct tab is selected");
+
+ // The tab should be empty now.
+ tab.testEmpty(messageNode);
+
+ // Wait till all updates and payload are received.
await updates;
- await testNetworkMessage(messageNode);
-});
+ await payload;
+
+ // Test content of the default tab.
+ await tab.testContent(messageNode);
+
+ // Test all tabs in the network log.
+ await testNetworkMessage(toolbox, messageNode);
+}
-async function testNetworkMessage(messageNode) {
- let headersTab = messageNode.querySelector("#headers-tab");
- let cookiesTab = messageNode.querySelector("#cookies-tab");
- let paramsTab = messageNode.querySelector("#params-tab");
- let responseTab = messageNode.querySelector("#response-tab");
- let timingsTab = messageNode.querySelector("#timings-tab");
+// Panel testing helpers
+
+async function testNetworkMessage(toolbox, messageNode) {
+ await testHeaders(messageNode);
+ await testCookies(messageNode);
+ await testParams(messageNode);
+ await testResponse(messageNode);
+ await testTimings(messageNode);
+ await testStackTrace(messageNode);
+ await waitForLazyRequests(toolbox);
+}
+
+// Headers
+
+function testEmptyHeaders(messageNode) {
+ let emptyNotice = messageNode.querySelector("#headers-panel .empty-notice");
+ ok(emptyNotice, "Headers tab is empty");
+}
+async function testHeaders(messageNode) {
+ let headersTab = messageNode.querySelector("#headers-tab");
ok(headersTab, "Headers tab is available");
+
+ // Select Headers tab and check the content.
+ headersTab.click();
+ await waitUntil(() => {
+ return !!messageNode.querySelector("#headers-panel .headers-overview");
+ });
+}
+
+// Cookies
+
+function testEmptyCookies(messageNode) {
+ let emptyNotice = messageNode.querySelector("#cookies-panel .empty-notice");
+ ok(emptyNotice, "Cookies tab is empty");
+}
+
+async function testCookies(messageNode) {
+ let cookiesTab = messageNode.querySelector("#cookies-tab");
ok(cookiesTab, "Cookies tab is available");
+
+ // Select tab and check the content.
+ cookiesTab.click();
+ await waitUntil(() => {
+ return !!messageNode.querySelector("#cookies-panel .treeValueCell");
+ });
+}
+
+// Params
+
+function testEmptyParams(messageNode) {
+ let emptyNotice = messageNode.querySelector("#params-panel .empty-notice");
+ ok(emptyNotice, "Params tab is empty");
+}
+
+async function testParams(messageNode) {
+ let paramsTab = messageNode.querySelector("#params-tab");
ok(paramsTab, "Params tab is available");
- ok(responseTab, "Response tab is available");
- ok(timingsTab, "Timings tab is available");
-
- // Headers tab should be selected by default, so just check its content.
- let headersContent = messageNode.querySelector(
- "#headers-panel .headers-overview");
- ok(headersContent, "Headers content is available");
// Select Params tab and check the content. CodeMirror initialization
// is delayed to prevent UI freeze, so wait for a little while.
paramsTab.click();
let paramsPanel = messageNode.querySelector("#params-panel");
await waitForSourceEditor(paramsPanel);
let paramsContent = messageNode.querySelector(
"#params-panel .panel-container .CodeMirror");
ok(paramsContent, "Params content is available");
ok(paramsContent.textContent.includes("Hello world!"), "Post body is correct");
+}
+
+// Response
+
+function testEmptyResponse(messageNode) {
+ let panel = messageNode.querySelector("#response-panel .tab-panel");
+ is(panel.textContent, "", "Cookies tab is empty");
+}
+
+async function testResponse(messageNode) {
+ let responseTab = messageNode.querySelector("#response-tab");
+ ok(responseTab, "Response tab is available");
// Select Response tab and check the content. CodeMirror initialization
// is delayed, so again wait for a little while.
responseTab.click();
let responsePanel = messageNode.querySelector("#response-panel");
await waitForSourceEditor(responsePanel);
let responseContent = messageNode.querySelector(
"#response-panel .editor-row-container .CodeMirror");
ok(responseContent, "Response content is available");
ok(responseContent.textContent, "Response text is available");
+}
+
+// Timings
+
+function testEmptyTimings(messageNode) {
+ let panel = messageNode.querySelector("#timings-panel .tab-panel");
+ is(panel.textContent, "", "Timings tab is empty");
+}
+
+async function testTimings(messageNode) {
+ let timingsTab = messageNode.querySelector("#timings-tab");
+ ok(timingsTab, "Timings tab is available");
// Select Timings tab and check the content.
timingsTab.click();
let timingsContent = messageNode.querySelector(
"#timings-panel .timings-container .timings-label");
ok(timingsContent, "Timings content is available");
ok(timingsContent.textContent, "Timings text is available");
}
+// Stack Trace
+
+function testEmptyStackTrace(messageNode) {
+ let panel = messageNode.querySelector("#stack-trace-panel .stack-trace");
+ is(panel.textContent, "", "StackTrace tab is empty");
+}
+
+async function testStackTrace(messageNode) {
+ let stackTraceTab = messageNode.querySelector("#stack-trace-tab");
+ ok(stackTraceTab, "StackTrace tab is available");
+
+ // Select Timings tab and check the content.
+ stackTraceTab.click();
+ await waitUntil(() => {
+ return !!messageNode.querySelector("#stack-trace-panel .frame-link");
+ });
+}
+
+// Waiting helpers
+
async function waitForPayloadReady(toolbox) {
let {ui} = toolbox.getCurrentPanel().hud;
return new Promise(resolve => {
ui.jsterm.hud.on("network-request-payload-ready", () => {
info("network-request-payload-ready received");
resolve();
});
});
@@ -113,8 +293,16 @@ async function waitForRequestUpdates(too
let {ui} = toolbox.getCurrentPanel().hud;
return new Promise(resolve => {
ui.jsterm.hud.on("network-message-updated", () => {
info("network-message-updated received");
resolve();
});
});
}
+
+async function waitForLazyRequests(toolbox) {
+ let {ui} = toolbox.getCurrentPanel().hud;
+ let proxy = ui.jsterm.hud.proxy;
+ return waitUntil(() => {
+ return !proxy.networkDataProvider.lazyRequestData.size;
+ });
+}
new file mode 100644
--- /dev/null
+++ b/devtools/client/webconsole/new-console-output/test/mochitest/sjs_slow-response-test-server.sjs
@@ -0,0 +1,19 @@
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+
+const { classes: Cc, interfaces: Ci } = Components;
+
+function handleRequest(request, response) {
+ response.processAsync();
+
+ let timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
+ timer.initWithCallback(() => {
+ // to avoid garbage collection
+ timer = null;
+ response.setStatusLine(request.httpVersion, 200, "OK");
+ response.setHeader("Content-Type", "text/plain", false);
+ response.setHeader("Set-Cookie", "foo=bar; Max-Age=10; HttpOnly", true);
+ response.write("Some response data");
+ response.finish();
+ }, 300, Ci.nsITimer.TYPE_ONE_SHOT); // Make sure this request takes a few hundred ms.
+}
--- a/devtools/client/webconsole/new-console-output/test/mochitest/test-network-request.html
+++ b/devtools/client/webconsole/new-console-output/test/mochitest/test-network-request.html
@@ -2,17 +2,17 @@
- License, v. 2.0. If a copy of the MPL was not distributed with this
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
<!DOCTYPE HTML>
<html dir="ltr" xml:lang="en-US" lang="en-US">
<head>
<meta charset="utf-8">
<title>Console HTTP test page</title>
<script type="text/javascript">
- /* exported testXhrGet, testXhrWarn, testXhrPost */
+ /* exported testXhrGet, testXhrWarn, testXhrPost, testXhrPostSlowResponse */
"use strict";
function makeXhr(method, url, requestBody, callback) {
let xmlhttp = new XMLHttpRequest();
xmlhttp.open(method, url, true);
xmlhttp.onreadystatechange = function () {
if (callback && xmlhttp.readyState == 4) {
callback();
@@ -27,16 +27,20 @@
function testXhrWarn(callback) {
makeXhr("get", "http://example.com/browser/devtools/client/netmonitor/test/sjs_cors-test-server.sjs", null, callback);
}
function testXhrPost(callback) {
makeXhr("post", "test-data.json", "Hello world!", callback);
}
+
+ function testXhrPostSlowResponse(callback) {
+ makeXhr("post", "sjs_slow-response-test-server.sjs", "Hello world!", callback);
+ }
</script>
</head>
<body>
<h1>Heads Up Display HTTP Logging Testpage</h1>
<h2>This page is used to test the HTTP logging.</h2>
<form action="https://example.com/browser/devtools/client/webconsole/test/test-network-request.html" method="post">
<input name="name" type="text" value="foo bar"><br>