зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1381834 - Remove old Console front-end;r=nchevobbe
MozReview-Commit-ID: LiKw2ZMRucL --HG-- extra : rebase_source : c9037d0acedd3416a233f42b7ffac50fc049c709
This commit is contained in:
Родитель
83a3e86872
Коммит
e9bdd93a16
|
@ -99,14 +99,8 @@ Tools.webConsole = {
|
|||
id: "webconsole",
|
||||
accesskey: l10n("webConsoleCmd.accesskey"),
|
||||
ordinal: 2,
|
||||
oldWebConsoleURL: "chrome://devtools/content/webconsole/old/webconsole.xul",
|
||||
newWebConsoleURL: "chrome://devtools/content/webconsole/webconsole.html",
|
||||
get browserConsoleURL() {
|
||||
if (Services.prefs.getBoolPref("devtools.browserconsole.new-frontend-enabled")) {
|
||||
return "chrome://devtools/content/webconsole/browserconsole.xul";
|
||||
}
|
||||
return Tools.webConsole.oldWebConsoleURL;
|
||||
},
|
||||
url: "chrome://devtools/content/webconsole/webconsole.html",
|
||||
browserConsoleURL: "chrome://devtools/content/webconsole/browserconsole.xul",
|
||||
icon: "chrome://devtools/skin/images/tool-webconsole.svg",
|
||||
label: l10n("ToolboxTabWebconsole.label"),
|
||||
menuLabel: l10n("MenuWebconsole.label"),
|
||||
|
@ -136,19 +130,6 @@ Tools.webConsole = {
|
|||
return new WebConsolePanel(iframeWindow, toolbox);
|
||||
}
|
||||
};
|
||||
function switchWebconsole() {
|
||||
if (Services.prefs.getBoolPref("devtools.webconsole.new-frontend-enabled")) {
|
||||
Tools.webConsole.url = Tools.webConsole.newWebConsoleURL;
|
||||
} else {
|
||||
Tools.webConsole.url = Tools.webConsole.oldWebConsoleURL;
|
||||
}
|
||||
}
|
||||
switchWebconsole();
|
||||
|
||||
Services.prefs.addObserver(
|
||||
"devtools.webconsole.new-frontend-enabled",
|
||||
{ observe: switchWebconsole }
|
||||
);
|
||||
|
||||
Tools.jsdebugger = {
|
||||
id: "jsdebugger",
|
||||
|
|
|
@ -372,11 +372,6 @@ OptionsPanel.prototype = {
|
|||
// Labels for these new buttons are nightly only and mostly intended for working on
|
||||
// devtools.
|
||||
let prefDefinitions = [{
|
||||
pref: "devtools.webconsole.new-frontend-enabled",
|
||||
label: L10N.getStr("toolbox.options.enableNewConsole.label"),
|
||||
id: "devtools-new-webconsole",
|
||||
parentId: "webconsole-options"
|
||||
}, {
|
||||
pref: "devtools.debugger.new-debugger-frontend",
|
||||
label: L10N.getStr("toolbox.options.enableNewDebugger.label"),
|
||||
id: "devtools-new-debugger",
|
||||
|
|
|
@ -102,7 +102,6 @@ function setPrefDefaults() {
|
|||
// Bug 1225160 - Using source maps with browser debugging can lead to a crash
|
||||
Services.prefs.setBoolPref("devtools.debugger.source-maps-enabled", false);
|
||||
Services.prefs.setBoolPref("devtools.debugger.new-debugger-frontend", true);
|
||||
Services.prefs.setBoolPref("devtools.webconsole.new-frontend-enabled", true);
|
||||
Services.prefs.setBoolPref("devtools.preference.new-panel-enabled", false);
|
||||
Services.prefs.setBoolPref("layout.css.emulate-moz-box-with-flex", false);
|
||||
}
|
||||
|
|
|
@ -10,7 +10,6 @@ devtools.jar:
|
|||
content/shared/widgets/VariablesView.xul (shared/widgets/VariablesView.xul)
|
||||
content/webconsole/webconsole.html (webconsole/webconsole.html)
|
||||
content/webconsole/browserconsole.xul (webconsole/browserconsole.xul)
|
||||
* content/webconsole/old/webconsole.xul (webconsole/old/webconsole.xul)
|
||||
* content/scratchpad/scratchpad.xul (scratchpad/scratchpad.xul)
|
||||
content/scratchpad/scratchpad.js (scratchpad/scratchpad.js)
|
||||
content/shared/splitview.css (shared/splitview.css)
|
||||
|
|
|
@ -207,7 +207,3 @@ toolbox.sourceMapSourceFailure=Error while fetching an original source: %1$S\nSo
|
|||
# checkbox to enable the new debugger frontend. Displayed only in Nightly and local
|
||||
# builds.
|
||||
toolbox.options.enableNewDebugger.label=Enable new debugger frontend
|
||||
|
||||
# LOCALIZATION NOTE (toolbox.options.enableNewConsole.label): Label of the options panel
|
||||
# checkbox to enable the new console frontend. Displayed only in Nightly and local builds.
|
||||
toolbox.options.enableNewConsole.label=Enable new console frontend
|
||||
|
|
|
@ -1,96 +0,0 @@
|
|||
<!-- 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/. -->
|
||||
<!-- LOCALIZATION NOTE : FILE The correct localization of this file might be to
|
||||
- keep it in English, or another language commonly spoken among web developers.
|
||||
- You want to make that choice consistent across the developer tools.
|
||||
- A good criteria is the language in which you'd find the best
|
||||
- documentation on web development on the web. -->
|
||||
<!ENTITY window.title "Web Console">
|
||||
<!-- LOCALIZATION NOTE (openURL.label): You can see this string in the Web
|
||||
- Console context menu. -->
|
||||
<!ENTITY openURL.label "Open URL in New Tab">
|
||||
<!ENTITY openURL.accesskey "T">
|
||||
<!-- LOCALIZATION NOTE (btnPageNet.label): This string is used for the menu
|
||||
- button that allows users to toggle the network logging output.
|
||||
- This string and the following strings toggle various kinds of output
|
||||
- filters. -->
|
||||
<!ENTITY btnPageNet.label "Net">
|
||||
<!ENTITY btnPageNet.tooltip "Log network access">
|
||||
<!ENTITY btnPageNet.accesskey "N">
|
||||
<!-- LOCALIZATION NOTE (btnPageNet.accesskeyMacOSX): This string is used as
|
||||
- access key for the menu button that allows users to toggle the network
|
||||
- logging output. On MacOSX accesskeys are available with Ctrl-*. Please make
|
||||
- sure you do not use the following letters: A, E, N and P. These are used
|
||||
- for editing commands in text inputs. -->
|
||||
<!ENTITY btnPageNet.accesskeyMacOSX "t">
|
||||
<!ENTITY btnPageCSS.label "CSS">
|
||||
<!ENTITY btnPageCSS.tooltip2 "Log CSS errors and warnings">
|
||||
<!ENTITY btnPageCSS.accesskey "C">
|
||||
<!ENTITY btnPageJS.label "JS">
|
||||
<!ENTITY btnPageJS.tooltip "Log JavaScript exceptions">
|
||||
<!ENTITY btnPageJS.accesskey "J">
|
||||
<!ENTITY btnPageSecurity.label "Security">
|
||||
<!ENTITY btnPageSecurity.tooltip "Log security errors and warnings">
|
||||
<!ENTITY btnPageSecurity.accesskey "u">
|
||||
|
||||
<!-- LOCALIZATION NOTE (btnPageLogging): This is used as the text of the
|
||||
- the toolbar. It shows or hides messages that the web developer inserted on
|
||||
- the page for debugging purposes, using calls such console.log() and
|
||||
- console.error(). -->
|
||||
<!ENTITY btnPageLogging.label "Logging">
|
||||
<!ENTITY btnPageLogging.tooltip "Log messages sent to the window.console object">
|
||||
<!ENTITY btnPageLogging.accesskey3 "L">
|
||||
<!ENTITY btnConsoleErrors "Errors">
|
||||
<!ENTITY btnConsoleInfo "Info">
|
||||
<!ENTITY btnConsoleWarnings "Warnings">
|
||||
<!ENTITY btnConsoleLog "Log">
|
||||
<!ENTITY btnConsoleXhr "XHR">
|
||||
<!ENTITY btnConsoleReflows "Reflows">
|
||||
|
||||
<!-- LOCALIZATION NOTE (btnServerLogging): This is used as the text of the
|
||||
- the toolbar. It shows or hides messages that the web developer inserted on
|
||||
- the page for debugging purposes, using calls on the HTTP server. -->
|
||||
<!ENTITY btnServerLogging.label "Server">
|
||||
<!ENTITY btnServerLogging.tooltip "Log messages received from a web server">
|
||||
<!ENTITY btnServerLogging.accesskey "S">
|
||||
<!ENTITY btnServerErrors "Errors">
|
||||
<!ENTITY btnServerInfo "Info">
|
||||
<!ENTITY btnServerWarnings "Warnings">
|
||||
<!ENTITY btnServerLog "Log">
|
||||
|
||||
<!-- LOCALIZATION NODE (btnConsoleSharedWorkers) the term "Shared Workers"
|
||||
- should not be translated. -->
|
||||
<!ENTITY btnConsoleSharedWorkers "Shared Workers">
|
||||
<!-- LOCALIZATION NODE (btnConsoleServiceWorkers) the term "Service Workers"
|
||||
- should not be translated. -->
|
||||
<!ENTITY btnConsoleServiceWorkers "Service Workers">
|
||||
<!-- LOCALIZATION NODE (btnConsoleWindowlessWorkers) the term "Workers"
|
||||
- should not be translated. -->
|
||||
<!ENTITY btnConsoleWindowlessWorkers "Add-on or Chrome Workers">
|
||||
|
||||
<!ENTITY filterOutput.placeholder "Filter output">
|
||||
<!ENTITY btnClear.label "Clear">
|
||||
<!ENTITY btnClear.tooltip "Clear the Web Console output">
|
||||
<!ENTITY btnClear.accesskey "r">
|
||||
|
||||
<!ENTITY fullZoomEnlargeCmd.commandkey "+">
|
||||
<!ENTITY fullZoomEnlargeCmd.commandkey2 "="> <!-- + is above this key on many keyboards -->
|
||||
<!ENTITY fullZoomEnlargeCmd.commandkey3 "">
|
||||
|
||||
<!ENTITY fullZoomReduceCmd.commandkey "-">
|
||||
<!ENTITY fullZoomReduceCmd.commandkey2 "">
|
||||
|
||||
<!ENTITY fullZoomResetCmd.commandkey "0">
|
||||
<!ENTITY fullZoomResetCmd.commandkey2 "">
|
||||
|
||||
<!ENTITY copyURLCmd.label "Copy Link Location">
|
||||
<!ENTITY copyURLCmd.accesskey "a">
|
||||
|
||||
<!ENTITY closeCmd.key "W">
|
||||
<!ENTITY findCmd.key "F">
|
||||
<!ENTITY clearOutputCtrl.key "L">
|
||||
<!ENTITY openInVarViewCmd.label "Open in Variables View">
|
||||
<!ENTITY openInVarViewCmd.accesskey "V">
|
||||
<!ENTITY storeAsGlobalVar.label "Store as global variable">
|
||||
<!ENTITY storeAsGlobalVar.accesskey "S">
|
|
@ -14,43 +14,17 @@ browserConsole.title=Browser Console
|
|||
# %2$02S = minutes, %3$02S = seconds, %4$03S = milliseconds.
|
||||
timestampFormat=%02S:%02S:%02S.%03S
|
||||
helperFuncUnsupportedTypeError=Can’t call pprint on this type of object.
|
||||
# LOCALIZATION NOTE (NetworkPanel.durationMS): this string is used to
|
||||
# show the duration between two network events (e.g request and response
|
||||
# header or response header and response body). Parameters: %S is the duration.
|
||||
NetworkPanel.durationMS=%Sms
|
||||
|
||||
ConsoleAPIDisabled=The Web Console logging API (console.log, console.info, console.warn, console.error) has been disabled by a script on this page.
|
||||
|
||||
# LOCALIZATION NOTE (webConsoleXhrIndicator): the indicator displayed before
|
||||
# a URL in the Web Console that was requested using an XMLHttpRequest.
|
||||
# Should probably be the same as &btnConsoleXhr; in webConsole.dtd
|
||||
webConsoleXhrIndicator=XHR
|
||||
|
||||
# LOCALIZATION NOTE (webConsoleMixedContentWarning): the message displayed
|
||||
# after a URL in the Web Console that has been flagged for Mixed Content (i.e.
|
||||
# http content in an https page).
|
||||
webConsoleMixedContentWarning=Mixed Content
|
||||
|
||||
# LOCALIZATION NOTE (webConsoleMoreInfoLabel): the more info tag displayed
|
||||
# after security related web console messages.
|
||||
webConsoleMoreInfoLabel=Learn More
|
||||
|
||||
# LOCALIZATION NOTE (scratchpad.linkText): the text used in the right hand
|
||||
# side of the Web Console command line when JavaScript is being entered, to
|
||||
# indicate how to jump into scratchpad mode.
|
||||
scratchpad.linkText=Shift+RETURN - Open in Scratchpad
|
||||
|
||||
# LOCALIZATION NOTE (reflow.*): the console displays reflow activity.
|
||||
# We can get 2 kind of lines: with JS link or without JS link. It looks like
|
||||
# that:
|
||||
# reflow: 12ms
|
||||
# reflow: 12ms function foobar, file.js line 42
|
||||
# The 2nd line, from "function" to the end of the line, is a link to the
|
||||
# JavaScript debugger.
|
||||
reflow.messageWithNoLink=reflow: %Sms
|
||||
reflow.messageWithLink=reflow: %Sms\u0020
|
||||
reflow.messageLinkText=function %1$S, %2$S line %3$S
|
||||
|
||||
# LOCALIZATION NOTE (stacktrace.anonymousFunction): this string is used to
|
||||
# display JavaScript functions that have no given name - they are said to be
|
||||
# anonymous. Test console.trace() in the webconsole.
|
||||
|
@ -61,10 +35,6 @@ stacktrace.anonymousFunction=<anonymous>
|
|||
# %S is the "Async Cause" of the frame.
|
||||
stacktrace.asyncStack=(Async: %S)
|
||||
|
||||
# LOCALIZATION NOTE (timerStarted): this string is used to display the result
|
||||
# of the console.time() call. Parameters: %S is the name of the timer.
|
||||
timerStarted=%S: timer started
|
||||
|
||||
# LOCALIZATION NOTE (timeEnd): this string is used to display the result of
|
||||
# the console.timeEnd() call. Parameters: %1$S is the name of the timer, %2$S
|
||||
# is the number of milliseconds.
|
||||
|
@ -92,19 +62,6 @@ timerAlreadyExists=Timer “%S” already exists.
|
|||
timerDoesntExist=Timer “%S” doesn’t exist.
|
||||
timerJSError=Failed to process the timer name.
|
||||
|
||||
# LOCALIZATION NOTE (maxCountersExceeded): Error message shown when the maximum
|
||||
# number of console.count()-counters was exceeded.
|
||||
maxCountersExceeded=The maximum allowed number of counters in this page was exceeded.
|
||||
|
||||
# LOCALIZATION NOTE (longStringEllipsis): the string displayed after a long
|
||||
# string. This string is clickable such that the rest of the string is
|
||||
# retrieved from the server.
|
||||
longStringEllipsis=[…]
|
||||
|
||||
# LOCALIZATION NOTE (longStringTooLong): the string displayed after the user
|
||||
# tries to expand a long string.
|
||||
longStringTooLong=The string you are trying to view is too long to be displayed by the Web Console.
|
||||
|
||||
# LOCALIZATION NOTE (connectionTimeout): message displayed when the Remote Web
|
||||
# Console fails to connect to the server due to a timeout.
|
||||
connectionTimeout=Connection timeout. Check the Error Console on both ends for potential error messages. Reopen the Web Console to try again.
|
||||
|
@ -154,15 +111,6 @@ messageToggleDetails=Show/hide message details.
|
|||
# you hover the arrow for expanding/collapsing the messages of a group.
|
||||
groupToggle=Show/hide group.
|
||||
|
||||
# LOCALIZATION NOTE (emptySlotLabel): the text is displayed when an Array
|
||||
# with empty slots is printed to the console.
|
||||
# This is a semi-colon list of plural forms.
|
||||
# See: http://developer.mozilla.org/en/docs/Localization_and_Plurals
|
||||
# #1 number of empty slots
|
||||
# example: 1 empty slot
|
||||
# example: 5 empty slots
|
||||
emptySlotLabel=#1 empty slot;#1 empty slots
|
||||
|
||||
# LOCALIZATION NOTE (table.index, table.iterationIndex, table.key, table.value):
|
||||
# the column header displayed in the console table widget.
|
||||
table.index=(index)
|
||||
|
@ -170,13 +118,6 @@ table.iterationIndex=(iteration index)
|
|||
table.key=Key
|
||||
table.value=Values
|
||||
|
||||
# LOCALIZATION NOTE (severity.error, severity.warn, severity.info, severity.log):
|
||||
# tooltip for icons next to console output
|
||||
severity.error=Error
|
||||
severity.warn=Warning
|
||||
severity.info=Info
|
||||
severity.log=Log
|
||||
|
||||
# LOCALIZATION NOTE (level.error, level.warn, level.info, level.log, level.debug):
|
||||
# tooltip for icons next to console output
|
||||
level.error=Error
|
||||
|
@ -216,12 +157,6 @@ webconsole.menu.openURL.accesskey=T
|
|||
webconsole.menu.openInNetworkPanel.label=Open in Network Panel
|
||||
webconsole.menu.openInNetworkPanel.accesskey=N
|
||||
|
||||
# LOCALIZATION NOTE (webconsole.menu.openInVarView.label)
|
||||
# Label used for a context-menu item displayed for object/variable logs. Clicking on it
|
||||
# opens the webconsole variable view for the logged variable.
|
||||
webconsole.menu.openInVarView.label=Open in Variables View
|
||||
webconsole.menu.openInVarView.accesskey=V
|
||||
|
||||
# LOCALIZATION NOTE (webconsole.menu.storeAsGlobalVar.label)
|
||||
# Label used for a context-menu item displayed for object/variable logs. Clicking on it
|
||||
# creates a new global variable pointing to the logged variable.
|
||||
|
|
|
@ -11,7 +11,6 @@ loader.lazyRequireGetter(this, "TargetFactory", "devtools/client/framework/targe
|
|||
loader.lazyRequireGetter(this, "gDevToolsBrowser", "devtools/client/framework/devtools-browser", true);
|
||||
loader.lazyRequireGetter(this, "Tools", "devtools/client/definitions", true);
|
||||
loader.lazyRequireGetter(this, "Telemetry", "devtools/client/shared/telemetry");
|
||||
loader.lazyRequireGetter(this, "WebConsoleFrame", "devtools/client/webconsole/old/webconsole", true);
|
||||
loader.lazyRequireGetter(this, "NewWebConsoleFrame", "devtools/client/webconsole/new-webconsole", true);
|
||||
loader.lazyRequireGetter(this, "gDevTools", "devtools/client/framework/devtools", true);
|
||||
loader.lazyRequireGetter(this, "DebuggerServer", "devtools/server/main", true);
|
||||
|
@ -193,10 +192,6 @@ HUD_SERVICE.prototype =
|
|||
|
||||
win.document.title = l10n.getStr("browserConsole.title");
|
||||
|
||||
if (browserConsoleURL === Tools.webConsole.oldWebConsoleURL) {
|
||||
return {iframeWindow: win, chromeWindow: win};
|
||||
}
|
||||
|
||||
let iframe = win.document.querySelector("iframe");
|
||||
await new Promise(resolve => {
|
||||
iframe.addEventListener("DOMContentLoaded", resolve, {once: true});
|
||||
|
@ -273,11 +268,7 @@ function WebConsole(target, iframeWindow, chromeWindow) {
|
|||
if (element.getAttribute("windowtype") != gDevTools.chromeWindowType) {
|
||||
this.browserWindow = HUDService.currentContext();
|
||||
}
|
||||
if (iframeWindow.location.href === Tools.webConsole.newWebConsoleURL) {
|
||||
this.ui = new NewWebConsoleFrame(this);
|
||||
} else {
|
||||
this.ui = new WebConsoleFrame(this);
|
||||
}
|
||||
this.ui = new NewWebConsoleFrame(this);
|
||||
}
|
||||
WebConsole.prototype = {
|
||||
iframeWindow: null,
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
DIRS += [
|
||||
'actions',
|
||||
'components',
|
||||
'old',
|
||||
'reducers',
|
||||
'selectors',
|
||||
'test',
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -1,18 +0,0 @@
|
|||
# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
|
||||
# vim: set filetype=python:
|
||||
# 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/.
|
||||
|
||||
BROWSER_CHROME_MANIFESTS += ['test/browser.ini']
|
||||
|
||||
DIRS += [
|
||||
'net',
|
||||
]
|
||||
DevToolsModules(
|
||||
'console-output.js',
|
||||
'jsterm.js',
|
||||
'webconsole.js',
|
||||
)
|
||||
with Files('**'):
|
||||
BUG_COMPONENT = ('Firefox', 'Developer Tools: Console')
|
|
@ -1,20 +0,0 @@
|
|||
"use strict";
|
||||
|
||||
module.exports = {
|
||||
"globals": {
|
||||
"Locale": true,
|
||||
"Document": true,
|
||||
"document": true,
|
||||
"Node": true,
|
||||
"Element": true,
|
||||
"MessageEvent": true,
|
||||
"BrowserLoader": true,
|
||||
"addEventListener": true,
|
||||
"DOMParser": true,
|
||||
"dispatchEvent": true,
|
||||
"setTimeout": true
|
||||
},
|
||||
"rules": {
|
||||
"no-unused-vars": ["error", {"args": "none"}],
|
||||
}
|
||||
};
|
|
@ -1,72 +0,0 @@
|
|||
/* 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";
|
||||
|
||||
const { Component, createFactory } = require("devtools/client/shared/vendor/react");
|
||||
const dom = require("devtools/client/shared/vendor/react-dom-factories");
|
||||
const PropTypes = require("devtools/client/shared/vendor/react-prop-types");
|
||||
const NetInfoGroupList = createFactory(require("./net-info-group-list"));
|
||||
|
||||
/**
|
||||
* This template represents 'Cookies' tab displayed when the user
|
||||
* expands network log in the Console panel. It's responsible for rendering
|
||||
* sent and received cookies.
|
||||
*/
|
||||
class CookiesTab extends Component {
|
||||
static get propTypes() {
|
||||
return {
|
||||
actions: PropTypes.shape({
|
||||
requestData: PropTypes.func.isRequired
|
||||
}),
|
||||
data: PropTypes.object.isRequired,
|
||||
};
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
let { actions, data } = this.props;
|
||||
let requestCookies = data.request.cookies;
|
||||
let responseCookies = data.response.cookies;
|
||||
|
||||
// TODO: use async action objects as soon as Redux is in place
|
||||
if (!requestCookies || !requestCookies.length) {
|
||||
actions.requestData("requestCookies");
|
||||
}
|
||||
|
||||
if (!responseCookies || !responseCookies.length) {
|
||||
actions.requestData("responseCookies");
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
let { data: file } = this.props;
|
||||
let requestCookies = file.request.cookies;
|
||||
let responseCookies = file.response.cookies;
|
||||
|
||||
// The cookie panel displays two groups of cookies:
|
||||
// 1) Response Cookies
|
||||
// 2) Request Cookies
|
||||
let groups = [{
|
||||
key: "responseCookies",
|
||||
name: Locale.$STR("responseCookies"),
|
||||
params: responseCookies
|
||||
}, {
|
||||
key: "requestCookies",
|
||||
name: Locale.$STR("requestCookies"),
|
||||
params: requestCookies
|
||||
}];
|
||||
|
||||
return (
|
||||
dom.div({className: "cookiesTabBox"},
|
||||
dom.div({className: "panelContent"},
|
||||
NetInfoGroupList({
|
||||
groups: groups
|
||||
})
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Exports from this module
|
||||
module.exports = CookiesTab;
|
|
@ -1,77 +0,0 @@
|
|||
/* 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";
|
||||
|
||||
const { Component, createFactory } = require("devtools/client/shared/vendor/react");
|
||||
const dom = require("devtools/client/shared/vendor/react-dom-factories");
|
||||
const PropTypes = require("devtools/client/shared/vendor/react-prop-types");
|
||||
const NetInfoGroupList = createFactory(require("./net-info-group-list"));
|
||||
const Spinner = createFactory(require("./spinner"));
|
||||
|
||||
/**
|
||||
* This template represents 'Headers' tab displayed when the user
|
||||
* expands network log in the Console panel. It's responsible for rendering
|
||||
* request and response HTTP headers.
|
||||
*/
|
||||
class HeadersTab extends Component {
|
||||
static get propTypes() {
|
||||
return {
|
||||
actions: PropTypes.shape({
|
||||
requestData: PropTypes.func.isRequired
|
||||
}),
|
||||
data: PropTypes.object.isRequired,
|
||||
};
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
let { actions, data } = this.props;
|
||||
let requestHeaders = data.request.headers;
|
||||
let responseHeaders = data.response.headers;
|
||||
|
||||
// Request headers if they are not available yet.
|
||||
// TODO: use async action objects as soon as Redux is in place
|
||||
if (!requestHeaders) {
|
||||
actions.requestData("requestHeaders");
|
||||
}
|
||||
|
||||
if (!responseHeaders) {
|
||||
actions.requestData("responseHeaders");
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
let { data } = this.props;
|
||||
let requestHeaders = data.request.headers;
|
||||
let responseHeaders = data.response.headers;
|
||||
|
||||
// TODO: Another groups to implement:
|
||||
// 1) Cached Headers
|
||||
// 2) Headers from upload stream
|
||||
let groups = [{
|
||||
key: "responseHeaders",
|
||||
name: Locale.$STR("responseHeaders"),
|
||||
params: responseHeaders
|
||||
}, {
|
||||
key: "requestHeaders",
|
||||
name: Locale.$STR("requestHeaders"),
|
||||
params: requestHeaders
|
||||
}];
|
||||
|
||||
// If response headers are not available yet, display a spinner
|
||||
if (!responseHeaders || !responseHeaders.length) {
|
||||
groups[0].content = Spinner();
|
||||
}
|
||||
|
||||
return (
|
||||
dom.div({className: "headersTabBox"},
|
||||
dom.div({className: "panelContent"},
|
||||
NetInfoGroupList({groups: groups})
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Exports from this module
|
||||
module.exports = HeadersTab;
|
|
@ -1,25 +0,0 @@
|
|||
# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
|
||||
# vim: set filetype=python:
|
||||
# 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/.
|
||||
|
||||
DevToolsModules(
|
||||
'cookies-tab.js',
|
||||
'headers-tab.js',
|
||||
'net-info-body.css',
|
||||
'net-info-body.js',
|
||||
'net-info-group-list.js',
|
||||
'net-info-group.css',
|
||||
'net-info-group.js',
|
||||
'net-info-params.css',
|
||||
'net-info-params.js',
|
||||
'params-tab.js',
|
||||
'post-tab.js',
|
||||
'response-tab.css',
|
||||
'response-tab.js',
|
||||
'size-limit.css',
|
||||
'size-limit.js',
|
||||
'spinner.js',
|
||||
'stacktrace-tab.js',
|
||||
)
|
|
@ -1,93 +0,0 @@
|
|||
/* 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/. */
|
||||
|
||||
/******************************************************************************/
|
||||
/* Network Info Body */
|
||||
|
||||
.netInfoBody {
|
||||
margin: 10px 0 0 0;
|
||||
width: 100%;
|
||||
cursor: default;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.netInfoBody *:focus {
|
||||
outline: 0 !important;
|
||||
}
|
||||
|
||||
.netInfoBody .panelContent {
|
||||
word-break: break-all;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
/* Network Info Body Tabs */
|
||||
|
||||
.netInfoBody > .tabs {
|
||||
background-color: transparent;
|
||||
background-image: none;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.netInfoBody > .tabs .tabs-navigation {
|
||||
border-bottom-color: var(--net-border);
|
||||
background-color: transparent;
|
||||
text-decoration: none;
|
||||
padding-top: 3px;
|
||||
padding-left: 7px;
|
||||
padding-bottom: 1px;
|
||||
border-bottom: 1px solid var(--net-border);
|
||||
}
|
||||
|
||||
.netInfoBody > .tabs .tabs-menu {
|
||||
display: table;
|
||||
list-style: none;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
/* This is the trick that makes the tab bottom border invisible */
|
||||
.netInfoBody > .tabs .tabs-menu-item {
|
||||
position: relative;
|
||||
bottom: -2px;
|
||||
float: left;
|
||||
}
|
||||
|
||||
.netInfoBody > .tabs .tabs-menu-item a {
|
||||
display: block;
|
||||
border: 1px solid transparent;
|
||||
text-decoration: none;
|
||||
padding: 5px 8px 4px 8px;;
|
||||
font-weight: bold;
|
||||
color: var(--theme-body-color);
|
||||
border-radius: 4px 4px 0 0;
|
||||
}
|
||||
|
||||
.netInfoBody > .tabs .tab-panel {
|
||||
background-color: var(--theme-body-background);
|
||||
border: 1px solid transparent;
|
||||
border-top: none;
|
||||
padding: 10px;
|
||||
overflow: auto;
|
||||
height: calc(100% - 31px); /* minus the height of the tab bar */
|
||||
}
|
||||
|
||||
.netInfoBody > .tabs .tab-panel > div,
|
||||
.netInfoBody > .tabs .tab-panel > div > div {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.netInfoBody > .tabs .tabs-menu-item.is-active a,
|
||||
.netInfoBody > .tabs .tabs-menu-item.is-active a:focus,
|
||||
.netInfoBody > .tabs .tabs-menu-item.is-active:hover a {
|
||||
background-color: var(--theme-body-background);
|
||||
border: 1px solid transparent;
|
||||
border-bottom-color: var(--theme-highlight-bluegrey);
|
||||
color: var(--theme-highlight-bluegrey);
|
||||
}
|
||||
|
||||
.netInfoBody > .tabs .tabs-menu-item:hover a {
|
||||
border: 1px solid transparent;
|
||||
border-bottom: 1px solid var(--net-border);
|
||||
background-color: var(--theme-body-background);
|
||||
}
|
|
@ -1,196 +0,0 @@
|
|||
/* 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";
|
||||
|
||||
const { Component, createFactory } = require("devtools/client/shared/vendor/react");
|
||||
const PropTypes = require("devtools/client/shared/vendor/react-prop-types");
|
||||
const { createFactories } = require("devtools/client/shared/react-utils");
|
||||
const { Tabs, TabPanel } = createFactories(require("devtools/client/shared/components/tabs/Tabs"));
|
||||
|
||||
// Network
|
||||
const HeadersTab = createFactory(require("./headers-tab"));
|
||||
const ResponseTab = createFactory(require("./response-tab"));
|
||||
const ParamsTab = createFactory(require("./params-tab"));
|
||||
const CookiesTab = createFactory(require("./cookies-tab"));
|
||||
const PostTab = createFactory(require("./post-tab"));
|
||||
const StackTraceTab = createFactory(require("./stacktrace-tab"));
|
||||
const NetUtils = require("../utils/net");
|
||||
|
||||
|
||||
/**
|
||||
* This template renders the basic Network log info body. It's not
|
||||
* visible by default, the user needs to expand the network log
|
||||
* to see it.
|
||||
*
|
||||
* This is the set of tabs displaying details about network events:
|
||||
* 1) Headers - request and response headers
|
||||
* 2) Params - URL parameters
|
||||
* 3) Response - response body
|
||||
* 4) Cookies - request and response cookies
|
||||
* 5) Post - posted data
|
||||
*/
|
||||
class NetInfoBody extends Component {
|
||||
static get propTypes() {
|
||||
return {
|
||||
tabActive: PropTypes.number.isRequired,
|
||||
actions: PropTypes.object.isRequired,
|
||||
data: PropTypes.shape({
|
||||
request: PropTypes.object.isRequired,
|
||||
response: PropTypes.object.isRequired
|
||||
}),
|
||||
// Service to enable the source map feature.
|
||||
sourceMapService: PropTypes.object,
|
||||
};
|
||||
}
|
||||
|
||||
static get defaultProps() {
|
||||
return {
|
||||
tabActive: 0
|
||||
};
|
||||
}
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
this.state = {
|
||||
data: {
|
||||
request: {},
|
||||
response: {}
|
||||
},
|
||||
tabActive: props.tabActive,
|
||||
};
|
||||
|
||||
this.onTabChanged = this.onTabChanged.bind(this);
|
||||
this.hasCookies = this.hasCookies.bind(this);
|
||||
this.hasStackTrace = this.hasStackTrace.bind(this);
|
||||
this.getTabPanels = this.getTabPanels.bind(this);
|
||||
}
|
||||
|
||||
onTabChanged(index) {
|
||||
this.setState({tabActive: index});
|
||||
}
|
||||
|
||||
hasCookies() {
|
||||
let {request, response} = this.state.data;
|
||||
return this.state.hasCookies ||
|
||||
NetUtils.getHeaderValue(request.headers, "Cookie") ||
|
||||
NetUtils.getHeaderValue(response.headers, "Set-Cookie");
|
||||
}
|
||||
|
||||
hasStackTrace() {
|
||||
let {cause} = this.state.data;
|
||||
return cause && cause.stacktrace && cause.stacktrace.length > 0;
|
||||
}
|
||||
|
||||
getTabPanels() {
|
||||
let { actions, sourceMapService } = this.props;
|
||||
let data = this.state.data;
|
||||
let {request} = data;
|
||||
|
||||
// Flags for optional tabs. Some tabs are visible only if there
|
||||
// are data to display.
|
||||
let hasParams = request.queryString && request.queryString.length;
|
||||
let hasPostData = request.bodySize > 0;
|
||||
|
||||
let panels = [];
|
||||
|
||||
// Headers tab
|
||||
panels.push(
|
||||
TabPanel({
|
||||
id: "headers",
|
||||
className: "headers",
|
||||
key: "headers",
|
||||
title: Locale.$STR("netRequest.headers")},
|
||||
HeadersTab({data: data, actions: actions})
|
||||
)
|
||||
);
|
||||
|
||||
// URL parameters tab
|
||||
if (hasParams) {
|
||||
panels.push(
|
||||
TabPanel({
|
||||
id: "params",
|
||||
className: "params",
|
||||
key: "params",
|
||||
title: Locale.$STR("netRequest.params")},
|
||||
ParamsTab({data: data, actions: actions})
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
// Posted data tab
|
||||
if (hasPostData) {
|
||||
panels.push(
|
||||
TabPanel({
|
||||
id: "post",
|
||||
className: "post",
|
||||
key: "post",
|
||||
title: Locale.$STR("netRequest.post")},
|
||||
PostTab({data: data, actions: actions})
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
// Response tab
|
||||
panels.push(
|
||||
TabPanel({
|
||||
id: "response",
|
||||
className: "response",
|
||||
key: "response",
|
||||
title: Locale.$STR("netRequest.response")},
|
||||
ResponseTab({data: data, actions: actions})
|
||||
)
|
||||
);
|
||||
|
||||
// Cookies tab
|
||||
if (this.hasCookies()) {
|
||||
panels.push(
|
||||
TabPanel({
|
||||
id: "cookies",
|
||||
className: "cookies",
|
||||
key: "cookies",
|
||||
title: Locale.$STR("netRequest.cookies")},
|
||||
CookiesTab({
|
||||
data: data,
|
||||
actions: actions
|
||||
})
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
// Stacktrace tab
|
||||
if (this.hasStackTrace()) {
|
||||
panels.push(
|
||||
TabPanel({
|
||||
id: "stacktrace-tab",
|
||||
className: "stacktrace-tab",
|
||||
key: "stacktrace",
|
||||
title: Locale.$STR("netRequest.callstack")},
|
||||
StackTraceTab({
|
||||
data: data,
|
||||
actions: actions,
|
||||
sourceMapService: sourceMapService,
|
||||
})
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
return panels;
|
||||
}
|
||||
|
||||
render() {
|
||||
let tabActive = this.state.tabActive;
|
||||
let tabPanels = this.getTabPanels();
|
||||
return (
|
||||
Tabs({
|
||||
tabActive: tabActive,
|
||||
onAfterChange: this.onTabChanged},
|
||||
tabPanels
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Exports from this module
|
||||
module.exports = NetInfoBody;
|
|
@ -1,45 +0,0 @@
|
|||
/* 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";
|
||||
|
||||
const { Component, createFactory } = require("devtools/client/shared/vendor/react");
|
||||
const dom = require("devtools/client/shared/vendor/react-dom-factories");
|
||||
const PropTypes = require("devtools/client/shared/vendor/react-prop-types");
|
||||
const NetInfoGroup = createFactory(require("./net-info-group"));
|
||||
|
||||
/**
|
||||
* This template is responsible for rendering sections/groups inside tabs.
|
||||
* It's used e.g to display Response and Request headers as separate groups.
|
||||
*/
|
||||
class NetInfoGroupList extends Component {
|
||||
static get propTypes() {
|
||||
return {
|
||||
groups: PropTypes.array.isRequired,
|
||||
};
|
||||
}
|
||||
|
||||
render() {
|
||||
let groups = this.props.groups;
|
||||
|
||||
// Filter out empty groups.
|
||||
groups = groups.filter(group => {
|
||||
return group && ((group.params && group.params.length) || group.content);
|
||||
});
|
||||
|
||||
// Render groups
|
||||
groups = groups.map(group => {
|
||||
group.type = group.key;
|
||||
return NetInfoGroup(group);
|
||||
});
|
||||
|
||||
return (
|
||||
dom.div({className: "netInfoGroupList"},
|
||||
groups
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Exports from this module
|
||||
module.exports = NetInfoGroupList;
|
|
@ -1,68 +0,0 @@
|
|||
/* 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/. */
|
||||
|
||||
/******************************************************************************/
|
||||
/* Net Info Group */
|
||||
|
||||
.netInfoBody .netInfoGroup {
|
||||
padding-bottom: 6px;
|
||||
}
|
||||
|
||||
/* Last group doesn't need bottom padding */
|
||||
.netInfoBody .netInfoGroup:last-child {
|
||||
padding-bottom: 0;
|
||||
}
|
||||
|
||||
.netInfoBody .netInfoGroup:last-child .netInfoGroupContent {
|
||||
padding-bottom: 0;
|
||||
}
|
||||
|
||||
.netInfoBody .netInfoGroupTitle {
|
||||
cursor: pointer;
|
||||
font-weight: bold;
|
||||
-moz-user-select: none;
|
||||
cursor: pointer;
|
||||
padding-left: 3px;
|
||||
}
|
||||
|
||||
.netInfoBody .netInfoGroupTwisty {
|
||||
background-image: url("chrome://devtools/skin/images/controls.png");
|
||||
background-size: 56px 28px;
|
||||
background-position: 0 -14px;
|
||||
background-repeat: no-repeat;
|
||||
width: 14px;
|
||||
height: 14px;
|
||||
cursor: pointer;
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.netInfoBody .netInfoGroup.opened .netInfoGroupTwisty {
|
||||
background-position: -14px -14px;
|
||||
}
|
||||
|
||||
/* Group content is expandable/collapsible by clicking on the title */
|
||||
.netInfoBody .netInfoGroupContent {
|
||||
padding-top: 7px;
|
||||
margin-top: 3px;
|
||||
padding-bottom: 14px;
|
||||
border-top: 1px solid var(--net-border);
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* Toggle group visibility */
|
||||
.netInfoBody .netInfoGroup.opened .netInfoGroupContent {
|
||||
display: block;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
/* Themes */
|
||||
|
||||
.theme-dark .netInfoBody .netInfoGroup {
|
||||
color: var(--theme-body-color);
|
||||
}
|
||||
|
||||
.theme-dark .netInfoBody .netInfoGroup .netInfoGroupTwisty {
|
||||
filter: invert(1);
|
||||
}
|
|
@ -1,82 +0,0 @@
|
|||
/* 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";
|
||||
|
||||
const { Component, createFactory } = require("devtools/client/shared/vendor/react");
|
||||
const dom = require("devtools/client/shared/vendor/react-dom-factories");
|
||||
const PropTypes = require("devtools/client/shared/vendor/react-prop-types");
|
||||
const NetInfoParams = createFactory(require("./net-info-params"));
|
||||
|
||||
/**
|
||||
* This template represents a group of data within a tab. For example,
|
||||
* Headers tab has two groups 'Request Headers' and 'Response Headers'
|
||||
* The Response tab can also have two groups 'Raw Data' and 'JSON'
|
||||
*/
|
||||
class NetInfoGroup extends Component {
|
||||
static get propTypes() {
|
||||
return {
|
||||
type: PropTypes.string.isRequired,
|
||||
name: PropTypes.string.isRequired,
|
||||
params: PropTypes.array,
|
||||
content: PropTypes.element,
|
||||
open: PropTypes.bool
|
||||
};
|
||||
}
|
||||
|
||||
static get defaultProps() {
|
||||
return {
|
||||
open: true,
|
||||
};
|
||||
}
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
this.state = {
|
||||
open: props.open,
|
||||
};
|
||||
|
||||
this.onToggle = this.onToggle.bind(this);
|
||||
}
|
||||
|
||||
onToggle(event) {
|
||||
this.setState({
|
||||
open: !this.state.open
|
||||
});
|
||||
}
|
||||
|
||||
render() {
|
||||
let content = this.props.content;
|
||||
|
||||
if (!content && this.props.params) {
|
||||
content = NetInfoParams({
|
||||
params: this.props.params
|
||||
});
|
||||
}
|
||||
|
||||
let open = this.state.open;
|
||||
let className = open ? "opened" : "";
|
||||
|
||||
return (
|
||||
dom.div({className: "netInfoGroup" + " " + className + " " +
|
||||
this.props.type},
|
||||
dom.span({
|
||||
className: "netInfoGroupTwisty",
|
||||
onClick: this.onToggle
|
||||
}),
|
||||
dom.span({
|
||||
className: "netInfoGroupTitle",
|
||||
onClick: this.onToggle},
|
||||
this.props.name
|
||||
),
|
||||
dom.div({className: "netInfoGroupContent"},
|
||||
content
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Exports from this module
|
||||
module.exports = NetInfoGroup;
|
|
@ -1,23 +0,0 @@
|
|||
/* 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/. */
|
||||
|
||||
/******************************************************************************/
|
||||
/* Net Info Params */
|
||||
|
||||
.netInfoBody .netInfoParamName {
|
||||
padding: 0 10px 0 0;
|
||||
font-weight: bold;
|
||||
vertical-align: top;
|
||||
text-align: right;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.netInfoBody .netInfoParamValue {
|
||||
width: 100%;
|
||||
word-wrap: break-word;
|
||||
}
|
||||
|
||||
.netInfoBody .netInfoParamValue > code {
|
||||
font-family: var(--monospace-font-family);
|
||||
}
|
|
@ -1,55 +0,0 @@
|
|||
/* 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";
|
||||
|
||||
const { Component } = require("devtools/client/shared/vendor/react");
|
||||
const PropTypes = require("devtools/client/shared/vendor/react-prop-types");
|
||||
const dom = require("devtools/client/shared/vendor/react-dom-factories");
|
||||
/**
|
||||
* This template renders list of parameters within a group.
|
||||
* It's essentially a list of name + value pairs.
|
||||
*/
|
||||
class NetInfoParams extends Component {
|
||||
static get propTypes() {
|
||||
return {
|
||||
params: PropTypes.arrayOf(PropTypes.shape({
|
||||
name: PropTypes.string.isRequired,
|
||||
value: PropTypes.string.isRequired
|
||||
})).isRequired,
|
||||
};
|
||||
}
|
||||
|
||||
render() {
|
||||
let params = this.props.params || [];
|
||||
|
||||
params.sort(function (a, b) {
|
||||
return a.name > b.name ? 1 : -1;
|
||||
});
|
||||
|
||||
let rows = [];
|
||||
params.forEach((param, index) => {
|
||||
rows.push(
|
||||
dom.tr({key: index},
|
||||
dom.td({className: "netInfoParamName"},
|
||||
dom.span({title: param.name}, param.name)
|
||||
),
|
||||
dom.td({className: "netInfoParamValue"},
|
||||
dom.code({}, param.value)
|
||||
)
|
||||
)
|
||||
);
|
||||
});
|
||||
|
||||
return (
|
||||
dom.table({cellPadding: 0, cellSpacing: 0},
|
||||
dom.tbody({},
|
||||
rows
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Exports from this module
|
||||
module.exports = NetInfoParams;
|
|
@ -1,39 +0,0 @@
|
|||
/* 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";
|
||||
|
||||
const { Component, createFactory } = require("devtools/client/shared/vendor/react");
|
||||
const dom = require("devtools/client/shared/vendor/react-dom-factories");
|
||||
const PropTypes = require("devtools/client/shared/vendor/react-prop-types");
|
||||
const NetInfoParams = createFactory(require("./net-info-params"));
|
||||
|
||||
/**
|
||||
* This template represents 'Params' tab displayed when the user
|
||||
* expands network log in the Console panel. It's responsible for
|
||||
* displaying URL parameters (query string).
|
||||
*/
|
||||
class ParamsTab extends Component {
|
||||
static get propTypes() {
|
||||
return {
|
||||
data: PropTypes.shape({
|
||||
request: PropTypes.object.isRequired
|
||||
})
|
||||
};
|
||||
}
|
||||
|
||||
render() {
|
||||
let data = this.props.data;
|
||||
|
||||
return (
|
||||
dom.div({className: "paramsTabBox"},
|
||||
dom.div({className: "panelContent"},
|
||||
NetInfoParams({params: data.request.queryString})
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Exports from this module
|
||||
module.exports = ParamsTab;
|
|
@ -1,290 +0,0 @@
|
|||
/* 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";
|
||||
|
||||
const { Component, createFactory } = require("devtools/client/shared/vendor/react");
|
||||
const dom = require("devtools/client/shared/vendor/react-dom-factories");
|
||||
const PropTypes = require("devtools/client/shared/vendor/react-prop-types");
|
||||
|
||||
const TreeView =
|
||||
createFactory(require("devtools/client/shared/components/tree/TreeView"));
|
||||
|
||||
const { REPS, MODE, parseURLEncodedText } =
|
||||
require("devtools/client/shared/components/reps/reps");
|
||||
const { Rep } = REPS;
|
||||
|
||||
// Network
|
||||
const NetInfoParams = createFactory(require("./net-info-params"));
|
||||
const NetInfoGroupList = createFactory(require("./net-info-group-list"));
|
||||
const Spinner = createFactory(require("./spinner"));
|
||||
const SizeLimit = createFactory(require("./size-limit"));
|
||||
const NetUtils = require("../utils/net");
|
||||
const Json = require("../utils/json");
|
||||
|
||||
/**
|
||||
* This template represents 'Post' tab displayed when the user
|
||||
* expands network log in the Console panel. It's responsible for
|
||||
* displaying posted data (HTTP post body).
|
||||
*/
|
||||
class PostTab extends Component {
|
||||
static get propTypes() {
|
||||
return {
|
||||
data: PropTypes.shape({
|
||||
request: PropTypes.object.isRequired
|
||||
}),
|
||||
actions: PropTypes.object.isRequired
|
||||
};
|
||||
}
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.isJson = this.isJson.bind(this);
|
||||
this.parseJson = this.parseJson.bind(this);
|
||||
this.renderJson = this.renderJson.bind(this);
|
||||
this.parseXml = this.parseXml.bind(this);
|
||||
this.isXml = this.isXml.bind(this);
|
||||
this.renderXml = this.renderXml.bind(this);
|
||||
this.renderMultiPart = this.renderMultiPart.bind(this);
|
||||
this.renderUrlEncoded = this.renderUrlEncoded.bind(this);
|
||||
this.renderRawData = this.renderRawData.bind(this);
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
let { actions, data: file } = this.props;
|
||||
|
||||
if (!file.request.postData) {
|
||||
// TODO: use async action objects as soon as Redux is in place
|
||||
actions.requestData("requestPostData");
|
||||
}
|
||||
}
|
||||
|
||||
isJson(file) {
|
||||
let text = file.request.postData.text;
|
||||
let value = NetUtils.getHeaderValue(file.request.headers, "content-type");
|
||||
return Json.isJSON(value, text);
|
||||
}
|
||||
|
||||
parseJson(file) {
|
||||
let postData = file.request.postData;
|
||||
if (!postData) {
|
||||
return null;
|
||||
}
|
||||
|
||||
let jsonString = new String(postData.text);
|
||||
return Json.parseJSONString(jsonString);
|
||||
}
|
||||
|
||||
/**
|
||||
* Render JSON post data as an expandable tree.
|
||||
*/
|
||||
renderJson(file) {
|
||||
let text = file.request.postData.text;
|
||||
if (!text || isLongString(text)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!this.isJson(file)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
let json = this.parseJson(file);
|
||||
if (!json) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return {
|
||||
key: "json",
|
||||
content: TreeView({
|
||||
columns: [{id: "value"}],
|
||||
object: json,
|
||||
mode: MODE.TINY,
|
||||
renderValue: props => Rep(Object.assign({}, props, {
|
||||
cropLimit: 50,
|
||||
})),
|
||||
}),
|
||||
name: Locale.$STR("jsonScopeName")
|
||||
};
|
||||
}
|
||||
|
||||
parseXml(file) {
|
||||
let text = file.request.postData.text;
|
||||
if (isLongString(text)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return NetUtils.parseXml({
|
||||
mimeType: NetUtils.getHeaderValue(file.request.headers, "content-type"),
|
||||
text: text,
|
||||
});
|
||||
}
|
||||
|
||||
isXml(file) {
|
||||
if (isLongString(file.request.postData.text)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
let value = NetUtils.getHeaderValue(file.request.headers, "content-type");
|
||||
if (!value) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return NetUtils.isHTML(value);
|
||||
}
|
||||
|
||||
renderXml(file) {
|
||||
let text = file.request.postData.text;
|
||||
if (!text || isLongString(text)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!this.isXml(file)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
let doc = this.parseXml(file);
|
||||
if (!doc) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Proper component for rendering XML should be used (see bug 1247392)
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Multipart post data are parsed and nicely rendered
|
||||
* as an expandable tree of individual parts.
|
||||
*/
|
||||
renderMultiPart(file) {
|
||||
let text = file.request.postData.text;
|
||||
if (!text || isLongString(text)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (NetUtils.isMultiPartRequest(file)) {
|
||||
// TODO: render multi part request (bug: 1247423)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* URL encoded post data are nicely rendered as a list
|
||||
* of parameters.
|
||||
*/
|
||||
renderUrlEncoded(file) {
|
||||
let text = file.request.postData.text;
|
||||
if (!text || isLongString(text)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!NetUtils.isURLEncodedRequest(file)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
let lines = text.split("\n");
|
||||
let params = parseURLEncodedText(lines[lines.length - 1]);
|
||||
|
||||
return {
|
||||
key: "url-encoded",
|
||||
content: NetInfoParams({params: params}),
|
||||
name: Locale.$STR("netRequest.params")
|
||||
};
|
||||
}
|
||||
|
||||
renderRawData(file) {
|
||||
let text = file.request.postData.text;
|
||||
|
||||
let group;
|
||||
|
||||
// The post body might reached the limit, so check if we are
|
||||
// dealing with a long string.
|
||||
if (typeof text == "object") {
|
||||
group = {
|
||||
key: "raw-longstring",
|
||||
name: Locale.$STR("netRequest.rawData"),
|
||||
content: dom.div({className: "netInfoResponseContent"},
|
||||
sanitize(text.initial),
|
||||
SizeLimit({
|
||||
actions: this.props.actions,
|
||||
data: file.request.postData,
|
||||
message: Locale.$STR("netRequest.sizeLimitMessage"),
|
||||
link: Locale.$STR("netRequest.sizeLimitMessageLink")
|
||||
})
|
||||
)
|
||||
};
|
||||
} else {
|
||||
group = {
|
||||
key: "raw",
|
||||
name: Locale.$STR("netRequest.rawData"),
|
||||
content: dom.div({className: "netInfoResponseContent"},
|
||||
sanitize(text)
|
||||
)
|
||||
};
|
||||
}
|
||||
|
||||
return group;
|
||||
}
|
||||
|
||||
render() {
|
||||
let { data: file } = this.props;
|
||||
|
||||
if (file.discardRequestBody) {
|
||||
return dom.span({className: "netInfoBodiesDiscarded"},
|
||||
Locale.$STR("netRequest.requestBodyDiscarded")
|
||||
);
|
||||
}
|
||||
|
||||
if (!file.request.postData) {
|
||||
return (
|
||||
Spinner()
|
||||
);
|
||||
}
|
||||
|
||||
// Render post body data. The right representation of the data
|
||||
// is picked according to the content type.
|
||||
let groups = [];
|
||||
groups.push(this.renderUrlEncoded(file));
|
||||
// TODO: render multi part request (bug: 1247423)
|
||||
// groups.push(this.renderMultiPart(file));
|
||||
groups.push(this.renderJson(file));
|
||||
groups.push(this.renderXml(file));
|
||||
groups.push(this.renderRawData(file));
|
||||
|
||||
// Filter out empty groups.
|
||||
groups = groups.filter(group => group);
|
||||
|
||||
// The raw response is collapsed by default if a nice formatted
|
||||
// version is available.
|
||||
if (groups.length > 1) {
|
||||
groups[groups.length - 1].open = false;
|
||||
}
|
||||
|
||||
return (
|
||||
dom.div({className: "postTabBox"},
|
||||
dom.div({className: "panelContent"},
|
||||
NetInfoGroupList({
|
||||
groups: groups
|
||||
})
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Helpers
|
||||
|
||||
/**
|
||||
* Workaround for a "not well-formed" error that react
|
||||
* reports when there's multipart data passed to render.
|
||||
*/
|
||||
function sanitize(text) {
|
||||
text = JSON.stringify(text);
|
||||
text = text.replace(/\\r\\n/g, "\r\n").replace(/\\"/g, "\"");
|
||||
return text.slice(1, text.length - 1);
|
||||
}
|
||||
|
||||
function isLongString(text) {
|
||||
return typeof text == "object";
|
||||
}
|
||||
|
||||
// Exports from this module
|
||||
module.exports = PostTab;
|
|
@ -1,21 +0,0 @@
|
|||
/* 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/. */
|
||||
|
||||
/******************************************************************************/
|
||||
/* Response Tab */
|
||||
|
||||
.netInfoBody .netInfoBodiesDiscarded {
|
||||
font-style: italic;
|
||||
color: gray;
|
||||
}
|
||||
|
||||
.netInfoBody .netInfoResponseContent {
|
||||
font-family: var(--monospace-font-family);
|
||||
word-wrap: break-word;
|
||||
}
|
||||
|
||||
.netInfoBody .responseTabBox img {
|
||||
max-width: 300px;
|
||||
max-height: 300px;
|
||||
}
|
|
@ -1,291 +0,0 @@
|
|||
/* 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";
|
||||
|
||||
const { Component, createFactory } = require("devtools/client/shared/vendor/react");
|
||||
const dom = require("devtools/client/shared/vendor/react-dom-factories");
|
||||
const PropTypes = require("devtools/client/shared/vendor/react-prop-types");
|
||||
|
||||
// Reps
|
||||
const TreeView = createFactory(require("devtools/client/shared/components/tree/TreeView"));
|
||||
const { REPS, MODE } = require("devtools/client/shared/components/reps/reps");
|
||||
const { Rep } = REPS;
|
||||
|
||||
// Network
|
||||
const SizeLimit = createFactory(require("./size-limit"));
|
||||
const NetInfoGroupList = createFactory(require("./net-info-group-list"));
|
||||
const Spinner = createFactory(require("./spinner"));
|
||||
const Json = require("../utils/json");
|
||||
const NetUtils = require("../utils/net");
|
||||
|
||||
/**
|
||||
* This template represents 'Response' tab displayed when the user
|
||||
* expands network log in the Console panel. It's responsible for
|
||||
* rendering HTTP response body.
|
||||
*
|
||||
* In case of supported response mime-type (e.g. application/json,
|
||||
* text/xml, etc.), the response is parsed using appropriate parser
|
||||
* and rendered accordingly.
|
||||
*/
|
||||
class ResponseTab extends Component {
|
||||
static get propTypes() {
|
||||
return {
|
||||
data: PropTypes.shape({
|
||||
request: PropTypes.object.isRequired,
|
||||
response: PropTypes.object.isRequired
|
||||
}),
|
||||
actions: PropTypes.object.isRequired
|
||||
};
|
||||
}
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.isJson = this.isJson.bind(this);
|
||||
this.parseJson = this.parseJson.bind(this);
|
||||
this.isImage = this.isImage.bind(this);
|
||||
this.isXml = this.isXml.bind(this);
|
||||
this.parseXml = this.parseXml.bind(this);
|
||||
this.renderJson = this.renderJson.bind(this);
|
||||
this.renderImage = this.renderImage.bind(this);
|
||||
this.renderXml = this.renderXml.bind(this);
|
||||
this.renderFormattedResponse = this.renderFormattedResponse.bind(this);
|
||||
this.renderRawResponse = this.renderRawResponse.bind(this);
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
let { actions, data: file } = this.props;
|
||||
let content = file.response.content;
|
||||
|
||||
if (!content || typeof (content.text) == "undefined") {
|
||||
// TODO: use async action objects as soon as Redux is in place
|
||||
actions.requestData("responseContent");
|
||||
}
|
||||
}
|
||||
|
||||
// Response Types
|
||||
|
||||
isJson(content) {
|
||||
if (isLongString(content.text)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return Json.isJSON(content.mimeType, content.text);
|
||||
}
|
||||
|
||||
parseJson(file) {
|
||||
let content = file.response.content;
|
||||
if (isLongString(content.text)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
let jsonString = new String(content.text);
|
||||
return Json.parseJSONString(jsonString);
|
||||
}
|
||||
|
||||
isImage(content) {
|
||||
if (isLongString(content.text)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return NetUtils.isImage(content.mimeType);
|
||||
}
|
||||
|
||||
isXml(content) {
|
||||
if (isLongString(content.text)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return NetUtils.isHTML(content.mimeType);
|
||||
}
|
||||
|
||||
parseXml(file) {
|
||||
let content = file.response.content;
|
||||
if (isLongString(content.text)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return NetUtils.parseXml(content);
|
||||
}
|
||||
|
||||
// Rendering
|
||||
|
||||
renderJson(file) {
|
||||
let content = file.response.content;
|
||||
if (!this.isJson(content)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
let json = this.parseJson(file);
|
||||
if (!json) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return {
|
||||
key: "json",
|
||||
content: TreeView({
|
||||
columns: [{id: "value"}],
|
||||
object: json,
|
||||
mode: MODE.TINY,
|
||||
renderValue: props => Rep(Object.assign({}, props, {
|
||||
cropLimit: 50,
|
||||
})),
|
||||
}),
|
||||
name: Locale.$STR("jsonScopeName")
|
||||
};
|
||||
}
|
||||
|
||||
renderImage(file) {
|
||||
let content = file.response.content;
|
||||
if (!this.isImage(content)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
let dataUri = "data:" + content.mimeType + ";base64," + content.text;
|
||||
return {
|
||||
key: "image",
|
||||
content: dom.img({src: dataUri}),
|
||||
name: Locale.$STR("netRequest.image")
|
||||
};
|
||||
}
|
||||
|
||||
renderXml(file) {
|
||||
let content = file.response.content;
|
||||
if (!this.isXml(content)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
let doc = this.parseXml(file);
|
||||
if (!doc) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Proper component for rendering XML should be used (see bug 1247392)
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* If full response text is available, let's try to parse and
|
||||
* present nicely according to the underlying format.
|
||||
*/
|
||||
renderFormattedResponse(file) {
|
||||
let content = file.response.content;
|
||||
if (typeof content.text == "object") {
|
||||
return null;
|
||||
}
|
||||
|
||||
let group = this.renderJson(file);
|
||||
if (group) {
|
||||
return group;
|
||||
}
|
||||
|
||||
group = this.renderImage(file);
|
||||
if (group) {
|
||||
return group;
|
||||
}
|
||||
|
||||
group = this.renderXml(file);
|
||||
if (group) {
|
||||
return group;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
renderRawResponse(file) {
|
||||
let group;
|
||||
let content = file.response.content;
|
||||
|
||||
// The response might reached the limit, so check if we are
|
||||
// dealing with a long string.
|
||||
if (typeof content.text == "object") {
|
||||
group = {
|
||||
key: "raw-longstring",
|
||||
name: Locale.$STR("netRequest.rawData"),
|
||||
content: dom.div({className: "netInfoResponseContent"},
|
||||
content.text.initial,
|
||||
SizeLimit({
|
||||
actions: this.props.actions,
|
||||
data: content,
|
||||
message: Locale.$STR("netRequest.sizeLimitMessage"),
|
||||
link: Locale.$STR("netRequest.sizeLimitMessageLink")
|
||||
})
|
||||
)
|
||||
};
|
||||
} else {
|
||||
group = {
|
||||
key: "raw",
|
||||
name: Locale.$STR("netRequest.rawData"),
|
||||
content: dom.div({className: "netInfoResponseContent"},
|
||||
content.text
|
||||
)
|
||||
};
|
||||
}
|
||||
|
||||
return group;
|
||||
}
|
||||
|
||||
/**
|
||||
* The response panel displays two groups:
|
||||
*
|
||||
* 1) Formatted response (in case of supported format, e.g. JSON, XML, etc.)
|
||||
* 2) Raw response data (always displayed if not discarded)
|
||||
*/
|
||||
render() {
|
||||
let { data: file } = this.props;
|
||||
|
||||
// If response bodies are discarded (not collected) let's just
|
||||
// display a info message indicating what to do to collect even
|
||||
// response bodies.
|
||||
if (file.discardResponseBody) {
|
||||
return dom.span({className: "netInfoBodiesDiscarded"},
|
||||
Locale.$STR("netRequest.responseBodyDiscarded")
|
||||
);
|
||||
}
|
||||
|
||||
// Request for the response content is done only if the response
|
||||
// is not fetched yet - i.e. the `content.text` is undefined.
|
||||
// Empty content.text` can also be a valid response either
|
||||
// empty or not available yet.
|
||||
let content = file.response.content;
|
||||
if (!content || typeof (content.text) == "undefined") {
|
||||
return (
|
||||
Spinner()
|
||||
);
|
||||
}
|
||||
|
||||
// Render response body data. The right representation of the data
|
||||
// is picked according to the content type.
|
||||
let groups = [];
|
||||
groups.push(this.renderFormattedResponse(file));
|
||||
groups.push(this.renderRawResponse(file));
|
||||
|
||||
// Filter out empty groups.
|
||||
groups = groups.filter(group => group);
|
||||
|
||||
// The raw response is collapsed by default if a nice formatted
|
||||
// version is available.
|
||||
if (groups.length > 1) {
|
||||
groups[1].open = false;
|
||||
}
|
||||
|
||||
return (
|
||||
dom.div({className: "responseTabBox"},
|
||||
dom.div({className: "panelContent"},
|
||||
NetInfoGroupList({
|
||||
groups: groups
|
||||
})
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Helpers
|
||||
|
||||
function isLongString(text) {
|
||||
return typeof text == "object";
|
||||
}
|
||||
|
||||
// Exports from this module
|
||||
module.exports = ResponseTab;
|
|
@ -1,15 +0,0 @@
|
|||
/* 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/. */
|
||||
|
||||
/******************************************************************************/
|
||||
/* Response Size Limit */
|
||||
|
||||
.netInfoBody .netInfoSizeLimit {
|
||||
font-weight: bold;
|
||||
padding-top: 10px;
|
||||
}
|
||||
|
||||
.netInfoBody .netInfoSizeLimit .objectLink {
|
||||
color: var(--theme-highlight-blue);
|
||||
}
|
|
@ -1,65 +0,0 @@
|
|||
/* 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";
|
||||
|
||||
const { Component } = require("devtools/client/shared/vendor/react");
|
||||
const PropTypes = require("devtools/client/shared/vendor/react-prop-types");
|
||||
const dom = require("devtools/client/shared/vendor/react-dom-factories");
|
||||
|
||||
/**
|
||||
* This template represents a size limit notification message
|
||||
* used e.g. in the Response tab when response body exceeds
|
||||
* size limit. The message contains a link allowing the user
|
||||
* to fetch the rest of the data from the backend (debugger server).
|
||||
*/
|
||||
class SizeLimit extends Component {
|
||||
static get propTypes() {
|
||||
return {
|
||||
data: PropTypes.object.isRequired,
|
||||
message: PropTypes.string.isRequired,
|
||||
link: PropTypes.string.isRequired,
|
||||
actions: PropTypes.shape({
|
||||
resolveString: PropTypes.func.isRequired
|
||||
}),
|
||||
};
|
||||
}
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.onClickLimit = this.onClickLimit.bind(this);
|
||||
}
|
||||
|
||||
// Event Handlers
|
||||
|
||||
onClickLimit(event) {
|
||||
let actions = this.props.actions;
|
||||
let content = this.props.data;
|
||||
|
||||
actions.resolveString(content, "text");
|
||||
}
|
||||
|
||||
// Rendering
|
||||
|
||||
render() {
|
||||
let message = this.props.message;
|
||||
let link = this.props.link;
|
||||
let reLink = /^(.*)\{\{link\}\}(.*$)/;
|
||||
let m = message.match(reLink);
|
||||
|
||||
return (
|
||||
dom.div({className: "netInfoSizeLimit"},
|
||||
dom.span({}, m[1]),
|
||||
dom.a({
|
||||
className: "objectLink",
|
||||
onClick: this.onClickLimit},
|
||||
link
|
||||
),
|
||||
dom.span({}, m[2])
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Exports from this module
|
||||
module.exports = SizeLimit;
|
|
@ -1,22 +0,0 @@
|
|||
/* 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";
|
||||
|
||||
const { Component } = require("devtools/client/shared/vendor/react");
|
||||
const dom = require("devtools/client/shared/vendor/react-dom-factories");
|
||||
|
||||
/**
|
||||
* This template represents a throbber displayed when the UI
|
||||
* is waiting for data coming from the backend (debugging server).
|
||||
*/
|
||||
class Spinner extends Component {
|
||||
render() {
|
||||
return (
|
||||
dom.div({className: "devtools-throbber"})
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Exports from this module
|
||||
module.exports = Spinner;
|
|
@ -1,33 +0,0 @@
|
|||
/* 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";
|
||||
|
||||
const { Component, createFactory } = require("devtools/client/shared/vendor/react");
|
||||
const PropTypes = require("devtools/client/shared/vendor/react-prop-types");
|
||||
const StackTrace =
|
||||
createFactory(require("devtools/client/shared/components/StackTrace"));
|
||||
|
||||
class StackTraceTab extends Component {
|
||||
static get propTypes() {
|
||||
return {
|
||||
data: PropTypes.object.isRequired,
|
||||
actions: PropTypes.shape({
|
||||
onViewSourceInDebugger: PropTypes.func.isRequired
|
||||
}),
|
||||
// Service to enable the source map feature.
|
||||
sourceMapService: PropTypes.object,
|
||||
};
|
||||
}
|
||||
|
||||
render() {
|
||||
let { stacktrace } = this.props.data.cause;
|
||||
let { actions, sourceMapService } = this.props;
|
||||
let onViewSourceInDebugger = actions.onViewSourceInDebugger.bind(actions);
|
||||
|
||||
return StackTrace({ stacktrace, onViewSourceInDebugger, sourceMapService });
|
||||
}
|
||||
}
|
||||
|
||||
// Exports from this module
|
||||
module.exports = StackTraceTab;
|
|
@ -1,67 +0,0 @@
|
|||
/* 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";
|
||||
|
||||
const promise = require("promise");
|
||||
const defer = require("devtools/shared/defer");
|
||||
|
||||
/**
|
||||
* Map of pending requests. Used mainly by tests to wait
|
||||
* till things are ready.
|
||||
*/
|
||||
var promises = new Map();
|
||||
|
||||
/**
|
||||
* This object is used to fetch network data from the backend.
|
||||
* Communication with the chrome scope is based on message
|
||||
* exchange.
|
||||
*/
|
||||
var DataProvider = {
|
||||
hasPendingRequests: function () {
|
||||
return promises.size > 0;
|
||||
},
|
||||
|
||||
requestData: function (client, actor, method) {
|
||||
let key = actor + ":" + method;
|
||||
let p = promises.get(key);
|
||||
if (p) {
|
||||
return p;
|
||||
}
|
||||
|
||||
let deferred = defer();
|
||||
let realMethodName = "get" + method.charAt(0).toUpperCase() +
|
||||
method.slice(1);
|
||||
|
||||
if (!client[realMethodName]) {
|
||||
return null;
|
||||
}
|
||||
|
||||
client[realMethodName](actor, response => {
|
||||
promises.delete(key);
|
||||
deferred.resolve(response);
|
||||
});
|
||||
|
||||
promises.set(key, deferred.promise);
|
||||
return deferred.promise;
|
||||
},
|
||||
|
||||
resolveString: function (client, stringGrip) {
|
||||
let key = stringGrip.actor + ":getString";
|
||||
let p = promises.get(key);
|
||||
if (p) {
|
||||
return p;
|
||||
}
|
||||
|
||||
p = client.getString(stringGrip).then(result => {
|
||||
promises.delete(key);
|
||||
return result;
|
||||
});
|
||||
|
||||
promises.set(key, p);
|
||||
return p;
|
||||
},
|
||||
};
|
||||
|
||||
// Exports from this module
|
||||
module.exports = DataProvider;
|
|
@ -1,95 +0,0 @@
|
|||
/* 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";
|
||||
|
||||
/* global BrowserLoader */
|
||||
|
||||
// Initialize module loader and load all modules of the new inline
|
||||
// preview feature. The entire code-base doesn't need any extra
|
||||
// privileges and runs entirely in content scope.
|
||||
const rootUrl = "resource://devtools/client/webconsole/old/net/";
|
||||
const require = BrowserLoader({
|
||||
baseURI: rootUrl,
|
||||
window}).require;
|
||||
|
||||
const NetRequest = require("./net-request");
|
||||
const { loadSheet } = require("devtools/shared/layout/utils");
|
||||
|
||||
// Localization
|
||||
const {LocalizationHelper} = require("devtools/shared/l10n");
|
||||
const L10N = new LocalizationHelper("devtools/client/locales/netmonitor.properties");
|
||||
|
||||
// Stylesheets
|
||||
var styleSheets = [
|
||||
"resource://devtools/client/jsonview/css/toolbar.css",
|
||||
"resource://devtools/client/shared/components/tree/TreeView.css",
|
||||
"resource://devtools/client/shared/components/reps.css",
|
||||
"resource://devtools/client/webconsole/old/net/net-request.css",
|
||||
"resource://devtools/client/webconsole/old/net/components/size-limit.css",
|
||||
"resource://devtools/client/webconsole/old/net/components/net-info-body.css",
|
||||
"resource://devtools/client/webconsole/old/net/components/net-info-group.css",
|
||||
"resource://devtools/client/webconsole/old/net/components/net-info-params.css",
|
||||
"resource://devtools/client/webconsole/old/net/components/response-tab.css"
|
||||
];
|
||||
|
||||
// Load theme stylesheets into the Console frame. This should be
|
||||
// done automatically by UI Components as soon as we have consensus
|
||||
// on the right CSS strategy FIXME.
|
||||
// It would also be nice to include them using @import.
|
||||
styleSheets.forEach(url => {
|
||||
loadSheet(window, url, "author");
|
||||
});
|
||||
|
||||
// Localization API used by React components
|
||||
// accessing strings from *.properties file.
|
||||
// Example:
|
||||
// let localizedString = Locale.$STR('string-key');
|
||||
//
|
||||
// Resources:
|
||||
// http://l20n.org/
|
||||
// https://github.com/yahoo/react-intl
|
||||
this.Locale = {
|
||||
$STR: key => {
|
||||
try {
|
||||
return L10N.getStr(key);
|
||||
} catch (err) {
|
||||
console.error(key + ": " + err);
|
||||
}
|
||||
return key;
|
||||
}
|
||||
};
|
||||
|
||||
// List of NetRequest instances represents the state.
|
||||
// As soon as Redux is in place it should be maintained using a reducer.
|
||||
var netRequests = new Map();
|
||||
|
||||
/**
|
||||
* This function handles network events received from the backend. It's
|
||||
* executed from within the webconsole.js
|
||||
*/
|
||||
function onNetworkEvent(log) {
|
||||
// The 'from' field is set only in case of a 'networkEventUpdate' packet.
|
||||
// The initial 'networkEvent' packet uses 'actor'.
|
||||
// Check if NetRequest object is already created for this event actor and
|
||||
// if there is none make sure to create one.
|
||||
let response = log.response;
|
||||
let netRequest = response.from ? netRequests.get(response.from) : null;
|
||||
if (!netRequest && !log.update) {
|
||||
netRequest = new NetRequest(log);
|
||||
netRequests.set(response.actor, netRequest);
|
||||
}
|
||||
|
||||
if (!netRequest) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (log.update) {
|
||||
netRequest.updateBody(response);
|
||||
}
|
||||
}
|
||||
|
||||
// Make the 'onNetworkEvent' accessible from chrome (see webconsole.js)
|
||||
this.NetRequest = {
|
||||
onNetworkEvent: onNetworkEvent
|
||||
};
|
|
@ -1,19 +0,0 @@
|
|||
# vim: set filetype=python:
|
||||
# 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/.
|
||||
|
||||
DIRS += [
|
||||
'components',
|
||||
'utils'
|
||||
]
|
||||
|
||||
DevToolsModules(
|
||||
'data-provider.js',
|
||||
'main.js',
|
||||
'net-request.css',
|
||||
'net-request.js',
|
||||
)
|
||||
|
||||
XPCSHELL_TESTS_MANIFESTS += ['test/unit/xpcshell.ini']
|
||||
BROWSER_CHROME_MANIFESTS += ['test/mochitest/browser.ini']
|
|
@ -1,31 +0,0 @@
|
|||
/* 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/. */
|
||||
|
||||
/******************************************************************************/
|
||||
/* General */
|
||||
|
||||
:root {
|
||||
--net-border: #d7d7d7;
|
||||
}
|
||||
|
||||
:root.theme-dark {
|
||||
--net-border: #5f7387;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
/* Network log */
|
||||
|
||||
/* No background if a Net log is opened */
|
||||
.netRequest.message.opened,
|
||||
.netRequest.message.opened:hover {
|
||||
background: transparent !important;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
/* Themes */
|
||||
|
||||
.theme-dark .netRequest.opened:hover,
|
||||
.theme-dark .netRequest.opened {
|
||||
background: transparent;
|
||||
}
|
|
@ -1,324 +0,0 @@
|
|||
/* 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";
|
||||
|
||||
// React
|
||||
const React = require("devtools/client/shared/vendor/react");
|
||||
const ReactDOM = require("devtools/client/shared/vendor/react-dom");
|
||||
|
||||
// Reps
|
||||
const { parseURLParams } = require("devtools/client/shared/components/reps/reps");
|
||||
|
||||
// Network
|
||||
const { cancelEvent, isLeftClick } = require("./utils/events");
|
||||
const NetInfoBody = React.createFactory(require("./components/net-info-body"));
|
||||
const DataProvider = require("./data-provider");
|
||||
|
||||
// Constants
|
||||
const XHTML_NS = "http://www.w3.org/1999/xhtml";
|
||||
|
||||
/**
|
||||
* This object represents a network log in the Console panel (and in the
|
||||
* Network panel in the future).
|
||||
* It's associated with an existing log and so, also with an existing
|
||||
* element in the DOM.
|
||||
*
|
||||
* The object neither render no request for more data by default. It only
|
||||
* reqisters a click listener to the associated log entry (a network event)
|
||||
* and changes the class attribute of the log entry, so a twisty icon
|
||||
* appears to indicates that there are more details displayed if the
|
||||
* log entry is expanded.
|
||||
*
|
||||
* When the user expands the log, data are requested from the backend
|
||||
* and rendered directly within the Console iframe.
|
||||
*/
|
||||
function NetRequest(log) {
|
||||
this.initialize(log);
|
||||
}
|
||||
|
||||
NetRequest.prototype = {
|
||||
initialize: function (log) {
|
||||
this.client = log.consoleFrame.webConsoleClient;
|
||||
this.owner = log.consoleFrame.owner;
|
||||
|
||||
// 'this.file' field is following HAR spec.
|
||||
// http://www.softwareishard.com/blog/har-12-spec/
|
||||
this.file = log.response;
|
||||
this.parentNode = log.node;
|
||||
this.file.request.queryString = parseURLParams(this.file.request.url);
|
||||
this.hasCookies = false;
|
||||
|
||||
// Map of fetched responses (to avoid unnecessary RDP round trip).
|
||||
this.cachedResponses = new Map();
|
||||
|
||||
let doc = this.parentNode.ownerDocument;
|
||||
let twisty = doc.createElementNS(XHTML_NS, "a");
|
||||
twisty.className = "theme-twisty";
|
||||
twisty.href = "#";
|
||||
|
||||
let messageBody = this.parentNode.querySelector(".message-body-wrapper");
|
||||
this.parentNode.insertBefore(twisty, messageBody);
|
||||
this.parentNode.setAttribute("collapsible", true);
|
||||
|
||||
this.parentNode.classList.add("netRequest");
|
||||
|
||||
// Register a click listener.
|
||||
this.addClickListener();
|
||||
},
|
||||
|
||||
addClickListener: function () {
|
||||
// Add an event listener to toggle the expanded state when clicked.
|
||||
// The event bubbling is canceled if the user clicks on the log
|
||||
// itself (not on the expanded body), so opening of the default
|
||||
// modal dialog is avoided.
|
||||
this.parentNode.addEventListener("click", (event) => {
|
||||
if (!isLeftClick(event)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Clicking on the toggle button or the method expands/collapses
|
||||
// the body with HTTP details.
|
||||
let classList = event.originalTarget.classList;
|
||||
if (!(classList.contains("theme-twisty") ||
|
||||
classList.contains("method"))) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Alright, the user is clicking fine, let's open HTTP details!
|
||||
this.onToggleBody(event);
|
||||
|
||||
// Avoid the default modal dialog
|
||||
cancelEvent(event);
|
||||
}, true);
|
||||
},
|
||||
|
||||
onToggleBody: function (event) {
|
||||
let target = event.currentTarget;
|
||||
let logRow = target.closest(".netRequest");
|
||||
logRow.classList.toggle("opened");
|
||||
|
||||
let twisty = this.parentNode.querySelector(".theme-twisty");
|
||||
if (logRow.classList.contains("opened")) {
|
||||
twisty.setAttribute("open", true);
|
||||
} else {
|
||||
twisty.removeAttribute("open");
|
||||
}
|
||||
|
||||
let isOpen = logRow.classList.contains("opened");
|
||||
if (isOpen) {
|
||||
this.renderBody();
|
||||
} else {
|
||||
this.closeBody();
|
||||
}
|
||||
},
|
||||
|
||||
updateCookies: function(method, response) {
|
||||
// TODO: This code will be part of a reducer.
|
||||
let result;
|
||||
if (response.cookies > 0 &&
|
||||
["requestCookies", "responseCookies"].includes(method)) {
|
||||
this.hasCookies = true;
|
||||
this.refresh();
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Executed when 'networkEventUpdate' is received from the backend.
|
||||
*/
|
||||
updateBody: function (response) {
|
||||
// 'networkEventUpdate' event indicates that there are new data
|
||||
// available on the backend. The following logic checks the response
|
||||
// cache and if this data has been already requested before they
|
||||
// need to be updated now (re-requested).
|
||||
let method = response.updateType;
|
||||
this.updateCookies(method, response);
|
||||
if (this.cachedResponses.get(method)) {
|
||||
this.cachedResponses.delete(method);
|
||||
this.requestData(method);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Close network inline preview body.
|
||||
*/
|
||||
closeBody: function () {
|
||||
this.netInfoBodyBox.remove();
|
||||
},
|
||||
|
||||
/**
|
||||
* Render network inline preview body.
|
||||
*/
|
||||
renderBody: function () {
|
||||
let messageBody = this.parentNode.querySelector(".message-body-wrapper");
|
||||
|
||||
// Create box for all markup rendered by ReactJS. Since we are
|
||||
// rendering within webconsole.xul (i.e. XUL document) we need
|
||||
// to explicitly specify XHTML namespace.
|
||||
let doc = messageBody.ownerDocument;
|
||||
this.netInfoBodyBox = doc.createElementNS(XHTML_NS, "div");
|
||||
this.netInfoBodyBox.classList.add("netInfoBody");
|
||||
messageBody.appendChild(this.netInfoBodyBox);
|
||||
|
||||
// As soon as Redux is in place state and actions will come from
|
||||
// separate modules.
|
||||
let body = NetInfoBody({
|
||||
actions: this,
|
||||
sourceMapService: this.owner.sourceMapURLService,
|
||||
});
|
||||
|
||||
// Render net info body!
|
||||
this.body = ReactDOM.render(body, this.netInfoBodyBox);
|
||||
|
||||
this.refresh();
|
||||
},
|
||||
|
||||
/**
|
||||
* Render top level ReactJS component.
|
||||
*/
|
||||
refresh: function () {
|
||||
if (!this.netInfoBodyBox) {
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO: As soon as Redux is in place there will be reducer
|
||||
// computing a new state.
|
||||
let newState = Object.assign({}, this.body.state, {
|
||||
data: this.file,
|
||||
hasCookies: this.hasCookies
|
||||
});
|
||||
|
||||
this.body.setState(newState);
|
||||
},
|
||||
|
||||
// Communication with the backend
|
||||
|
||||
requestData: function (method) {
|
||||
// If the response has already been received bail out.
|
||||
let response = this.cachedResponses.get(method);
|
||||
if (response) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Set an attribute indicating that this net log is waiting for
|
||||
// data coming from the backend. Intended mainly for tests.
|
||||
this.parentNode.setAttribute("loading", "true");
|
||||
|
||||
let actor = this.file.actor;
|
||||
DataProvider.requestData(this.client, actor, method).then(args => {
|
||||
this.cachedResponses.set(method, args);
|
||||
this.onRequestData(method, args);
|
||||
|
||||
if (!DataProvider.hasPendingRequests()) {
|
||||
this.parentNode.removeAttribute("loading");
|
||||
|
||||
// Fire an event indicating that all pending requests for
|
||||
// data from the backend has finished. Intended for tests.
|
||||
// Do it asynchronously so, it's done after all handlers
|
||||
// for the current promise are executed.
|
||||
setTimeout(() => {
|
||||
let event = document.createEvent("Event");
|
||||
event.initEvent("netlog-no-pending-requests", true, true);
|
||||
this.parentNode.dispatchEvent(event);
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
onRequestData: function (method, response) {
|
||||
// TODO: This code will be part of a reducer.
|
||||
let result;
|
||||
switch (method) {
|
||||
case "requestHeaders":
|
||||
result = this.onRequestHeaders(response);
|
||||
break;
|
||||
case "responseHeaders":
|
||||
result = this.onResponseHeaders(response);
|
||||
break;
|
||||
case "requestCookies":
|
||||
result = this.onRequestCookies(response);
|
||||
break;
|
||||
case "responseCookies":
|
||||
result = this.onResponseCookies(response);
|
||||
break;
|
||||
case "responseContent":
|
||||
result = this.onResponseContent(response);
|
||||
break;
|
||||
case "requestPostData":
|
||||
result = this.onRequestPostData(response);
|
||||
break;
|
||||
}
|
||||
|
||||
result.then(() => {
|
||||
this.refresh();
|
||||
});
|
||||
},
|
||||
|
||||
onRequestHeaders: function (response) {
|
||||
this.file.request.headers = response.headers;
|
||||
|
||||
return this.resolveHeaders(this.file.request.headers);
|
||||
},
|
||||
|
||||
onResponseHeaders: function (response) {
|
||||
this.file.response.headers = response.headers;
|
||||
|
||||
return this.resolveHeaders(this.file.response.headers);
|
||||
},
|
||||
|
||||
onResponseContent: function (response) {
|
||||
let content = response.content;
|
||||
|
||||
for (let p in content) {
|
||||
this.file.response.content[p] = content[p];
|
||||
}
|
||||
|
||||
return Promise.resolve();
|
||||
},
|
||||
|
||||
onRequestPostData: function (response) {
|
||||
this.file.request.postData = response.postData;
|
||||
return Promise.resolve();
|
||||
},
|
||||
|
||||
onRequestCookies: function (response) {
|
||||
this.file.request.cookies = response.cookies;
|
||||
return this.resolveHeaders(this.file.request.cookies);
|
||||
},
|
||||
|
||||
onResponseCookies: function (response) {
|
||||
this.file.response.cookies = response.cookies;
|
||||
return this.resolveHeaders(this.file.response.cookies);
|
||||
},
|
||||
|
||||
onViewSourceInDebugger: function (frame) {
|
||||
this.owner.viewSourceInDebugger(frame.source, frame.line);
|
||||
},
|
||||
|
||||
resolveHeaders: function (headers) {
|
||||
let promises = [];
|
||||
|
||||
for (let header of headers) {
|
||||
if (typeof header.value == "object") {
|
||||
promises.push(this.resolveString(header.value).then(value => {
|
||||
header.value = value;
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
return Promise.all(promises);
|
||||
},
|
||||
|
||||
resolveString: function (object, propName) {
|
||||
let stringGrip = object[propName];
|
||||
if (typeof stringGrip == "object") {
|
||||
DataProvider.resolveString(this.client, stringGrip).then(args => {
|
||||
object[propName] = args;
|
||||
this.refresh();
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// Exports from this module
|
||||
module.exports = NetRequest;
|
|
@ -1,6 +0,0 @@
|
|||
"use strict";
|
||||
|
||||
module.exports = {
|
||||
// Extend from the shared list of defined globals for mochitests.
|
||||
"extends": "../../../../../../.eslintrc.mochitests.js",
|
||||
};
|
|
@ -1,23 +0,0 @@
|
|||
[DEFAULT]
|
||||
tags = devtools
|
||||
subsuite = devtools
|
||||
support-files =
|
||||
head.js
|
||||
page_basic.html
|
||||
test.json
|
||||
test.json^headers^
|
||||
test-cookies.json
|
||||
test-cookies.json^headers^
|
||||
test.txt
|
||||
test.xml
|
||||
test.xml^headers^
|
||||
!/devtools/client/shared/test/frame-script-utils.js
|
||||
!/devtools/client/shared/test/shared-head.js
|
||||
!/devtools/client/webconsole/old/test/head.js
|
||||
|
||||
[browser_net_basic.js]
|
||||
[browser_net_cookies.js]
|
||||
[browser_net_headers.js]
|
||||
[browser_net_params.js]
|
||||
[browser_net_post.js]
|
||||
[browser_net_response.js]
|
|
@ -1,33 +0,0 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim: set ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
const TEST_PAGE_URL = URL_ROOT + "page_basic.html";
|
||||
const JSON_XHR_URL = URL_ROOT + "test.json";
|
||||
|
||||
/**
|
||||
* Basic test that generates XHR in the content and
|
||||
* checks the related log in the Console panel can
|
||||
* be expanded.
|
||||
*/
|
||||
add_task(async function () {
|
||||
info("Test XHR Spy basic started");
|
||||
|
||||
let {hud} = await addTestTab(TEST_PAGE_URL);
|
||||
|
||||
let netInfoBody = await executeAndInspectXhr(hud, {
|
||||
method: "GET",
|
||||
url: JSON_XHR_URL
|
||||
});
|
||||
|
||||
ok(netInfoBody, "The network details must be available");
|
||||
|
||||
// There should be at least two tabs: Headers and Response
|
||||
ok(netInfoBody.querySelector(".tabs .tabs-menu-item.headers"),
|
||||
"Headers tab must be available");
|
||||
ok(netInfoBody.querySelector(".tabs .tabs-menu-item.response"),
|
||||
"Response tab must be available");
|
||||
});
|
|
@ -1,54 +0,0 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim: set ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
const TEST_PAGE_URL = URL_ROOT + "page_basic.html";
|
||||
const JSON_XHR_URL = URL_ROOT + "test-cookies.json";
|
||||
|
||||
/**
|
||||
* This test generates XHR requests in the page, expands
|
||||
* networks details in the Console panel and checks that
|
||||
* Cookies are properly displayed.
|
||||
*/
|
||||
add_task(async function () {
|
||||
info("Test XHR Spy cookies started");
|
||||
|
||||
let {hud} = await addTestTab(TEST_PAGE_URL);
|
||||
|
||||
let netInfoBody = await executeAndInspectXhr(hud, {
|
||||
method: "GET",
|
||||
url: JSON_XHR_URL
|
||||
});
|
||||
|
||||
// Select "Cookies" tab
|
||||
let tabBody = await selectNetInfoTab(hud, netInfoBody, "cookies");
|
||||
|
||||
let requestCookieName = tabBody.querySelector(
|
||||
".netInfoGroup.requestCookies .netInfoParamName > span[title='bar']");
|
||||
|
||||
// Verify request cookies (name and value)
|
||||
ok(requestCookieName, "Request Cookie name must exist");
|
||||
is(requestCookieName.textContent, "bar",
|
||||
"The cookie name must have proper value");
|
||||
|
||||
let requestCookieValue = requestCookieName.parentNode.nextSibling;
|
||||
ok(requestCookieValue, "Request Cookie value must exist");
|
||||
is(requestCookieValue.textContent, "foo",
|
||||
"The cookie value must have proper value");
|
||||
|
||||
let responseCookieName = tabBody.querySelector(
|
||||
".netInfoGroup.responseCookies .netInfoParamName > span[title='test']");
|
||||
|
||||
// Verify response cookies (name and value)
|
||||
ok(responseCookieName, "Response Cookie name must exist");
|
||||
is(responseCookieName.textContent, "test",
|
||||
"The cookie name must have proper value");
|
||||
|
||||
let responseCookieValue = responseCookieName.parentNode.nextSibling;
|
||||
ok(responseCookieValue, "Response Cookie value must exist");
|
||||
is(responseCookieValue.textContent, "abc",
|
||||
"The cookie value must have proper value");
|
||||
});
|
|
@ -1,43 +0,0 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim: set ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
const TEST_PAGE_URL = URL_ROOT + "page_basic.html";
|
||||
const JSON_XHR_URL = URL_ROOT + "test.json";
|
||||
|
||||
/**
|
||||
* This test generates XHR requests in the page, expands
|
||||
* networks details in the Console panel and checks that
|
||||
* HTTP headers are there.
|
||||
*/
|
||||
add_task(async function () {
|
||||
// Disable rcwn to make cache behavior deterministic.
|
||||
await pushPref("network.http.rcwn.enabled", false);
|
||||
|
||||
info("Test XHR Spy headers started");
|
||||
|
||||
let {hud} = await addTestTab(TEST_PAGE_URL);
|
||||
|
||||
let netInfoBody = await executeAndInspectXhr(hud, {
|
||||
method: "GET",
|
||||
url: JSON_XHR_URL
|
||||
});
|
||||
|
||||
// Select "Headers" tab
|
||||
let tabBody = await selectNetInfoTab(hud, netInfoBody, "headers");
|
||||
let paramName = tabBody.querySelector(
|
||||
".netInfoParamName > span[title='content-type']");
|
||||
|
||||
// Verify "Content-Type" header (name and value)
|
||||
ok(paramName, "Header name must exist");
|
||||
is(paramName.textContent, "content-type",
|
||||
"The header name must have proper value");
|
||||
|
||||
let paramValue = paramName.parentNode.nextSibling;
|
||||
ok(paramValue, "Header value must exist");
|
||||
is(paramValue.textContent, "application/json; charset=utf-8",
|
||||
"The header value must have proper value");
|
||||
});
|
|
@ -1,69 +0,0 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim: set ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
const TEST_PAGE_URL = URL_ROOT + "page_basic.html";
|
||||
const JSON_XHR_URL = URL_ROOT + "test.json";
|
||||
|
||||
/**
|
||||
* This test generates XHR requests in the page, expands
|
||||
* networks details in the Console panel and checks that
|
||||
* HTTP parameters (query string) are there.
|
||||
*/
|
||||
add_task(async function () {
|
||||
info("Test XHR Spy params started");
|
||||
|
||||
let {hud} = await addTestTab(TEST_PAGE_URL);
|
||||
|
||||
let netInfoBody = await executeAndInspectXhr(hud, {
|
||||
method: "GET",
|
||||
url: JSON_XHR_URL,
|
||||
queryString: "?foo=bar"
|
||||
});
|
||||
|
||||
// Check headers
|
||||
let tabBody = await selectNetInfoTab(hud, netInfoBody, "params");
|
||||
|
||||
let paramName = tabBody.querySelector(
|
||||
".netInfoParamName > span[title='foo']");
|
||||
|
||||
// Verify "Content-Type" header (name and value)
|
||||
ok(paramName, "Header name must exist");
|
||||
is(paramName.textContent, "foo",
|
||||
"The param name must have proper value");
|
||||
|
||||
let paramValue = paramName.parentNode.nextSibling;
|
||||
ok(paramValue, "param value must exist");
|
||||
is(paramValue.textContent, "bar",
|
||||
"The param value must have proper value");
|
||||
});
|
||||
|
||||
/**
|
||||
* Test URL parameters with the same name.
|
||||
*/
|
||||
add_task(async function () {
|
||||
info("Test XHR Spy params started");
|
||||
|
||||
let {hud} = await addTestTab(TEST_PAGE_URL);
|
||||
|
||||
let netInfoBody = await executeAndInspectXhr(hud, {
|
||||
method: "GET",
|
||||
url: JSON_XHR_URL,
|
||||
queryString: "?box[]=123&box[]=456"
|
||||
});
|
||||
|
||||
// Check headers
|
||||
let tabBody = await selectNetInfoTab(hud, netInfoBody, "params");
|
||||
|
||||
let params = tabBody.querySelectorAll(
|
||||
".netInfoParamName > span[title='box[]']");
|
||||
is(params.length, 2, "Two URI parameters must exist");
|
||||
|
||||
let values = tabBody.querySelectorAll(
|
||||
".netInfoParamValue > code");
|
||||
is(values[0].textContent, 123, "First value must match");
|
||||
is(values[1].textContent, 456, "Second value must match");
|
||||
});
|
|
@ -1,88 +0,0 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim: set ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
const TEST_PAGE_URL = URL_ROOT + "page_basic.html";
|
||||
const JSON_XHR_URL = URL_ROOT + "test.json";
|
||||
|
||||
const plainPostBody = "test-data";
|
||||
const jsonData = "{\"bar\": \"baz\"}";
|
||||
const jsonRendered = "bar\"baz\"";
|
||||
const xmlPostBody = "<xml><name>John</name></xml>";
|
||||
|
||||
/**
|
||||
* This test generates XHR requests in the page, expands
|
||||
* networks details in the Console panel and checks that
|
||||
* Post data are properly rendered.
|
||||
*/
|
||||
add_task(async function () {
|
||||
info("Test XHR Spy post plain body started");
|
||||
|
||||
let {hud} = await addTestTab(TEST_PAGE_URL);
|
||||
|
||||
let netInfoBody = await executeAndInspectXhr(hud, {
|
||||
method: "POST",
|
||||
url: JSON_XHR_URL,
|
||||
body: plainPostBody
|
||||
});
|
||||
|
||||
// Check post body data
|
||||
let tabBody = await selectNetInfoTab(hud, netInfoBody, "post");
|
||||
let postContent = tabBody.querySelector(
|
||||
".netInfoGroup.raw.opened .netInfoGroupContent");
|
||||
is(postContent.textContent, plainPostBody,
|
||||
"Post body must be properly rendered");
|
||||
});
|
||||
|
||||
add_task(async function () {
|
||||
info("Test XHR Spy post JSON body started");
|
||||
|
||||
let {hud} = await addTestTab(TEST_PAGE_URL);
|
||||
|
||||
let netInfoBody = await executeAndInspectXhr(hud, {
|
||||
method: "POST",
|
||||
url: JSON_XHR_URL,
|
||||
body: jsonData,
|
||||
requestHeaders: [{
|
||||
name: "Content-Type",
|
||||
value: "application/json"
|
||||
}]
|
||||
});
|
||||
|
||||
// Check post body data
|
||||
let tabBody = await selectNetInfoTab(hud, netInfoBody, "post");
|
||||
let postContent = tabBody.querySelector(
|
||||
".netInfoGroup.json.opened .netInfoGroupContent");
|
||||
is(postContent.textContent, jsonRendered,
|
||||
"Post body must be properly rendered");
|
||||
|
||||
let rawPostContent = tabBody.querySelector(
|
||||
".netInfoGroup.raw.opened .netInfoGroupContent");
|
||||
ok(!rawPostContent, "Raw response group must be collapsed");
|
||||
});
|
||||
|
||||
add_task(async function () {
|
||||
info("Test XHR Spy post XML body started");
|
||||
|
||||
let {hud} = await addTestTab(TEST_PAGE_URL);
|
||||
|
||||
let netInfoBody = await executeAndInspectXhr(hud, {
|
||||
method: "POST",
|
||||
url: JSON_XHR_URL,
|
||||
body: xmlPostBody,
|
||||
requestHeaders: [{
|
||||
name: "Content-Type",
|
||||
value: "application/xml"
|
||||
}]
|
||||
});
|
||||
|
||||
// Check post body data
|
||||
let tabBody = await selectNetInfoTab(hud, netInfoBody, "post");
|
||||
let rawPostContent = tabBody.querySelector(
|
||||
".netInfoGroup.raw.opened .netInfoGroupContent");
|
||||
is(rawPostContent.textContent, xmlPostBody,
|
||||
"Raw response group must not be collapsed");
|
||||
});
|
|
@ -1,86 +0,0 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim: set ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
const TEST_PAGE_URL = URL_ROOT + "page_basic.html";
|
||||
const TEXT_XHR_URL = URL_ROOT + "test.txt";
|
||||
const JSON_XHR_URL = URL_ROOT + "test.json";
|
||||
const XML_XHR_URL = URL_ROOT + "test.xml";
|
||||
|
||||
const textResponseBody = "this is a response";
|
||||
const jsonResponseBody = "name\"John\"";
|
||||
|
||||
// Individual tests below generate XHR request in the page, expand
|
||||
// network details in the Console panel and checks various types
|
||||
// of response bodies.
|
||||
|
||||
/**
|
||||
* Validate plain text response
|
||||
*/
|
||||
add_task(async function () {
|
||||
info("Test XHR Spy respone plain body started");
|
||||
|
||||
let {hud} = await addTestTab(TEST_PAGE_URL);
|
||||
|
||||
let netInfoBody = await executeAndInspectXhr(hud, {
|
||||
method: "GET",
|
||||
url: TEXT_XHR_URL,
|
||||
});
|
||||
|
||||
// Check response body data
|
||||
let tabBody = await selectNetInfoTab(hud, netInfoBody, "response");
|
||||
let responseContent = tabBody.querySelector(
|
||||
".netInfoGroup.raw.opened .netInfoGroupContent");
|
||||
|
||||
ok(responseContent.textContent.indexOf(textResponseBody) > -1,
|
||||
"Response body must be properly rendered");
|
||||
});
|
||||
|
||||
/**
|
||||
* Validate XML response
|
||||
*/
|
||||
add_task(async function () {
|
||||
info("Test XHR Spy response XML body started");
|
||||
|
||||
let {hud} = await addTestTab(TEST_PAGE_URL);
|
||||
|
||||
let netInfoBody = await executeAndInspectXhr(hud, {
|
||||
method: "GET",
|
||||
url: XML_XHR_URL,
|
||||
});
|
||||
|
||||
// Check response body data
|
||||
let tabBody = await selectNetInfoTab(hud, netInfoBody, "response");
|
||||
let rawResponseContent = tabBody.querySelector(
|
||||
".netInfoGroup.raw.opened .netInfoGroupContent");
|
||||
ok(rawResponseContent, "Raw response group must not be collapsed");
|
||||
});
|
||||
|
||||
/**
|
||||
* Validate JSON response
|
||||
*/
|
||||
add_task(async function () {
|
||||
info("Test XHR Spy response JSON body started");
|
||||
|
||||
let {hud} = await addTestTab(TEST_PAGE_URL);
|
||||
|
||||
let netInfoBody = await executeAndInspectXhr(hud, {
|
||||
method: "GET",
|
||||
url: JSON_XHR_URL,
|
||||
});
|
||||
|
||||
// Check response body data
|
||||
let tabBody = await selectNetInfoTab(hud, netInfoBody, "response");
|
||||
let responseContent = tabBody.querySelector(
|
||||
".netInfoGroup.json .netInfoGroupContent");
|
||||
|
||||
is(responseContent.textContent, jsonResponseBody,
|
||||
"Response body must be properly rendered");
|
||||
|
||||
let rawResponseContent = tabBody.querySelector(
|
||||
".netInfoGroup.raw.opened .netInfoGroupContent");
|
||||
ok(!rawResponseContent, "Raw response group must be collapsed");
|
||||
});
|
|
@ -1,201 +0,0 @@
|
|||
/* vim: set ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
/* eslint no-unused-vars: [2, {"vars": "local", "args": "none"}] */
|
||||
/* import-globals-from ../../../test/head.js */
|
||||
|
||||
"use strict";
|
||||
|
||||
// Load Web Console head.js, it implements helper console test API
|
||||
Services.scriptloader.loadSubScript(
|
||||
"chrome://mochitests/content/browser/devtools/client/webconsole/old/test/head.js", this);
|
||||
|
||||
const NET_INFO_PREF = "devtools.webconsole.filter.networkinfo";
|
||||
const NET_XHR_PREF = "devtools.webconsole.filter.netxhr";
|
||||
|
||||
// Enable XHR logging for the test
|
||||
Services.prefs.setBoolPref(NET_INFO_PREF, true);
|
||||
Services.prefs.setBoolPref(NET_XHR_PREF, true);
|
||||
|
||||
registerCleanupFunction(() => {
|
||||
Services.prefs.clearUserPref(NET_INFO_PREF);
|
||||
Services.prefs.clearUserPref(NET_XHR_PREF);
|
||||
});
|
||||
|
||||
// Use the old webconsole since the new one doesn't yet support
|
||||
// XHR spy. See Bug 1304794.
|
||||
Services.prefs.setBoolPref("devtools.webconsole.new-frontend-enabled", false);
|
||||
registerCleanupFunction(function() {
|
||||
Services.prefs.clearUserPref("devtools.webconsole.new-frontend-enabled");
|
||||
});
|
||||
|
||||
/**
|
||||
* Add a new test tab in the browser and load the given url.
|
||||
* @param {String} url The url to be loaded in the new tab
|
||||
* @return a promise that resolves to the tab object when the url is loaded
|
||||
*/
|
||||
function addTestTab(url) {
|
||||
info("Adding a new JSON tab with URL: '" + url + "'");
|
||||
|
||||
return (async function () {
|
||||
let tab = await addTab(url);
|
||||
|
||||
// Load devtools/shared/test/frame-script-utils.js
|
||||
loadFrameScriptUtils(tab.linkedBrowser);
|
||||
|
||||
// Open the Console panel
|
||||
let hud = await openConsole();
|
||||
|
||||
return {
|
||||
tab: tab,
|
||||
browser: tab.linkedBrowser,
|
||||
hud: hud
|
||||
};
|
||||
})();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param hud
|
||||
* @param options
|
||||
*/
|
||||
function executeAndInspectXhr(hud, options) {
|
||||
hud.jsterm.clearOutput();
|
||||
|
||||
options.queryString = options.queryString || "";
|
||||
|
||||
// Execute XHR in the content scope.
|
||||
performRequestsInContent({
|
||||
method: options.method,
|
||||
url: options.url + options.queryString,
|
||||
body: options.body,
|
||||
nocache: options.nocache,
|
||||
requestHeaders: options.requestHeaders
|
||||
});
|
||||
|
||||
return (async function () {
|
||||
// Wait till the appropriate Net log appears in the Console panel.
|
||||
let rules = await waitForMessages({
|
||||
webconsole: hud,
|
||||
messages: [{
|
||||
text: options.url,
|
||||
category: CATEGORY_NETWORK,
|
||||
severity: SEVERITY_INFO,
|
||||
isXhr: true,
|
||||
}]
|
||||
});
|
||||
|
||||
// The log is here, get its parent element (className: 'message').
|
||||
let msg = [...rules[0].matched][0];
|
||||
let body = msg.querySelector(".message-body");
|
||||
|
||||
// Open XHR HTTP details body and wait till the UI fetches
|
||||
// all necessary data from the backend. All RPD requests
|
||||
// needs to be finished before we can continue testing.
|
||||
await synthesizeMouseClickSoon(hud, body);
|
||||
await waitForBackend(msg);
|
||||
let netInfoBody = body.querySelector(".netInfoBody");
|
||||
ok(netInfoBody, "Net info body must exist");
|
||||
return netInfoBody;
|
||||
})();
|
||||
}
|
||||
|
||||
/**
|
||||
* Wait till XHR data are fetched from the backend (i.e. there are
|
||||
* no pending RDP requests.
|
||||
*/
|
||||
function waitForBackend(element) {
|
||||
if (!element.hasAttribute("loading")) {
|
||||
return;
|
||||
}
|
||||
return once(element, "netlog-no-pending-requests", true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Select specific tab in XHR info body.
|
||||
*
|
||||
* @param netInfoBody The main XHR info body
|
||||
* @param tabId Tab ID (possible values: 'headers', 'cookies', 'params',
|
||||
* 'post', 'response');
|
||||
*
|
||||
* @returns Tab body element.
|
||||
*/
|
||||
function selectNetInfoTab(hud, netInfoBody, tabId) {
|
||||
let tab = netInfoBody.querySelector(".tabs-menu-item." + tabId);
|
||||
ok(tab, "Tab must exist " + tabId);
|
||||
|
||||
// Click to select specified tab and wait till its
|
||||
// UI is populated with data from the backend.
|
||||
// There must be no pending RDP requests before we can
|
||||
// continue testing the UI.
|
||||
return (async function () {
|
||||
await synthesizeMouseClickSoon(hud, tab);
|
||||
let msg = getAncestorByClass(netInfoBody, "message");
|
||||
await waitForBackend(msg);
|
||||
let tabBody = netInfoBody.querySelector("." + tabId + "TabBox");
|
||||
ok(tabBody, "Tab body must exist");
|
||||
return tabBody;
|
||||
})();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return parent node with specified class.
|
||||
*
|
||||
* @param node A child element
|
||||
* @param className Specified class name.
|
||||
*
|
||||
* @returns A parent element.
|
||||
*/
|
||||
function getAncestorByClass(node, className) {
|
||||
for (let parent = node; parent; parent = parent.parentNode) {
|
||||
if (parent.classList && parent.classList.contains(className)) {
|
||||
return parent;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Synthesize asynchronous click event (with clean stack trace).
|
||||
*/
|
||||
function synthesizeMouseClickSoon(hud, element) {
|
||||
return new Promise((resolve) => {
|
||||
executeSoon(() => {
|
||||
EventUtils.synthesizeMouse(element, 2, 2, {}, hud.iframeWindow);
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute XHR in the content scope.
|
||||
*/
|
||||
function performRequestsInContent(requests) {
|
||||
info("Performing requests in the context of the content.");
|
||||
return executeInContent("devtools:test:xhr", requests);
|
||||
}
|
||||
|
||||
function executeInContent(name, data = {}, objects = {},
|
||||
expectResponse = true) {
|
||||
let mm = gBrowser.selectedBrowser.messageManager;
|
||||
|
||||
mm.sendAsyncMessage(name, data, objects);
|
||||
if (expectResponse) {
|
||||
return waitForContentMessage(name);
|
||||
}
|
||||
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
function waitForContentMessage(name) {
|
||||
info("Expecting message " + name + " from content");
|
||||
|
||||
let mm = gBrowser.selectedBrowser.messageManager;
|
||||
|
||||
return new Promise((resolve) => {
|
||||
mm.addMessageListener(name, function onMessage(msg) {
|
||||
mm.removeMessageListener(name, onMessage);
|
||||
resolve(msg.data);
|
||||
});
|
||||
});
|
||||
}
|
|
@ -1,14 +0,0 @@
|
|||
<!-- Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ -->
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8"/>
|
||||
<title>XHR Spy test page</title>
|
||||
</head>
|
||||
<body>
|
||||
<script type="text/javascript">
|
||||
document.cookie = "bar=foo";
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -1 +0,0 @@
|
|||
{"name":"Cookies Test"}
|
|
@ -1,2 +0,0 @@
|
|||
Content-Type: application/json; charset=utf-8
|
||||
Set-Cookie: test=abc
|
|
@ -1 +0,0 @@
|
|||
{"name":"John"}
|
|
@ -1 +0,0 @@
|
|||
Content-Type: application/json; charset=utf-8
|
|
@ -1 +0,0 @@
|
|||
this is a response
|
|
@ -1 +0,0 @@
|
|||
<xml><name>John</name></xml>
|
|
@ -1 +0,0 @@
|
|||
Content-Type: application/xml; charset=utf-8
|
|
@ -1,6 +0,0 @@
|
|||
"use strict";
|
||||
|
||||
module.exports = {
|
||||
// Extend from the common devtools xpcshell eslintrc config.
|
||||
"extends": "../../../../../../.eslintrc.xpcshell.js"
|
||||
};
|
|
@ -1,44 +0,0 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim: set ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
const { require } = ChromeUtils.import("resource://devtools/shared/Loader.jsm", {});
|
||||
const { parseJSONString, isJSON } = require("devtools/client/webconsole/old/net/utils/json");
|
||||
|
||||
// Test data
|
||||
const simpleJson = '{"name":"John"}';
|
||||
const jsonInFunc = 'someFunc({"name":"John"})';
|
||||
|
||||
const json1 = "{'a': 1}";
|
||||
const json2 = " {'a': 1}";
|
||||
const json3 = "\t {'a': 1}";
|
||||
const json4 = "\n\n\t {'a': 1}";
|
||||
const json5 = "\n\n\t ";
|
||||
|
||||
const textMimeType = "text/plain";
|
||||
const jsonMimeType = "text/javascript";
|
||||
const unknownMimeType = "text/unknown";
|
||||
|
||||
/**
|
||||
* Testing API provided by webconsole/old/net/utils/json.js
|
||||
*/
|
||||
function run_test() {
|
||||
// parseJSONString
|
||||
equal(parseJSONString(simpleJson).name, "John");
|
||||
equal(parseJSONString(jsonInFunc).name, "John");
|
||||
|
||||
// isJSON
|
||||
equal(isJSON(textMimeType, json1), true);
|
||||
equal(isJSON(textMimeType, json2), true);
|
||||
equal(isJSON(jsonMimeType, json3), true);
|
||||
equal(isJSON(jsonMimeType, json4), true);
|
||||
|
||||
equal(isJSON(unknownMimeType, json1), true);
|
||||
equal(isJSON(textMimeType, json1), true);
|
||||
|
||||
equal(isJSON(unknownMimeType), false);
|
||||
equal(isJSON(unknownMimeType, json5), false);
|
||||
}
|
|
@ -1,76 +0,0 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim: set ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
const { require } = ChromeUtils.import("resource://devtools/shared/Loader.jsm", {});
|
||||
const {
|
||||
isImage,
|
||||
isHTML,
|
||||
getHeaderValue,
|
||||
isURLEncodedRequest,
|
||||
isMultiPartRequest
|
||||
} = require("devtools/client/webconsole/old/net/utils/net");
|
||||
|
||||
// Test data
|
||||
const imageMimeTypes = ["image/jpeg", "image/jpg", "image/gif",
|
||||
"image/png", "image/bmp"];
|
||||
|
||||
const htmlMimeTypes = ["text/html", "text/xml", "application/xml",
|
||||
"application/rss+xml", "application/atom+xml", "application/xhtml+xml",
|
||||
"application/mathml+xml", "application/rdf+xml"];
|
||||
|
||||
const headers = [{name: "headerName", value: "value1"}];
|
||||
|
||||
const har1 = {
|
||||
request: {
|
||||
postData: {
|
||||
text: "content-type: application/x-www-form-urlencoded"
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const har2 = {
|
||||
request: {
|
||||
headers: [{
|
||||
name: "content-type",
|
||||
value: "application/x-www-form-urlencoded"
|
||||
}]
|
||||
}
|
||||
};
|
||||
|
||||
const har3 = {
|
||||
request: {
|
||||
headers: [{
|
||||
name: "content-type",
|
||||
value: "multipart/form-data"
|
||||
}]
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Testing API provided by webconsole/old/net/utils/net.js
|
||||
*/
|
||||
function run_test() {
|
||||
// isImage
|
||||
imageMimeTypes.forEach(mimeType => {
|
||||
ok(isImage(mimeType));
|
||||
});
|
||||
|
||||
// isHTML
|
||||
htmlMimeTypes.forEach(mimeType => {
|
||||
ok(isHTML(mimeType));
|
||||
});
|
||||
|
||||
// getHeaderValue
|
||||
equal(getHeaderValue(headers, "headerName"), "value1");
|
||||
|
||||
// isURLEncodedRequest
|
||||
ok(isURLEncodedRequest(har1));
|
||||
ok(isURLEncodedRequest(har2));
|
||||
|
||||
// isMultiPartRequest
|
||||
ok(isMultiPartRequest(har3));
|
||||
}
|
|
@ -1,8 +0,0 @@
|
|||
[DEFAULT]
|
||||
tags = devtools
|
||||
head =
|
||||
firefox-appdir = browser
|
||||
skip-if = toolkit == 'android'
|
||||
|
||||
[test_json-utils.js]
|
||||
[test_net-utils.js]
|
|
@ -1,21 +0,0 @@
|
|||
/* 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";
|
||||
|
||||
function isLeftClick(event, allowKeyModifiers) {
|
||||
return event.button === 0 && (allowKeyModifiers || noKeyModifiers(event));
|
||||
}
|
||||
|
||||
function noKeyModifiers(event) {
|
||||
return !event.ctrlKey && !event.shiftKey && !event.altKey && !event.metaKey;
|
||||
}
|
||||
|
||||
function cancelEvent(event) {
|
||||
event.stopPropagation();
|
||||
event.preventDefault();
|
||||
}
|
||||
|
||||
// Exports from this module
|
||||
exports.isLeftClick = isLeftClick;
|
||||
exports.cancelEvent = cancelEvent;
|
|
@ -1,234 +0,0 @@
|
|||
/* 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";
|
||||
|
||||
// List of JSON content types.
|
||||
const contentTypes = {
|
||||
"text/plain": 1,
|
||||
"text/javascript": 1,
|
||||
"text/x-javascript": 1,
|
||||
"text/json": 1,
|
||||
"text/x-json": 1,
|
||||
"application/json": 1,
|
||||
"application/x-json": 1,
|
||||
"application/javascript": 1,
|
||||
"application/x-javascript": 1,
|
||||
"application/json-rpc": 1
|
||||
};
|
||||
|
||||
// Implementation
|
||||
var Json = {};
|
||||
|
||||
/**
|
||||
* Parsing JSON
|
||||
*/
|
||||
Json.parseJSONString = function (jsonString) {
|
||||
if (!jsonString.length) {
|
||||
return null;
|
||||
}
|
||||
|
||||
let regex, matches;
|
||||
|
||||
let first = firstNonWs(jsonString);
|
||||
if (first !== "[" && first !== "{") {
|
||||
// This (probably) isn't pure JSON. Let's try to strip various sorts
|
||||
// of XSSI protection/wrapping and see if that works better.
|
||||
|
||||
// Prototype-style secure requests
|
||||
regex = /^\s*\/\*-secure-([\s\S]*)\*\/\s*$/;
|
||||
matches = regex.exec(jsonString);
|
||||
if (matches) {
|
||||
jsonString = matches[1];
|
||||
|
||||
if (jsonString[0] === "\\" && jsonString[1] === "n") {
|
||||
jsonString = jsonString.substr(2);
|
||||
}
|
||||
|
||||
if (jsonString[jsonString.length - 2] === "\\" &&
|
||||
jsonString[jsonString.length - 1] === "n") {
|
||||
jsonString = jsonString.substr(0, jsonString.length - 2);
|
||||
}
|
||||
}
|
||||
|
||||
// Google-style (?) delimiters
|
||||
if (jsonString.includes("&&&START&&&")) {
|
||||
regex = /&&&START&&&([\s\S]*)&&&END&&&/;
|
||||
matches = regex.exec(jsonString);
|
||||
if (matches) {
|
||||
jsonString = matches[1];
|
||||
}
|
||||
}
|
||||
|
||||
// while(1);, for(;;);, and )]}'
|
||||
regex = /^\s*(\)\]\}[^\n]*\n|while\s*\(1\);|for\s*\(;;\);)([\s\S]*)/;
|
||||
matches = regex.exec(jsonString);
|
||||
if (matches) {
|
||||
jsonString = matches[2];
|
||||
}
|
||||
|
||||
// JSONP
|
||||
regex = /^\s*([A-Za-z0-9_$.]+\s*(?:\[.*\]|))\s*\(([\s\S]*)\)/;
|
||||
matches = regex.exec(jsonString);
|
||||
if (matches) {
|
||||
jsonString = matches[2];
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
return JSON.parse(jsonString);
|
||||
} catch (err) {
|
||||
// eslint-disable-line no-empty
|
||||
}
|
||||
|
||||
// Give up if we don't have valid start, to avoid some unnecessary overhead.
|
||||
first = firstNonWs(jsonString);
|
||||
if (first !== "[" && first !== "{" && isNaN(first) && first !== '"') {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Remove JavaScript comments, quote non-quoted identifiers, and merge
|
||||
// multi-line structures like |{"a": 1} \n {"b": 2}| into a single JSON
|
||||
// object [{"a": 1}, {"b": 2}].
|
||||
jsonString = pseudoJsonToJson(jsonString);
|
||||
|
||||
try {
|
||||
return JSON.parse(jsonString);
|
||||
} catch (err) {
|
||||
// eslint-disable-line no-empty
|
||||
}
|
||||
|
||||
return null;
|
||||
};
|
||||
|
||||
function firstNonWs(str) {
|
||||
for (let i = 0, len = str.length; i < len; i++) {
|
||||
let ch = str[i];
|
||||
if (ch !== " " && ch !== "\n" && ch !== "\t" && ch !== "\r") {
|
||||
return ch;
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
function pseudoJsonToJson(json) {
|
||||
let ret = "";
|
||||
let at = 0, lasti = 0, lastch = "", hasMultipleParts = false;
|
||||
for (let i = 0, len = json.length; i < len; ++i) {
|
||||
let ch = json[i];
|
||||
if (/\s/.test(ch)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ch === '"') {
|
||||
// Consume a string.
|
||||
++i;
|
||||
while (i < len) {
|
||||
if (json[i] === "\\") {
|
||||
++i;
|
||||
} else if (json[i] === '"') {
|
||||
break;
|
||||
}
|
||||
++i;
|
||||
}
|
||||
} else if (ch === "'") {
|
||||
// Convert an invalid string into a valid one.
|
||||
ret += json.slice(at, i) + "\"";
|
||||
at = i + 1;
|
||||
++i;
|
||||
|
||||
while (i < len) {
|
||||
if (json[i] === "\\") {
|
||||
++i;
|
||||
} else if (json[i] === "'") {
|
||||
break;
|
||||
}
|
||||
++i;
|
||||
}
|
||||
|
||||
if (i < len) {
|
||||
ret += json.slice(at, i) + "\"";
|
||||
at = i + 1;
|
||||
}
|
||||
} else if ((ch === "[" || ch === "{") &&
|
||||
(lastch === "]" || lastch === "}")) {
|
||||
// Multiple JSON messages in one... Make it into a single array by
|
||||
// inserting a comma and setting the "multiple parts" flag.
|
||||
ret += json.slice(at, i) + ",";
|
||||
hasMultipleParts = true;
|
||||
at = i;
|
||||
} else if (lastch === "," && (ch === "]" || ch === "}")) {
|
||||
// Trailing commas in arrays/objects.
|
||||
ret += json.slice(at, lasti);
|
||||
at = i;
|
||||
} else if (lastch === "/" && lasti === i - 1) {
|
||||
// Some kind of comment; remove it.
|
||||
if (ch === "/") {
|
||||
ret += json.slice(at, i - 1);
|
||||
at = i + json.slice(i).search(/\n|\r|$/);
|
||||
i = at - 1;
|
||||
} else if (ch === "*") {
|
||||
ret += json.slice(at, i - 1);
|
||||
at = json.indexOf("*/", i + 1) + 2;
|
||||
if (at === 1) {
|
||||
at = len;
|
||||
}
|
||||
i = at - 1;
|
||||
}
|
||||
ch = "\0";
|
||||
} else if (/[a-zA-Z$_]/.test(ch) && lastch !== ":") {
|
||||
// Non-quoted identifier. Quote it.
|
||||
ret += json.slice(at, i) + "\"";
|
||||
at = i;
|
||||
i = i + json.slice(i).search(/[^a-zA-Z0-9$_]|$/);
|
||||
ret += json.slice(at, i) + "\"";
|
||||
at = i;
|
||||
}
|
||||
|
||||
lastch = ch;
|
||||
lasti = i;
|
||||
}
|
||||
|
||||
ret += json.slice(at);
|
||||
if (hasMultipleParts) {
|
||||
ret = "[" + ret + "]";
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
Json.isJSON = function (contentType, data) {
|
||||
// Workaround for JSON responses without proper content type
|
||||
// Let's consider all responses starting with "{" as JSON. In the worst
|
||||
// case there will be an exception when parsing. This means that no-JSON
|
||||
// responses (and post data) (with "{") can be parsed unnecessarily,
|
||||
// which represents a little overhead, but this happens only if the request
|
||||
// is actually expanded by the user in the UI (Net & Console panels).
|
||||
// Do a manual string search instead of checking (data.strip()[0] === "{")
|
||||
// to improve performance/memory usage.
|
||||
let len = data ? data.length : 0;
|
||||
for (let i = 0; i < len; i++) {
|
||||
let ch = data.charAt(i);
|
||||
if (ch === "{") {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (ch === " " || ch === "\t" || ch === "\n" || ch === "\r") {
|
||||
continue;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if (!contentType) {
|
||||
return false;
|
||||
}
|
||||
|
||||
contentType = contentType.split(";")[0];
|
||||
contentType = contentType.trim();
|
||||
return !!contentTypes[contentType];
|
||||
};
|
||||
|
||||
// Exports from this module
|
||||
module.exports = Json;
|
||||
|
|
@ -1,11 +0,0 @@
|
|||
# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
|
||||
# vim: set filetype=python:
|
||||
# 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/.
|
||||
|
||||
DevToolsModules(
|
||||
'events.js',
|
||||
'json.js',
|
||||
'net.js',
|
||||
)
|
|
@ -1,134 +0,0 @@
|
|||
/* 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";
|
||||
|
||||
const mimeCategoryMap = {
|
||||
"text/plain": "txt",
|
||||
"application/octet-stream": "bin",
|
||||
"text/html": "html",
|
||||
"text/xml": "html",
|
||||
"application/xml": "html",
|
||||
"application/rss+xml": "html",
|
||||
"application/atom+xml": "html",
|
||||
"application/xhtml+xml": "html",
|
||||
"application/mathml+xml": "html",
|
||||
"application/rdf+xml": "html",
|
||||
"text/css": "css",
|
||||
"application/x-javascript": "js",
|
||||
"text/javascript": "js",
|
||||
"application/javascript": "js",
|
||||
"text/ecmascript": "js",
|
||||
"application/ecmascript": "js",
|
||||
"image/jpeg": "image",
|
||||
"image/jpg": "image",
|
||||
"image/gif": "image",
|
||||
"image/png": "image",
|
||||
"image/bmp": "image",
|
||||
"application/x-shockwave-flash": "plugin",
|
||||
"application/x-silverlight-app": "plugin",
|
||||
"video/x-flv": "media",
|
||||
"audio/mpeg3": "media",
|
||||
"audio/x-mpeg-3": "media",
|
||||
"video/mpeg": "media",
|
||||
"video/x-mpeg": "media",
|
||||
"video/webm": "media",
|
||||
"video/mp4": "media",
|
||||
"video/ogg": "media",
|
||||
"audio/ogg": "media",
|
||||
"application/ogg": "media",
|
||||
"application/x-ogg": "media",
|
||||
"application/x-midi": "media",
|
||||
"audio/midi": "media",
|
||||
"audio/x-mid": "media",
|
||||
"audio/x-midi": "media",
|
||||
"music/crescendo": "media",
|
||||
"audio/wav": "media",
|
||||
"audio/x-wav": "media",
|
||||
"application/x-woff": "font",
|
||||
"application/font-woff": "font",
|
||||
"application/x-font-woff": "font",
|
||||
"application/x-ttf": "font",
|
||||
"application/x-font-ttf": "font",
|
||||
"font/ttf": "font",
|
||||
"font/woff": "font",
|
||||
"application/x-otf": "font",
|
||||
"application/x-font-otf": "font"
|
||||
};
|
||||
|
||||
var NetUtils = {};
|
||||
|
||||
NetUtils.isImage = function (contentType) {
|
||||
if (!contentType) {
|
||||
return false;
|
||||
}
|
||||
|
||||
contentType = contentType.split(";")[0];
|
||||
contentType = contentType.trim();
|
||||
return mimeCategoryMap[contentType] == "image";
|
||||
};
|
||||
|
||||
NetUtils.isHTML = function (contentType) {
|
||||
if (!contentType) {
|
||||
return false;
|
||||
}
|
||||
|
||||
contentType = contentType.split(";")[0];
|
||||
contentType = contentType.trim();
|
||||
return mimeCategoryMap[contentType] == "html";
|
||||
};
|
||||
|
||||
NetUtils.getHeaderValue = function (headers, name) {
|
||||
if (!headers) {
|
||||
return null;
|
||||
}
|
||||
|
||||
name = name.toLowerCase();
|
||||
for (let i = 0; i < headers.length; ++i) {
|
||||
let headerName = headers[i].name.toLowerCase();
|
||||
if (headerName == name) {
|
||||
return headers[i].value;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
NetUtils.parseXml = function (content) {
|
||||
let contentType = content.mimeType.split(";")[0];
|
||||
contentType = contentType.trim();
|
||||
|
||||
let parser = new DOMParser();
|
||||
let doc = parser.parseFromString(content.text, contentType);
|
||||
let root = doc.documentElement;
|
||||
|
||||
// Error handling
|
||||
let nsURI = "http://www.mozilla.org/newlayout/xml/parsererror.xml";
|
||||
if (root.namespaceURI == nsURI && root.nodeName == "parsererror") {
|
||||
return null;
|
||||
}
|
||||
|
||||
return doc;
|
||||
};
|
||||
|
||||
NetUtils.isURLEncodedRequest = function (file) {
|
||||
let mimeType = "application/x-www-form-urlencoded";
|
||||
|
||||
let postData = file.request.postData;
|
||||
if (postData && postData.text) {
|
||||
let text = postData.text.toLowerCase();
|
||||
if (text.startsWith("content-type: " + mimeType)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
let value = NetUtils.getHeaderValue(file.request.headers, "content-type");
|
||||
return value && value.startsWith(mimeType);
|
||||
};
|
||||
|
||||
NetUtils.isMultiPartRequest = function (file) {
|
||||
let mimeType = "multipart/form-data";
|
||||
let value = NetUtils.getHeaderValue(file.request.headers, "content-type");
|
||||
return value && value.startsWith(mimeType);
|
||||
};
|
||||
|
||||
// Exports from this module
|
||||
module.exports = NetUtils;
|
|
@ -1,6 +0,0 @@
|
|||
"use strict";
|
||||
|
||||
module.exports = {
|
||||
// Extend from the shared list of defined globals for mochitests.
|
||||
"extends": "../../../../.eslintrc.mochitests.js"
|
||||
};
|
|
@ -1,409 +0,0 @@
|
|||
[DEFAULT]
|
||||
tags = devtools
|
||||
subsuite = devtools
|
||||
support-files =
|
||||
head.js
|
||||
test-bug-585956-console-trace.html
|
||||
test-bug-593003-iframe-wrong-hud-iframe.html
|
||||
test-bug-593003-iframe-wrong-hud.html
|
||||
test-bug-595934-canvas-css.html
|
||||
test-bug-595934-canvas-css.js
|
||||
test-bug-595934-css-loader.css
|
||||
test-bug-595934-css-loader.css^headers^
|
||||
test-bug-595934-css-loader.html
|
||||
test-bug-595934-css-parser.css
|
||||
test-bug-595934-css-parser.html
|
||||
test-bug-595934-empty-getelementbyid.html
|
||||
test-bug-595934-empty-getelementbyid.js
|
||||
test-bug-595934-html.html
|
||||
test-bug-595934-image.html
|
||||
test-bug-595934-image.jpg
|
||||
test-bug-595934-imagemap.html
|
||||
test-bug-595934-malformedxml-external.html
|
||||
test-bug-595934-malformedxml-external.xml
|
||||
test-bug-595934-malformedxml.xhtml
|
||||
test-bug-595934-svg.xhtml
|
||||
test-bug-595934-workers.html
|
||||
test-bug-595934-workers.js
|
||||
test-bug-597136-external-script-errors.html
|
||||
test-bug-597136-external-script-errors.js
|
||||
test-bug-597756-reopen-closed-tab.html
|
||||
test-bug-599725-response-headers.sjs
|
||||
test-bug-600183-charset.html
|
||||
test-bug-600183-charset.html^headers^
|
||||
test-bug-601177-log-levels.html
|
||||
test-bug-601177-log-levels.js
|
||||
test-bug-603750-websocket.html
|
||||
test-bug-603750-websocket.js
|
||||
test-bug-613013-console-api-iframe.html
|
||||
test-bug-618078-network-exceptions.html
|
||||
test-bug-621644-jsterm-dollar.html
|
||||
test-bug-630733-response-redirect-headers.sjs
|
||||
test-bug-632275-getters.html
|
||||
test-bug-632347-iterators-generators.html
|
||||
test-bug-644419-log-limits.html
|
||||
test-bug-646025-console-file-location.html
|
||||
test-bug-658368-time-methods.html
|
||||
test-bug-737873-mixedcontent.html
|
||||
test-bug-752559-ineffective-iframe-sandbox-warning0.html
|
||||
test-bug-752559-ineffective-iframe-sandbox-warning1.html
|
||||
test-bug-752559-ineffective-iframe-sandbox-warning2.html
|
||||
test-bug-752559-ineffective-iframe-sandbox-warning3.html
|
||||
test-bug-752559-ineffective-iframe-sandbox-warning4.html
|
||||
test-bug-752559-ineffective-iframe-sandbox-warning5.html
|
||||
test-bug-752559-ineffective-iframe-sandbox-warning-inner.html
|
||||
test-bug-752559-ineffective-iframe-sandbox-warning-nested1.html
|
||||
test-bug-752559-ineffective-iframe-sandbox-warning-nested2.html
|
||||
test-bug-762593-insecure-passwords-about-blank-web-console-warning.html
|
||||
test-bug-762593-insecure-passwords-web-console-warning.html
|
||||
test-bug-766001-console-log.js
|
||||
test-bug-766001-js-console-links.html
|
||||
test-bug-766001-js-errors.js
|
||||
test-bug-782653-css-errors-1.css
|
||||
test-bug-782653-css-errors-2.css
|
||||
test-bug-782653-css-errors.html
|
||||
test-bug-837351-security-errors.html
|
||||
test-bug-859170-longstring-hang.html
|
||||
test-bug-869003-iframe.html
|
||||
test-bug-869003-top-window.html
|
||||
test-closure-optimized-out.html
|
||||
test-closures.html
|
||||
test-console-assert.html
|
||||
test-console-clear.html
|
||||
test-console-count.html
|
||||
test-console-count-external-file.js
|
||||
test-console-extras.html
|
||||
test-console-replaced-api.html
|
||||
test-console-server-logging.sjs
|
||||
test-console-server-logging-array.sjs
|
||||
test-console-server-logging-backtrace.sjs
|
||||
test-console.html
|
||||
test-console-workers.html
|
||||
test-console-table.html
|
||||
test-console-output-02.html
|
||||
test-console-output-03.html
|
||||
test-console-output-04.html
|
||||
test-console-output-dom-elements.html
|
||||
test-console-output-events.html
|
||||
test-console-column.html
|
||||
test-consoleiframes.html
|
||||
test-console-trace-async.html
|
||||
test-certificate-messages.html
|
||||
test-cu-reporterror.js
|
||||
test-data.json
|
||||
test-data.json^headers^
|
||||
test-duplicate-error.html
|
||||
test-encoding-ISO-8859-1.html
|
||||
test-error.html
|
||||
test-eval-in-stackframe.html
|
||||
test-file-location.js
|
||||
test-filter.html
|
||||
test-for-of.html
|
||||
test_hpkp-invalid-headers.sjs
|
||||
test_hsts-invalid-headers.sjs
|
||||
test-iframe-762593-insecure-form-action.html
|
||||
test-iframe-762593-insecure-frame.html
|
||||
test-iframe1.html
|
||||
test-iframe2.html
|
||||
test-iframe3.html
|
||||
test-image.png
|
||||
test-mixedcontent-securityerrors.html
|
||||
test-mutation.html
|
||||
test-network-request.html
|
||||
test-network.html
|
||||
test-observe-http-ajax.html
|
||||
test-own-console.html
|
||||
test-property-provider.html
|
||||
test-repeated-messages.html
|
||||
test-result-format-as-string.html
|
||||
test-trackingprotection-securityerrors.html
|
||||
test-webconsole-error-observer.html
|
||||
test_bug_770099_violation.html
|
||||
test_bug_770099_violation.html^headers^
|
||||
test-autocomplete-in-stackframe.html
|
||||
testscript.js
|
||||
test-bug_923281_console_log_filter.html
|
||||
test-bug_923281_test1.js
|
||||
test-bug_923281_test2.js
|
||||
test-bug_939783_console_trace_duplicates.html
|
||||
test-bug-952277-highlight-nodes-in-vview.html
|
||||
test-bug-609872-cd-iframe-parent.html
|
||||
test-bug-609872-cd-iframe-child.html
|
||||
test-bug-989025-iframe-parent.html
|
||||
test-bug_1050691_click_function_to_source.html
|
||||
test-bug_1050691_click_function_to_source.js
|
||||
test-console-api-stackframe.html
|
||||
test-exception-stackframe.html
|
||||
test_bug_1010953_cspro.html^headers^
|
||||
test_bug_1010953_cspro.html
|
||||
test_bug1045902_console_csp_ignore_reflected_xss_message.html^headers^
|
||||
test_bug1045902_console_csp_ignore_reflected_xss_message.html
|
||||
test_bug1092055_shouldwarn.js^headers^
|
||||
test_bug1092055_shouldwarn.js
|
||||
test_bug1092055_shouldwarn.html
|
||||
test_bug_1247459_violation.html
|
||||
!/devtools/client/netmonitor/test/sjs_cors-test-server.sjs
|
||||
!/devtools/client/shared/test/shared-head.js
|
||||
!/image/test/mochitest/blue.png
|
||||
|
||||
[browser_bug1045902_console_csp_ignore_reflected_xss_message.js]
|
||||
skip-if = (e10s && debug) || (e10s && os == 'win') # Bug 1221499 enabled these on windows
|
||||
[browser_bug664688_sandbox_update_after_navigation.js]
|
||||
[browser_bug_638949_copy_link_location.js]
|
||||
subsuite = clipboard
|
||||
skip-if = (os == 'linux' && bits == 32 && debug) # bug 1328915, disable linux32 debug devtools for timeouts
|
||||
[browser_bug_862916_console_dir_and_filter_off.js]
|
||||
skip-if = (e10s && (os == 'win' || os == 'mac')) # Bug 1243976
|
||||
[browser_bug_865288_repeat_different_objects.js]
|
||||
[browser_bug_865871_variables_view_close_on_esc_key.js]
|
||||
[browser_bug_869003_inspect_cross_domain_object.js]
|
||||
[browser_bug_871156_ctrlw_close_tab.js]
|
||||
[browser_cached_messages.js]
|
||||
[browser_console.js]
|
||||
[browser_console_certificate_imminent_distrust.js]
|
||||
[browser_console_clear_method.js]
|
||||
[browser_console_clear_on_reload.js]
|
||||
[browser_console_click_focus.js]
|
||||
[browser_console_consolejsm_output.js]
|
||||
[browser_console_copy_command.js]
|
||||
subsuite = clipboard
|
||||
skip-if = (os == 'linux' && bits == 32 && debug) # bug 1328915, disable linux32 debug devtools for timeouts
|
||||
[browser_console_dead_objects.js]
|
||||
skip-if = e10s # Bug 1042253 - webconsole tests disabled with e10s
|
||||
[browser_console_copy_entire_message_context_menu.js]
|
||||
subsuite = clipboard
|
||||
skip-if = (os == 'linux' && bits == 32 && debug) # bug 1328915, disable linux32 debug devtools for timeouts
|
||||
[browser_console_devtools_loader_exception.js]
|
||||
[browser_console_error_source_click.js]
|
||||
[browser_console_filters.js]
|
||||
[browser_console_iframe_messages.js]
|
||||
[browser_console_keyboard_accessibility.js]
|
||||
[browser_console_log_inspectable_object.js]
|
||||
[browser_console_native_getters.js]
|
||||
[browser_console_navigation_marker.js]
|
||||
[browser_console_netlogging.js]
|
||||
[browser_console_nsiconsolemessage.js]
|
||||
[browser_console_optimized_out_vars.js]
|
||||
[browser_console_private_browsing.js]
|
||||
skip-if = e10s # Bug 1042253 - webconsole e10s tests
|
||||
[browser_console_restore.js]
|
||||
[browser_console_server_logging.js]
|
||||
[browser_console_variables_view.js]
|
||||
[browser_console_variables_view_filter.js]
|
||||
[browser_console_variables_view_dom_nodes.js]
|
||||
[browser_console_variables_view_dont_sort_non_sortable_classes_properties.js]
|
||||
[browser_console_variables_view_special_names.js]
|
||||
[browser_console_variables_view_while_debugging.js]
|
||||
[browser_console_variables_view_while_debugging_and_inspecting.js]
|
||||
[browser_eval_in_debugger_stackframe.js]
|
||||
[browser_eval_in_debugger_stackframe2.js]
|
||||
[browser_jsterm_inspect.js]
|
||||
skip-if = e10s && debug && (os == 'win' || os == 'mac') # Bug 1243966
|
||||
[browser_longstring_hang.js]
|
||||
[browser_output_breaks_after_console_dir_uninspectable.js]
|
||||
[browser_output_longstring_expand.js]
|
||||
[browser_repeated_messages_accuracy.js]
|
||||
[browser_result_format_as_string.js]
|
||||
[browser_warn_user_about_replaced_api.js]
|
||||
[browser_webconsole_allow_mixedcontent_securityerrors.js]
|
||||
tags = mcb
|
||||
skip-if = (os == 'win' && bits == 64) # Bug 1390001
|
||||
[browser_webconsole_script_errordoc_urls.js]
|
||||
skip-if = e10s # Bug 1042253 - webconsole tests disabled with e10s
|
||||
[browser_webconsole_assert.js]
|
||||
[browser_webconsole_block_mixedcontent_securityerrors.js]
|
||||
tags = mcb
|
||||
skip-if = (os == 'win' && bits == 64) # Bug 1390001
|
||||
[browser_webconsole_bug_579412_input_focus.js]
|
||||
[browser_webconsole_bug_580001_closing_after_completion.js]
|
||||
[browser_webconsole_bug_580030_errors_after_page_reload.js]
|
||||
[browser_webconsole_bug_582201_duplicate_errors.js]
|
||||
[browser_webconsole_bug_583816_No_input_and_Tab_key_pressed.js]
|
||||
[browser_webconsole_bug_585237_line_limit.js]
|
||||
[browser_webconsole_bug_585956_console_trace.js]
|
||||
[browser_webconsole_bug_585991_autocomplete_keys.js]
|
||||
[browser_webconsole_bug_585991_autocomplete_popup.js]
|
||||
[browser_webconsole_bug_586388_select_all.js]
|
||||
[browser_webconsole_bug_587617_output_copy.js]
|
||||
subsuite = clipboard
|
||||
skip-if = (os == 'linux' && bits == 32 && debug) # bug 1328915, disable linux32 debug devtools for timeouts
|
||||
[browser_webconsole_bug_588342_document_focus.js]
|
||||
[browser_webconsole_bug_588730_text_node_insertion.js]
|
||||
[browser_webconsole_bug_588967_input_expansion.js]
|
||||
[browser_webconsole_bug_589162_css_filter.js]
|
||||
[browser_webconsole_bug_592442_closing_brackets.js]
|
||||
[browser_webconsole_bug_593003_iframe_wrong_hud.js]
|
||||
[browser_webconsole_bug_594497_history_arrow_keys.js]
|
||||
[browser_webconsole_bug_595223_file_uri.js]
|
||||
[browser_webconsole_bug_595350_multiple_windows_and_tabs.js]
|
||||
skip-if = e10s # Bug 1042253 - webconsole tests disabled with e10s
|
||||
[browser_webconsole_bug_595934_message_categories.js]
|
||||
skip-if = e10s # Bug 1042253 - webconsole tests disabled with e10s
|
||||
[browser_webconsole_bug_597103_deactivateHUDForContext_unfocused_window.js]
|
||||
[browser_webconsole_bug_597136_external_script_errors.js]
|
||||
[browser_webconsole_bug_597136_network_requests_from_chrome.js]
|
||||
[browser_webconsole_bug_597460_filter_scroll.js]
|
||||
[browser_webconsole_bug_597756_reopen_closed_tab.js]
|
||||
[browser_webconsole_bug_599725_response_headers.js]
|
||||
[browser_webconsole_bug_600183_charset.js]
|
||||
[browser_webconsole_bug_601177_log_levels.js]
|
||||
[browser_webconsole_bug_601352_scroll.js]
|
||||
[browser_webconsole_bug_601667_filter_buttons.js]
|
||||
[browser_webconsole_bug_603750_websocket.js]
|
||||
[browser_webconsole_bug_611795.js]
|
||||
[browser_webconsole_bug_613013_console_api_iframe.js]
|
||||
[browser_webconsole_bug_613280_jsterm_copy.js]
|
||||
subsuite = clipboard
|
||||
skip-if = (os == 'linux' && bits == 32 && debug) # bug 1328915, disable linux32 debug devtools for timeouts
|
||||
[browser_webconsole_bug_613642_maintain_scroll.js]
|
||||
[browser_webconsole_bug_613642_prune_scroll.js]
|
||||
[browser_webconsole_bug_614793_jsterm_scroll.js]
|
||||
[browser_webconsole_bug_618078_network_exceptions.js]
|
||||
[browser_webconsole_bug_621644_jsterm_dollar.js]
|
||||
[browser_webconsole_bug_622303_persistent_filters.js]
|
||||
[browser_webconsole_bug_623749_ctrl_a_select_all_winnt.js]
|
||||
skip-if = os != "win"
|
||||
[browser_webconsole_bug_630733_response_redirect_headers.js]
|
||||
[browser_webconsole_bug_632275_getters_document_width.js]
|
||||
[browser_webconsole_bug_632347_iterators_generators.js]
|
||||
skip-if = e10s # Bug 1042253 - webconsole tests disabled with e10s
|
||||
[browser_webconsole_bug_632817.js]
|
||||
skip-if = true # Bug 1244707
|
||||
[browser_webconsole_bug_642108_pruneTest.js]
|
||||
[browser_webconsole_autocomplete_and_selfxss.js]
|
||||
subsuite = clipboard
|
||||
skip-if = (os == 'linux' && bits == 32 && debug) # bug 1328915, disable linux32 debug devtools for timeouts
|
||||
[browser_webconsole_bug_644419_log_limits.js]
|
||||
[browser_webconsole_bug_646025_console_file_location.js]
|
||||
[browser_webconsole_bug_651501_document_body_autocomplete.js]
|
||||
[browser_webconsole_bug_653531_highlighter_console_helper.js]
|
||||
skip-if = true # Requires direct access to content nodes
|
||||
[browser_webconsole_bug_658368_time_methods.js]
|
||||
[browser_webconsole_bug_659907_console_dir.js]
|
||||
[browser_webconsole_bug_660806_history_nav.js]
|
||||
[browser_webconsole_bug_664131_console_group.js]
|
||||
[browser_webconsole_bug_686937_autocomplete_JSTerm_helpers.js]
|
||||
[browser_webconsole_bug_704295.js]
|
||||
[browser_webconsole_bug_734061_No_input_change_and_Tab_key_pressed.js]
|
||||
[browser_webconsole_bug_737873_mixedcontent.js]
|
||||
tags = mcb
|
||||
[browser_webconsole_bug_752559_ineffective_iframe_sandbox_warning.js]
|
||||
skip-if = (os == 'win' && bits == 64) # Bug 1390001
|
||||
[browser_webconsole_bug_762593_insecure_passwords_about_blank_web_console_warning.js]
|
||||
[browser_webconsole_bug_762593_insecure_passwords_web_console_warning.js]
|
||||
skip-if = true # Bug 1110500 - mouse event failure in test
|
||||
[browser_webconsole_bug_764572_output_open_url.js]
|
||||
skip-if = e10s # Bug 1042253 - webconsole tests disabled with e10s
|
||||
[browser_webconsole_bug_766001_JS_Console_in_Debugger.js]
|
||||
[browser_webconsole_bug_770099_violation.js]
|
||||
skip-if = e10s && (os == 'win' || os == 'mac') # Bug 1243978
|
||||
[browser_webconsole_bug_782653_CSS_links_in_Style_Editor.js]
|
||||
[browser_webconsole_bug_804845_ctrl_key_nav.js]
|
||||
skip-if = os != "mac"
|
||||
[browser_webconsole_bug_817834_add_edited_input_to_history.js]
|
||||
[browser_webconsole_bug_837351_securityerrors.js]
|
||||
skip-if = (os == 'win' && bits == 64) # Bug 1390001
|
||||
[browser_webconsole_filter_buttons_contextmenu.js]
|
||||
[browser_webconsole_bug_1006027_message_timestamps_incorrect.js]
|
||||
skip-if = e10s # Bug 1042253 - webconsole e10s tests (Linux debug intermittent)
|
||||
[browser_webconsole_bug_1010953_cspro.js]
|
||||
skip-if = e10s && (os == 'win' || os == 'mac') # Bug 1243967
|
||||
[browser_webconsole_bug_1247459_violation.js]
|
||||
skip-if = e10s && (os == 'win') # Bug 1264955
|
||||
[browser_webconsole_certificate_messages.js]
|
||||
skip-if = e10s # Bug 1042253 - webconsole tests disabled with e10s
|
||||
[browser_webconsole_show_subresource_security_errors.js]
|
||||
skip-if = e10s && (os == 'win' || os == 'mac') # Bug 1243987
|
||||
[browser_webconsole_cached_autocomplete.js]
|
||||
[browser_webconsole_chrome.js]
|
||||
[browser_webconsole_clear_method.js]
|
||||
[browser_webconsole_clickable_urls.js]
|
||||
[browser_webconsole_closure_inspection.js]
|
||||
[browser_webconsole_completion.js]
|
||||
[browser_webconsole_console_extras.js]
|
||||
[browser_webconsole_console_logging_api.js]
|
||||
[browser_webconsole_console_logging_workers_api.js]
|
||||
[browser_webconsole_console_trace_async.js]
|
||||
[browser_webconsole_count.js]
|
||||
[browser_webconsole_dont_navigate_on_doubleclick.js]
|
||||
[browser_webconsole_execution_scope.js]
|
||||
[browser_webconsole_for_of.js]
|
||||
[browser_webconsole_history.js]
|
||||
[browser_webconsole_hpkp_invalid-headers.js]
|
||||
skip-if = (os == 'win' && bits == 64) # Bug 1390001
|
||||
[browser_webconsole_hsts_invalid-headers.js]
|
||||
skip-if = e10s # Bug 1042253 - webconsole e10s tests
|
||||
[browser_webconsole_input_field_focus_on_panel_select.js]
|
||||
[browser_webconsole_inspect-parsed-documents.js]
|
||||
[browser_webconsole_js_input_expansion.js]
|
||||
[browser_webconsole_jsterm.js]
|
||||
skip-if = e10s # Bug 1042253 - webconsole e10s tests (Linux debug timeout)
|
||||
[browser_webconsole_live_filtering_of_message_types.js]
|
||||
[browser_webconsole_live_filtering_on_search_strings.js]
|
||||
[browser_webconsole_message_node_id.js]
|
||||
[browser_webconsole_multiline_input.js]
|
||||
[browser_webconsole_netlogging.js]
|
||||
skip-if = true # Bug 1298364
|
||||
[browser_webconsole_netlogging_basic.js]
|
||||
[browser_webconsole_netlogging_panel.js]
|
||||
[browser_webconsole_netlogging_reset_filter.js]
|
||||
[browser_webconsole_notifications.js]
|
||||
[browser_webconsole_open-links-without-callback.js]
|
||||
[browser_webconsole_promise.js]
|
||||
[browser_webconsole_output_copy_newlines.js]
|
||||
subsuite = clipboard
|
||||
skip-if = (os == 'linux' && bits == 32 && debug) # bug 1328915, disable linux32 debug devtools for timeouts
|
||||
[browser_webconsole_output_order.js]
|
||||
[browser_webconsole_scratchpad_panel_link.js]
|
||||
[browser_webconsole_split.js]
|
||||
[browser_webconsole_split_escape_key.js]
|
||||
[browser_webconsole_split_focus.js]
|
||||
[browser_webconsole_split_persist.js]
|
||||
[browser_webconsole_trackingprotection_errors.js]
|
||||
tags = trackingprotection
|
||||
skip-if = (os == 'win' && bits == 64) # Bug 1390001
|
||||
[browser_webconsole_view_source.js]
|
||||
skip-if = (os == 'win' && bits == 64) # Bug 1390001
|
||||
[browser_webconsole_reflow.js]
|
||||
[browser_webconsole_log_file_filter.js]
|
||||
[browser_webconsole_expandable_timestamps.js]
|
||||
[browser_webconsole_autocomplete_accessibility.js]
|
||||
[browser_webconsole_autocomplete_in_debugger_stackframe.js]
|
||||
[browser_webconsole_autocomplete_popup_close_on_tab_switch.js]
|
||||
[browser_webconsole_autocomplete-properties-with-non-alphanumeric-names.js]
|
||||
[browser_console_hide_jsterm_when_devtools_chrome_enabled_false.js]
|
||||
[browser_console_history_persist.js]
|
||||
[browser_webconsole_output_01.js]
|
||||
[browser_webconsole_output_02.js]
|
||||
[browser_webconsole_output_03.js]
|
||||
[browser_webconsole_output_04.js]
|
||||
[browser_webconsole_output_05.js]
|
||||
[browser_webconsole_output_06.js]
|
||||
[browser_webconsole_output_dom_elements_01.js]
|
||||
[browser_webconsole_output_dom_elements_02.js]
|
||||
skip-if = e10s # Bug 1042253 - webconsole e10s tests (Linux debug timeout)
|
||||
[browser_webconsole_output_dom_elements_03.js]
|
||||
skip-if = e10s # Bug 1241019
|
||||
[browser_webconsole_output_dom_elements_04.js]
|
||||
skip-if = e10s # Bug 1042253 - webconsole e10s tests (Linux debug timeout)
|
||||
[browser_webconsole_output_dom_elements_05.js]
|
||||
[browser_webconsole_output_events.js]
|
||||
[browser_webconsole_output_regexp.js]
|
||||
[browser_webconsole_output_table.js]
|
||||
[browser_console_variables_view_highlighter.js]
|
||||
[browser_webconsole_start_netmon_first.js]
|
||||
[browser_webconsole_console_trace_duplicates.js]
|
||||
[browser_webconsole_cd_iframe.js]
|
||||
[browser_webconsole_autocomplete_crossdomain_iframe.js]
|
||||
[browser_webconsole_console_custom_styles.js]
|
||||
[browser_webconsole_console_api_stackframe.js]
|
||||
[browser_webconsole_exception_stackframe.js]
|
||||
[browser_webconsole_column_numbers.js]
|
||||
[browser_console_open_or_focus.js]
|
||||
[browser_webconsole_bug_922212_console_dirxml.js]
|
||||
[browser_webconsole_shows_reqs_in_netmonitor.js]
|
||||
[browser_netmonitor_shows_reqs_in_webconsole.js]
|
||||
[browser_webconsole_bug_1050691_click_function_to_source.js]
|
||||
[browser_webconsole_context_menu_open_in_var_view.js]
|
||||
[browser_webconsole_context_menu_store_as_global.js]
|
||||
[browser_webconsole_strict_mode_errors.js]
|
|
@ -1,52 +0,0 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* 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/ */
|
||||
|
||||
// Tests that a file with an unsupported CSP directive ('reflected-xss filter')
|
||||
// displays the appropriate message to the console.
|
||||
|
||||
"use strict";
|
||||
|
||||
const EXPECTED_RESULT = "Not supporting directive \u2018reflected-xss\u2019. " +
|
||||
"Directive and values will be ignored.";
|
||||
const TEST_FILE = "http://example.com/browser/devtools/client/webconsole/old/" +
|
||||
"test/test_bug1045902_console_csp_ignore_reflected_xss_" +
|
||||
"message.html";
|
||||
|
||||
var hud = undefined;
|
||||
|
||||
var TEST_URI = "data:text/html;charset=utf8,Web Console CSP ignoring " +
|
||||
"reflected XSS (bug 1045902)";
|
||||
|
||||
add_task(function* () {
|
||||
let { browser } = yield loadTab(TEST_URI);
|
||||
|
||||
hud = yield openConsole();
|
||||
|
||||
yield loadDocument(browser);
|
||||
yield testViolationMessage();
|
||||
|
||||
hud = null;
|
||||
});
|
||||
|
||||
function loadDocument(browser) {
|
||||
hud.jsterm.clearOutput();
|
||||
browser.loadURI(TEST_FILE);
|
||||
return BrowserTestUtils.browserLoaded(browser);
|
||||
}
|
||||
|
||||
function testViolationMessage() {
|
||||
let aOutputNode = hud.outputNode;
|
||||
|
||||
return waitForSuccess({
|
||||
name: "Confirming that CSP logs messages to the console when " +
|
||||
"\u2018reflected-xss\u2019 directive is used!",
|
||||
validator: function () {
|
||||
console.log(aOutputNode.textContent);
|
||||
let success = false;
|
||||
success = aOutputNode.textContent.indexOf(EXPECTED_RESULT) > -1;
|
||||
return success;
|
||||
}
|
||||
});
|
||||
}
|
|
@ -1,92 +0,0 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* 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/ */
|
||||
|
||||
// Tests if the JSTerm sandbox is updated when the user navigates from one
|
||||
// domain to another, in order to avoid permission denied errors with a sandbox
|
||||
// created for a different origin.
|
||||
|
||||
"use strict";
|
||||
|
||||
add_task(function* () {
|
||||
const TEST_URI1 = "http://example.com/browser/devtools/client/webconsole/old/" +
|
||||
"test/test-console.html";
|
||||
const TEST_URI2 = "http://example.org/browser/devtools/client/webconsole/old/" +
|
||||
"test/test-console.html";
|
||||
|
||||
yield loadTab(TEST_URI1);
|
||||
let hud = yield openConsole();
|
||||
|
||||
hud.jsterm.clearOutput();
|
||||
hud.jsterm.execute("window.location.href");
|
||||
|
||||
info("wait for window.location.href");
|
||||
|
||||
let msgForLocation1 = {
|
||||
webconsole: hud,
|
||||
messages: [
|
||||
{
|
||||
name: "window.location.href jsterm input",
|
||||
text: "window.location.href",
|
||||
category: CATEGORY_INPUT,
|
||||
},
|
||||
{
|
||||
name: "window.location.href result is displayed",
|
||||
text: TEST_URI1,
|
||||
category: CATEGORY_OUTPUT,
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
yield waitForMessages(msgForLocation1);
|
||||
|
||||
// load second url
|
||||
BrowserTestUtils.loadURI(gBrowser.selectedBrowser, TEST_URI2);
|
||||
yield loadBrowser(gBrowser.selectedBrowser);
|
||||
|
||||
is(hud.outputNode.textContent.indexOf("Permission denied"), -1,
|
||||
"no permission denied errors");
|
||||
|
||||
hud.jsterm.clearOutput();
|
||||
hud.jsterm.execute("window.location.href");
|
||||
|
||||
info("wait for window.location.href after page navigation");
|
||||
|
||||
yield waitForMessages({
|
||||
webconsole: hud,
|
||||
messages: [
|
||||
{
|
||||
name: "window.location.href jsterm input",
|
||||
text: "window.location.href",
|
||||
category: CATEGORY_INPUT,
|
||||
},
|
||||
{
|
||||
name: "window.location.href result is displayed",
|
||||
text: TEST_URI2,
|
||||
category: CATEGORY_OUTPUT,
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
is(hud.outputNode.textContent.indexOf("Permission denied"), -1,
|
||||
"no permission denied errors");
|
||||
|
||||
// Navigation clears messages. Wait for that clear to happen before
|
||||
// continuing the test or it might destroy messages we wait later on (Bug
|
||||
// 1270234).
|
||||
let cleared = hud.jsterm.once("messages-cleared");
|
||||
|
||||
gBrowser.goBack();
|
||||
|
||||
info("Waiting for messages to be cleared due to navigation");
|
||||
yield cleared;
|
||||
|
||||
info("Messages cleared after navigation; checking location");
|
||||
hud.jsterm.execute("window.location.href");
|
||||
|
||||
info("wait for window.location.href after goBack()");
|
||||
yield waitForMessages(msgForLocation1);
|
||||
is(hud.outputNode.textContent.indexOf("Permission denied"), -1,
|
||||
"no permission denied errors");
|
||||
});
|
|
@ -1,109 +0,0 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* 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/ */
|
||||
|
||||
// Test for the "Copy link location" context menu item shown when you right
|
||||
// click network requests in the output.
|
||||
|
||||
"use strict";
|
||||
|
||||
add_task(function* () {
|
||||
const TEST_URI = "http://example.com/browser/devtools/client/webconsole/old/" +
|
||||
"test/test-console.html?_date=" + Date.now();
|
||||
const COMMAND_NAME = "consoleCmd_copyURL";
|
||||
const CONTEXT_MENU_ID = "#menu_copyURL";
|
||||
|
||||
registerCleanupFunction(() => {
|
||||
Services.prefs.clearUserPref("devtools.webconsole.filter.networkinfo");
|
||||
});
|
||||
|
||||
Services.prefs.setBoolPref("devtools.webconsole.filter.networkinfo", true);
|
||||
|
||||
yield loadTab(TEST_URI);
|
||||
let hud = yield openConsole();
|
||||
let output = hud.outputNode;
|
||||
let menu = hud.iframeWindow.document.getElementById("output-contextmenu");
|
||||
|
||||
hud.jsterm.clearOutput();
|
||||
yield ContentTask.spawn(gBrowser.selectedBrowser, null, function() {
|
||||
content.console.log("bug 638949");
|
||||
});
|
||||
|
||||
// Test that the "Copy Link Location" command is disabled for non-network
|
||||
// messages.
|
||||
let [result] = yield waitForMessages({
|
||||
webconsole: hud,
|
||||
messages: [{
|
||||
text: "bug 638949",
|
||||
category: CATEGORY_WEBDEV,
|
||||
severity: SEVERITY_LOG,
|
||||
}],
|
||||
});
|
||||
|
||||
output.focus();
|
||||
let message = [...result.matched][0];
|
||||
|
||||
goUpdateCommand(COMMAND_NAME);
|
||||
ok(!isEnabled(), COMMAND_NAME + " is disabled");
|
||||
|
||||
// Test that the "Copy Link Location" menu item is hidden for non-network
|
||||
// messages.
|
||||
yield waitForContextMenu(menu, message, () => {
|
||||
let isHidden = menu.querySelector(CONTEXT_MENU_ID).hidden;
|
||||
ok(isHidden, CONTEXT_MENU_ID + " is hidden");
|
||||
});
|
||||
|
||||
hud.jsterm.clearOutput();
|
||||
// Reloading will produce network logging
|
||||
gBrowser.reload();
|
||||
|
||||
// Test that the "Copy Link Location" command is enabled and works
|
||||
// as expected for any network-related message.
|
||||
// This command should copy only the URL.
|
||||
[result] = yield waitForMessages({
|
||||
webconsole: hud,
|
||||
messages: [{
|
||||
text: "test-console.html",
|
||||
category: CATEGORY_NETWORK,
|
||||
severity: SEVERITY_LOG,
|
||||
}],
|
||||
});
|
||||
|
||||
output.focus();
|
||||
message = [...result.matched][0];
|
||||
hud.ui.output.selectMessage(message);
|
||||
|
||||
goUpdateCommand(COMMAND_NAME);
|
||||
ok(isEnabled(), COMMAND_NAME + " is enabled");
|
||||
|
||||
info("expected clipboard value: " + message.url);
|
||||
|
||||
let deferred = defer();
|
||||
|
||||
waitForClipboard((aData) => {
|
||||
return aData.trim() == message.url;
|
||||
}, () => {
|
||||
goDoCommand(COMMAND_NAME);
|
||||
}, () => {
|
||||
deferred.resolve(null);
|
||||
}, () => {
|
||||
deferred.reject(null);
|
||||
});
|
||||
|
||||
yield deferred.promise;
|
||||
|
||||
// Test that the "Copy Link Location" menu item is visible for network-related
|
||||
// messages.
|
||||
yield waitForContextMenu(menu, message, () => {
|
||||
let isVisible = !menu.querySelector(CONTEXT_MENU_ID).hidden;
|
||||
ok(isVisible, CONTEXT_MENU_ID + " is visible");
|
||||
});
|
||||
|
||||
// Return whether "Copy Link Location" command is enabled or not.
|
||||
function isEnabled() {
|
||||
let controller = top.document.commandDispatcher
|
||||
.getControllerForCommand(COMMAND_NAME);
|
||||
return controller && controller.isCommandEnabled(COMMAND_NAME);
|
||||
}
|
||||
});
|
|
@ -1,31 +0,0 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* 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/ */
|
||||
|
||||
// Check that the output for console.dir() works even if Logging filter is off.
|
||||
|
||||
"use strict";
|
||||
|
||||
const TEST_URI = "data:text/html;charset=utf8,<p>test for bug 862916";
|
||||
|
||||
add_task(function* () {
|
||||
yield loadTab(TEST_URI);
|
||||
let hud = yield openConsole();
|
||||
|
||||
ok(hud, "web console opened");
|
||||
|
||||
hud.setFilterState("log", false);
|
||||
registerCleanupFunction(() => hud.setFilterState("log", true));
|
||||
|
||||
hud.jsterm.execute("window.fooBarz = 'bug862916'; " +
|
||||
"console.dir(window)");
|
||||
|
||||
let varView = yield hud.jsterm.once("variablesview-fetched");
|
||||
ok(varView, "variables view object");
|
||||
|
||||
yield findVariableViewProperties(varView, [
|
||||
{ name: "fooBarz", value: "bug862916" },
|
||||
], { webconsole: hud });
|
||||
});
|
||||
|
|
@ -1,63 +0,0 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* 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/ */
|
||||
|
||||
// Test that makes sure messages are not considered repeated when console.log()
|
||||
// is invoked with different objects, see bug 865288.
|
||||
|
||||
"use strict";
|
||||
|
||||
const TEST_URI = "http://example.com/browser/devtools/client/webconsole/old/" +
|
||||
"test/test-repeated-messages.html";
|
||||
|
||||
add_task(function* () {
|
||||
yield loadTab(TEST_URI);
|
||||
let hud = yield openConsole();
|
||||
|
||||
info("waiting for 3 console.log objects");
|
||||
|
||||
hud.jsterm.clearOutput(true);
|
||||
hud.jsterm.execute("window.testConsoleObjects()");
|
||||
|
||||
let [result] = yield waitForMessages({
|
||||
webconsole: hud,
|
||||
messages: [{
|
||||
name: "3 console.log messages",
|
||||
text: "abba",
|
||||
category: CATEGORY_WEBDEV,
|
||||
severity: SEVERITY_LOG,
|
||||
count: 3,
|
||||
repeats: 1,
|
||||
objects: true,
|
||||
}],
|
||||
});
|
||||
|
||||
let msgs = [...result.matched];
|
||||
is(msgs.length, 3, "3 message elements");
|
||||
|
||||
for (let i = 0; i < msgs.length; i++) {
|
||||
info("test message element #" + i);
|
||||
|
||||
let msg = msgs[i];
|
||||
let clickable = msg.querySelector(".message-body a");
|
||||
ok(clickable, "clickable object #" + i);
|
||||
|
||||
msg.scrollIntoView(false);
|
||||
yield clickObject(clickable, i);
|
||||
}
|
||||
|
||||
function* clickObject(obj, i) {
|
||||
executeSoon(() => {
|
||||
EventUtils.synthesizeMouse(obj, 2, 2, {}, hud.iframeWindow);
|
||||
});
|
||||
|
||||
let varView = yield hud.jsterm.once("variablesview-fetched");
|
||||
ok(varView, "variables view fetched #" + i);
|
||||
|
||||
yield findVariableViewProperties(varView, [
|
||||
{ name: "id", value: "abba" + i },
|
||||
], { webconsole: hud });
|
||||
}
|
||||
});
|
||||
|
|
@ -1,75 +0,0 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* 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/ */
|
||||
|
||||
// Check that the variables view sidebar can be closed by pressing Escape in the
|
||||
// web console.
|
||||
|
||||
"use strict";
|
||||
|
||||
const TEST_URI = "http://example.com/browser/devtools/client/webconsole/old/" +
|
||||
"test/test-eval-in-stackframe.html";
|
||||
|
||||
function test() {
|
||||
let hud;
|
||||
|
||||
Task.spawn(runner).then(finishTest);
|
||||
|
||||
function* runner() {
|
||||
let {tab} = yield loadTab(TEST_URI);
|
||||
hud = yield openConsole(tab);
|
||||
let jsterm = hud.jsterm;
|
||||
let result;
|
||||
let vview;
|
||||
let msg;
|
||||
|
||||
yield openSidebar("fooObj",
|
||||
'testProp: "testValue"',
|
||||
{ name: "testProp", value: "testValue" });
|
||||
|
||||
let prop = result.matchedProp;
|
||||
ok(prop, "matched the |testProp| property in the variables view");
|
||||
|
||||
vview.window.focus();
|
||||
|
||||
let sidebarClosed = jsterm.once("sidebar-closed");
|
||||
EventUtils.synthesizeKey("KEY_Escape");
|
||||
yield sidebarClosed;
|
||||
|
||||
jsterm.clearOutput();
|
||||
|
||||
yield openSidebar("window.location",
|
||||
"Location \u2192 http://example.com/browser/",
|
||||
{ name: "host", value: "example.com" });
|
||||
|
||||
vview.window.focus();
|
||||
|
||||
msg.scrollIntoView();
|
||||
sidebarClosed = jsterm.once("sidebar-closed");
|
||||
EventUtils.synthesizeKey("KEY_Escape");
|
||||
yield sidebarClosed;
|
||||
|
||||
function* openSidebar(objName, expectedText, expectedObj) {
|
||||
msg = yield jsterm.execute(objName);
|
||||
ok(msg, "output message found");
|
||||
|
||||
let anchor = msg.querySelector("a");
|
||||
let body = msg.querySelector(".message-body");
|
||||
ok(anchor, "object anchor");
|
||||
ok(body, "message body");
|
||||
ok(body.textContent.includes(expectedText), "message text check");
|
||||
|
||||
msg.scrollIntoView();
|
||||
yield EventUtils.synthesizeMouse(anchor, 2, 2, {}, hud.iframeWindow);
|
||||
|
||||
let vviewVar = yield jsterm.once("variablesview-fetched");
|
||||
vview = vviewVar._variablesView;
|
||||
ok(vview, "variables view object exists");
|
||||
|
||||
[result] = yield findVariableViewProperties(vviewVar, [
|
||||
expectedObj,
|
||||
], { webconsole: hud });
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,83 +0,0 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* 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/ */
|
||||
|
||||
// Check that users can inspect objects logged from cross-domain iframes -
|
||||
// bug 869003.
|
||||
|
||||
"use strict";
|
||||
|
||||
const TEST_URI = "http://example.com/browser/devtools/client/webconsole/old/" +
|
||||
"test/test-bug-869003-top-window.html";
|
||||
|
||||
add_task(function* () {
|
||||
// This test is slightly more involved: it opens the web console, then the
|
||||
// variables view for a given object, it updates a property in the view and
|
||||
// checks the result. We can get a timeout with debug builds on slower
|
||||
// machines.
|
||||
requestLongerTimeout(2);
|
||||
|
||||
yield loadTab("data:text/html;charset=utf8,<p>hello");
|
||||
let hud = yield openConsole();
|
||||
|
||||
BrowserTestUtils.loadURI(gBrowser.selectedBrowser, TEST_URI);
|
||||
|
||||
let [result] = yield waitForMessages({
|
||||
webconsole: hud,
|
||||
messages: [{
|
||||
name: "console.log message",
|
||||
text: "foobar",
|
||||
category: CATEGORY_WEBDEV,
|
||||
severity: SEVERITY_LOG,
|
||||
objects: true,
|
||||
}],
|
||||
});
|
||||
|
||||
let msg = [...result.matched][0];
|
||||
ok(msg, "message element");
|
||||
|
||||
let body = msg.querySelector(".message-body");
|
||||
ok(body, "message body");
|
||||
ok(body.textContent.includes('{ hello: "world!",'), "message text check");
|
||||
ok(body.textContent.includes('function func()'), "message text check");
|
||||
|
||||
yield testClickable(result.clickableElements[0], [
|
||||
{ name: "hello", value: "world!" },
|
||||
{ name: "bug", value: 869003 },
|
||||
], hud);
|
||||
yield testClickable(result.clickableElements[1], [
|
||||
{ name: "hello", value: "world!" },
|
||||
{ name: "name", value: "func" },
|
||||
{ name: "length", value: 1 },
|
||||
], hud);
|
||||
});
|
||||
|
||||
function* testClickable(clickable, props, hud) {
|
||||
ok(clickable, "clickable object found");
|
||||
|
||||
executeSoon(() => {
|
||||
EventUtils.synthesizeMouse(clickable, 2, 2, {}, hud.iframeWindow);
|
||||
});
|
||||
|
||||
let aVar = yield hud.jsterm.once("variablesview-fetched");
|
||||
ok(aVar, "variables view fetched");
|
||||
ok(aVar._variablesView, "variables view object");
|
||||
|
||||
let [result] = yield findVariableViewProperties(aVar, props, { webconsole: hud });
|
||||
let prop = result.matchedProp;
|
||||
ok(prop, "matched the |" + props[0].name + "| property in the variables view");
|
||||
|
||||
// Check that property value updates work.
|
||||
aVar = yield updateVariablesViewProperty({
|
||||
property: prop,
|
||||
field: "value",
|
||||
string: "'omgtest'",
|
||||
webconsole: hud,
|
||||
});
|
||||
|
||||
info("onFetchAfterUpdate");
|
||||
|
||||
props[0].value = "omgtest";
|
||||
yield findVariableViewProperties(aVar, props, { webconsole: hud });
|
||||
}
|
|
@ -1,76 +0,0 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* 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/ */
|
||||
|
||||
// Check that Ctrl-W closes the Browser Console and that Ctrl-W closes the
|
||||
// current tab when using the Web Console - bug 871156.
|
||||
|
||||
"use strict";
|
||||
|
||||
add_task(function* () {
|
||||
const TEST_URI = "data:text/html;charset=utf8,<title>bug871156</title>\n" +
|
||||
"<p>hello world";
|
||||
let firstTab = gBrowser.selectedTab;
|
||||
|
||||
Services.prefs.setBoolPref("toolkit.cosmeticAnimations.enabled", false);
|
||||
registerCleanupFunction(() => {
|
||||
Services.prefs.clearUserPref("toolkit.cosmeticAnimations.enabled");
|
||||
});
|
||||
|
||||
yield loadTab(TEST_URI);
|
||||
|
||||
let hud = yield openConsole();
|
||||
ok(hud, "Web Console opened");
|
||||
|
||||
let tabClosed = defer();
|
||||
let toolboxDestroyed = defer();
|
||||
let tabSelected = defer();
|
||||
|
||||
let target = TargetFactory.forTab(gBrowser.selectedTab);
|
||||
let toolbox = gDevTools.getToolbox(target);
|
||||
|
||||
gBrowser.tabContainer.addEventListener("TabClose", function () {
|
||||
info("tab closed");
|
||||
tabClosed.resolve(null);
|
||||
}, {once: true});
|
||||
|
||||
gBrowser.tabContainer.addEventListener("TabSelect", function () {
|
||||
if (gBrowser.selectedTab == firstTab) {
|
||||
info("tab selected");
|
||||
tabSelected.resolve(null);
|
||||
}
|
||||
}, {once: true});
|
||||
|
||||
toolbox.once("destroyed", () => {
|
||||
info("toolbox destroyed");
|
||||
toolboxDestroyed.resolve(null);
|
||||
});
|
||||
|
||||
// Get out of the web console initialization.
|
||||
executeSoon(() => {
|
||||
EventUtils.synthesizeKey("w", { accelKey: true });
|
||||
});
|
||||
|
||||
yield promise.all([tabClosed.promise, toolboxDestroyed.promise,
|
||||
tabSelected.promise]);
|
||||
info("promise.all resolved. start testing the Browser Console");
|
||||
|
||||
hud = yield HUDService.toggleBrowserConsole();
|
||||
ok(hud, "Browser Console opened");
|
||||
|
||||
let deferred = defer();
|
||||
|
||||
Services.obs.addObserver(function onDestroy() {
|
||||
Services.obs.removeObserver(onDestroy, "web-console-destroyed");
|
||||
ok(true, "the Browser Console closed");
|
||||
|
||||
deferred.resolve(null);
|
||||
}, "web-console-destroyed");
|
||||
|
||||
waitForFocus(() => {
|
||||
EventUtils.synthesizeKey("w", { accelKey: true }, hud.iframeWindow);
|
||||
}, hud.iframeWindow);
|
||||
|
||||
yield deferred.promise;
|
||||
});
|
|
@ -1,59 +0,0 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* 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/ */
|
||||
|
||||
// Test to see if the cached messages are displayed when the console UI is
|
||||
// opened.
|
||||
|
||||
"use strict";
|
||||
|
||||
const TEST_URI = "http://example.com/browser/devtools/client/webconsole/old/" +
|
||||
"test/test-webconsole-error-observer.html";
|
||||
|
||||
// On e10s, the exception is triggered in child process
|
||||
// and is ignored by test harness
|
||||
if (!Services.appinfo.browserTabsRemoteAutostart) {
|
||||
expectUncaughtException();
|
||||
}
|
||||
|
||||
function test() {
|
||||
waitForExplicitFinish();
|
||||
|
||||
loadTab(TEST_URI).then(testOpenUI);
|
||||
}
|
||||
|
||||
function testOpenUI(aTestReopen) {
|
||||
openConsole().then((hud) => {
|
||||
waitForMessages({
|
||||
webconsole: hud,
|
||||
messages: [
|
||||
{
|
||||
text: "log Bazzle",
|
||||
category: CATEGORY_WEBDEV,
|
||||
severity: SEVERITY_LOG,
|
||||
},
|
||||
{
|
||||
text: "error Bazzle",
|
||||
category: CATEGORY_WEBDEV,
|
||||
severity: SEVERITY_ERROR,
|
||||
},
|
||||
{
|
||||
text: "bazBug611032",
|
||||
category: CATEGORY_JS,
|
||||
severity: SEVERITY_ERROR,
|
||||
},
|
||||
{
|
||||
text: "cssColorBug611032",
|
||||
category: CATEGORY_CSS,
|
||||
severity: SEVERITY_WARNING,
|
||||
},
|
||||
],
|
||||
}).then(() => {
|
||||
closeConsole(gBrowser.selectedTab).then(() => {
|
||||
aTestReopen && info("will reopen the Web Console");
|
||||
executeSoon(aTestReopen ? testOpenUI : finishTest);
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
|
@ -1,246 +0,0 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* 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/ */
|
||||
|
||||
// Test the basic features of the Browser Console, bug 587757.
|
||||
|
||||
"use strict";
|
||||
|
||||
const TEST_URI = "http://example.com/browser/devtools/client/webconsole/old/" +
|
||||
"test/test-console.html?" + Date.now();
|
||||
const TEST_FILE = "chrome://mochitests/content/browser/devtools/client/" +
|
||||
"webconsole/old/test/test-cu-reporterror.js";
|
||||
|
||||
const TEST_XHR_ERROR_URI = `http://example.com/404.html?${Date.now()}`;
|
||||
|
||||
const TEST_IMAGE = "http://example.com/browser/devtools/client/webconsole/old/" +
|
||||
"test/test-image.png";
|
||||
|
||||
const ObjectClient = require("devtools/shared/client/object-client");
|
||||
|
||||
add_task(function* () {
|
||||
yield loadTab(TEST_URI);
|
||||
|
||||
let opened = waitForBrowserConsole();
|
||||
|
||||
let hud = HUDService.getBrowserConsole();
|
||||
ok(!hud, "browser console is not open");
|
||||
info("wait for the browser console to open with ctrl-shift-j");
|
||||
EventUtils.synthesizeKey("j", { accelKey: true, shiftKey: true }, window);
|
||||
|
||||
hud = yield opened;
|
||||
ok(hud, "browser console opened");
|
||||
yield testMessages(hud);
|
||||
yield testCPOWInspection(hud);
|
||||
});
|
||||
|
||||
function testMessages(hud) {
|
||||
hud.jsterm.clearOutput(true);
|
||||
|
||||
expectUncaughtException();
|
||||
executeSoon(() => {
|
||||
foobarExceptionBug587757();
|
||||
});
|
||||
|
||||
// Add a message from a chrome window.
|
||||
hud.iframeWindow.console.log("bug587757a");
|
||||
|
||||
// Check Cu.reportError stack.
|
||||
// Use another js script to not depend on the test file line numbers.
|
||||
Services.scriptloader.loadSubScript(TEST_FILE, hud.iframeWindow);
|
||||
|
||||
// Bug 1348885: test that error from nuked globals do not throw
|
||||
let sandbox = new Cu.Sandbox(null, {
|
||||
wantComponents: false,
|
||||
wantGlobalProperties: ["URL", "URLSearchParams"],
|
||||
});
|
||||
let error = Cu.evalInSandbox(`
|
||||
new Error("1348885");
|
||||
`, sandbox);
|
||||
Cu.reportError(error);
|
||||
Cu.nukeSandbox(sandbox);
|
||||
|
||||
// Add a message from a content window.
|
||||
gBrowser.contentWindowAsCPOW.console.log("bug587757b");
|
||||
|
||||
// Test eval.
|
||||
hud.jsterm.execute("document.location.href");
|
||||
|
||||
// Test eval frame script
|
||||
hud.jsterm.execute(`
|
||||
gBrowser.selectedBrowser.messageManager.loadFrameScript('data:application/javascript,console.log("framescript-message")', false);
|
||||
"framescript-eval";
|
||||
`);
|
||||
|
||||
// Check for network requests.
|
||||
let xhr = new XMLHttpRequest();
|
||||
xhr.onload = () => console.log("xhr loaded, status is: " + xhr.status);
|
||||
xhr.open("get", TEST_URI, true);
|
||||
xhr.send();
|
||||
|
||||
// Check for xhr error.
|
||||
let xhrErr = new XMLHttpRequest();
|
||||
xhrErr.onload = () => {
|
||||
console.log("xhr error loaded, status is: " + xhrErr.status);
|
||||
};
|
||||
xhrErr.open("get", TEST_XHR_ERROR_URI, true);
|
||||
xhrErr.send();
|
||||
|
||||
// Check that Fetch requests are categorized as "XHR".
|
||||
fetch(TEST_IMAGE).then(() => { console.log("fetch loaded"); });
|
||||
|
||||
return waitForMessages({
|
||||
webconsole: hud,
|
||||
messages: [
|
||||
{
|
||||
name: "chrome window console.log() is displayed",
|
||||
text: "bug587757a",
|
||||
category: CATEGORY_WEBDEV,
|
||||
severity: SEVERITY_LOG,
|
||||
},
|
||||
{
|
||||
name: "Cu.reportError is displayed",
|
||||
text: "bug1141222",
|
||||
category: CATEGORY_JS,
|
||||
severity: SEVERITY_ERROR,
|
||||
stacktrace: [{
|
||||
file: TEST_FILE,
|
||||
line: 2,
|
||||
}, {
|
||||
file: TEST_FILE,
|
||||
line: 4,
|
||||
},
|
||||
// Ignore the rest of the stack,
|
||||
// just assert Cu.reportError call site
|
||||
// and consoleOpened call
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "Error from nuked global works",
|
||||
text: "1348885",
|
||||
category: CATEGORY_JS,
|
||||
severity: SEVERITY_ERROR,
|
||||
},
|
||||
{
|
||||
name: "content window console.log() is displayed",
|
||||
text: "bug587757b",
|
||||
category: CATEGORY_WEBDEV,
|
||||
severity: SEVERITY_LOG,
|
||||
},
|
||||
{
|
||||
name: "jsterm eval result",
|
||||
text: "browser.xul",
|
||||
category: CATEGORY_OUTPUT,
|
||||
severity: SEVERITY_LOG,
|
||||
},
|
||||
{
|
||||
name: "jsterm eval result 2",
|
||||
text: "framescript-eval",
|
||||
category: CATEGORY_OUTPUT,
|
||||
severity: SEVERITY_LOG,
|
||||
},
|
||||
{
|
||||
name: "frame script message",
|
||||
text: "framescript-message",
|
||||
category: CATEGORY_WEBDEV,
|
||||
severity: SEVERITY_LOG,
|
||||
},
|
||||
{
|
||||
name: "exception message",
|
||||
text: "foobarExceptionBug587757",
|
||||
category: CATEGORY_JS,
|
||||
severity: SEVERITY_ERROR,
|
||||
},
|
||||
{
|
||||
name: "network message",
|
||||
text: "test-console.html",
|
||||
category: CATEGORY_NETWORK,
|
||||
severity: SEVERITY_INFO,
|
||||
isXhr: true,
|
||||
},
|
||||
{
|
||||
name: "xhr error message",
|
||||
text: "404.html",
|
||||
category: CATEGORY_NETWORK,
|
||||
severity: SEVERITY_ERROR,
|
||||
isXhr: true,
|
||||
},
|
||||
{
|
||||
name: "network message",
|
||||
text: "test-image.png",
|
||||
category: CATEGORY_NETWORK,
|
||||
severity: SEVERITY_INFO,
|
||||
isXhr: true,
|
||||
},
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
function* testCPOWInspection(hud) {
|
||||
// Directly request evaluation to get an actor for the selected browser.
|
||||
// Note that this doesn't actually render a message, and instead allows us
|
||||
// us to assert that inspecting an object doesn't throw in the server.
|
||||
// This would be done in a mochitest-chrome suite, but that doesn't run in
|
||||
// e10s, so it's harder to get ahold of a CPOW.
|
||||
let cpowEval = yield hud.jsterm.requestEvaluation("gBrowser.selectedBrowser");
|
||||
info("Creating an ObjectClient with: " + cpowEval.result.actor);
|
||||
|
||||
let objectClient = new ObjectClient(hud.jsterm.hud.proxy.client, {
|
||||
actor: cpowEval.result.actor,
|
||||
});
|
||||
|
||||
// Before the fix for Bug 1382833, this wouldn't resolve due to a CPOW error
|
||||
// in the ObjectActor.
|
||||
let prototypeAndProperties = yield objectClient.getPrototypeAndProperties();
|
||||
|
||||
// Just a sanity check to make sure a valid packet came back
|
||||
is(prototypeAndProperties.prototype.class, "XBL prototype JSClass",
|
||||
"Looks like a valid response");
|
||||
|
||||
// The CPOW is in the _contentWindow property.
|
||||
let cpow = prototypeAndProperties.ownProperties._contentWindow.value;
|
||||
|
||||
// But it's only a CPOW in e10s.
|
||||
let e10sCheck = yield hud.jsterm.requestEvaluation(
|
||||
"Cu.isCrossProcessWrapper(gBrowser.selectedBrowser._contentWindow)");
|
||||
if (!e10sCheck.result) {
|
||||
is(cpow.class, "Window", "The object is not a CPOW.");
|
||||
return;
|
||||
}
|
||||
|
||||
is(cpow.class, "CPOW: Window", "The CPOW grip has the right class.");
|
||||
|
||||
// Check that various protocol request methods work for the CPOW.
|
||||
let response, slice;
|
||||
let objClient = new ObjectClient(hud.jsterm.hud.proxy.client, cpow);
|
||||
|
||||
response = yield objClient.getPrototypeAndProperties();
|
||||
is(Reflect.ownKeys(response.ownProperties).length, 0, "No property was retrieved.");
|
||||
is(response.ownSymbols.length, 0, "No symbol property was retrieved.");
|
||||
is(response.prototype.type, "null", "The prototype is null.");
|
||||
|
||||
response = yield objClient.enumProperties({ignoreIndexedProperties: true});
|
||||
slice = yield response.iterator.slice(0, response.iterator.count);
|
||||
is(Reflect.ownKeys(slice.ownProperties).length, 0, "No property was retrieved.");
|
||||
|
||||
response = yield objClient.enumProperties({});
|
||||
slice = yield response.iterator.slice(0, response.iterator.count);
|
||||
is(Reflect.ownKeys(slice.ownProperties).length, 0, "No property was retrieved.");
|
||||
|
||||
response = yield objClient.getOwnPropertyNames();
|
||||
is(response.ownPropertyNames.length, 0, "No property was retrieved.");
|
||||
|
||||
response = yield objClient.getProperty("x");
|
||||
is(response.descriptor, undefined, "The property does not exist.");
|
||||
|
||||
response = yield objClient.enumSymbols();
|
||||
slice = yield response.iterator.slice(0, response.iterator.count);
|
||||
is(slice.ownSymbols.length, 0, "No symbol property was retrieved.");
|
||||
|
||||
response = yield objClient.getPrototype();
|
||||
is(response.prototype.type, "null", "The prototype is null.");
|
||||
|
||||
response = yield objClient.getDisplayString();
|
||||
is(response.displayString, "<cpow>", "The CPOW stringifies to <cpow>");
|
||||
}
|
|
@ -1,99 +0,0 @@
|
|||
/* 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";
|
||||
|
||||
// Tests handling of certificates that will be imminently distrusted, and thus
|
||||
// should emit a warning to the console.
|
||||
//
|
||||
// This test requires a cert to be created in build/pgo/certs.
|
||||
//
|
||||
// Change directories to build/pgo/certs:
|
||||
// cd build/pgo/certs
|
||||
//
|
||||
// certutil -S -d . -n "imminently_distrusted" -s "CN=Imminently Distrusted End Entity" -c "pgo temporary ca" -t "P,," -k rsa -g 2048 -Z SHA256 -m 1519140221 -v 120 -8 "imminently-distrusted.example.com"
|
||||
//
|
||||
|
||||
|
||||
const TEST_URI = "data:text/html;charset=utf8,Browser Console imminent " +
|
||||
"distrust warnings test";
|
||||
const TEST_URI_PATH = "/browser/devtools/client/webconsole/old/test/" +
|
||||
"test-certificate-messages.html";
|
||||
|
||||
var gWebconsoleTests = [
|
||||
{url: "https://sha256ee.example.com" + TEST_URI_PATH,
|
||||
name: "Imminent distrust warnings appropriately not present",
|
||||
warning: [], nowarning: ["Upcoming_Distrust_Actions"]},
|
||||
{url: "https://imminently-distrusted.example.com" +
|
||||
TEST_URI_PATH,
|
||||
name: "Imminent distrust warning displayed successfully",
|
||||
warning: ["Upcoming_Distrust_Actions"], nowarning: []},
|
||||
];
|
||||
const TRIGGER_MSG = "If you haven't seen ssl warnings yet, you won't";
|
||||
|
||||
var gHud = undefined, gContentBrowser;
|
||||
var gCurrentTest;
|
||||
|
||||
function test() {
|
||||
registerCleanupFunction(function () {
|
||||
gHud = gContentBrowser = null;
|
||||
});
|
||||
|
||||
loadTab(TEST_URI).then(({browser}) => {
|
||||
gContentBrowser = browser;
|
||||
|
||||
let opened = waitForBrowserConsole();
|
||||
|
||||
let hud = HUDService.getBrowserConsole();
|
||||
ok(!hud, "browser console is not open");
|
||||
|
||||
HUDService.toggleBrowserConsole();
|
||||
|
||||
opened.then(function (hud) {
|
||||
ok(hud, "browser console opened");
|
||||
runTestLoop(hud);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function runTestLoop(theHud) {
|
||||
gCurrentTest = gWebconsoleTests.shift();
|
||||
if (!gCurrentTest) {
|
||||
finishTest();
|
||||
return;
|
||||
}
|
||||
if (!gHud) {
|
||||
gHud = theHud;
|
||||
}
|
||||
gHud.jsterm.clearOutput();
|
||||
BrowserTestUtils.browserLoaded(gContentBrowser).then(onLoad);
|
||||
if (gCurrentTest.pref) {
|
||||
SpecialPowers.pushPrefEnv({"set": gCurrentTest.pref},
|
||||
function () {
|
||||
BrowserTestUtils.loadURI(gBrowser.selectedBrowser, gCurrentTest.url);
|
||||
});
|
||||
} else {
|
||||
BrowserTestUtils.loadURI(gBrowser.selectedBrowser, gCurrentTest.url);
|
||||
}
|
||||
}
|
||||
|
||||
function onLoad() {
|
||||
waitForSuccess({
|
||||
name: gCurrentTest.name,
|
||||
validator: function () {
|
||||
if (gHud.outputNode.textContent.includes(TRIGGER_MSG)) {
|
||||
for (let warning of gCurrentTest.warning) {
|
||||
if (!gHud.outputNode.textContent.includes(warning)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
for (let nowarning of gCurrentTest.nowarning) {
|
||||
if (gHud.outputNode.textContent.includes(nowarning)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}).then(runTestLoop);
|
||||
}
|
|
@ -1,41 +0,0 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* 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/ */
|
||||
|
||||
// Check that console.clear() does not clear the output of the browser console.
|
||||
|
||||
"use strict";
|
||||
|
||||
const TEST_URI = "data:text/html;charset=utf8,<p>Bug 1296870";
|
||||
|
||||
add_task(function* () {
|
||||
yield loadTab(TEST_URI);
|
||||
let hud = yield HUDService.toggleBrowserConsole();
|
||||
|
||||
info("Log a new message from the content page");
|
||||
ContentTask.spawn(gBrowser.selectedBrowser, {}, function* () {
|
||||
content.wrappedJSObject.console.log("msg");
|
||||
});
|
||||
yield waitForMessage("msg", hud);
|
||||
|
||||
info("Send a console.clear() from the content page");
|
||||
ContentTask.spawn(gBrowser.selectedBrowser, {}, function* () {
|
||||
content.wrappedJSObject.console.clear();
|
||||
});
|
||||
yield waitForMessage("Console was cleared", hud);
|
||||
|
||||
info("Check that the messages logged after the first clear are still displayed");
|
||||
isnot(hud.outputNode.textContent.indexOf("msg"), -1, "msg is in the output");
|
||||
});
|
||||
|
||||
function waitForMessage(message, webconsole) {
|
||||
return waitForMessages({
|
||||
webconsole,
|
||||
messages: [{
|
||||
text: message,
|
||||
category: CATEGORY_WEBDEV,
|
||||
severity: SEVERITY_LOG,
|
||||
}],
|
||||
});
|
||||
}
|
|
@ -1,86 +0,0 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* 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/ */
|
||||
|
||||
// Check that clear output on page reload works - bug 705921.
|
||||
// Check that clear output and page reload remove the sidebar - bug 971967.
|
||||
|
||||
"use strict";
|
||||
|
||||
add_task(function* () {
|
||||
const PREF = "devtools.webconsole.persistlog";
|
||||
const TEST_URI = "http://example.com/browser/devtools/client/webconsole/old/" +
|
||||
"test/test-console.html";
|
||||
|
||||
Services.prefs.setBoolPref(PREF, false);
|
||||
registerCleanupFunction(() => Services.prefs.clearUserPref(PREF));
|
||||
|
||||
yield loadTab(TEST_URI);
|
||||
|
||||
let hud = yield openConsole();
|
||||
ok(hud, "Web Console opened");
|
||||
|
||||
yield openSidebar("fooObj", { name: "testProp", value: "testValue" });
|
||||
|
||||
let sidebarClosed = hud.jsterm.once("sidebar-closed");
|
||||
hud.jsterm.clearOutput();
|
||||
yield sidebarClosed;
|
||||
|
||||
hud.jsterm.execute("console.log('foobarz1')");
|
||||
|
||||
yield waitForMessages({
|
||||
webconsole: hud,
|
||||
messages: [{
|
||||
text: "foobarz1",
|
||||
category: CATEGORY_WEBDEV,
|
||||
severity: SEVERITY_LOG,
|
||||
}],
|
||||
});
|
||||
|
||||
yield openSidebar("fooObj", { name: "testProp", value: "testValue" });
|
||||
|
||||
BrowserReload();
|
||||
|
||||
sidebarClosed = hud.jsterm.once("sidebar-closed");
|
||||
loadBrowser(gBrowser.selectedBrowser);
|
||||
yield sidebarClosed;
|
||||
|
||||
hud.jsterm.execute("console.log('foobarz2')");
|
||||
|
||||
yield waitForMessages({
|
||||
webconsole: hud,
|
||||
messages: [{
|
||||
text: "test-console.html",
|
||||
category: CATEGORY_NETWORK,
|
||||
},
|
||||
{
|
||||
text: "foobarz2",
|
||||
category: CATEGORY_WEBDEV,
|
||||
severity: SEVERITY_LOG,
|
||||
}],
|
||||
});
|
||||
|
||||
is(hud.outputNode.textContent.indexOf("foobarz1"), -1,
|
||||
"foobarz1 has been removed from output");
|
||||
|
||||
function* openSidebar(objName, expectedObj) {
|
||||
let msg = yield hud.jsterm.execute(objName);
|
||||
ok(msg, "output message found");
|
||||
|
||||
let anchor = msg.querySelector("a");
|
||||
let body = msg.querySelector(".message-body");
|
||||
ok(anchor, "object anchor");
|
||||
ok(body, "message body");
|
||||
|
||||
yield EventUtils.synthesizeMouse(anchor, 2, 2, {}, hud.iframeWindow);
|
||||
|
||||
let vviewVar = yield hud.jsterm.once("variablesview-fetched");
|
||||
let vview = vviewVar._variablesView;
|
||||
ok(vview, "variables view object exists");
|
||||
|
||||
yield findVariableViewProperties(vviewVar, [
|
||||
expectedObj,
|
||||
], { webconsole: hud });
|
||||
}
|
||||
});
|
|
@ -1,59 +0,0 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* 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/ */
|
||||
|
||||
// Tests that the input field is focused when the console is opened.
|
||||
|
||||
"use strict";
|
||||
|
||||
const TEST_URI = "http://example.com/browser/devtools/client/webconsole/old/" +
|
||||
"test/test-console.html";
|
||||
|
||||
add_task(function* () {
|
||||
yield loadTab(TEST_URI);
|
||||
let hud = yield openConsole();
|
||||
|
||||
let [result] = yield waitForMessages({
|
||||
webconsole: hud,
|
||||
messages: [{
|
||||
text: "Dolske Digs Bacon",
|
||||
category: CATEGORY_WEBDEV,
|
||||
severity: SEVERITY_LOG,
|
||||
}],
|
||||
});
|
||||
|
||||
let msg = [...result.matched][0];
|
||||
let outputItem = msg.querySelector(".message-body");
|
||||
ok(outputItem, "found a logged message");
|
||||
|
||||
let inputNode = hud.jsterm.inputNode;
|
||||
ok(inputNode.getAttribute("focused"), "input node is focused, first");
|
||||
|
||||
yield waitForBlurredInput(inputNode);
|
||||
|
||||
EventUtils.sendMouseEvent({type: "click"}, hud.outputNode);
|
||||
ok(inputNode.getAttribute("focused"), "input node is focused, second time");
|
||||
|
||||
yield waitForBlurredInput(inputNode);
|
||||
|
||||
info("Setting a text selection and making sure a click does not re-focus");
|
||||
let selection = hud.iframeWindow.getSelection();
|
||||
selection.selectAllChildren(outputItem);
|
||||
|
||||
EventUtils.sendMouseEvent({type: "click"}, hud.outputNode);
|
||||
ok(!inputNode.getAttribute("focused"),
|
||||
"input node is not focused after drag");
|
||||
});
|
||||
|
||||
function waitForBlurredInput(inputNode) {
|
||||
return new Promise(resolve => {
|
||||
let lostFocus = () => {
|
||||
inputNode.removeEventListener("blur", lostFocus);
|
||||
ok(!inputNode.getAttribute("focused"), "input node is not focused");
|
||||
resolve();
|
||||
};
|
||||
inputNode.addEventListener("blur", lostFocus);
|
||||
document.getElementById("urlbar").click();
|
||||
});
|
||||
}
|
|
@ -1,322 +0,0 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* 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/ */
|
||||
|
||||
// Test that Console.jsm outputs messages to the Browser Console, bug 851231.
|
||||
|
||||
"use strict";
|
||||
|
||||
function onNewMessage(aNewMessages) {
|
||||
for (let msg of aNewMessages) {
|
||||
// Messages that shouldn't be output contain the substring FAIL_TEST
|
||||
if (msg.node.textContent.includes("FAIL_TEST")) {
|
||||
ok(false, "Message shouldn't have been output: " + msg.node.textContent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
add_task(function* () {
|
||||
let consoleStorage = Cc["@mozilla.org/consoleAPI-storage;1"];
|
||||
let storage = consoleStorage.getService(Ci.nsIConsoleAPIStorage);
|
||||
storage.clearEvents();
|
||||
|
||||
let {console} = ChromeUtils.import("resource://gre/modules/Console.jsm", {});
|
||||
console.log("bug861338-log-cached");
|
||||
|
||||
let hud = yield HUDService.toggleBrowserConsole();
|
||||
|
||||
yield waitForMessages({
|
||||
webconsole: hud,
|
||||
messages: [{
|
||||
name: "cached console.log message",
|
||||
text: "bug861338-log-cached",
|
||||
category: CATEGORY_WEBDEV,
|
||||
severity: SEVERITY_LOG,
|
||||
}],
|
||||
});
|
||||
|
||||
hud.jsterm.clearOutput(true);
|
||||
|
||||
function testTrace() {
|
||||
console.trace();
|
||||
}
|
||||
|
||||
console.time("foobarTimer");
|
||||
let foobar = { bug851231prop: "bug851231value" };
|
||||
|
||||
console.log("bug851231-log");
|
||||
console.info("bug851231-info");
|
||||
console.warn("bug851231-warn");
|
||||
console.error("bug851231-error", foobar);
|
||||
console.debug("bug851231-debug");
|
||||
console.dir(document);
|
||||
testTrace();
|
||||
console.timeEnd("foobarTimer");
|
||||
|
||||
info("wait for the Console.jsm messages");
|
||||
|
||||
let results = yield waitForMessages({
|
||||
webconsole: hud,
|
||||
messages: [
|
||||
{
|
||||
name: "console.log output",
|
||||
text: "bug851231-log",
|
||||
category: CATEGORY_WEBDEV,
|
||||
severity: SEVERITY_LOG,
|
||||
},
|
||||
{
|
||||
name: "console.info output",
|
||||
text: "bug851231-info",
|
||||
category: CATEGORY_WEBDEV,
|
||||
severity: SEVERITY_INFO,
|
||||
},
|
||||
{
|
||||
name: "console.warn output",
|
||||
text: "bug851231-warn",
|
||||
category: CATEGORY_WEBDEV,
|
||||
severity: SEVERITY_WARNING,
|
||||
},
|
||||
{
|
||||
name: "console.error output",
|
||||
text: /\bbug851231-error\b.+\{\s*bug851231prop:\s"bug851231value"\s*\}/,
|
||||
category: CATEGORY_WEBDEV,
|
||||
severity: SEVERITY_ERROR,
|
||||
objects: true,
|
||||
},
|
||||
{
|
||||
name: "console.debug output",
|
||||
text: "bug851231-debug",
|
||||
category: CATEGORY_WEBDEV,
|
||||
severity: SEVERITY_LOG,
|
||||
},
|
||||
{
|
||||
name: "console.trace output",
|
||||
consoleTrace: {
|
||||
file: "browser_console_consolejsm_output.js",
|
||||
fn: "testTrace",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "console.dir output",
|
||||
consoleDir: /XULDocument\s+.+\s+chrome:\/\/.+\/browser\.xul/,
|
||||
},
|
||||
{
|
||||
name: "console.time output",
|
||||
consoleTime: "foobarTimer",
|
||||
},
|
||||
{
|
||||
name: "console.timeEnd output",
|
||||
consoleTimeEnd: "foobarTimer",
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
let consoleErrorMsg = results[3];
|
||||
ok(consoleErrorMsg, "console.error message element found");
|
||||
let clickable = consoleErrorMsg.clickableElements[0];
|
||||
ok(clickable, "clickable object found for console.error");
|
||||
|
||||
let deferred = defer();
|
||||
|
||||
let onFetch = (aVar) => {
|
||||
// Skip the notification from console.dir variablesview-fetched.
|
||||
if (aVar._variablesView != hud.jsterm._variablesView) {
|
||||
return;
|
||||
}
|
||||
hud.jsterm.off("variablesview-fetched", onFetch);
|
||||
|
||||
deferred.resolve(aVar);
|
||||
};
|
||||
|
||||
hud.jsterm.on("variablesview-fetched", onFetch);
|
||||
|
||||
clickable.scrollIntoView(false);
|
||||
|
||||
info("wait for variablesview-fetched");
|
||||
executeSoon(() =>
|
||||
EventUtils.synthesizeMouse(clickable, 2, 2, {}, hud.iframeWindow));
|
||||
|
||||
let varView = yield deferred.promise;
|
||||
ok(varView, "object inspector opened on click");
|
||||
|
||||
yield findVariableViewProperties(varView, [{
|
||||
name: "bug851231prop",
|
||||
value: "bug851231value",
|
||||
}], { webconsole: hud });
|
||||
|
||||
yield HUDService.toggleBrowserConsole();
|
||||
});
|
||||
|
||||
add_task(function* testPrefix() {
|
||||
let consoleStorage = Cc["@mozilla.org/consoleAPI-storage;1"];
|
||||
let storage = consoleStorage.getService(Ci.nsIConsoleAPIStorage);
|
||||
storage.clearEvents();
|
||||
|
||||
let {ConsoleAPI} = ChromeUtils.import("resource://gre/modules/Console.jsm", {});
|
||||
let consoleOptions = {
|
||||
maxLogLevel: "error",
|
||||
prefix: "Log Prefix",
|
||||
};
|
||||
let console2 = new ConsoleAPI(consoleOptions);
|
||||
console2.error("Testing a prefix");
|
||||
console2.log("FAIL_TEST: Below the maxLogLevel");
|
||||
|
||||
let hud = yield HUDService.toggleBrowserConsole();
|
||||
hud.ui.on("new-messages", onNewMessage);
|
||||
yield waitForMessages({
|
||||
webconsole: hud,
|
||||
messages: [{
|
||||
name: "cached console.error message",
|
||||
prefix: "Log Prefix:",
|
||||
severity: SEVERITY_ERROR,
|
||||
text: "Testing a prefix",
|
||||
}],
|
||||
});
|
||||
|
||||
hud.jsterm.clearOutput(true);
|
||||
hud.ui.off("new-messages", onNewMessage);
|
||||
yield HUDService.toggleBrowserConsole();
|
||||
});
|
||||
|
||||
add_task(function* testMaxLogLevelPrefMissing() {
|
||||
let consoleStorage = Cc["@mozilla.org/consoleAPI-storage;1"];
|
||||
let storage = consoleStorage.getService(Ci.nsIConsoleAPIStorage);
|
||||
storage.clearEvents();
|
||||
|
||||
let {ConsoleAPI} = ChromeUtils.import("resource://gre/modules/Console.jsm", {});
|
||||
let consoleOptions = {
|
||||
maxLogLevel: "error",
|
||||
maxLogLevelPref: "testing.maxLogLevel",
|
||||
};
|
||||
let console = new ConsoleAPI(consoleOptions);
|
||||
|
||||
is(Services.prefs.getPrefType(consoleOptions.maxLogLevelPref),
|
||||
Services.prefs.PREF_INVALID,
|
||||
"Check log level pref is missing");
|
||||
|
||||
// Since the maxLogLevelPref doesn't exist, we should fallback to the passed
|
||||
// maxLogLevel of "error".
|
||||
console.warn("FAIL_TEST: Below the maxLogLevel");
|
||||
console.error("Error should be shown");
|
||||
|
||||
let hud = yield HUDService.toggleBrowserConsole();
|
||||
|
||||
hud.ui.on("new-messages", onNewMessage);
|
||||
|
||||
yield waitForMessages({
|
||||
webconsole: hud,
|
||||
messages: [{
|
||||
name: "defaulting to error level",
|
||||
severity: SEVERITY_ERROR,
|
||||
text: "Error should be shown",
|
||||
}],
|
||||
});
|
||||
|
||||
hud.jsterm.clearOutput(true);
|
||||
hud.ui.off("new-messages", onNewMessage);
|
||||
yield HUDService.toggleBrowserConsole();
|
||||
});
|
||||
|
||||
add_task(function* testMaxLogLevelPref() {
|
||||
let consoleStorage = Cc["@mozilla.org/consoleAPI-storage;1"];
|
||||
let storage = consoleStorage.getService(Ci.nsIConsoleAPIStorage);
|
||||
storage.clearEvents();
|
||||
|
||||
let {ConsoleAPI} = ChromeUtils.import("resource://gre/modules/Console.jsm", {});
|
||||
let consoleOptions = {
|
||||
maxLogLevel: "error",
|
||||
maxLogLevelPref: "testing.maxLogLevel",
|
||||
};
|
||||
|
||||
info("Setting the pref to warn");
|
||||
Services.prefs.setCharPref(consoleOptions.maxLogLevelPref, "Warn");
|
||||
|
||||
let console = new ConsoleAPI(consoleOptions);
|
||||
|
||||
is(console.maxLogLevel, "warn", "Check pref was read at initialization");
|
||||
|
||||
console.info("FAIL_TEST: info is below the maxLogLevel");
|
||||
console.error("Error should be shown");
|
||||
console.warn("Warn should be shown due to the initial pref value");
|
||||
|
||||
info("Setting the pref to info");
|
||||
Services.prefs.setCharPref(consoleOptions.maxLogLevelPref, "INFO");
|
||||
is(console.maxLogLevel, "info", "Check pref was lowercased");
|
||||
|
||||
console.info("info should be shown due to the pref change being observed");
|
||||
|
||||
info("Clearing the pref");
|
||||
Services.prefs.clearUserPref(consoleOptions.maxLogLevelPref);
|
||||
|
||||
console.warn("FAIL_TEST: Shouldn't be shown due to defaulting to error");
|
||||
console.error("Should be shown due to defaulting to error");
|
||||
|
||||
let hud = yield HUDService.toggleBrowserConsole();
|
||||
hud.ui.on("new-messages", onNewMessage);
|
||||
|
||||
yield waitForMessages({
|
||||
webconsole: hud,
|
||||
messages: [{
|
||||
name: "error > warn",
|
||||
severity: SEVERITY_ERROR,
|
||||
text: "Error should be shown",
|
||||
},
|
||||
{
|
||||
name: "warn is the inital pref value",
|
||||
severity: SEVERITY_WARNING,
|
||||
text: "Warn should be shown due to the initial pref value",
|
||||
},
|
||||
{
|
||||
name: "pref changed to info",
|
||||
severity: SEVERITY_INFO,
|
||||
text: "info should be shown due to the pref change being observed",
|
||||
},
|
||||
{
|
||||
name: "default to intial maxLogLevel if pref is removed",
|
||||
severity: SEVERITY_ERROR,
|
||||
text: "Should be shown due to defaulting to error",
|
||||
}],
|
||||
});
|
||||
|
||||
hud.jsterm.clearOutput(true);
|
||||
hud.ui.off("new-messages", onNewMessage);
|
||||
yield HUDService.toggleBrowserConsole();
|
||||
});
|
||||
|
||||
// Test that console.profile/profileEnd trigger the right events
|
||||
add_task(function* testProfile() {
|
||||
let consoleStorage = Cc["@mozilla.org/consoleAPI-storage;1"];
|
||||
let storage = consoleStorage.getService(Ci.nsIConsoleAPIStorage);
|
||||
let { console } = ChromeUtils.import("resource://gre/modules/Console.jsm", {});
|
||||
|
||||
storage.clearEvents();
|
||||
|
||||
let profilerEvents = [];
|
||||
|
||||
function observer(subject, topic) {
|
||||
is(topic, "console-api-profiler", "The topic is 'console-api-profiler'");
|
||||
const subjectObj = subject.wrappedJSObject;
|
||||
const event = { action: subjectObj.action, name: subjectObj.arguments[0] };
|
||||
info(`Profiler event: action=${event.action}, name=${event.name}`);
|
||||
profilerEvents.push(event);
|
||||
}
|
||||
|
||||
Services.obs.addObserver(observer, "console-api-profiler");
|
||||
|
||||
console.profile("test");
|
||||
console.profileEnd("test");
|
||||
|
||||
Services.obs.removeObserver(observer, "console-api-profiler");
|
||||
|
||||
// Test that no messages were logged to the storage
|
||||
let consoleEvents = storage.getEvents();
|
||||
is(consoleEvents.length, 0, "There are zero logged messages");
|
||||
|
||||
// Test that two profiler events were fired
|
||||
is(profilerEvents.length, 2, "Got two profiler events");
|
||||
is(profilerEvents[0].action, "profile", "First event has the right action");
|
||||
is(profilerEvents[0].name, "test", "First event has the right name");
|
||||
is(profilerEvents[1].action, "profileEnd", "Second event has the right action");
|
||||
is(profilerEvents[1].name, "test", "Second event has the right name");
|
||||
});
|
|
@ -1,78 +0,0 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* 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/ */
|
||||
|
||||
// Tests that the `copy` console helper works as intended.
|
||||
|
||||
"use strict";
|
||||
|
||||
var gWebConsole, gJSTerm;
|
||||
|
||||
var TEXT = "Lorem ipsum dolor sit amet, consectetur adipisicing " +
|
||||
"elit, sed do eiusmod tempor incididunt ut labore et dolore magna " +
|
||||
"aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco " +
|
||||
"laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure " +
|
||||
"dolor in reprehenderit in voluptate velit esse cillum dolore eu " +
|
||||
"fugiat nulla pariatur. Excepteur sint occaecat cupidatat non " +
|
||||
"proident, sunt in culpa qui officia deserunt mollit anim id est laborum." +
|
||||
new Date();
|
||||
|
||||
var ID = "select-me";
|
||||
|
||||
add_task(function* init() {
|
||||
yield loadTab("data:text/html;charset=utf-8," +
|
||||
"<body>" +
|
||||
" <div>" +
|
||||
" <h1>Testing copy command</h1>" +
|
||||
" <p>This is some example text</p>" +
|
||||
" <p id='select-me'>" + TEXT + "</p>" +
|
||||
" </div>" +
|
||||
" <div><p></p></div>" +
|
||||
"</body>");
|
||||
|
||||
gWebConsole = yield openConsole();
|
||||
gJSTerm = gWebConsole.jsterm;
|
||||
});
|
||||
|
||||
add_task(function* testCopy() {
|
||||
let RANDOM = Math.random();
|
||||
let string = "Text: " + RANDOM;
|
||||
let obj = {a: 1, b: "foo", c: RANDOM};
|
||||
|
||||
let samples = [
|
||||
[RANDOM, RANDOM],
|
||||
[JSON.stringify(string), string],
|
||||
[obj.toSource(), JSON.stringify(obj, null, " ")],
|
||||
[
|
||||
"$('#" + ID + "')",
|
||||
yield ContentTask.spawn(gBrowser.selectedBrowser, ID, function(id) {
|
||||
return content.document.getElementById(id).outerHTML;
|
||||
})
|
||||
]
|
||||
];
|
||||
for (let [source, reference] of samples) {
|
||||
let deferredResult = defer();
|
||||
|
||||
SimpleTest.waitForClipboard(
|
||||
"" + reference,
|
||||
() => {
|
||||
let command = "copy(" + source + ")";
|
||||
info("Attempting to copy: " + source);
|
||||
info("Executing command: " + command);
|
||||
gJSTerm.execute(command, msg => {
|
||||
is(msg, undefined, "Command success: " + command);
|
||||
});
|
||||
},
|
||||
deferredResult.resolve,
|
||||
deferredResult.reject);
|
||||
|
||||
yield deferredResult.promise;
|
||||
}
|
||||
});
|
||||
|
||||
add_task(function* cleanup() {
|
||||
gWebConsole = gJSTerm = null;
|
||||
gBrowser.removeTab(gBrowser.selectedTab);
|
||||
finishTest();
|
||||
});
|
|
@ -1,97 +0,0 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* 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/ */
|
||||
|
||||
/* globals goDoCommand */
|
||||
|
||||
"use strict";
|
||||
|
||||
// Test copying of the entire console message when right-clicked
|
||||
// with no other text selected. See Bug 1100562.
|
||||
|
||||
add_task(function* () {
|
||||
let hud;
|
||||
let outputNode;
|
||||
let contextMenu;
|
||||
|
||||
const TEST_URI = "http://example.com/browser/devtools/client/webconsole/old/test/test-console.html";
|
||||
|
||||
const { tab, browser } = yield loadTab(TEST_URI);
|
||||
hud = yield openConsole(tab);
|
||||
outputNode = hud.outputNode;
|
||||
contextMenu = hud.iframeWindow.document.getElementById("output-contextmenu");
|
||||
|
||||
registerCleanupFunction(() => {
|
||||
hud = outputNode = contextMenu = null;
|
||||
});
|
||||
|
||||
hud.jsterm.clearOutput();
|
||||
|
||||
yield ContentTask.spawn(browser, {}, function* () {
|
||||
let button = content.document.getElementById("testTrace");
|
||||
button.click();
|
||||
});
|
||||
|
||||
let results = yield waitForMessages({
|
||||
webconsole: hud,
|
||||
messages: [
|
||||
{
|
||||
text: "bug 1100562",
|
||||
category: CATEGORY_WEBDEV,
|
||||
severity: SEVERITY_LOG,
|
||||
lines: 1,
|
||||
},
|
||||
{
|
||||
name: "console.trace output",
|
||||
consoleTrace: true,
|
||||
lines: 3,
|
||||
},
|
||||
]
|
||||
});
|
||||
|
||||
outputNode.focus();
|
||||
|
||||
for (let result of results) {
|
||||
let message = [...result.matched][0];
|
||||
|
||||
yield waitForContextMenu(contextMenu, message, () => {
|
||||
let copyItem = contextMenu.querySelector("#cMenu_copy");
|
||||
copyItem.doCommand();
|
||||
|
||||
let controller = top.document.commandDispatcher
|
||||
.getControllerForCommand("cmd_copy");
|
||||
is(controller.isCommandEnabled("cmd_copy"), true, "cmd_copy is enabled");
|
||||
});
|
||||
|
||||
let clipboardText;
|
||||
|
||||
yield waitForClipboardPromise(
|
||||
() => goDoCommand("cmd_copy"),
|
||||
(str) => {
|
||||
clipboardText = str;
|
||||
return message.textContent == clipboardText;
|
||||
}
|
||||
);
|
||||
|
||||
ok(clipboardText, "Clipboard text was found and saved");
|
||||
|
||||
let lines = clipboardText.split("\n");
|
||||
ok(lines.length > 0, "There is at least one newline in the message");
|
||||
is(lines.pop(), "", "There is a newline at the end");
|
||||
is(lines.length, result.lines, `There are ${result.lines} lines in the message`);
|
||||
|
||||
// Test the first line for "timestamp message repeat file:line"
|
||||
let firstLine = lines.shift();
|
||||
ok(/^[\d:.]+ .+ \d+ .+:\d+$/.test(firstLine),
|
||||
"The message's first line has the right format");
|
||||
|
||||
// Test the remaining lines (stack trace) for "TABfunctionName sourceURL:line:col"
|
||||
for (let line of lines) {
|
||||
ok(/^\t.+ .+:\d+:\d+$/.test(line), "The stack trace line has the right format");
|
||||
}
|
||||
}
|
||||
|
||||
yield closeConsole(tab);
|
||||
yield finishTest();
|
||||
});
|
|
@ -1,95 +0,0 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* 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/ */
|
||||
|
||||
// Check that Dead Objects do not break the Web/Browser Consoles.
|
||||
// See bug 883649.
|
||||
// This test does:
|
||||
// - opens a new tab,
|
||||
// - opens the Browser Console,
|
||||
// - stores a reference to the content document of the tab on the chrome
|
||||
// window object,
|
||||
// - closes the tab,
|
||||
// - tries to use the object that was pointing to the now-defunct content
|
||||
// document. This is the dead object.
|
||||
|
||||
"use strict";
|
||||
|
||||
const TEST_URI = "data:text/html;charset=utf8,<p>dead objects!";
|
||||
|
||||
function test() {
|
||||
let hud = null;
|
||||
|
||||
registerCleanupFunction(() => {
|
||||
Services.prefs.clearUserPref("devtools.chrome.enabled");
|
||||
});
|
||||
|
||||
Task.spawn(runner).then(finishTest);
|
||||
|
||||
function* runner() {
|
||||
Services.prefs.setBoolPref("devtools.chrome.enabled", true);
|
||||
yield loadTab(TEST_URI);
|
||||
let browser = gBrowser.selectedBrowser;
|
||||
let winID = browser.outerWindowID;
|
||||
|
||||
info("open the browser console");
|
||||
|
||||
hud = yield HUDService.toggleBrowserConsole();
|
||||
ok(hud, "browser console opened");
|
||||
|
||||
let jsterm = hud.jsterm;
|
||||
|
||||
jsterm.clearOutput();
|
||||
|
||||
// Add the reference to the content document.
|
||||
yield jsterm.execute("Cu = Components.utils;" +
|
||||
"Cu.import('resource://gre/modules/Services.jsm');" +
|
||||
"chromeWindow = Services.wm.getMostRecentWindow('" +
|
||||
"navigator:browser');" +
|
||||
"foobarzTezt = chromeWindow.content.document;" +
|
||||
"delete chromeWindow");
|
||||
|
||||
gBrowser.removeCurrentTab();
|
||||
|
||||
yield TestUtils.topicObserved("outer-window-nuked", (subject, data) => {
|
||||
let id = subject.QueryInterface(Ci.nsISupportsPRUint64).data;
|
||||
return id == winID;
|
||||
});
|
||||
|
||||
let msg = yield jsterm.execute("foobarzTezt");
|
||||
|
||||
isnot(hud.outputNode.textContent.indexOf("DeadObject"), -1,
|
||||
"dead object found");
|
||||
|
||||
jsterm.setInputValue("foobarzTezt");
|
||||
|
||||
for (let c of ".hello") {
|
||||
EventUtils.synthesizeKey(c, {}, hud.iframeWindow);
|
||||
}
|
||||
|
||||
yield jsterm.execute();
|
||||
|
||||
isnot(hud.outputNode.textContent.indexOf("can't access dead object"), -1,
|
||||
"'cannot access dead object' message found");
|
||||
|
||||
// Click the second execute output.
|
||||
let clickable = msg.querySelector("a");
|
||||
ok(clickable, "clickable object found");
|
||||
isnot(clickable.textContent.indexOf("DeadObject"), -1,
|
||||
"message text check");
|
||||
|
||||
msg.scrollIntoView();
|
||||
|
||||
executeSoon(() => {
|
||||
EventUtils.synthesizeMouseAtCenter(clickable, {}, hud.iframeWindow);
|
||||
});
|
||||
|
||||
yield jsterm.once("variablesview-fetched");
|
||||
ok(true, "variables view fetched");
|
||||
|
||||
msg = yield jsterm.execute("delete window.foobarzTezt; 2013-26");
|
||||
|
||||
isnot(msg.textContent.indexOf("1987"), -1, "result message found");
|
||||
}
|
||||
}
|
|
@ -1,92 +0,0 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* 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/ */
|
||||
|
||||
// Check that exceptions from scripts loaded with the DevTools loader are
|
||||
// opened correctly in View Source from the Browser Console.
|
||||
// See bug 866950.
|
||||
|
||||
"use strict";
|
||||
|
||||
const TEST_URI = "data:text/html;charset=utf8,<p>hello world from bug 866950";
|
||||
|
||||
function test() {
|
||||
requestLongerTimeout(2);
|
||||
|
||||
let webconsole, browserconsole;
|
||||
|
||||
Task.spawn(runner).then(finishTest);
|
||||
|
||||
function* runner() {
|
||||
let {tab} = yield loadTab(TEST_URI);
|
||||
webconsole = yield openConsole(tab);
|
||||
ok(webconsole, "web console opened");
|
||||
|
||||
browserconsole = yield HUDService.toggleBrowserConsole();
|
||||
ok(browserconsole, "browser console opened");
|
||||
|
||||
// Cause an exception in a script loaded with the DevTools loader.
|
||||
let toolbox = gDevTools.getToolbox(webconsole.target);
|
||||
let oldPanels = toolbox._toolPanels;
|
||||
// non-iterable
|
||||
toolbox._toolPanels = {};
|
||||
|
||||
function fixToolbox() {
|
||||
toolbox._toolPanels = oldPanels;
|
||||
}
|
||||
|
||||
info("generate exception and wait for message");
|
||||
|
||||
executeSoon(() => {
|
||||
executeSoon(fixToolbox);
|
||||
expectUncaughtException();
|
||||
toolbox.getToolPanels();
|
||||
});
|
||||
|
||||
let [result] = yield waitForMessages({
|
||||
webconsole: browserconsole,
|
||||
messages: [{
|
||||
text: "TypeError: this._toolPanels is not iterable",
|
||||
category: CATEGORY_JS,
|
||||
severity: SEVERITY_ERROR,
|
||||
}],
|
||||
});
|
||||
|
||||
fixToolbox();
|
||||
|
||||
let msg = [...result.matched][0];
|
||||
ok(msg, "message element found");
|
||||
let locationNode = msg
|
||||
.querySelector(".message .message-location > .frame-link");
|
||||
ok(locationNode, "message location element found");
|
||||
|
||||
let url = locationNode.getAttribute("data-url");
|
||||
info("location node url: " + url);
|
||||
ok(url.indexOf("resource://") === 0, "error comes from a subscript");
|
||||
|
||||
let viewSource = browserconsole.viewSource;
|
||||
let URL = null;
|
||||
let clickPromise = defer();
|
||||
browserconsole.viewSourceInDebugger = (sourceURL) => {
|
||||
info("browserconsole.viewSourceInDebugger() was invoked: " + sourceURL);
|
||||
URL = sourceURL;
|
||||
clickPromise.resolve(null);
|
||||
};
|
||||
|
||||
msg.scrollIntoView();
|
||||
EventUtils.synthesizeMouse(locationNode, 2, 2, {},
|
||||
browserconsole.iframeWindow);
|
||||
|
||||
info("wait for click on locationNode");
|
||||
yield clickPromise.promise;
|
||||
|
||||
info("view-source url: " + URL);
|
||||
ok(URL, "we have some source URL after the click");
|
||||
isnot(URL.indexOf("toolbox.js"), -1,
|
||||
"we have the expected view source URL");
|
||||
is(URL.indexOf("->"), -1, "no -> in the URL given to view-source");
|
||||
|
||||
browserconsole.viewSourceInDebugger = viewSource;
|
||||
}
|
||||
}
|
|
@ -1,79 +0,0 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* 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/ */
|
||||
|
||||
// Check that JS errors and CSS warnings open view source when their source link
|
||||
// is clicked in the Browser Console. See bug 877778.
|
||||
|
||||
"use strict";
|
||||
|
||||
const TEST_URI = "data:text/html;charset=utf8,<p>hello world from bug 877778 " +
|
||||
"<button onclick='foobar.explode()' " +
|
||||
"style='test-color: green-please'>click!</button>";
|
||||
|
||||
add_task(function* () {
|
||||
yield new Promise(resolve => {
|
||||
SpecialPowers.pushPrefEnv({"set": [
|
||||
["devtools.browserconsole.filter.cssparser", true]
|
||||
]}, resolve);
|
||||
});
|
||||
|
||||
yield loadTab(TEST_URI);
|
||||
let hud = yield HUDService.toggleBrowserConsole();
|
||||
ok(hud, "browser console opened");
|
||||
|
||||
// On e10s, the exception is triggered in child process
|
||||
// and is ignored by test harness
|
||||
if (!Services.appinfo.browserTabsRemoteAutostart) {
|
||||
expectUncaughtException();
|
||||
}
|
||||
|
||||
info("generate exception and wait for the message");
|
||||
ContentTask.spawn(gBrowser.selectedBrowser, {}, function* () {
|
||||
let button = content.document.querySelector("button");
|
||||
button.click();
|
||||
});
|
||||
|
||||
let results = yield waitForMessages({
|
||||
webconsole: hud,
|
||||
messages: [
|
||||
{
|
||||
text: "ReferenceError: foobar is not defined",
|
||||
category: CATEGORY_JS,
|
||||
severity: SEVERITY_ERROR,
|
||||
},
|
||||
{
|
||||
text: "Unknown property \u2018test-color\u2019",
|
||||
category: CATEGORY_CSS,
|
||||
severity: SEVERITY_WARNING,
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
let viewSourceCalled = false;
|
||||
|
||||
let viewSource = hud.viewSource;
|
||||
hud.viewSource = () => {
|
||||
viewSourceCalled = true;
|
||||
};
|
||||
|
||||
for (let result of results) {
|
||||
viewSourceCalled = false;
|
||||
|
||||
let msg = [...result.matched][0];
|
||||
ok(msg, "message element found for: " + result.text);
|
||||
ok(!msg.classList.contains("filtered-by-type"), "message element is not filtered");
|
||||
let selector = ".message .message-location .frame-link-source";
|
||||
let locationNode = msg.querySelector(selector);
|
||||
ok(locationNode, "message location element found");
|
||||
|
||||
locationNode.click();
|
||||
|
||||
ok(viewSourceCalled, "view source opened");
|
||||
}
|
||||
|
||||
hud.viewSource = viewSource;
|
||||
|
||||
yield finishTest();
|
||||
});
|
|
@ -1,60 +0,0 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* 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/ */
|
||||
|
||||
// Check that the Browser Console does not use the same filter prefs as the Web
|
||||
// Console. See bug 878186.
|
||||
|
||||
"use strict";
|
||||
|
||||
const TEST_URI = "data:text/html;charset=utf8,<p>browser console filters";
|
||||
const WEB_CONSOLE_PREFIX = "devtools.webconsole.filter.";
|
||||
const BROWSER_CONSOLE_PREFIX = "devtools.browserconsole.filter.";
|
||||
|
||||
add_task(function* () {
|
||||
yield loadTab(TEST_URI);
|
||||
|
||||
info("open the web console");
|
||||
let hud = yield openConsole();
|
||||
ok(hud, "web console opened");
|
||||
|
||||
is(Services.prefs.getBoolPref(BROWSER_CONSOLE_PREFIX + "exception"), true,
|
||||
"'exception' filter is enabled (browser console)");
|
||||
is(Services.prefs.getBoolPref(WEB_CONSOLE_PREFIX + "exception"), true,
|
||||
"'exception' filter is enabled (web console)");
|
||||
|
||||
info("toggle 'exception' filter");
|
||||
hud.setFilterState("exception", false);
|
||||
|
||||
is(Services.prefs.getBoolPref(BROWSER_CONSOLE_PREFIX + "exception"), true,
|
||||
"'exception' filter is enabled (browser console)");
|
||||
is(Services.prefs.getBoolPref(WEB_CONSOLE_PREFIX + "exception"), false,
|
||||
"'exception' filter is disabled (web console)");
|
||||
|
||||
hud.setFilterState("exception", true);
|
||||
|
||||
// We need to let the console opening event loop to finish.
|
||||
let deferred = defer();
|
||||
executeSoon(() => closeConsole().then(() => deferred.resolve(null)));
|
||||
yield deferred.promise;
|
||||
|
||||
info("web console closed");
|
||||
hud = yield HUDService.toggleBrowserConsole();
|
||||
ok(hud, "browser console opened");
|
||||
|
||||
is(Services.prefs.getBoolPref(BROWSER_CONSOLE_PREFIX + "exception"), true,
|
||||
"'exception' filter is enabled (browser console)");
|
||||
is(Services.prefs.getBoolPref(WEB_CONSOLE_PREFIX + "exception"), true,
|
||||
"'exception' filter is enabled (web console)");
|
||||
|
||||
info("toggle 'exception' filter");
|
||||
hud.setFilterState("exception", false);
|
||||
|
||||
is(Services.prefs.getBoolPref(BROWSER_CONSOLE_PREFIX + "exception"), false,
|
||||
"'exception' filter is disabled (browser console)");
|
||||
is(Services.prefs.getBoolPref(WEB_CONSOLE_PREFIX + "exception"), true,
|
||||
"'exception' filter is enabled (web console)");
|
||||
|
||||
hud.setFilterState("exception", true);
|
||||
});
|
|
@ -1,114 +0,0 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* 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/ */
|
||||
|
||||
/*
|
||||
* Bug 922161 - Hide Browser Console JS input field if devtools.chrome.enabled
|
||||
* is false.
|
||||
* when devtools.chrome.enabled then
|
||||
* -browser console jsterm should be enabled
|
||||
* -browser console object inspector properties should be set.
|
||||
* -webconsole jsterm should be enabled
|
||||
* -webconsole object inspector properties should be set.
|
||||
*
|
||||
* when devtools.chrome.enabled == false then
|
||||
* -browser console jsterm should be disabled
|
||||
* -browser console object inspector properties should not be set.
|
||||
* -webconsole jsterm should be enabled
|
||||
* -webconsole object inspector properties should be set.
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
function testObjectInspectorPropertiesAreNotSet(variablesView) {
|
||||
is(variablesView.eval, null, "vview.eval is null");
|
||||
is(variablesView.switch, null, "vview.switch is null");
|
||||
is(variablesView.delete, null, "vview.delete is null");
|
||||
}
|
||||
|
||||
function* getVariablesView(hud) {
|
||||
function openVariablesView(vview) {
|
||||
deferred.resolve(vview._variablesView);
|
||||
}
|
||||
|
||||
let deferred = defer();
|
||||
|
||||
// Filter out other messages to ensure ours stays visible.
|
||||
hud.ui.filterBox.value = "browser_console_hide_jsterm_test";
|
||||
|
||||
hud.jsterm.clearOutput();
|
||||
hud.jsterm.execute("new Object({ browser_console_hide_jsterm_test: true })");
|
||||
|
||||
let [message] = yield waitForMessages({
|
||||
webconsole: hud,
|
||||
messages: [{
|
||||
text: "Object { browser_console_hide_jsterm_test: true }",
|
||||
category: CATEGORY_OUTPUT,
|
||||
}],
|
||||
});
|
||||
|
||||
hud.jsterm.once("variablesview-fetched", openVariablesView);
|
||||
|
||||
let anchor = [...message.matched][0].querySelector("a");
|
||||
|
||||
executeSoon(() =>
|
||||
EventUtils.synthesizeMouse(anchor, 2, 2, {}, hud.iframeWindow)
|
||||
);
|
||||
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
function testJSTermIsVisible(hud) {
|
||||
let inputContainer = hud.ui.window.document
|
||||
.querySelector(".jsterm-input-container");
|
||||
isnot(inputContainer.style.display, "none", "input is visible");
|
||||
}
|
||||
|
||||
function testObjectInspectorPropertiesAreSet(variablesView) {
|
||||
isnot(variablesView.eval, null, "vview.eval is set");
|
||||
isnot(variablesView.switch, null, "vview.switch is set");
|
||||
isnot(variablesView.delete, null, "vview.delete is set");
|
||||
}
|
||||
|
||||
function testJSTermIsNotVisible(hud) {
|
||||
let inputContainer = hud.ui.window.document
|
||||
.querySelector(".jsterm-input-container");
|
||||
is(inputContainer.style.display, "none", "input is not visible");
|
||||
}
|
||||
|
||||
function* testRunner() {
|
||||
let browserConsole, webConsole, variablesView;
|
||||
|
||||
Services.prefs.setBoolPref("devtools.chrome.enabled", true);
|
||||
|
||||
browserConsole = yield HUDService.toggleBrowserConsole();
|
||||
variablesView = yield getVariablesView(browserConsole);
|
||||
testJSTermIsVisible(browserConsole);
|
||||
testObjectInspectorPropertiesAreSet(variablesView);
|
||||
|
||||
let {tab: browserTab} = yield loadTab("data:text/html;charset=utf8,hello world");
|
||||
webConsole = yield openConsole(browserTab);
|
||||
variablesView = yield getVariablesView(webConsole);
|
||||
testJSTermIsVisible(webConsole);
|
||||
testObjectInspectorPropertiesAreSet(variablesView);
|
||||
yield closeConsole(browserTab);
|
||||
|
||||
yield HUDService.toggleBrowserConsole();
|
||||
Services.prefs.setBoolPref("devtools.chrome.enabled", false);
|
||||
|
||||
browserConsole = yield HUDService.toggleBrowserConsole();
|
||||
variablesView = yield getVariablesView(browserConsole);
|
||||
testJSTermIsNotVisible(browserConsole);
|
||||
testObjectInspectorPropertiesAreNotSet(variablesView);
|
||||
|
||||
webConsole = yield openConsole(browserTab);
|
||||
variablesView = yield getVariablesView(webConsole);
|
||||
testJSTermIsVisible(webConsole);
|
||||
testObjectInspectorPropertiesAreSet(variablesView);
|
||||
yield closeConsole(browserTab);
|
||||
}
|
||||
|
||||
function test() {
|
||||
Task.spawn(testRunner).then(finishTest);
|
||||
}
|
|
@ -1,119 +0,0 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* 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/ */
|
||||
|
||||
// Test that console command input is persisted across toolbox loads.
|
||||
// See Bug 943306.
|
||||
|
||||
"use strict";
|
||||
|
||||
requestLongerTimeout(2);
|
||||
|
||||
const TEST_URI = "data:text/html;charset=utf-8,Web Console test for " +
|
||||
"persisting history - bug 943306";
|
||||
const INPUT_HISTORY_COUNT = 10;
|
||||
|
||||
add_task(function* () {
|
||||
info("Setting custom input history pref to " + INPUT_HISTORY_COUNT);
|
||||
Services.prefs.setIntPref("devtools.webconsole.inputHistoryCount",
|
||||
INPUT_HISTORY_COUNT);
|
||||
|
||||
// First tab: run a bunch of commands and then make sure that you can
|
||||
// navigate through their history.
|
||||
yield loadTab(TEST_URI);
|
||||
let hud1 = yield openConsole();
|
||||
is(JSON.stringify(hud1.jsterm.history), "[]",
|
||||
"No history on first tab initially");
|
||||
yield populateInputHistory(hud1);
|
||||
is(JSON.stringify(hud1.jsterm.history),
|
||||
'["0","1","2","3","4","5","6","7","8","9"]',
|
||||
"First tab has populated history");
|
||||
|
||||
// Second tab: Just make sure that you can navigate through the history
|
||||
// generated by the first tab.
|
||||
yield loadTab(TEST_URI);
|
||||
let hud2 = yield openConsole();
|
||||
is(JSON.stringify(hud2.jsterm.history),
|
||||
'["0","1","2","3","4","5","6","7","8","9"]',
|
||||
"Second tab has populated history");
|
||||
yield testNaviatingHistoryInUI(hud2);
|
||||
is(JSON.stringify(hud2.jsterm.history),
|
||||
'["0","1","2","3","4","5","6","7","8","9",""]',
|
||||
"An empty entry has been added in the second tab due to history perusal");
|
||||
|
||||
// Third tab: Should have the same history as first tab, but if we run a
|
||||
// command, then the history of the first and second shouldn't be affected
|
||||
yield loadTab(TEST_URI);
|
||||
let hud3 = yield openConsole();
|
||||
is(JSON.stringify(hud3.jsterm.history),
|
||||
'["0","1","2","3","4","5","6","7","8","9"]',
|
||||
"Third tab has populated history");
|
||||
|
||||
// Set input value separately from execute so UP arrow accurately navigates
|
||||
// history.
|
||||
hud3.jsterm.setInputValue('"hello from third tab"');
|
||||
yield hud3.jsterm.execute();
|
||||
|
||||
is(JSON.stringify(hud1.jsterm.history),
|
||||
'["0","1","2","3","4","5","6","7","8","9"]',
|
||||
"First tab history hasn't changed due to command in third tab");
|
||||
is(JSON.stringify(hud2.jsterm.history),
|
||||
'["0","1","2","3","4","5","6","7","8","9",""]',
|
||||
"Second tab history hasn't changed due to command in third tab");
|
||||
is(JSON.stringify(hud3.jsterm.history),
|
||||
'["1","2","3","4","5","6","7","8","9","\\"hello from third tab\\""]',
|
||||
"Third tab has updated history (and purged the first result) after " +
|
||||
"running a command");
|
||||
|
||||
// Fourth tab: Should have the latest command from the third tab, followed
|
||||
// by the rest of the history from the first tab.
|
||||
yield loadTab(TEST_URI);
|
||||
let hud4 = yield openConsole();
|
||||
is(JSON.stringify(hud4.jsterm.history),
|
||||
'["1","2","3","4","5","6","7","8","9","\\"hello from third tab\\""]',
|
||||
"Fourth tab has most recent history");
|
||||
|
||||
yield hud4.jsterm.clearHistory();
|
||||
is(JSON.stringify(hud4.jsterm.history), "[]",
|
||||
"Clearing history for a tab works");
|
||||
|
||||
yield loadTab(TEST_URI);
|
||||
let hud5 = yield openConsole();
|
||||
is(JSON.stringify(hud5.jsterm.history), "[]",
|
||||
"Clearing history carries over to a new tab");
|
||||
|
||||
info("Clearing custom input history pref");
|
||||
Services.prefs.clearUserPref("devtools.webconsole.inputHistoryCount");
|
||||
});
|
||||
|
||||
/**
|
||||
* Populate the history by running the following commands:
|
||||
* [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
|
||||
*/
|
||||
function* populateInputHistory(hud) {
|
||||
let jsterm = hud.jsterm;
|
||||
|
||||
for (let i = 0; i < INPUT_HISTORY_COUNT; i++) {
|
||||
// Set input value separately from execute so UP arrow accurately navigates
|
||||
// history.
|
||||
jsterm.setInputValue(i);
|
||||
yield jsterm.execute();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check pressing up results in history traversal like:
|
||||
* [9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
|
||||
*/
|
||||
function* testNaviatingHistoryInUI(hud) {
|
||||
let jsterm = hud.jsterm;
|
||||
jsterm.focus();
|
||||
|
||||
// Count backwards from original input and make sure that pressing up
|
||||
// restores this.
|
||||
for (let i = INPUT_HISTORY_COUNT - 1; i >= 0; i--) {
|
||||
EventUtils.synthesizeKey("KEY_ArrowUp");
|
||||
is(jsterm.getInputValue(), i, "Pressing up restores last input");
|
||||
}
|
||||
}
|
|
@ -1,114 +0,0 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* 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/ */
|
||||
|
||||
// Check that cached messages from nested iframes are displayed in the
|
||||
// Web/Browser Console.
|
||||
|
||||
"use strict";
|
||||
|
||||
const TEST_URI = "http://example.com/browser/devtools/client/webconsole/old/" +
|
||||
"test/test-consoleiframes.html";
|
||||
|
||||
const expectedMessages = [
|
||||
{
|
||||
text: "main file",
|
||||
category: CATEGORY_WEBDEV,
|
||||
severity: SEVERITY_LOG,
|
||||
},
|
||||
{
|
||||
text: "blah",
|
||||
category: CATEGORY_JS,
|
||||
severity: SEVERITY_ERROR
|
||||
},
|
||||
{
|
||||
text: "iframe 2",
|
||||
category: CATEGORY_WEBDEV,
|
||||
severity: SEVERITY_LOG
|
||||
},
|
||||
{
|
||||
text: "iframe 3",
|
||||
category: CATEGORY_WEBDEV,
|
||||
severity: SEVERITY_LOG
|
||||
}
|
||||
];
|
||||
|
||||
// "iframe 1" console messages can be coalesced into one if they follow each
|
||||
// other in the sequence of messages (depending on timing). If they do not, then
|
||||
// they will be displayed in the console output independently, as separate
|
||||
// messages. This is why we need to match any of the following two rules.
|
||||
const expectedMessagesAny = [
|
||||
{
|
||||
name: "iframe 1 (count: 2)",
|
||||
text: "iframe 1",
|
||||
category: CATEGORY_WEBDEV,
|
||||
severity: SEVERITY_LOG,
|
||||
count: 2
|
||||
},
|
||||
{
|
||||
name: "iframe 1 (repeats: 2)",
|
||||
text: "iframe 1",
|
||||
category: CATEGORY_WEBDEV,
|
||||
severity: SEVERITY_LOG,
|
||||
repeats: 2
|
||||
},
|
||||
];
|
||||
|
||||
add_task(function* () {
|
||||
// On e10s, the exception is triggered in child process
|
||||
// and is ignored by test harness
|
||||
if (!Services.appinfo.browserTabsRemoteAutostart) {
|
||||
expectUncaughtException();
|
||||
}
|
||||
|
||||
yield loadTab(TEST_URI);
|
||||
let hud = yield openConsole();
|
||||
ok(hud, "web console opened");
|
||||
|
||||
yield testWebConsole(hud);
|
||||
yield closeConsole();
|
||||
info("web console closed");
|
||||
|
||||
hud = yield HUDService.toggleBrowserConsole();
|
||||
yield testBrowserConsole(hud);
|
||||
yield closeConsole();
|
||||
});
|
||||
|
||||
function* testWebConsole(hud) {
|
||||
yield waitForMessages({
|
||||
webconsole: hud,
|
||||
messages: expectedMessages,
|
||||
});
|
||||
|
||||
info("first messages matched");
|
||||
|
||||
yield waitForMessages({
|
||||
webconsole: hud,
|
||||
messages: expectedMessagesAny,
|
||||
matchCondition: "any",
|
||||
});
|
||||
}
|
||||
|
||||
function* testBrowserConsole(hud) {
|
||||
ok(hud, "browser console opened");
|
||||
|
||||
// TODO: The browser console doesn't show page's console.log statements
|
||||
// in e10s windows. See Bug 1241289.
|
||||
if (Services.appinfo.browserTabsRemoteAutostart) {
|
||||
todo(false, "Bug 1241289");
|
||||
return;
|
||||
}
|
||||
|
||||
yield waitForMessages({
|
||||
webconsole: hud,
|
||||
messages: expectedMessages,
|
||||
});
|
||||
|
||||
info("first messages matched");
|
||||
yield waitForMessages({
|
||||
webconsole: hud,
|
||||
messages: expectedMessagesAny,
|
||||
matchCondition: "any",
|
||||
});
|
||||
}
|
|
@ -1,80 +0,0 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* 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/ */
|
||||
|
||||
// Check that basic keyboard shortcuts work in the web console.
|
||||
|
||||
"use strict";
|
||||
|
||||
add_task(async function () {
|
||||
const TEST_URI = "http://example.com/browser/devtools/client/webconsole/old/" +
|
||||
"test/test-console.html";
|
||||
|
||||
await loadTab(TEST_URI);
|
||||
|
||||
let hud = await openConsole();
|
||||
ok(hud, "Web Console opened");
|
||||
|
||||
info("dump some spew into the console for scrolling");
|
||||
hud.jsterm.execute("(function() { for (var i = 0; i < 100; i++) { " +
|
||||
"console.log('foobarz' + i);" +
|
||||
"}})();");
|
||||
|
||||
await waitForMessages({
|
||||
webconsole: hud,
|
||||
messages: [{
|
||||
text: "foobarz99",
|
||||
category: CATEGORY_WEBDEV,
|
||||
severity: SEVERITY_LOG,
|
||||
}],
|
||||
});
|
||||
|
||||
let currentPosition = hud.ui.outputWrapper.scrollTop;
|
||||
let bottom = currentPosition;
|
||||
|
||||
EventUtils.synthesizeKey("KEY_PageUp");
|
||||
isnot(hud.ui.outputWrapper.scrollTop, currentPosition,
|
||||
"scroll position changed after page up");
|
||||
|
||||
currentPosition = hud.ui.outputWrapper.scrollTop;
|
||||
EventUtils.synthesizeKey("KEY_PageDown");
|
||||
ok(hud.ui.outputWrapper.scrollTop > currentPosition,
|
||||
"scroll position now at bottom");
|
||||
|
||||
EventUtils.synthesizeKey("KEY_Home");
|
||||
is(hud.ui.outputWrapper.scrollTop, 0, "scroll position now at top");
|
||||
|
||||
EventUtils.synthesizeKey("KEY_End");
|
||||
|
||||
let scrollTop = hud.ui.outputWrapper.scrollTop;
|
||||
ok(scrollTop > 0 && Math.abs(scrollTop - bottom) <= 5,
|
||||
"scroll position now at bottom");
|
||||
|
||||
info("try ctrl-l to clear output");
|
||||
executeSoon(() => {
|
||||
let clearShortcut;
|
||||
if (Services.appinfo.OS === "Darwin") {
|
||||
clearShortcut = WCUL10n.getStr("webconsole.clear.keyOSX");
|
||||
} else {
|
||||
clearShortcut = WCUL10n.getStr("webconsole.clear.key");
|
||||
}
|
||||
synthesizeKeyShortcut(clearShortcut);
|
||||
});
|
||||
await hud.jsterm.once("messages-cleared");
|
||||
|
||||
// Wait for the next event tick to make sure keyup for the shortcut above
|
||||
// finishes. Otherwise the 2 shortcuts are mixed.
|
||||
await new Promise(executeSoon);
|
||||
|
||||
is(hud.outputNode.textContent.indexOf("foobarz1"), -1, "output cleared");
|
||||
is(hud.jsterm.inputNode.getAttribute("focused"), "true",
|
||||
"jsterm input is focused");
|
||||
|
||||
info("try ctrl-f to focus filter");
|
||||
synthesizeKeyShortcut(WCUL10n.getStr("webconsole.find.key"));
|
||||
ok(!hud.jsterm.inputNode.getAttribute("focused"),
|
||||
"jsterm input is not focused");
|
||||
is(hud.ui.filterBox.getAttribute("focused"), "true",
|
||||
"filter input is focused");
|
||||
});
|
|
@ -1,52 +0,0 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* 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/ */
|
||||
|
||||
// Test that objects given to console.log() are inspectable.
|
||||
|
||||
"use strict";
|
||||
|
||||
add_task(function* () {
|
||||
yield loadTab("data:text/html;charset=utf8,test for bug 676722 - " +
|
||||
"inspectable objects for window.console");
|
||||
|
||||
let hud = yield openConsole();
|
||||
hud.jsterm.clearOutput(true);
|
||||
|
||||
yield hud.jsterm.execute("myObj = {abba: 'omgBug676722'}");
|
||||
hud.jsterm.execute("console.log('fooBug676722', myObj)");
|
||||
|
||||
let [result] = yield waitForMessages({
|
||||
webconsole: hud,
|
||||
messages: [{
|
||||
text: "fooBug676722",
|
||||
category: CATEGORY_WEBDEV,
|
||||
severity: SEVERITY_LOG,
|
||||
objects: true,
|
||||
}],
|
||||
});
|
||||
|
||||
let msg = [...result.matched][0];
|
||||
ok(msg, "message element");
|
||||
|
||||
let body = msg.querySelector(".message-body");
|
||||
ok(body, "message body");
|
||||
|
||||
let clickable = result.clickableElements[0];
|
||||
ok(clickable, "the console.log() object anchor was found");
|
||||
ok(body.textContent.includes('{ abba: "omgBug676722" }'),
|
||||
"clickable node content is correct");
|
||||
|
||||
executeSoon(() => {
|
||||
EventUtils.synthesizeMouse(clickable, 2, 2, {}, hud.iframeWindow);
|
||||
});
|
||||
|
||||
let varView = yield hud.jsterm.once("variablesview-fetched");
|
||||
ok(varView, "object inspector opened on click");
|
||||
|
||||
yield findVariableViewProperties(varView, [{
|
||||
name: "abba",
|
||||
value: "omgBug676722",
|
||||
}], { webconsole: hud });
|
||||
});
|
|
@ -1,101 +0,0 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* 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/ */
|
||||
|
||||
// Check that native getters and setters for DOM elements work as expected in
|
||||
// variables view - bug 870220.
|
||||
|
||||
"use strict";
|
||||
|
||||
const TEST_URI = "data:text/html;charset=utf8,<title>bug870220</title>\n" +
|
||||
"<p>hello world\n<p>native getters!";
|
||||
|
||||
requestLongerTimeout(2);
|
||||
|
||||
add_task(function* () {
|
||||
yield loadTab(TEST_URI);
|
||||
let hud = yield openConsole();
|
||||
let jsterm = hud.jsterm;
|
||||
|
||||
jsterm.execute("document");
|
||||
|
||||
let [result] = yield waitForMessages({
|
||||
webconsole: hud,
|
||||
messages: [{
|
||||
text: "HTMLDocument \u2192 data:text/html;charset=utf8",
|
||||
category: CATEGORY_OUTPUT,
|
||||
objects: true,
|
||||
}],
|
||||
});
|
||||
|
||||
let clickable = result.clickableElements[0];
|
||||
ok(clickable, "clickable object found");
|
||||
|
||||
executeSoon(() => {
|
||||
EventUtils.synthesizeMouse(clickable, 2, 2, {}, hud.iframeWindow);
|
||||
});
|
||||
|
||||
let fetchedVar = yield jsterm.once("variablesview-fetched");
|
||||
|
||||
let variablesView = fetchedVar._variablesView;
|
||||
ok(variablesView, "variables view object");
|
||||
|
||||
let results = yield findVariableViewProperties(fetchedVar, [
|
||||
{ name: "title", value: "bug870220" },
|
||||
{ name: "bgColor" },
|
||||
], { webconsole: hud });
|
||||
|
||||
let prop = results[1].matchedProp;
|
||||
ok(prop, "matched the |bgColor| property in the variables view");
|
||||
|
||||
// Check that property value updates work.
|
||||
let updatedVar = yield updateVariablesViewProperty({
|
||||
property: prop,
|
||||
field: "value",
|
||||
string: "'red'",
|
||||
webconsole: hud,
|
||||
});
|
||||
|
||||
info("on fetch after background update");
|
||||
|
||||
jsterm.clearOutput(true);
|
||||
jsterm.execute("document.bgColor");
|
||||
|
||||
[result] = yield waitForMessages({
|
||||
webconsole: hud,
|
||||
messages: [{
|
||||
text: "red",
|
||||
category: CATEGORY_OUTPUT,
|
||||
}],
|
||||
});
|
||||
|
||||
yield findVariableViewProperties(updatedVar, [
|
||||
{ name: "bgColor", value: "red" },
|
||||
], { webconsole: hud });
|
||||
|
||||
jsterm.execute("$$('p')");
|
||||
|
||||
[result] = yield waitForMessages({
|
||||
webconsole: hud,
|
||||
messages: [{
|
||||
text: "Array [",
|
||||
category: CATEGORY_OUTPUT,
|
||||
objects: true,
|
||||
}],
|
||||
});
|
||||
|
||||
clickable = result.clickableElements[0];
|
||||
ok(clickable, "clickable object found");
|
||||
|
||||
executeSoon(() => {
|
||||
EventUtils.synthesizeMouse(clickable, 2, 2, {}, hud.iframeWindow);
|
||||
});
|
||||
|
||||
fetchedVar = yield jsterm.once("variablesview-fetched");
|
||||
|
||||
yield findVariableViewProperties(fetchedVar, [
|
||||
{ name: "0.textContent", value: /hello world/ },
|
||||
{ name: "1.textContent", value: /native getters/ },
|
||||
], { webconsole: hud });
|
||||
});
|
|
@ -1,81 +0,0 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* 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/ */
|
||||
|
||||
// Check that the navigation marker shows on page reload - bug 793996.
|
||||
|
||||
"use strict";
|
||||
|
||||
const PREF = "devtools.webconsole.persistlog";
|
||||
const TEST_URI = "http://example.com/browser/devtools/client/webconsole/old/" +
|
||||
"test/test-console.html";
|
||||
|
||||
var hud;
|
||||
|
||||
add_task(function* () {
|
||||
Services.prefs.setBoolPref(PREF, true);
|
||||
|
||||
let { browser } = yield loadTab(TEST_URI);
|
||||
hud = yield openConsole();
|
||||
|
||||
yield consoleOpened();
|
||||
|
||||
let loaded = loadBrowser(browser);
|
||||
BrowserReload();
|
||||
yield loaded;
|
||||
|
||||
yield onReload();
|
||||
|
||||
isnot(hud.outputNode.textContent.indexOf("foobarz1"), -1,
|
||||
"foobarz1 is still in the output");
|
||||
|
||||
Services.prefs.clearUserPref(PREF);
|
||||
|
||||
hud = null;
|
||||
});
|
||||
|
||||
function consoleOpened() {
|
||||
ok(hud, "Web Console opened");
|
||||
|
||||
hud.jsterm.clearOutput();
|
||||
|
||||
ContentTask.spawn(gBrowser.selectedBrowser, null, function* () {
|
||||
content.console.log("foobarz1");
|
||||
});
|
||||
|
||||
return waitForMessages({
|
||||
webconsole: hud,
|
||||
messages: [{
|
||||
text: "foobarz1",
|
||||
category: CATEGORY_WEBDEV,
|
||||
severity: SEVERITY_LOG,
|
||||
}],
|
||||
});
|
||||
}
|
||||
|
||||
function onReload() {
|
||||
ContentTask.spawn(gBrowser.selectedBrowser, null, function* () {
|
||||
content.console.log("foobarz2");
|
||||
});
|
||||
|
||||
return waitForMessages({
|
||||
webconsole: hud,
|
||||
messages: [{
|
||||
name: "page reload",
|
||||
text: "test-console.html",
|
||||
category: CATEGORY_NETWORK,
|
||||
severity: SEVERITY_LOG,
|
||||
},
|
||||
{
|
||||
text: "foobarz2",
|
||||
category: CATEGORY_WEBDEV,
|
||||
severity: SEVERITY_LOG,
|
||||
},
|
||||
{
|
||||
name: "navigation marker",
|
||||
text: "test-console.html",
|
||||
type: Messages.NavigationMarker,
|
||||
}],
|
||||
});
|
||||
}
|
|
@ -1,37 +0,0 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* 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/ */
|
||||
|
||||
// Tests that network log messages bring up the network panel.
|
||||
|
||||
"use strict";
|
||||
|
||||
const TEST_NETWORK_REQUEST_URI =
|
||||
"http://example.com/browser/devtools/client/webconsole/old/test/" +
|
||||
"test-network-request.html";
|
||||
|
||||
add_task(function* () {
|
||||
let finishedRequest = waitForFinishedRequest(({ request }) => {
|
||||
return request.url === TEST_NETWORK_REQUEST_URI;
|
||||
});
|
||||
|
||||
const hud = yield loadPageAndGetHud(TEST_NETWORK_REQUEST_URI,
|
||||
"browserConsole");
|
||||
let request = yield finishedRequest;
|
||||
|
||||
ok(request, "Page load was logged");
|
||||
|
||||
let client = hud.ui.webConsoleClient;
|
||||
const postData = yield client.getRequestPostData(request.actor);
|
||||
const responseContent = yield client.getResponseContent(request.actor);
|
||||
|
||||
is(request.request.url, TEST_NETWORK_REQUEST_URI,
|
||||
"Logged network entry is page load");
|
||||
is(request.request.method, "GET", "Method is correct");
|
||||
ok(!postData.postData.text, "No request body was stored");
|
||||
ok(postData.postDataDiscarded, "Request body was discarded");
|
||||
ok(!responseContent.content.text, "No response body was stored");
|
||||
ok(responseContent.contentDiscarded || request.fromCache,
|
||||
"Response body was discarded or response came from the cache");
|
||||
});
|
|
@ -1,85 +0,0 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* 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/ */
|
||||
|
||||
// Check that nsIConsoleMessages are displayed in the Browser Console.
|
||||
// See bug 859756.
|
||||
|
||||
"use strict";
|
||||
|
||||
const TEST_URI = "data:text/html;charset=utf8,<title>bug859756</title>\n" +
|
||||
"<p>hello world\n<p>nsIConsoleMessages ftw!";
|
||||
|
||||
function test() {
|
||||
const FILTER_PREF = "devtools.browserconsole.filter.jslog";
|
||||
Services.prefs.setBoolPref(FILTER_PREF, true);
|
||||
|
||||
registerCleanupFunction(() => {
|
||||
Services.prefs.clearUserPref(FILTER_PREF);
|
||||
});
|
||||
|
||||
Task.spawn(function* () {
|
||||
const {tab} = yield loadTab(TEST_URI);
|
||||
|
||||
// Test for cached nsIConsoleMessages.
|
||||
Services.console.logStringMessage("test1 for bug859756");
|
||||
|
||||
info("open web console");
|
||||
let hud = yield openConsole(tab);
|
||||
|
||||
ok(hud, "web console opened");
|
||||
Services.console.logStringMessage("do-not-show-me");
|
||||
|
||||
ContentTask.spawn(gBrowser.selectedBrowser, null, function* () {
|
||||
content.console.log("foobarz");
|
||||
});
|
||||
|
||||
yield waitForMessages({
|
||||
webconsole: hud,
|
||||
messages: [{
|
||||
text: "foobarz",
|
||||
category: CATEGORY_WEBDEV,
|
||||
severity: SEVERITY_LOG,
|
||||
}],
|
||||
});
|
||||
|
||||
let text = hud.outputNode.textContent;
|
||||
is(text.indexOf("do-not-show-me"), -1,
|
||||
"nsIConsoleMessages are not displayed");
|
||||
is(text.indexOf("test1 for bug859756"), -1,
|
||||
"nsIConsoleMessages are not displayed (confirmed)");
|
||||
|
||||
yield closeConsole(tab);
|
||||
|
||||
info("web console closed");
|
||||
hud = yield HUDService.toggleBrowserConsole();
|
||||
ok(hud, "browser console opened");
|
||||
|
||||
Services.console.logStringMessage("test2 for bug859756");
|
||||
|
||||
let results = yield waitForMessages({
|
||||
webconsole: hud,
|
||||
messages: [{
|
||||
text: "test1 for bug859756",
|
||||
category: CATEGORY_JS,
|
||||
}, {
|
||||
text: "test2 for bug859756",
|
||||
category: CATEGORY_JS,
|
||||
}, {
|
||||
text: "do-not-show-me",
|
||||
category: CATEGORY_JS,
|
||||
}],
|
||||
});
|
||||
|
||||
let msg = [...results[2].matched][0];
|
||||
ok(msg, "message element for do-not-show-me (nsIConsoleMessage)");
|
||||
isnot(msg.textContent.indexOf("do-not-show"), -1,
|
||||
"element content is correct");
|
||||
ok(!msg.classList.contains("filtered-by-type"), "element is not filtered");
|
||||
|
||||
hud.setFilterState("jslog", false);
|
||||
|
||||
ok(msg.classList.contains("filtered-by-type"), "element is filtered");
|
||||
}).then(finishTest);
|
||||
}
|
|
@ -1,40 +0,0 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* 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/ */
|
||||
|
||||
// Test that the "browser console" menu item opens or focuses (if already open)
|
||||
// the console window instead of toggling it open/close.
|
||||
|
||||
"use strict";
|
||||
|
||||
var {Tools} = require("devtools/client/definitions");
|
||||
|
||||
add_task(function* () {
|
||||
let currWindow, hud, mainWindow;
|
||||
|
||||
mainWindow = Services.wm.getMostRecentWindow(null);
|
||||
|
||||
yield HUDService.openBrowserConsoleOrFocus();
|
||||
|
||||
hud = HUDService.getBrowserConsole();
|
||||
|
||||
console.log("testmessage");
|
||||
yield waitForMessages({
|
||||
webconsole: hud,
|
||||
messages: [{
|
||||
text: "testmessage"
|
||||
}],
|
||||
});
|
||||
currWindow = Services.wm.getMostRecentWindow(null);
|
||||
is(currWindow.document.documentURI, Tools.webConsole.oldWebConsoleURL,
|
||||
"The Browser Console is open and has focus");
|
||||
mainWindow.focus();
|
||||
yield HUDService.openBrowserConsoleOrFocus();
|
||||
currWindow = Services.wm.getMostRecentWindow(null);
|
||||
is(currWindow.document.documentURI, Tools.webConsole.oldWebConsoleURL,
|
||||
"The Browser Console is open and has focus");
|
||||
yield HUDService.toggleBrowserConsole();
|
||||
hud = HUDService.getBrowserConsole();
|
||||
ok(!hud, "Browser Console has been closed");
|
||||
});
|
|
@ -1,91 +0,0 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* 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/ */
|
||||
|
||||
// Check that inspecting an optimized out variable works when execution is
|
||||
// paused.
|
||||
|
||||
"use strict";
|
||||
|
||||
// Force the old debugger UI since it's directly used (see Bug 1301705)
|
||||
Services.prefs.setBoolPref("devtools.debugger.new-debugger-frontend", false);
|
||||
registerCleanupFunction(function* () {
|
||||
Services.prefs.clearUserPref("devtools.debugger.new-debugger-frontend");
|
||||
});
|
||||
|
||||
function test() {
|
||||
Task.spawn(function* () {
|
||||
const TEST_URI = "http://example.com/browser/devtools/client/webconsole/old/" +
|
||||
"test/test-closure-optimized-out.html";
|
||||
let {tab} = yield loadTab(TEST_URI);
|
||||
let hud = yield openConsole(tab);
|
||||
let { toolbox, panel, panelWin } = yield openDebugger();
|
||||
|
||||
let sources = panelWin.DebuggerView.Sources;
|
||||
yield panel.addBreakpoint({ actor: sources.values[0], line: 18 });
|
||||
yield ensureThreadClientState(panel, "resumed");
|
||||
|
||||
let fetchedScopes = panelWin.once(panelWin.EVENTS.FETCHED_SCOPES);
|
||||
|
||||
// Cause the debuggee to pause
|
||||
ContentTask.spawn(gBrowser.selectedBrowser, {}, function* () {
|
||||
let button = content.document.querySelector("button");
|
||||
button.click();
|
||||
});
|
||||
|
||||
yield fetchedScopes;
|
||||
ok(true, "Scopes were fetched");
|
||||
|
||||
yield toolbox.selectTool("webconsole");
|
||||
|
||||
// This is the meat of the test: evaluate the optimized out variable.
|
||||
yield hud.jsterm.execute("upvar");
|
||||
yield waitForMessages({
|
||||
webconsole: hud,
|
||||
messages: [{
|
||||
text: "optimized out",
|
||||
category: CATEGORY_OUTPUT,
|
||||
}]
|
||||
});
|
||||
|
||||
finishTest();
|
||||
}).catch(aError => {
|
||||
ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
|
||||
});
|
||||
}
|
||||
|
||||
// Debugger helper functions stolen from devtools/client/debugger/test/head.js.
|
||||
|
||||
function ensureThreadClientState(aPanel, aState) {
|
||||
let thread = aPanel.panelWin.gThreadClient;
|
||||
let state = thread.state;
|
||||
|
||||
info("Thread is: '" + state + "'.");
|
||||
|
||||
if (state == aState) {
|
||||
return promise.resolve(null);
|
||||
}
|
||||
return waitForThreadEvents(aPanel, aState);
|
||||
}
|
||||
|
||||
function waitForThreadEvents(aPanel, aEventName, aEventRepeat = 1) {
|
||||
info("Waiting for thread event: '" + aEventName + "' to fire: " +
|
||||
aEventRepeat + " time(s).");
|
||||
|
||||
let deferred = defer();
|
||||
let thread = aPanel.panelWin.gThreadClient;
|
||||
let count = 0;
|
||||
|
||||
thread.addListener(aEventName, function onEvent(eventName, ...args) {
|
||||
info("Thread event '" + eventName + "' fired: " + (++count) + " time(s).");
|
||||
|
||||
if (count == aEventRepeat) {
|
||||
ok(true, "Enough '" + eventName + "' thread events have been fired.");
|
||||
thread.removeListener(eventName, onEvent);
|
||||
deferred.resolve.apply(deferred, args);
|
||||
}
|
||||
});
|
||||
|
||||
return deferred.promise;
|
||||
}
|
|
@ -1,192 +0,0 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* 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/ */
|
||||
|
||||
// Bug 874061: test for how the browser and web consoles display messages coming
|
||||
// from private windows. See bug for description of expected behavior.
|
||||
|
||||
"use strict";
|
||||
|
||||
function test() {
|
||||
const TEST_URI = "data:text/html;charset=utf8,<p>hello world! bug 874061" +
|
||||
"<button onclick='console.log(\"foobar bug 874061\");" +
|
||||
"fooBazBaz.yummy()'>click</button>";
|
||||
let ConsoleAPIStorage = Cc["@mozilla.org/consoleAPI-storage;1"]
|
||||
.getService(Ci.nsIConsoleAPIStorage);
|
||||
let privateWindow, privateBrowser, privateTab, privateContent;
|
||||
let hud, expectedMessages, nonPrivateMessage;
|
||||
|
||||
// This test is slightly more involved: it opens the web console twice,
|
||||
// a new private window once, and the browser console twice. We can get
|
||||
// a timeout with debug builds on slower machines.
|
||||
requestLongerTimeout(2);
|
||||
start();
|
||||
|
||||
function start() {
|
||||
gBrowser.selectedTab = BrowserTestUtils.addTab(gBrowser, "data:text/html;charset=utf8," +
|
||||
"<p>hello world! I am not private!");
|
||||
gBrowser.selectedBrowser.addEventListener("load", onLoadTab, true);
|
||||
}
|
||||
|
||||
function onLoadTab() {
|
||||
gBrowser.selectedBrowser.removeEventListener("load", onLoadTab, true);
|
||||
info("onLoadTab()");
|
||||
|
||||
// Make sure we have a clean state to start with.
|
||||
Services.console.reset();
|
||||
ConsoleAPIStorage.clearEvents();
|
||||
|
||||
// Add a non-private message to the browser console.
|
||||
ContentTask.spawn(gBrowser.selectedBrowser, null, function* () {
|
||||
content.console.log("bug874061-not-private");
|
||||
});
|
||||
|
||||
nonPrivateMessage = {
|
||||
name: "console message from a non-private window",
|
||||
text: "bug874061-not-private",
|
||||
category: CATEGORY_WEBDEV,
|
||||
severity: SEVERITY_LOG,
|
||||
};
|
||||
|
||||
privateWindow = OpenBrowserWindow({ private: true });
|
||||
ok(privateWindow, "new private window");
|
||||
ok(PrivateBrowsingUtils.isWindowPrivate(privateWindow), "window's private");
|
||||
|
||||
whenDelayedStartupFinished(privateWindow, onPrivateWindowReady);
|
||||
}
|
||||
|
||||
function onPrivateWindowReady() {
|
||||
info("private browser window opened");
|
||||
privateBrowser = privateWindow.gBrowser;
|
||||
|
||||
privateTab = privateBrowser.selectedTab = privateBrowser.addTab(TEST_URI);
|
||||
privateBrowser.selectedBrowser.addEventListener("load", function onLoad() {
|
||||
info("private tab opened");
|
||||
privateBrowser.selectedBrowser.removeEventListener("load", onLoad, true);
|
||||
privateContent = privateBrowser.selectedBrowser.contentWindow;
|
||||
ok(PrivateBrowsingUtils.isBrowserPrivate(privateBrowser.selectedBrowser),
|
||||
"tab window is private");
|
||||
openConsole(privateTab).then(consoleOpened);
|
||||
}, true);
|
||||
}
|
||||
|
||||
function addMessages() {
|
||||
let button = privateContent.document.querySelector("button");
|
||||
ok(button, "button in page");
|
||||
EventUtils.synthesizeMouse(button, 2, 2, {}, privateContent);
|
||||
}
|
||||
|
||||
function consoleOpened(injectedHud) {
|
||||
hud = injectedHud;
|
||||
ok(hud, "web console opened");
|
||||
|
||||
addMessages();
|
||||
expectedMessages = [
|
||||
{
|
||||
name: "script error",
|
||||
text: "fooBazBaz is not defined",
|
||||
category: CATEGORY_JS,
|
||||
severity: SEVERITY_ERROR,
|
||||
},
|
||||
{
|
||||
name: "console message",
|
||||
text: "foobar bug 874061",
|
||||
category: CATEGORY_WEBDEV,
|
||||
severity: SEVERITY_LOG,
|
||||
},
|
||||
];
|
||||
|
||||
// Make sure messages are displayed in the web console as they happen, even
|
||||
// if this is a private tab.
|
||||
waitForMessages({
|
||||
webconsole: hud,
|
||||
messages: expectedMessages,
|
||||
}).then(testCachedMessages);
|
||||
}
|
||||
|
||||
function testCachedMessages() {
|
||||
info("testCachedMessages()");
|
||||
closeConsole(privateTab).then(() => {
|
||||
info("web console closed");
|
||||
openConsole(privateTab).then(consoleReopened);
|
||||
});
|
||||
}
|
||||
|
||||
function consoleReopened(injectedHud) {
|
||||
hud = injectedHud;
|
||||
ok(hud, "web console reopened");
|
||||
|
||||
// Make sure that cached messages are displayed in the web console, even
|
||||
// if this is a private tab.
|
||||
waitForMessages({
|
||||
webconsole: hud,
|
||||
messages: expectedMessages,
|
||||
}).then(testBrowserConsole);
|
||||
}
|
||||
|
||||
function testBrowserConsole() {
|
||||
info("testBrowserConsole()");
|
||||
closeConsole(privateTab).then(() => {
|
||||
info("web console closed");
|
||||
HUDService.toggleBrowserConsole().then(onBrowserConsoleOpen);
|
||||
});
|
||||
}
|
||||
|
||||
// Make sure that the cached messages from private tabs are not displayed in
|
||||
// the browser console.
|
||||
function checkNoPrivateMessages() {
|
||||
let text = hud.outputNode.textContent;
|
||||
is(text.indexOf("fooBazBaz"), -1, "no exception displayed");
|
||||
is(text.indexOf("bug 874061"), -1, "no console message displayed");
|
||||
}
|
||||
|
||||
function onBrowserConsoleOpen(injectedHud) {
|
||||
hud = injectedHud;
|
||||
ok(hud, "browser console opened");
|
||||
|
||||
checkNoPrivateMessages();
|
||||
addMessages();
|
||||
expectedMessages.push(nonPrivateMessage);
|
||||
|
||||
// Make sure that live messages are displayed in the browser console, even
|
||||
// from private tabs.
|
||||
waitForMessages({
|
||||
webconsole: hud,
|
||||
messages: expectedMessages,
|
||||
}).then(testPrivateWindowClose);
|
||||
}
|
||||
|
||||
function testPrivateWindowClose() {
|
||||
info("close the private window and check if private messages are removed");
|
||||
hud.jsterm.once("private-messages-cleared", () => {
|
||||
isnot(hud.outputNode.textContent.indexOf("bug874061-not-private"), -1,
|
||||
"non-private messages are still shown after private window closed");
|
||||
checkNoPrivateMessages();
|
||||
|
||||
info("close the browser console");
|
||||
HUDService.toggleBrowserConsole().then(() => {
|
||||
info("reopen the browser console");
|
||||
executeSoon(() =>
|
||||
HUDService.toggleBrowserConsole().then(onBrowserConsoleReopen));
|
||||
});
|
||||
});
|
||||
privateWindow.BrowserTryToCloseWindow();
|
||||
}
|
||||
|
||||
function onBrowserConsoleReopen(injectedHud) {
|
||||
hud = injectedHud;
|
||||
ok(hud, "browser console reopened");
|
||||
|
||||
// Make sure that the non-private message is still shown after reopen.
|
||||
waitForMessages({
|
||||
webconsole: hud,
|
||||
messages: [nonPrivateMessage],
|
||||
}).then(() => {
|
||||
// Make sure that no private message is displayed after closing the
|
||||
// private window and reopening the Browser Console.
|
||||
checkNoPrivateMessages();
|
||||
executeSoon(finishTest);
|
||||
});
|
||||
}
|
||||
}
|
|
@ -1,32 +0,0 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* 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/ */
|
||||
|
||||
// Check that the browser console gets session state is set correctly, and that
|
||||
// it re-opens when restore is requested.
|
||||
|
||||
"use strict";
|
||||
|
||||
add_task(async function() {
|
||||
is(HUDService.getBrowserConsoleSessionState(), false, "Session state false by default");
|
||||
HUDService.storeBrowserConsoleSessionState();
|
||||
is(HUDService.getBrowserConsoleSessionState(), false,
|
||||
"Session state still not true even after setting (since Browser Console is closed)");
|
||||
|
||||
await HUDService.toggleBrowserConsole();
|
||||
HUDService.storeBrowserConsoleSessionState();
|
||||
is(HUDService.getBrowserConsoleSessionState(), true,
|
||||
"Session state true (since Browser Console is opened)");
|
||||
|
||||
info("Closing the browser console and waiting for the session restore to reopen it")
|
||||
await HUDService.toggleBrowserConsole();
|
||||
|
||||
let opened = waitForBrowserConsole();
|
||||
gDevTools.restoreDevToolsSession({
|
||||
browserConsole: true
|
||||
});
|
||||
|
||||
info("Waiting for the console to open after session restore")
|
||||
await opened;
|
||||
});
|
|
@ -1,117 +0,0 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* 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";
|
||||
|
||||
// Check that server log appears in the console panel - bug 1168872
|
||||
add_task(function* () {
|
||||
const TEST_URI = "http://example.com/browser/devtools/client/webconsole/old/test/test-console-server-logging.sjs";
|
||||
|
||||
yield loadTab(TEST_URI);
|
||||
|
||||
let hud = yield openConsole();
|
||||
|
||||
// Set logging filter and wait till it's set on the backend
|
||||
hud.setFilterState("serverlog", true);
|
||||
yield updateServerLoggingListener(hud);
|
||||
|
||||
BrowserReloadSkipCache();
|
||||
|
||||
// Note that the test is also checking out the (printf like)
|
||||
// formatters and encoding of UTF8 characters (see the one at the end).
|
||||
let text = "values: string Object { a: 10 } 123 1.12 \u2713";
|
||||
|
||||
yield waitForMessages({
|
||||
webconsole: hud,
|
||||
messages: [{
|
||||
text: text,
|
||||
category: CATEGORY_SERVER,
|
||||
severity: SEVERITY_LOG,
|
||||
}],
|
||||
});
|
||||
// Clean up filter
|
||||
hud.setFilterState("serverlog", false);
|
||||
yield updateServerLoggingListener(hud);
|
||||
});
|
||||
|
||||
add_task(function* () {
|
||||
const TEST_URI = "http://example.com/browser/devtools/client/webconsole/old/test/test-console-server-logging-array.sjs";
|
||||
|
||||
yield loadTab(TEST_URI);
|
||||
|
||||
let hud = yield openConsole();
|
||||
|
||||
// Set logging filter and wait till it's set on the backend
|
||||
hud.setFilterState("serverlog", true);
|
||||
yield updateServerLoggingListener(hud);
|
||||
|
||||
BrowserReloadSkipCache();
|
||||
// Note that the test is also checking out the (printf like)
|
||||
// formatters and encoding of UTF8 characters (see the one at the end).
|
||||
let text = "Object { best: \"Firefox\", reckless: \"Chrome\", " +
|
||||
"new_ie: \"Safari\", new_new_ie: \"Edge\" }";
|
||||
yield waitForMessages({
|
||||
webconsole: hud,
|
||||
messages: [{
|
||||
text: text,
|
||||
category: CATEGORY_SERVER,
|
||||
severity: SEVERITY_LOG,
|
||||
}],
|
||||
});
|
||||
// Clean up filter
|
||||
hud.setFilterState("serverlog", false);
|
||||
yield updateServerLoggingListener(hud);
|
||||
});
|
||||
|
||||
add_task(function* () {
|
||||
const TEST_URI = "http://example.com/browser/devtools/client/webconsole/old/test/test-console-server-logging-backtrace.sjs";
|
||||
|
||||
yield loadTab(TEST_URI);
|
||||
|
||||
let hud = yield openConsole();
|
||||
|
||||
// Set logging filter and wait till it's set on the backend
|
||||
hud.setFilterState("serverlog", true);
|
||||
yield updateServerLoggingListener(hud);
|
||||
|
||||
BrowserReloadSkipCache();
|
||||
// Note that the test is also checking out the (printf like)
|
||||
// formatters and encoding of UTF8 characters (see the one at the end).
|
||||
yield waitForMessages({
|
||||
webconsole: hud,
|
||||
messages: [{
|
||||
text: "correct 1",
|
||||
category: CATEGORY_SERVER,
|
||||
severity: SEVERITY_ERROR,
|
||||
source: {url: "/some/path/to/file.py", line: 33}
|
||||
}, {
|
||||
text: "correct 2",
|
||||
category: CATEGORY_SERVER,
|
||||
severity: SEVERITY_ERROR,
|
||||
source: {url: "/some/path/to/file.py", line: 33}
|
||||
}, {
|
||||
text: "wrong 1",
|
||||
category: CATEGORY_SERVER,
|
||||
severity: SEVERITY_ERROR,
|
||||
source: {url: "/some/path/to/file.py:33wrong"}
|
||||
}, {
|
||||
text: "wrong 2",
|
||||
category: CATEGORY_SERVER,
|
||||
severity: SEVERITY_ERROR,
|
||||
source: {url: "/some/path/to/file.py"}
|
||||
}],
|
||||
});
|
||||
// Clean up filter
|
||||
hud.setFilterState("serverlog", false);
|
||||
yield updateServerLoggingListener(hud);
|
||||
});
|
||||
|
||||
function updateServerLoggingListener(hud) {
|
||||
let deferred = defer();
|
||||
hud.ui._updateServerLoggingListener(response => {
|
||||
deferred.resolve(response);
|
||||
});
|
||||
return deferred.promise;
|
||||
}
|
|
@ -1,238 +0,0 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* 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/ */
|
||||
|
||||
// Check that variables view works as expected in the web console.
|
||||
|
||||
"use strict";
|
||||
|
||||
const TEST_URI = "http://example.com/browser/devtools/client/webconsole/old/" +
|
||||
"test/test-eval-in-stackframe.html";
|
||||
|
||||
var hud, gVariablesView;
|
||||
|
||||
registerCleanupFunction(function () {
|
||||
hud = gVariablesView = null;
|
||||
});
|
||||
|
||||
add_task(function* () {
|
||||
yield loadTab(TEST_URI);
|
||||
|
||||
hud = yield openConsole();
|
||||
|
||||
let msg = yield hud.jsterm.execute("(function foo(){})");
|
||||
|
||||
ok(msg, "output message found");
|
||||
ok(msg.textContent.includes("function foo()"),
|
||||
"message text check");
|
||||
|
||||
executeSoon(() => {
|
||||
EventUtils.synthesizeMouse(msg.querySelector("a"), 2, 2, {}, hud.iframeWindow);
|
||||
});
|
||||
|
||||
let varView = yield hud.jsterm.once("variablesview-fetched");
|
||||
ok(varView, "object inspector opened on click");
|
||||
|
||||
yield findVariableViewProperties(varView, [{
|
||||
name: "name",
|
||||
value: "foo",
|
||||
}], { webconsole: hud });
|
||||
});
|
||||
|
||||
add_task(function* () {
|
||||
yield loadTab(TEST_URI);
|
||||
|
||||
hud = yield openConsole();
|
||||
|
||||
let msg = yield hud.jsterm.execute("Function.prototype");
|
||||
|
||||
ok(msg, "output message found");
|
||||
ok(msg.textContent.includes("function ()"),
|
||||
"message text check");
|
||||
|
||||
executeSoon(() => {
|
||||
EventUtils.synthesizeMouse(msg.querySelector("a"), 2, 2, {}, hud.iframeWindow);
|
||||
});
|
||||
|
||||
let varView = yield hud.jsterm.once("variablesview-fetched");
|
||||
ok(varView, "object inspector opened on click");
|
||||
|
||||
yield findVariableViewProperties(varView, [{
|
||||
name: "constructor",
|
||||
value: "Function()",
|
||||
}], { webconsole: hud });
|
||||
});
|
||||
|
||||
add_task(function* () {
|
||||
let msg = yield hud.jsterm.execute("fooObj");
|
||||
|
||||
ok(msg, "output message found");
|
||||
ok(msg.textContent.includes('{ testProp: "testValue" }'),
|
||||
"message text check");
|
||||
|
||||
let anchor = msg.querySelector("a");
|
||||
ok(anchor, "object link found");
|
||||
|
||||
let fetched = hud.jsterm.once("variablesview-fetched");
|
||||
|
||||
// executeSoon
|
||||
EventUtils.synthesizeMouse(anchor, 2, 2, {}, hud.iframeWindow);
|
||||
|
||||
let view = yield fetched;
|
||||
|
||||
let results = yield onFooObjFetch(view);
|
||||
|
||||
let vView = yield onTestPropFound(results);
|
||||
let results2 = yield onFooObjFetchAfterUpdate(vView);
|
||||
|
||||
let vView2 = yield onUpdatedTestPropFound(results2);
|
||||
let results3 = yield onFooObjFetchAfterPropRename(vView2);
|
||||
|
||||
let vView3 = yield onRenamedTestPropFound(results3);
|
||||
let results4 = yield onPropUpdateError(vView3);
|
||||
|
||||
yield onRenamedTestPropFoundAgain(results4);
|
||||
|
||||
let prop = results4[0].matchedProp;
|
||||
yield testPropDelete(prop);
|
||||
});
|
||||
|
||||
function onFooObjFetch(aVar) {
|
||||
gVariablesView = aVar._variablesView;
|
||||
ok(gVariablesView, "variables view object");
|
||||
|
||||
return findVariableViewProperties(aVar, [
|
||||
{ name: "testProp", value: "testValue" },
|
||||
], { webconsole: hud });
|
||||
}
|
||||
|
||||
function onTestPropFound(aResults) {
|
||||
let prop = aResults[0].matchedProp;
|
||||
ok(prop, "matched the |testProp| property in the variables view");
|
||||
|
||||
is("testValue", aResults[0].value,
|
||||
"|fooObj.testProp| value is correct");
|
||||
|
||||
// Check that property value updates work and that jsterm functions can be
|
||||
// used.
|
||||
return updateVariablesViewProperty({
|
||||
property: prop,
|
||||
field: "value",
|
||||
string: "document.title + window.location + $('p')",
|
||||
webconsole: hud
|
||||
});
|
||||
}
|
||||
|
||||
function onFooObjFetchAfterUpdate(aVar) {
|
||||
info("onFooObjFetchAfterUpdate");
|
||||
let expectedValue = gBrowser.contentTitle + gBrowser.currentURI.spec +
|
||||
"[object HTMLParagraphElement]";
|
||||
|
||||
return findVariableViewProperties(aVar, [
|
||||
{ name: "testProp", value: expectedValue },
|
||||
], { webconsole: hud });
|
||||
}
|
||||
|
||||
async function onUpdatedTestPropFound(aResults) {
|
||||
let prop = aResults[0].matchedProp;
|
||||
ok(prop, "matched the updated |testProp| property value");
|
||||
|
||||
await ContentTask.spawn(gBrowser.selectedBrowser, aResults[0].value, function(value) {
|
||||
is(content.wrappedJSObject.fooObj.testProp, value,
|
||||
"|fooObj.testProp| value has been updated");
|
||||
});
|
||||
|
||||
// Check that property name updates work.
|
||||
return updateVariablesViewProperty({
|
||||
property: prop,
|
||||
field: "name",
|
||||
string: "testUpdatedProp",
|
||||
webconsole: hud
|
||||
});
|
||||
}
|
||||
|
||||
function* onFooObjFetchAfterPropRename(aVar) {
|
||||
info("onFooObjFetchAfterPropRename");
|
||||
|
||||
let expectedValue = yield ContentTask.spawn(gBrowser.selectedBrowser, {}, function* () {
|
||||
let para = content.wrappedJSObject.document.querySelector("p");
|
||||
return content.document.title + content.location + para;
|
||||
});
|
||||
|
||||
// Check that the new value is in the variables view.
|
||||
return findVariableViewProperties(aVar, [
|
||||
{ name: "testUpdatedProp", value: expectedValue },
|
||||
], { webconsole: hud });
|
||||
}
|
||||
|
||||
async function onRenamedTestPropFound(aResults) {
|
||||
let prop = aResults[0].matchedProp;
|
||||
ok(prop, "matched the renamed |testProp| property");
|
||||
|
||||
await ContentTask.spawn(gBrowser.selectedBrowser, aResults[0].value, function(value) {
|
||||
ok(!content.wrappedJSObject.fooObj.testProp,
|
||||
"|fooObj.testProp| has been deleted");
|
||||
is(content.wrappedJSObject.fooObj.testUpdatedProp, value,
|
||||
"|fooObj.testUpdatedProp| is correct");
|
||||
});
|
||||
|
||||
// Check that property value updates that cause exceptions are reported in
|
||||
// the web console output.
|
||||
return updateVariablesViewProperty({
|
||||
property: prop,
|
||||
field: "value",
|
||||
string: "foobarzFailure()",
|
||||
webconsole: hud
|
||||
});
|
||||
}
|
||||
|
||||
function* onPropUpdateError(aVar) {
|
||||
info("onPropUpdateError");
|
||||
|
||||
let expectedValue = yield ContentTask.spawn(gBrowser.selectedBrowser, {}, function* () {
|
||||
let para = content.wrappedJSObject.document.querySelector("p");
|
||||
return content.document.title + content.location + para;
|
||||
});
|
||||
|
||||
// Make sure the property did not change.
|
||||
return findVariableViewProperties(aVar, [
|
||||
{ name: "testUpdatedProp", value: expectedValue },
|
||||
], { webconsole: hud });
|
||||
}
|
||||
|
||||
function onRenamedTestPropFoundAgain(aResults) {
|
||||
let prop = aResults[0].matchedProp;
|
||||
ok(prop, "matched the renamed |testProp| property again");
|
||||
|
||||
return waitForMessages({
|
||||
webconsole: hud,
|
||||
messages: [{
|
||||
name: "exception in property update reported in the web console output",
|
||||
text: "foobarzFailure",
|
||||
category: CATEGORY_OUTPUT,
|
||||
severity: SEVERITY_ERROR,
|
||||
}],
|
||||
});
|
||||
}
|
||||
|
||||
function testPropDelete(aProp) {
|
||||
gVariablesView.window.focus();
|
||||
aProp.focus();
|
||||
|
||||
executeSoon(() => {
|
||||
EventUtils.synthesizeKey("VK_DELETE", {}, gVariablesView.window);
|
||||
});
|
||||
|
||||
let success = false;
|
||||
return waitForSuccess({
|
||||
name: "property deleted",
|
||||
timeout: 60000,
|
||||
validator: function() {
|
||||
ContentTask.spawn(gBrowser.selectedBrowser, null, function() {
|
||||
return !("testUpdatedProp" in content.wrappedJSObject.fooObj);
|
||||
}).then((result) => success = result);
|
||||
return success;
|
||||
}
|
||||
});
|
||||
}
|
|
@ -1,59 +0,0 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* 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/ */
|
||||
|
||||
// Test that ensures DOM nodes are rendered correctly in VariablesView.
|
||||
|
||||
"use strict";
|
||||
|
||||
function test() {
|
||||
const TEST_URI = `
|
||||
data:text/html;charset=utf-8,
|
||||
<html>
|
||||
<head>
|
||||
<title>Test for DOM nodes in variables view</title>
|
||||
</head>
|
||||
<body>
|
||||
<div></div>
|
||||
<div id="testID"></div>
|
||||
<div class="single-class"></div>
|
||||
<div class="multiple-classes another-class"></div>
|
||||
<div class="class-and-id" id="class-and-id"></div>
|
||||
<div class="multiple-classes-and-id another-class"
|
||||
id="multiple-classes-and-id"></div>
|
||||
<div class=" whitespace-start"></div>
|
||||
<div class="whitespace-end "></div>
|
||||
<div class="multiple spaces"></div>
|
||||
</body>
|
||||
</html>
|
||||
`;
|
||||
|
||||
Task.spawn(runner).then(finishTest);
|
||||
|
||||
function* runner() {
|
||||
const {tab} = yield loadTab(TEST_URI);
|
||||
const hud = yield openConsole(tab);
|
||||
const jsterm = hud.jsterm;
|
||||
|
||||
let deferred = defer();
|
||||
jsterm.once("variablesview-fetched", (val) => deferred.resolve(val));
|
||||
jsterm.execute("inspect(document.querySelectorAll('div'))");
|
||||
|
||||
let variableScope = yield deferred.promise;
|
||||
ok(variableScope, "Variables view opened");
|
||||
|
||||
yield findVariableViewProperties(variableScope, [
|
||||
{ name: "0", value: "<div>"},
|
||||
{ name: "1", value: "<div#testID>"},
|
||||
{ name: "2", value: "<div.single-class>"},
|
||||
{ name: "3", value: "<div.multiple-classes.another-class>"},
|
||||
{ name: "4", value: "<div#class-and-id.class-and-id>"},
|
||||
{ name: "5", value: "<div#multiple-classes-and-id." +
|
||||
"multiple-classes-and-id.another-class>"},
|
||||
{ name: "6", value: "<div.whitespace-start>"},
|
||||
{ name: "7", value: "<div.whitespace-end>"},
|
||||
{ name: "8", value: "<div.multiple.spaces>"},
|
||||
], { webconsole: hud});
|
||||
}
|
||||
}
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче