From 5f8de423f190bbb79a62f804151bc24824fa32d8 Mon Sep 17 00:00:00 2001 From: "Matt A. Tobin" Date: Fri, 2 Feb 2018 04:16:08 -0500 Subject: Add m-esr52 at 52.6.0 --- devtools/shared/webconsole/test/chrome.ini | 41 +++ devtools/shared/webconsole/test/common.js | 345 +++++++++++++++++++++ .../shared/webconsole/test/console-test-worker.js | 16 + devtools/shared/webconsole/test/data.json | 3 + devtools/shared/webconsole/test/data.json^headers^ | 3 + .../shared/webconsole/test/helper_serviceworker.js | 19 ++ .../webconsole/test/network_requests_iframe.html | 61 ++++ .../shared/webconsole/test/sandboxed_iframe.html | 8 + devtools/shared/webconsole/test/test_basics.html | 80 +++++ .../test/test_bug819670_getter_throws.html | 76 +++++ .../webconsole/test/test_cached_messages.html | 230 ++++++++++++++ .../webconsole/test/test_commands_other.html | 83 +++++ .../test/test_commands_registration.html | 191 ++++++++++++ .../test/test_console_serviceworker.html | 157 ++++++++++ .../test/test_console_serviceworker_cached.html | 117 +++++++ .../webconsole/test/test_console_styling.html | 126 ++++++++ .../shared/webconsole/test/test_consoleapi.html | 233 ++++++++++++++ .../webconsole/test/test_consoleapi_innerID.html | 164 ++++++++++ devtools/shared/webconsole/test/test_file_uri.html | 106 +++++++ devtools/shared/webconsole/test/test_jsterm.html | 309 ++++++++++++++++++ .../webconsole/test/test_jsterm_autocomplete.html | 183 +++++++++++ .../webconsole/test/test_jsterm_cd_iframe.html | 223 +++++++++++++ .../webconsole/test/test_jsterm_last_result.html | 130 ++++++++ .../webconsole/test/test_jsterm_queryselector.html | 134 ++++++++ .../shared/webconsole/test/test_network_get.html | 260 ++++++++++++++++ .../webconsole/test/test_network_longstring.html | 293 +++++++++++++++++ .../shared/webconsole/test/test_network_post.html | 272 ++++++++++++++++ .../test/test_network_security-hpkp.html | 108 +++++++ .../test/test_network_security-hsts.html | 100 ++++++ .../webconsole/test/test_nsiconsolemessage.html | 74 +++++ .../shared/webconsole/test/test_object_actor.html | 178 +++++++++++ .../test/test_object_actor_native_getters.html | 106 +++++++ ...t_object_actor_native_getters_lenient_this.html | 79 +++++ .../shared/webconsole/test/test_page_errors.html | 186 +++++++++++ devtools/shared/webconsole/test/test_reflow.html | 94 ++++++ devtools/shared/webconsole/test/test_throw.html | 93 ++++++ devtools/shared/webconsole/test/unit/.eslintrc.js | 6 + .../test/unit/test_js_property_provider.js | 170 ++++++++++ .../webconsole/test/unit/test_network_helper.js | 47 +++ .../test/unit/test_security-info-certificate.js | 68 ++++ .../test/unit/test_security-info-parser.js | 64 ++++ .../unit/test_security-info-protocol-version.js | 54 ++++ .../test/unit/test_security-info-state.js | 100 ++++++ .../test/unit/test_security-info-static-hpkp.js | 47 +++ .../unit/test_security-info-weakness-reasons.js | 47 +++ .../shared/webconsole/test/unit/test_throttle.js | 140 +++++++++ devtools/shared/webconsole/test/unit/xpcshell.ini | 17 + 47 files changed, 5641 insertions(+) create mode 100644 devtools/shared/webconsole/test/chrome.ini create mode 100644 devtools/shared/webconsole/test/common.js create mode 100644 devtools/shared/webconsole/test/console-test-worker.js create mode 100644 devtools/shared/webconsole/test/data.json create mode 100644 devtools/shared/webconsole/test/data.json^headers^ create mode 100644 devtools/shared/webconsole/test/helper_serviceworker.js create mode 100644 devtools/shared/webconsole/test/network_requests_iframe.html create mode 100644 devtools/shared/webconsole/test/sandboxed_iframe.html create mode 100644 devtools/shared/webconsole/test/test_basics.html create mode 100644 devtools/shared/webconsole/test/test_bug819670_getter_throws.html create mode 100644 devtools/shared/webconsole/test/test_cached_messages.html create mode 100644 devtools/shared/webconsole/test/test_commands_other.html create mode 100644 devtools/shared/webconsole/test/test_commands_registration.html create mode 100644 devtools/shared/webconsole/test/test_console_serviceworker.html create mode 100644 devtools/shared/webconsole/test/test_console_serviceworker_cached.html create mode 100644 devtools/shared/webconsole/test/test_console_styling.html create mode 100644 devtools/shared/webconsole/test/test_consoleapi.html create mode 100644 devtools/shared/webconsole/test/test_consoleapi_innerID.html create mode 100644 devtools/shared/webconsole/test/test_file_uri.html create mode 100644 devtools/shared/webconsole/test/test_jsterm.html create mode 100644 devtools/shared/webconsole/test/test_jsterm_autocomplete.html create mode 100644 devtools/shared/webconsole/test/test_jsterm_cd_iframe.html create mode 100644 devtools/shared/webconsole/test/test_jsterm_last_result.html create mode 100644 devtools/shared/webconsole/test/test_jsterm_queryselector.html create mode 100644 devtools/shared/webconsole/test/test_network_get.html create mode 100644 devtools/shared/webconsole/test/test_network_longstring.html create mode 100644 devtools/shared/webconsole/test/test_network_post.html create mode 100644 devtools/shared/webconsole/test/test_network_security-hpkp.html create mode 100644 devtools/shared/webconsole/test/test_network_security-hsts.html create mode 100644 devtools/shared/webconsole/test/test_nsiconsolemessage.html create mode 100644 devtools/shared/webconsole/test/test_object_actor.html create mode 100644 devtools/shared/webconsole/test/test_object_actor_native_getters.html create mode 100644 devtools/shared/webconsole/test/test_object_actor_native_getters_lenient_this.html create mode 100644 devtools/shared/webconsole/test/test_page_errors.html create mode 100644 devtools/shared/webconsole/test/test_reflow.html create mode 100644 devtools/shared/webconsole/test/test_throw.html create mode 100644 devtools/shared/webconsole/test/unit/.eslintrc.js create mode 100644 devtools/shared/webconsole/test/unit/test_js_property_provider.js create mode 100644 devtools/shared/webconsole/test/unit/test_network_helper.js create mode 100644 devtools/shared/webconsole/test/unit/test_security-info-certificate.js create mode 100644 devtools/shared/webconsole/test/unit/test_security-info-parser.js create mode 100644 devtools/shared/webconsole/test/unit/test_security-info-protocol-version.js create mode 100644 devtools/shared/webconsole/test/unit/test_security-info-state.js create mode 100644 devtools/shared/webconsole/test/unit/test_security-info-static-hpkp.js create mode 100644 devtools/shared/webconsole/test/unit/test_security-info-weakness-reasons.js create mode 100644 devtools/shared/webconsole/test/unit/test_throttle.js create mode 100644 devtools/shared/webconsole/test/unit/xpcshell.ini (limited to 'devtools/shared/webconsole/test') diff --git a/devtools/shared/webconsole/test/chrome.ini b/devtools/shared/webconsole/test/chrome.ini new file mode 100644 index 000000000..ae867b821 --- /dev/null +++ b/devtools/shared/webconsole/test/chrome.ini @@ -0,0 +1,41 @@ +[DEFAULT] +tags = devtools +support-files = + common.js + data.json + data.json^headers^ + helper_serviceworker.js + network_requests_iframe.html + sandboxed_iframe.html + console-test-worker.js + !/browser/base/content/test/general/browser_star_hsts.sjs + !/browser/base/content/test/general/pinning_headers.sjs + +[test_basics.html] +[test_bug819670_getter_throws.html] +[test_cached_messages.html] +[test_commands_other.html] +[test_commands_registration.html] +[test_consoleapi.html] +[test_consoleapi_innerID.html] +[test_console_serviceworker.html] +[test_console_serviceworker_cached.html] +[test_console_styling.html] +[test_file_uri.html] +[test_reflow.html] +[test_jsterm.html] +[test_jsterm_autocomplete.html] +[test_jsterm_cd_iframe.html] +[test_jsterm_last_result.html] +[test_jsterm_queryselector.html] +[test_network_get.html] +[test_network_longstring.html] +[test_network_post.html] +[test_network_security-hpkp.html] +[test_network_security-hsts.html] +[test_nsiconsolemessage.html] +[test_object_actor.html] +[test_object_actor_native_getters.html] +[test_object_actor_native_getters_lenient_this.html] +[test_page_errors.html] +[test_throw.html] diff --git a/devtools/shared/webconsole/test/common.js b/devtools/shared/webconsole/test/common.js new file mode 100644 index 000000000..b6649bc44 --- /dev/null +++ b/devtools/shared/webconsole/test/common.js @@ -0,0 +1,345 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ +/* vim: set ft= javascript ts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * 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/. */ + +"use strict"; + +var {classes: Cc, interfaces: Ci, utils: Cu} = Components; + +const XHTML_NS = "http://www.w3.org/1999/xhtml"; + +// This gives logging to stdout for tests +var {console} = Cu.import("resource://gre/modules/Console.jsm", {}); + +var {require} = Cu.import("resource://devtools/shared/Loader.jsm", {}); +var Services = require("Services"); +var WebConsoleUtils = require("devtools/client/webconsole/utils").Utils; +var {Task} = require("devtools/shared/task"); + +var ConsoleAPIStorage = Cc["@mozilla.org/consoleAPI-storage;1"] + .getService(Ci.nsIConsoleAPIStorage); +var {DebuggerServer} = require("devtools/server/main"); +var {DebuggerClient, ObjectClient} = require("devtools/shared/client/main"); + +var {ConsoleServiceListener, ConsoleAPIListener} = + require("devtools/server/actors/utils/webconsole-utils"); + +function initCommon() +{ + // Services.prefs.setBoolPref("devtools.debugger.log", true); +} + +function initDebuggerServer() +{ + if (!DebuggerServer.initialized) { + DebuggerServer.init(); + DebuggerServer.addBrowserActors(); + } + DebuggerServer.allowChromeProcess = true; +} + +function connectToDebugger(aCallback) +{ + initCommon(); + initDebuggerServer(); + + let transport = DebuggerServer.connectPipe(); + let client = new DebuggerClient(transport); + + let dbgState = { dbgClient: client }; + client.connect().then(response => aCallback(dbgState, response)); +} + +function attachConsole(aListeners, aCallback) { + _attachConsole(aListeners, aCallback); +} +function attachConsoleToTab(aListeners, aCallback) { + _attachConsole(aListeners, aCallback, true); +} +function attachConsoleToWorker(aListeners, aCallback) { + _attachConsole(aListeners, aCallback, true, true); +} + +function _attachConsole(aListeners, aCallback, aAttachToTab, aAttachToWorker) +{ + function _onAttachConsole(aState, aResponse, aWebConsoleClient) + { + if (aResponse.error) { + console.error("attachConsole failed: " + aResponse.error + " " + + aResponse.message); + } + + aState.client = aWebConsoleClient; + + aCallback(aState, aResponse); + } + + connectToDebugger(function _onConnect(aState, aResponse) { + if (aResponse.error) { + console.error("client.connect() failed: " + aResponse.error + " " + + aResponse.message); + aCallback(aState, aResponse); + return; + } + + if (aAttachToTab) { + aState.dbgClient.listTabs(function _onListTabs(aResponse) { + if (aResponse.error) { + console.error("listTabs failed: " + aResponse.error + " " + + aResponse.message); + aCallback(aState, aResponse); + return; + } + let tab = aResponse.tabs[aResponse.selected]; + aState.dbgClient.attachTab(tab.actor, function (response, tabClient) { + if (aAttachToWorker) { + let workerName = "console-test-worker.js#" + new Date().getTime(); + var worker = new Worker(workerName); + // Keep a strong reference to the Worker to avoid it being + // GCd during the test (bug 1237492). + aState._worker_ref = worker; + worker.addEventListener("message", function listener() { + worker.removeEventListener("message", listener); + tabClient.listWorkers(function (response) { + let worker = response.workers.filter(w => w.url == workerName)[0]; + if (!worker) { + console.error("listWorkers failed. Unable to find the " + + "worker actor\n"); + return; + } + tabClient.attachWorker(worker.actor, function (response, workerClient) { + if (!workerClient || response.error) { + console.error("attachWorker failed. No worker client or " + + " error: " + response.error); + return; + } + workerClient.attachThread({}, function (aResponse) { + aState.actor = workerClient.consoleActor; + aState.dbgClient.attachConsole(workerClient.consoleActor, aListeners, + _onAttachConsole.bind(null, aState)); + }); + }); + }); + }); + } else { + aState.actor = tab.consoleActor; + aState.dbgClient.attachConsole(tab.consoleActor, aListeners, + _onAttachConsole.bind(null, aState)); + } + }); + }); + } else { + aState.dbgClient.getProcess().then(response => { + aState.dbgClient.attachTab(response.form.actor, function () { + let consoleActor = response.form.consoleActor; + aState.actor = consoleActor; + aState.dbgClient.attachConsole(consoleActor, aListeners, + _onAttachConsole.bind(null, aState)); + }); + }); + } + }); +} + +function closeDebugger(aState, aCallback) +{ + aState.dbgClient.close().then(aCallback); + aState.dbgClient = null; + aState.client = null; +} + +function checkConsoleAPICalls(consoleCalls, expectedConsoleCalls) +{ + is(consoleCalls.length, expectedConsoleCalls.length, + "received correct number of console calls"); + expectedConsoleCalls.forEach(function (aMessage, aIndex) { + info("checking received console call #" + aIndex); + checkConsoleAPICall(consoleCalls[aIndex], expectedConsoleCalls[aIndex]); + }); +} + +function checkConsoleAPICall(aCall, aExpected) +{ + if (aExpected.level != "trace" && aExpected.arguments) { + is(aCall.arguments.length, aExpected.arguments.length, + "number of arguments"); + } + + checkObject(aCall, aExpected); +} + +function checkObject(aObject, aExpected) +{ + for (let name of Object.keys(aExpected)) + { + let expected = aExpected[name]; + let value = aObject[name]; + checkValue(name, value, expected); + } +} + +function checkValue(aName, aValue, aExpected) +{ + if (aExpected === null) { + ok(!aValue, "'" + aName + "' is null"); + } + else if (aValue === undefined) { + ok(false, "'" + aName + "' is undefined"); + } + else if (aValue === null) { + ok(false, "'" + aName + "' is null"); + } + else if (typeof aExpected == "string" || typeof aExpected == "number" || + typeof aExpected == "boolean") { + is(aValue, aExpected, "property '" + aName + "'"); + } + else if (aExpected instanceof RegExp) { + ok(aExpected.test(aValue), aName + ": " + aExpected + " matched " + aValue); + } + else if (Array.isArray(aExpected)) { + info("checking array for property '" + aName + "'"); + checkObject(aValue, aExpected); + } + else if (typeof aExpected == "object") { + info("checking object for property '" + aName + "'"); + checkObject(aValue, aExpected); + } +} + +function checkHeadersOrCookies(aArray, aExpected) +{ + let foundHeaders = {}; + + for (let elem of aArray) { + if (!(elem.name in aExpected)) { + continue; + } + foundHeaders[elem.name] = true; + info("checking value of header " + elem.name); + checkValue(elem.name, elem.value, aExpected[elem.name]); + } + + for (let header in aExpected) { + if (!(header in foundHeaders)) { + ok(false, header + " was not found"); + } + } +} + +function checkRawHeaders(aText, aExpected) +{ + let headers = aText.split(/\r\n|\n|\r/); + let arr = []; + for (let header of headers) { + let index = header.indexOf(": "); + if (index < 0) { + continue; + } + arr.push({ + name: header.substr(0, index), + value: header.substr(index + 2) + }); + } + + checkHeadersOrCookies(arr, aExpected); +} + +var gTestState = {}; + +function runTests(aTests, aEndCallback) +{ + function* driver() + { + let lastResult, sendToNext; + for (let i = 0; i < aTests.length; i++) { + gTestState.index = i; + let fn = aTests[i]; + info("will run test #" + i + ": " + fn.name); + lastResult = fn(sendToNext, lastResult); + sendToNext = yield lastResult; + } + yield aEndCallback(sendToNext, lastResult); + } + gTestState.driver = driver(); + return gTestState.driver.next(); +} + +function nextTest(aMessage) +{ + return gTestState.driver.next(aMessage); +} + +function withFrame(url) { + return new Promise(resolve => { + let iframe = document.createElement("iframe"); + iframe.onload = function () { + resolve(iframe); + }; + iframe.src = url; + document.body.appendChild(iframe); + }); +} + +function navigateFrame(iframe, url) { + return new Promise(resolve => { + iframe.onload = function () { + resolve(iframe); + }; + iframe.src = url; + }); +} + +function forceReloadFrame(iframe) { + return new Promise(resolve => { + iframe.onload = function () { + resolve(iframe); + }; + iframe.contentWindow.location.reload(true); + }); +} + +function withActiveServiceWorker(win, url, scope) { + let opts = {}; + if (scope) { + opts.scope = scope; + } + return win.navigator.serviceWorker.register(url, opts).then(swr => { + if (swr.active) { + return swr; + } + + // Unfortunately we can't just use navigator.serviceWorker.ready promise + // here. If the service worker is for a scope that does not cover the window + // then the ready promise will never resolve. Instead monitor the service + // workers state change events to determine when its activated. + return new Promise(resolve => { + let sw = swr.waiting || swr.installing; + sw.addEventListener("statechange", function stateHandler(evt) { + if (sw.state === "activated") { + sw.removeEventListener("statechange", stateHandler); + resolve(swr); + } + }); + }); + }); +} + +function messageServiceWorker(win, scope, message) { + return win.navigator.serviceWorker.getRegistration(scope).then(swr => { + return new Promise(resolve => { + win.navigator.serviceWorker.onmessage = evt => { + resolve(); + }; + let sw = swr.active || swr.waiting || swr.installing; + sw.postMessage({ type: "PING", message: message }); + }); + }); +} + +function unregisterServiceWorker(win) { + return win.navigator.serviceWorker.ready.then(swr => { + return swr.unregister(); + }); +} diff --git a/devtools/shared/webconsole/test/console-test-worker.js b/devtools/shared/webconsole/test/console-test-worker.js new file mode 100644 index 000000000..881eab0b8 --- /dev/null +++ b/devtools/shared/webconsole/test/console-test-worker.js @@ -0,0 +1,16 @@ +"use strict"; + +function f() { + var a = 1; + var b = 2; + var c = 3; +} + +self.onmessage = function (event) { + if (event.data == "ping") { + f(); + postMessage("pong"); + } +}; + +postMessage("load"); diff --git a/devtools/shared/webconsole/test/data.json b/devtools/shared/webconsole/test/data.json new file mode 100644 index 000000000..d46085c12 --- /dev/null +++ b/devtools/shared/webconsole/test/data.json @@ -0,0 +1,3 @@ +{ id: "test JSON data", myArray: [ "foo", "bar", "baz", "biff" ], + veryLong: "foo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo bar" +} diff --git a/devtools/shared/webconsole/test/data.json^headers^ b/devtools/shared/webconsole/test/data.json^headers^ new file mode 100644 index 000000000..bb6b45500 --- /dev/null +++ b/devtools/shared/webconsole/test/data.json^headers^ @@ -0,0 +1,3 @@ +Content-Type: application/json +x-very-long: Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse a ipsum massa. Phasellus at elit dictum libero laoreet sagittis. Phasellus condimentum ultricies imperdiet. Nam eu ligula justo, ut tincidunt quam. Etiam sollicitudin, tortor sed egestas blandit, sapien sem tincidunt nulla, eu luctus libero odio quis leo. Nam elit massa, mattis quis blandit ac, facilisis vitae arcu. Donec vitae dictum neque. Proin ornare nisl at lectus commodo iaculis eget eget est. Quisque scelerisque vestibulum quam sed interdum. +x-very-short: hello world diff --git a/devtools/shared/webconsole/test/helper_serviceworker.js b/devtools/shared/webconsole/test/helper_serviceworker.js new file mode 100644 index 000000000..633f3e09b --- /dev/null +++ b/devtools/shared/webconsole/test/helper_serviceworker.js @@ -0,0 +1,19 @@ +console.log("script evaluation"); + +addEventListener("install", function (evt) { + console.log("install event"); +}); + +addEventListener("activate", function (evt) { + console.log("activate event"); +}); + +addEventListener("fetch", function (evt) { + console.log("fetch event: " + evt.request.url); + evt.respondWith(new Response("Hello world")); +}); + +addEventListener("message", function (evt) { + console.log("message event: " + evt.data.message); + evt.source.postMessage({ type: "PONG" }); +}); diff --git a/devtools/shared/webconsole/test/network_requests_iframe.html b/devtools/shared/webconsole/test/network_requests_iframe.html new file mode 100644 index 000000000..9147b6720 --- /dev/null +++ b/devtools/shared/webconsole/test/network_requests_iframe.html @@ -0,0 +1,61 @@ + + + + + Console HTTP test page + + + + +

Web Console HTTP Logging Testpage

+

This page is used to test the HTTP logging.

+ +
+
+
+
+ + diff --git a/devtools/shared/webconsole/test/sandboxed_iframe.html b/devtools/shared/webconsole/test/sandboxed_iframe.html new file mode 100644 index 000000000..55a6224b5 --- /dev/null +++ b/devtools/shared/webconsole/test/sandboxed_iframe.html @@ -0,0 +1,8 @@ + +Sandboxed iframe + + + + diff --git a/devtools/shared/webconsole/test/test_basics.html b/devtools/shared/webconsole/test/test_basics.html new file mode 100644 index 000000000..fa54557ae --- /dev/null +++ b/devtools/shared/webconsole/test/test_basics.html @@ -0,0 +1,80 @@ + + + + + Basic Web Console Actor tests + + + + + +

Basic Web Console Actor tests

+ + + + diff --git a/devtools/shared/webconsole/test/test_bug819670_getter_throws.html b/devtools/shared/webconsole/test/test_bug819670_getter_throws.html new file mode 100644 index 000000000..1b45c2d88 --- /dev/null +++ b/devtools/shared/webconsole/test/test_bug819670_getter_throws.html @@ -0,0 +1,76 @@ + + + + + Test for Bug 819670 - Web console object inspection does not handle native getters throwing very well + + + + + +

Test for Bug 819670 - Web console object inspection does not handle native getters throwing very well

+ + + + diff --git a/devtools/shared/webconsole/test/test_cached_messages.html b/devtools/shared/webconsole/test/test_cached_messages.html new file mode 100644 index 000000000..210543ca3 --- /dev/null +++ b/devtools/shared/webconsole/test/test_cached_messages.html @@ -0,0 +1,230 @@ + + + + + Test for cached messages + + + + + +

Test for cached messages

+ + + + + + diff --git a/devtools/shared/webconsole/test/test_commands_other.html b/devtools/shared/webconsole/test/test_commands_other.html new file mode 100644 index 000000000..47d1142c9 --- /dev/null +++ b/devtools/shared/webconsole/test/test_commands_other.html @@ -0,0 +1,83 @@ + + + + + Test for the other command helpers + + + + + +

Test for the querySelector / querySelectorAll helpers

+ + + + diff --git a/devtools/shared/webconsole/test/test_commands_registration.html b/devtools/shared/webconsole/test/test_commands_registration.html new file mode 100644 index 000000000..2a68f7cdc --- /dev/null +++ b/devtools/shared/webconsole/test/test_commands_registration.html @@ -0,0 +1,191 @@ + + + + + Test for Web Console commands registration. + + + + + +

Test for Web Console commands registration.

+

+ + + + + diff --git a/devtools/shared/webconsole/test/test_console_serviceworker.html b/devtools/shared/webconsole/test/test_console_serviceworker.html new file mode 100644 index 000000000..83d728d92 --- /dev/null +++ b/devtools/shared/webconsole/test/test_console_serviceworker.html @@ -0,0 +1,157 @@ + + + + + Test for the Console API and Service Workers + + + + + +

Test for the Console API and Service Workers

+ + + + diff --git a/devtools/shared/webconsole/test/test_console_serviceworker_cached.html b/devtools/shared/webconsole/test/test_console_serviceworker_cached.html new file mode 100644 index 000000000..5aab64d7f --- /dev/null +++ b/devtools/shared/webconsole/test/test_console_serviceworker_cached.html @@ -0,0 +1,117 @@ + + + + + Test for getCachedMessages and Service Workers + + + + + +

Test for getCachedMessages and Service Workers

+ + + + diff --git a/devtools/shared/webconsole/test/test_console_styling.html b/devtools/shared/webconsole/test/test_console_styling.html new file mode 100644 index 000000000..97d21bcb9 --- /dev/null +++ b/devtools/shared/webconsole/test/test_console_styling.html @@ -0,0 +1,126 @@ + + + + + Test for console.log styling with %c + + + + + +

Test for console.log styling with %c

+ + + + diff --git a/devtools/shared/webconsole/test/test_consoleapi.html b/devtools/shared/webconsole/test/test_consoleapi.html new file mode 100644 index 000000000..848db9cb6 --- /dev/null +++ b/devtools/shared/webconsole/test/test_consoleapi.html @@ -0,0 +1,233 @@ + + + + + Test for the Console API + + + + + +

Test for the Console API

+ + + + diff --git a/devtools/shared/webconsole/test/test_consoleapi_innerID.html b/devtools/shared/webconsole/test/test_consoleapi_innerID.html new file mode 100644 index 000000000..b477a36be --- /dev/null +++ b/devtools/shared/webconsole/test/test_consoleapi_innerID.html @@ -0,0 +1,164 @@ + + + + + Test for the innerID property of the Console API + + + + + +

Test for the Console API

+ + + + diff --git a/devtools/shared/webconsole/test/test_file_uri.html b/devtools/shared/webconsole/test/test_file_uri.html new file mode 100644 index 000000000..f5aada5b1 --- /dev/null +++ b/devtools/shared/webconsole/test/test_file_uri.html @@ -0,0 +1,106 @@ + + + + + Test for file activity tracking + + + + + +

Test for file activity tracking

+ + + + diff --git a/devtools/shared/webconsole/test/test_jsterm.html b/devtools/shared/webconsole/test/test_jsterm.html new file mode 100644 index 000000000..b6eefad4b --- /dev/null +++ b/devtools/shared/webconsole/test/test_jsterm.html @@ -0,0 +1,309 @@ + + + + + Test for JavaScript terminal functionality + + + + + +

Test for JavaScript terminal functionality

+ + + + + + diff --git a/devtools/shared/webconsole/test/test_jsterm_autocomplete.html b/devtools/shared/webconsole/test/test_jsterm_autocomplete.html new file mode 100644 index 000000000..0e32e1a63 --- /dev/null +++ b/devtools/shared/webconsole/test/test_jsterm_autocomplete.html @@ -0,0 +1,183 @@ + + + + + Test for JavaScript terminal functionality + + + + + +

Test for JavaScript terminal autocomplete functionality

+ + + + diff --git a/devtools/shared/webconsole/test/test_jsterm_cd_iframe.html b/devtools/shared/webconsole/test/test_jsterm_cd_iframe.html new file mode 100644 index 000000000..7207a00a1 --- /dev/null +++ b/devtools/shared/webconsole/test/test_jsterm_cd_iframe.html @@ -0,0 +1,223 @@ + + + + + Test for the cd() function + + + + + +

Test for the cd() function

+ + + + + + diff --git a/devtools/shared/webconsole/test/test_jsterm_last_result.html b/devtools/shared/webconsole/test/test_jsterm_last_result.html new file mode 100644 index 000000000..e90ce14ed --- /dev/null +++ b/devtools/shared/webconsole/test/test_jsterm_last_result.html @@ -0,0 +1,130 @@ + + + + + Test for the $_ getter + + + + + +

Test for the $_ getter

+ + + + + + diff --git a/devtools/shared/webconsole/test/test_jsterm_queryselector.html b/devtools/shared/webconsole/test/test_jsterm_queryselector.html new file mode 100644 index 000000000..b75ee399c --- /dev/null +++ b/devtools/shared/webconsole/test/test_jsterm_queryselector.html @@ -0,0 +1,134 @@ + + + + + Test for the querySelector / querySelectorAll helpers + + + + + +

Test for the querySelector / querySelectorAll helpers

+ + + + diff --git a/devtools/shared/webconsole/test/test_network_get.html b/devtools/shared/webconsole/test/test_network_get.html new file mode 100644 index 000000000..710c9b0d7 --- /dev/null +++ b/devtools/shared/webconsole/test/test_network_get.html @@ -0,0 +1,260 @@ + + + + + Test for the network actor (GET request) + + + + + +

Test for the network actor (GET request)

+ + + + + + diff --git a/devtools/shared/webconsole/test/test_network_longstring.html b/devtools/shared/webconsole/test/test_network_longstring.html new file mode 100644 index 000000000..d55136896 --- /dev/null +++ b/devtools/shared/webconsole/test/test_network_longstring.html @@ -0,0 +1,293 @@ + + + + + Test that the network actor uses the LongStringActor + + + + + +

Test that the network actor uses the LongStringActor

+ + + + + + diff --git a/devtools/shared/webconsole/test/test_network_post.html b/devtools/shared/webconsole/test/test_network_post.html new file mode 100644 index 000000000..d96b9b0b7 --- /dev/null +++ b/devtools/shared/webconsole/test/test_network_post.html @@ -0,0 +1,272 @@ + + + + + Test for the network actor (POST request) + + + + + +

Test for the network actor (POST request)

+ + + + + + diff --git a/devtools/shared/webconsole/test/test_network_security-hpkp.html b/devtools/shared/webconsole/test/test_network_security-hpkp.html new file mode 100644 index 000000000..55e2621a8 --- /dev/null +++ b/devtools/shared/webconsole/test/test_network_security-hpkp.html @@ -0,0 +1,108 @@ + + + + + Test for the network actor (HPKP detection) + + + + + +

Test for the network actor (HPKP detection)

+ + + + + + diff --git a/devtools/shared/webconsole/test/test_network_security-hsts.html b/devtools/shared/webconsole/test/test_network_security-hsts.html new file mode 100644 index 000000000..f69244d8d --- /dev/null +++ b/devtools/shared/webconsole/test/test_network_security-hsts.html @@ -0,0 +1,100 @@ + + + + + Test for the network actor (HSTS detection) + + + + + +

Test for the network actor (HSTS detection)

+ + + + + + diff --git a/devtools/shared/webconsole/test/test_nsiconsolemessage.html b/devtools/shared/webconsole/test/test_nsiconsolemessage.html new file mode 100644 index 000000000..ef8b8067e --- /dev/null +++ b/devtools/shared/webconsole/test/test_nsiconsolemessage.html @@ -0,0 +1,74 @@ + + + + + Test for nsIConsoleMessages + + + + + +

Make sure that nsIConsoleMessages are logged. See bug 859756.

+ + + + diff --git a/devtools/shared/webconsole/test/test_object_actor.html b/devtools/shared/webconsole/test/test_object_actor.html new file mode 100644 index 000000000..09176a5aa --- /dev/null +++ b/devtools/shared/webconsole/test/test_object_actor.html @@ -0,0 +1,178 @@ + + + + + Test for the object actor + + + + + +

Test for the object actor

+ + + + diff --git a/devtools/shared/webconsole/test/test_object_actor_native_getters.html b/devtools/shared/webconsole/test/test_object_actor_native_getters.html new file mode 100644 index 000000000..e22eb8cd5 --- /dev/null +++ b/devtools/shared/webconsole/test/test_object_actor_native_getters.html @@ -0,0 +1,106 @@ + + + + + Test for the native getters in object actors + + + + + +

Test for the native getters in object actors

+ + + + diff --git a/devtools/shared/webconsole/test/test_object_actor_native_getters_lenient_this.html b/devtools/shared/webconsole/test/test_object_actor_native_getters_lenient_this.html new file mode 100644 index 000000000..c4197a5b8 --- /dev/null +++ b/devtools/shared/webconsole/test/test_object_actor_native_getters_lenient_this.html @@ -0,0 +1,79 @@ + + + + + Test that WebIDL attributes with the LenientThis extended attribute + do not appear in the wrong objects + + + + + +

Test for the native getters in object actors

+ + + + diff --git a/devtools/shared/webconsole/test/test_page_errors.html b/devtools/shared/webconsole/test/test_page_errors.html new file mode 100644 index 000000000..19e5ba4b4 --- /dev/null +++ b/devtools/shared/webconsole/test/test_page_errors.html @@ -0,0 +1,186 @@ + + + + + Test for page errors + + + + + +

Test for page errors

+ + + + diff --git a/devtools/shared/webconsole/test/test_reflow.html b/devtools/shared/webconsole/test/test_reflow.html new file mode 100644 index 000000000..2ac2ca509 --- /dev/null +++ b/devtools/shared/webconsole/test/test_reflow.html @@ -0,0 +1,94 @@ + + + + + Test for the Reflow Activity + + + + + +

Test for reflow events

+ + + + diff --git a/devtools/shared/webconsole/test/test_throw.html b/devtools/shared/webconsole/test/test_throw.html new file mode 100644 index 000000000..7d7ea7b31 --- /dev/null +++ b/devtools/shared/webconsole/test/test_throw.html @@ -0,0 +1,93 @@ + + + + + Web Console throw tests + + + + + +

Web Console throw tests

+ + + + diff --git a/devtools/shared/webconsole/test/unit/.eslintrc.js b/devtools/shared/webconsole/test/unit/.eslintrc.js new file mode 100644 index 000000000..59adf410a --- /dev/null +++ b/devtools/shared/webconsole/test/unit/.eslintrc.js @@ -0,0 +1,6 @@ +"use strict"; + +module.exports = { + // Extend from the common devtools xpcshell eslintrc config. + "extends": "../../../../.eslintrc.xpcshell.js" +}; diff --git a/devtools/shared/webconsole/test/unit/test_js_property_provider.js b/devtools/shared/webconsole/test/unit/test_js_property_provider.js new file mode 100644 index 000000000..c360cf96d --- /dev/null +++ b/devtools/shared/webconsole/test/unit/test_js_property_provider.js @@ -0,0 +1,170 @@ +/* -*- js-indent-level: 2; indent-tabs-mode: nil -*- */ +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/publicdomain/zero/1.0/ + +"use strict"; +const { require } = Components.utils.import("resource://devtools/shared/Loader.jsm", {}); +const { FallibleJSPropertyProvider: JSPropertyProvider } = + require("devtools/shared/webconsole/js-property-provider"); + +Components.utils.import("resource://gre/modules/jsdebugger.jsm"); +addDebuggerToGlobal(this); + +function run_test() { + const testArray = `var testArray = [ + {propA: "A"}, + { + propB: "B", + propC: [ + "D" + ] + }, + [ + {propE: "E"} + ] + ]`; + + const testObject = 'var testObject = {"propA": [{"propB": "B"}]}'; + const testHyphenated = 'var testHyphenated = {"prop-A": "res-A"}'; + const testLet = "let foobar = {a: ''}; const blargh = {a: 1};"; + + let sandbox = Components.utils.Sandbox("http://example.com"); + let dbg = new Debugger; + let dbgObject = dbg.addDebuggee(sandbox); + let dbgEnv = dbgObject.asEnvironment(); + Components.utils.evalInSandbox(testArray, sandbox); + Components.utils.evalInSandbox(testObject, sandbox); + Components.utils.evalInSandbox(testHyphenated, sandbox); + Components.utils.evalInSandbox(testLet, sandbox); + + do_print("Running tests with dbgObject"); + runChecks(dbgObject, null); + + do_print("Running tests with dbgEnv"); + runChecks(null, dbgEnv); + +} + +function runChecks(dbgObject, dbgEnv) { + do_print("Test that suggestions are given for 'this'"); + let results = JSPropertyProvider(dbgObject, dbgEnv, "t"); + test_has_result(results, "this"); + + if (dbgObject != null) { + do_print("Test that suggestions are given for 'this.'"); + results = JSPropertyProvider(dbgObject, dbgEnv, "this."); + test_has_result(results, "testObject"); + + do_print("Test that no suggestions are given for 'this.this'"); + results = JSPropertyProvider(dbgObject, dbgEnv, "this.this"); + test_has_no_results(results); + } + + do_print("Testing lexical scope issues (Bug 1207868)"); + results = JSPropertyProvider(dbgObject, dbgEnv, "foobar"); + test_has_result(results, "foobar"); + + results = JSPropertyProvider(dbgObject, dbgEnv, "foobar."); + test_has_result(results, "a"); + + results = JSPropertyProvider(dbgObject, dbgEnv, "blargh"); + test_has_result(results, "blargh"); + + results = JSPropertyProvider(dbgObject, dbgEnv, "blargh."); + test_has_result(results, "a"); + + do_print("Test that suggestions are given for 'foo[n]' where n is an integer."); + results = JSPropertyProvider(dbgObject, dbgEnv, "testArray[0]."); + test_has_result(results, "propA"); + + do_print("Test that suggestions are given for multidimensional arrays."); + results = JSPropertyProvider(dbgObject, dbgEnv, "testArray[2][0]."); + test_has_result(results, "propE"); + + do_print("Test that suggestions are given for nested arrays."); + results = JSPropertyProvider(dbgObject, dbgEnv, "testArray[1].propC[0]."); + test_has_result(results, "indexOf"); + + do_print("Test that suggestions are given for literal arrays."); + results = JSPropertyProvider(dbgObject, dbgEnv, "[1,2,3]."); + test_has_result(results, "indexOf"); + + do_print("Test that suggestions are given for literal arrays with newlines."); + results = JSPropertyProvider(dbgObject, dbgEnv, "[1,2,3,\n4\n]."); + test_has_result(results, "indexOf"); + + do_print("Test that suggestions are given for literal strings."); + results = JSPropertyProvider(dbgObject, dbgEnv, "'foo'."); + test_has_result(results, "charAt"); + results = JSPropertyProvider(dbgObject, dbgEnv, '"foo".'); + test_has_result(results, "charAt"); + results = JSPropertyProvider(dbgObject, dbgEnv, "`foo`."); + test_has_result(results, "charAt"); + results = JSPropertyProvider(dbgObject, dbgEnv, "'[1,2,3]'."); + test_has_result(results, "charAt"); + + do_print("Test that suggestions are not given for syntax errors."); + results = JSPropertyProvider(dbgObject, dbgEnv, "'foo\""); + do_check_null(results); + results = JSPropertyProvider(dbgObject, dbgEnv, "[1,',2]"); + do_check_null(results); + results = JSPropertyProvider(dbgObject, dbgEnv, "'[1,2]."); + do_check_null(results); + results = JSPropertyProvider(dbgObject, dbgEnv, "'foo'.."); + do_check_null(results); + + do_print("Test that suggestions are not given without a dot."); + results = JSPropertyProvider(dbgObject, dbgEnv, "'foo'"); + test_has_no_results(results); + results = JSPropertyProvider(dbgObject, dbgEnv, "[1,2,3]"); + test_has_no_results(results); + results = JSPropertyProvider(dbgObject, dbgEnv, "[1,2,3].\n'foo'"); + test_has_no_results(results); + + do_print("Test that suggestions are not given for numeric literals."); + results = JSPropertyProvider(dbgObject, dbgEnv, "1."); + do_check_null(results); + + do_print("Test that suggestions are not given for index that's out of bounds."); + results = JSPropertyProvider(dbgObject, dbgEnv, "testArray[10]."); + do_check_null(results); + + do_print("Test that no suggestions are given if an index is not numerical somewhere in the chain."); + results = JSPropertyProvider(dbgObject, dbgEnv, "testArray[0]['propC'][0]."); + do_check_null(results); + + results = JSPropertyProvider(dbgObject, dbgEnv, "testObject['propA'][0]."); + do_check_null(results); + + results = JSPropertyProvider(dbgObject, dbgEnv, "testArray[0]['propC']."); + do_check_null(results); + + results = JSPropertyProvider(dbgObject, dbgEnv, "testArray[][1]."); + do_check_null(results); + + do_print("Test that suggestions are not given if there is an hyphen in the chain."); + results = JSPropertyProvider(dbgObject, dbgEnv, "testHyphenated['prop-A']."); + do_check_null(results); +} + +/** + * A helper that ensures an empty array of results were found. + * @param Object aResults + * The results returned by JSPropertyProvider. + */ +function test_has_no_results(aResults) { + do_check_neq(aResults, null); + do_check_eq(aResults.matches.length, 0); +} +/** + * A helper that ensures (required) results were found. + * @param Object aResults + * The results returned by JSPropertyProvider. + * @param String aRequiredSuggestion + * A suggestion that must be found from the results. + */ +function test_has_result(aResults, aRequiredSuggestion) { + do_check_neq(aResults, null); + do_check_true(aResults.matches.length > 0); + do_check_true(aResults.matches.indexOf(aRequiredSuggestion) !== -1); +} diff --git a/devtools/shared/webconsole/test/unit/test_network_helper.js b/devtools/shared/webconsole/test/unit/test_network_helper.js new file mode 100644 index 000000000..3a43ff432 --- /dev/null +++ b/devtools/shared/webconsole/test/unit/test_network_helper.js @@ -0,0 +1,47 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; +var Cu = Components.utils; +const { require } = Cu.import("resource://devtools/shared/Loader.jsm", {}); + +Object.defineProperty(this, "NetworkHelper", { + get: function () { + return require("devtools/shared/webconsole/network-helper"); + }, + configurable: true, + writeable: false, + enumerable: true +}); + +function run_test() { + test_isTextMimeType(); +} + +function test_isTextMimeType() { + do_check_eq(NetworkHelper.isTextMimeType("text/plain"), true); + do_check_eq(NetworkHelper.isTextMimeType("application/javascript"), true); + do_check_eq(NetworkHelper.isTextMimeType("application/json"), true); + do_check_eq(NetworkHelper.isTextMimeType("text/css"), true); + do_check_eq(NetworkHelper.isTextMimeType("text/html"), true); + do_check_eq(NetworkHelper.isTextMimeType("image/svg+xml"), true); + do_check_eq(NetworkHelper.isTextMimeType("application/xml"), true); + + // Test custom JSON subtype + do_check_eq(NetworkHelper.isTextMimeType("application/vnd.tent.posts-feed.v0+json"), true); + do_check_eq(NetworkHelper.isTextMimeType("application/vnd.tent.posts-feed.v0-json"), true); + // Test custom XML subtype + do_check_eq(NetworkHelper.isTextMimeType("application/vnd.tent.posts-feed.v0+xml"), true); + do_check_eq(NetworkHelper.isTextMimeType("application/vnd.tent.posts-feed.v0-xml"), false); + // Test case-insensitive + do_check_eq(NetworkHelper.isTextMimeType("application/vnd.BIG-CORP+json"), true); + // Test non-text type + do_check_eq(NetworkHelper.isTextMimeType("image/png"), false); + // Test invalid types + do_check_eq(NetworkHelper.isTextMimeType("application/foo-+json"), false); + do_check_eq(NetworkHelper.isTextMimeType("application/-foo+json"), false); + do_check_eq(NetworkHelper.isTextMimeType("application/foo--bar+json"), false); + + // Test we do not cause internal errors with unoptimized regex. Bug 961097 + do_check_eq(NetworkHelper.isTextMimeType("application/vnd.google.safebrowsing-chunk"), false); +} diff --git a/devtools/shared/webconsole/test/unit/test_security-info-certificate.js b/devtools/shared/webconsole/test/unit/test_security-info-certificate.js new file mode 100644 index 000000000..be223d87e --- /dev/null +++ b/devtools/shared/webconsole/test/unit/test_security-info-certificate.js @@ -0,0 +1,68 @@ +/* vim: set ft=javascript ts=2 et sw=2 tw=80: */ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ +"use strict"; + +// Tests that NetworkHelper.parseCertificateInfo parses certificate information +// correctly. + +const { require } = Components.utils.import("resource://devtools/shared/Loader.jsm", {}); + +Object.defineProperty(this, "NetworkHelper", { + get: function () { + return require("devtools/shared/webconsole/network-helper"); + }, + configurable: true, + writeable: false, + enumerable: true +}); + +var Ci = Components.interfaces; +const DUMMY_CERT = { + commonName: "cn", + organization: "o", + organizationalUnit: "ou", + issuerCommonName: "issuerCN", + issuerOrganization: "issuerO", + issuerOrganizationUnit: "issuerOU", + sha256Fingerprint: "qwertyuiopoiuytrewq", + sha1Fingerprint: "qwertyuiop", + validity: { + notBeforeLocalDay: "yesterday", + notAfterLocalDay: "tomorrow", + } +}; + +function run_test() { + do_print("Testing NetworkHelper.parseCertificateInfo."); + + let result = NetworkHelper.parseCertificateInfo(DUMMY_CERT); + + // Subject + equal(result.subject.commonName, DUMMY_CERT.commonName, + "Common name is correct."); + equal(result.subject.organization, DUMMY_CERT.organization, + "Organization is correct."); + equal(result.subject.organizationUnit, DUMMY_CERT.organizationUnit, + "Organizational unit is correct."); + + // Issuer + equal(result.issuer.commonName, DUMMY_CERT.issuerCommonName, + "Common name of the issuer is correct."); + equal(result.issuer.organization, DUMMY_CERT.issuerOrganization, + "Organization of the issuer is correct."); + equal(result.issuer.organizationUnit, DUMMY_CERT.issuerOrganizationUnit, + "Organizational unit of the issuer is correct."); + + // Validity + equal(result.validity.start, DUMMY_CERT.validity.notBeforeLocalDay, + "Start of the validity period is correct."); + equal(result.validity.end, DUMMY_CERT.validity.notAfterLocalDay, + "End of the validity period is correct."); + + // Fingerprints + equal(result.fingerprint.sha1, DUMMY_CERT.sha1Fingerprint, + "Certificate SHA1 fingerprint is correct."); + equal(result.fingerprint.sha256, DUMMY_CERT.sha256Fingerprint, + "Certificate SHA256 fingerprint is correct."); +} diff --git a/devtools/shared/webconsole/test/unit/test_security-info-parser.js b/devtools/shared/webconsole/test/unit/test_security-info-parser.js new file mode 100644 index 000000000..a5682e209 --- /dev/null +++ b/devtools/shared/webconsole/test/unit/test_security-info-parser.js @@ -0,0 +1,64 @@ +/* vim: set ft=javascript ts=2 et sw=2 tw=80: */ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ +"use strict"; + +// Test that NetworkHelper.parseSecurityInfo returns correctly formatted object. + +const { require } = Components.utils.import("resource://devtools/shared/Loader.jsm", {}); +Components.utils.import("resource://gre/modules/XPCOMUtils.jsm"); + +Object.defineProperty(this, "NetworkHelper", { + get: function () { + return require("devtools/shared/webconsole/network-helper"); + }, + configurable: true, + writeable: false, + enumerable: true +}); + +var Ci = Components.interfaces; +const wpl = Ci.nsIWebProgressListener; +const MockCertificate = { + commonName: "cn", + organization: "o", + organizationalUnit: "ou", + issuerCommonName: "issuerCN", + issuerOrganization: "issuerO", + issuerOrganizationUnit: "issuerOU", + sha256Fingerprint: "qwertyuiopoiuytrewq", + sha1Fingerprint: "qwertyuiop", + validity: { + notBeforeLocalDay: "yesterday", + notAfterLocalDay: "tomorrow", + } +}; + +const MockSecurityInfo = { + QueryInterface: XPCOMUtils.generateQI([Ci.nsITransportSecurityInfo, + Ci.nsISSLStatusProvider]), + securityState: wpl.STATE_IS_SECURE, + errorCode: 0, + SSLStatus: { + cipherSuite: "TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256", + protocolVersion: 3, // TLS_VERSION_1_2 + serverCert: MockCertificate, + } +}; + +function run_test() { + let result = NetworkHelper.parseSecurityInfo(MockSecurityInfo, {}); + + equal(result.state, "secure", "State is correct."); + + equal(result.cipherSuite, MockSecurityInfo.cipherSuite, + "Cipher suite is correct."); + + equal(result.protocolVersion, "TLSv1.2", "Protocol version is correct."); + + deepEqual(result.cert, NetworkHelper.parseCertificateInfo(MockCertificate), + "Certificate information is correct."); + + equal(result.hpkp, false, "HPKP is false when URI is not available."); + equal(result.hsts, false, "HSTS is false when URI is not available."); +} diff --git a/devtools/shared/webconsole/test/unit/test_security-info-protocol-version.js b/devtools/shared/webconsole/test/unit/test_security-info-protocol-version.js new file mode 100644 index 000000000..b84002131 --- /dev/null +++ b/devtools/shared/webconsole/test/unit/test_security-info-protocol-version.js @@ -0,0 +1,54 @@ +/* vim: set ft=javascript ts=2 et sw=2 tw=80: */ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ +"use strict"; + +// Tests that NetworkHelper.formatSecurityProtocol returns correct +// protocol version strings. + +const { require } = Components.utils.import("resource://devtools/shared/Loader.jsm", {}); + +Object.defineProperty(this, "NetworkHelper", { + get: function () { + return require("devtools/shared/webconsole/network-helper"); + }, + configurable: true, + writeable: false, + enumerable: true +}); + +var Ci = Components.interfaces; +const TEST_CASES = [ + { + description: "TLS_VERSION_1", + input: 1, + expected: "TLSv1" + }, { + description: "TLS_VERSION_1.1", + input: 2, + expected: "TLSv1.1" + }, { + description: "TLS_VERSION_1.2", + input: 3, + expected: "TLSv1.2" + }, { + description: "TLS_VERSION_1.3", + input: 4, + expected: "TLSv1.3" + }, { + description: "invalid version", + input: -1, + expected: "Unknown" + }, +]; + +function run_test() { + do_print("Testing NetworkHelper.formatSecurityProtocol."); + + for (let {description, input, expected} of TEST_CASES) { + do_print("Testing " + description); + + equal(NetworkHelper.formatSecurityProtocol(input), expected, + "Got the expected protocol string."); + } +} diff --git a/devtools/shared/webconsole/test/unit/test_security-info-state.js b/devtools/shared/webconsole/test/unit/test_security-info-state.js new file mode 100644 index 000000000..efa493a95 --- /dev/null +++ b/devtools/shared/webconsole/test/unit/test_security-info-state.js @@ -0,0 +1,100 @@ +/* vim: set ft=javascript ts=2 et sw=2 tw=80: */ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ +"use strict"; + +// Tests that security info parser gives correct general security state for +// different cases. + +const { require } = Components.utils.import("resource://devtools/shared/Loader.jsm", {}); +Components.utils.import("resource://gre/modules/XPCOMUtils.jsm"); + +Object.defineProperty(this, "NetworkHelper", { + get: function () { + return require("devtools/shared/webconsole/network-helper"); + }, + configurable: true, + writeable: false, + enumerable: true +}); + +var Ci = Components.interfaces; +const wpl = Ci.nsIWebProgressListener; +const MockSecurityInfo = { + QueryInterface: XPCOMUtils.generateQI([Ci.nsITransportSecurityInfo, + Ci.nsISSLStatusProvider]), + securityState: wpl.STATE_IS_BROKEN, + errorCode: 0, + SSLStatus: { + protocolVersion: 3, // nsISSLStatus.TLS_VERSION_1_2 + cipherSuite: "TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256", + } +}; + +function run_test() { + test_nullSecurityInfo(); + test_insecureSecurityInfoWithNSSError(); + test_insecureSecurityInfoWithoutNSSError(); + test_brokenSecurityInfo(); + test_secureSecurityInfo(); +} + +/** + * Test that undefined security information is returns "insecure". + */ +function test_nullSecurityInfo() { + let result = NetworkHelper.parseSecurityInfo(null, {}); + equal(result.state, "insecure", + "state == 'insecure' when securityInfo was undefined"); +} + +/** + * Test that STATE_IS_INSECURE with NSSError returns "broken" + */ +function test_insecureSecurityInfoWithNSSError() { + MockSecurityInfo.securityState = wpl.STATE_IS_INSECURE; + + // Taken from security/manager/ssl/tests/unit/head_psm.js. + MockSecurityInfo.errorCode = -8180; + + let result = NetworkHelper.parseSecurityInfo(MockSecurityInfo, {}); + equal(result.state, "broken", + "state == 'broken' if securityState contains STATE_IS_INSECURE flag AND " + + "errorCode is NSS error."); + + MockSecurityInfo.errorCode = 0; +} + +/** + * Test that STATE_IS_INSECURE without NSSError returns "insecure" + */ +function test_insecureSecurityInfoWithoutNSSError() { + MockSecurityInfo.securityState = wpl.STATE_IS_INSECURE; + + let result = NetworkHelper.parseSecurityInfo(MockSecurityInfo, {}); + equal(result.state, "insecure", + "state == 'insecure' if securityState contains STATE_IS_INSECURE flag BUT " + + "errorCode is not NSS error."); +} + +/** + * Test that STATE_IS_SECURE returns "secure" + */ +function test_secureSecurityInfo() { + MockSecurityInfo.securityState = wpl.STATE_IS_SECURE; + + let result = NetworkHelper.parseSecurityInfo(MockSecurityInfo, {}); + equal(result.state, "secure", + "state == 'secure' if securityState contains STATE_IS_SECURE flag"); +} + +/** + * Test that STATE_IS_BROKEN returns "weak" + */ +function test_brokenSecurityInfo() { + MockSecurityInfo.securityState = wpl.STATE_IS_BROKEN; + + let result = NetworkHelper.parseSecurityInfo(MockSecurityInfo, {}); + equal(result.state, "weak", + "state == 'weak' if securityState contains STATE_IS_BROKEN flag"); +} diff --git a/devtools/shared/webconsole/test/unit/test_security-info-static-hpkp.js b/devtools/shared/webconsole/test/unit/test_security-info-static-hpkp.js new file mode 100644 index 000000000..b76fa141a --- /dev/null +++ b/devtools/shared/webconsole/test/unit/test_security-info-static-hpkp.js @@ -0,0 +1,47 @@ +/* vim: set ft=javascript ts=2 et sw=2 tw=80: */ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ +"use strict"; + +// Test that NetworkHelper.parseSecurityInfo correctly detects static hpkp pins + +const { require } = Components.utils.import("resource://devtools/shared/Loader.jsm", {}); +Components.utils.import("resource://gre/modules/XPCOMUtils.jsm"); +const Services = require("Services"); + +Object.defineProperty(this, "NetworkHelper", { + get: function () { + return require("devtools/shared/webconsole/network-helper"); + }, + configurable: true, + writeable: false, + enumerable: true +}); + +var Ci = Components.interfaces; +const wpl = Ci.nsIWebProgressListener; + +const MockSecurityInfo = { + QueryInterface: XPCOMUtils.generateQI([Ci.nsITransportSecurityInfo, + Ci.nsISSLStatusProvider]), + securityState: wpl.STATE_IS_SECURE, + errorCode: 0, + SSLStatus: { + cipherSuite: "TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256", + protocolVersion: 3, // TLS_VERSION_1_2 + serverCert: { + validity: {} + }, + } +}; + +const MockHttpInfo = { + hostname: "include-subdomains.pinning.example.com", + private: false, +}; + +function run_test() { + Services.prefs.setIntPref("security.cert_pinning.enforcement_level", 1); + let result = NetworkHelper.parseSecurityInfo(MockSecurityInfo, MockHttpInfo); + equal(result.hpkp, true, "Static HPKP detected."); +} diff --git a/devtools/shared/webconsole/test/unit/test_security-info-weakness-reasons.js b/devtools/shared/webconsole/test/unit/test_security-info-weakness-reasons.js new file mode 100644 index 000000000..f91d8049e --- /dev/null +++ b/devtools/shared/webconsole/test/unit/test_security-info-weakness-reasons.js @@ -0,0 +1,47 @@ +/* vim: set ft=javascript ts=2 et sw=2 tw=80: */ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ +"use strict"; + +// Tests that NetworkHelper.getReasonsForWeakness returns correct reasons for +// weak requests. + +const { require } = Components.utils.import("resource://devtools/shared/Loader.jsm", {}); + +Object.defineProperty(this, "NetworkHelper", { + get: function () { + return require("devtools/shared/webconsole/network-helper"); + }, + configurable: true, + writeable: false, + enumerable: true +}); + +var Ci = Components.interfaces; +const wpl = Ci.nsIWebProgressListener; +const TEST_CASES = [ + { + description: "weak cipher", + input: wpl.STATE_IS_BROKEN | wpl.STATE_USES_WEAK_CRYPTO, + expected: ["cipher"] + }, { + description: "only STATE_IS_BROKEN flag", + input: wpl.STATE_IS_BROKEN, + expected: [] + }, { + description: "only STATE_IS_SECURE flag", + input: wpl.STATE_IS_SECURE, + expected: [] + }, +]; + +function run_test() { + do_print("Testing NetworkHelper.getReasonsForWeakness."); + + for (let {description, input, expected} of TEST_CASES) { + do_print("Testing " + description); + + deepEqual(NetworkHelper.getReasonsForWeakness(input), expected, + "Got the expected reasons for weakness."); + } +} diff --git a/devtools/shared/webconsole/test/unit/test_throttle.js b/devtools/shared/webconsole/test/unit/test_throttle.js new file mode 100644 index 000000000..fa8b26b61 --- /dev/null +++ b/devtools/shared/webconsole/test/unit/test_throttle.js @@ -0,0 +1,140 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +const Cu = Components.utils; +const Cc = Components.classes; +const Ci = Components.interfaces; +const { require } = Cu.import("resource://devtools/shared/Loader.jsm", {}); +const promise = require("promise"); +const { NetworkThrottleManager } = + require("devtools/shared/webconsole/throttle"); +const nsIScriptableInputStream = Ci.nsIScriptableInputStream; + +function TestStreamListener() { + this.state = "initial"; +} +TestStreamListener.prototype = { + onStartRequest: function() { + this.setState("start"); + }, + + onStopRequest: function() { + this.setState("stop"); + }, + + onDataAvailable: function(request, context, inputStream, offset, count) { + const sin = Components.classes["@mozilla.org/scriptableinputstream;1"] + .createInstance(nsIScriptableInputStream); + sin.init(inputStream); + this.data = sin.read(count); + this.setState("data"); + }, + + setState: function(state) { + this.state = state; + if (this._deferred) { + this._deferred.resolve(state); + this._deferred = null; + } + }, + + onStateChanged: function() { + if (!this._deferred) { + this._deferred = promise.defer(); + } + return this._deferred.promise; + } +}; + +function TestChannel() { + this.state = "initial"; + this.testListener = new TestStreamListener(); + this._throttleQueue = null; +} +TestChannel.prototype = { + QueryInterface: function() { + return this; + }, + + get throttleQueue() { + return this._throttleQueue; + }, + + set throttleQueue(q) { + this._throttleQueue = q; + this.state = "throttled"; + }, + + setNewListener: function(listener) { + this.listener = listener; + this.state = "listener"; + return this.testListener; + }, +}; + +add_task(function*() { + let throttler = new NetworkThrottleManager({ + roundTripTimeMean: 1, + roundTripTimeMax: 1, + downloadBPSMean: 500, + downloadBPSMax: 500, + uploadBPSMean: 500, + uploadBPSMax: 500, + }); + + let uploadChannel = new TestChannel(); + throttler.manageUpload(uploadChannel); + equal(uploadChannel.state, "throttled", + "NetworkThrottleManager set throttleQueue"); + + let downloadChannel = new TestChannel(); + let testListener = downloadChannel.testListener; + + let listener = throttler.manage(downloadChannel); + equal(downloadChannel.state, "listener", + "NetworkThrottleManager called setNewListener"); + + equal(testListener.state, "initial", "test listener in initial state"); + + // This method must be passed through immediately. + listener.onStartRequest(null, null); + equal(testListener.state, "start", "test listener started"); + + const TEST_INPUT = "hi bob"; + + let testStream = Cc["@mozilla.org/storagestream;1"] + .createInstance(Ci.nsIStorageStream); + testStream.init(512, 512); + let out = testStream.getOutputStream(0); + out.write(TEST_INPUT, TEST_INPUT.length); + out.close(); + let testInputStream = testStream.newInputStream(0); + + let activityDistributor = + Cc["@mozilla.org/network/http-activity-distributor;1"] + .getService(Ci.nsIHttpActivityDistributor); + let activitySeen = false; + listener.addActivityCallback(() => activitySeen = true, null, null, null, + activityDistributor + .ACTIVITY_SUBTYPE_RESPONSE_COMPLETE, + null, TEST_INPUT.length, null); + + // onDataAvailable is required to immediately read the data. + listener.onDataAvailable(null, null, testInputStream, 0, 6); + equal(testInputStream.available(), 0, "no more data should be available"); + equal(testListener.state, "start", + "test listener should not have received data"); + equal(activitySeen, false, "activity not distributed yet"); + + let newState = yield testListener.onStateChanged(); + equal(newState, "data", "test listener received data"); + equal(testListener.data, TEST_INPUT, "test listener received all the data"); + equal(activitySeen, true, "activity has been distributed"); + + let onChange = testListener.onStateChanged(); + listener.onStopRequest(null, null, null); + newState = yield onChange; + equal(newState, "stop", "onStateChanged reported"); +}); diff --git a/devtools/shared/webconsole/test/unit/xpcshell.ini b/devtools/shared/webconsole/test/unit/xpcshell.ini new file mode 100644 index 000000000..083950834 --- /dev/null +++ b/devtools/shared/webconsole/test/unit/xpcshell.ini @@ -0,0 +1,17 @@ +[DEFAULT] +tags = devtools +head = +tail = +firefox-appdir = browser +skip-if = toolkit == 'android' +support-files = + +[test_js_property_provider.js] +[test_network_helper.js] +[test_security-info-certificate.js] +[test_security-info-parser.js] +[test_security-info-protocol-version.js] +[test_security-info-state.js] +[test_security-info-static-hpkp.js] +[test_security-info-weakness-reasons.js] +[test_throttle.js] -- cgit v1.2.3