Bug 1317650 - Implement Params Panel r=Honza,jsnajdr

MozReview-Commit-ID: A0GjfZeSOJi

--HG--
extra : rebase_source : 7f3183605670114d8dec68d7625ee803ef3d2e4b
This commit is contained in:
Ricky Chien 2017-01-08 17:54:53 +08:00
Родитель 608c443bd1
Коммит 31024c90f2
17 изменённых файлов: 521 добавлений и 467 удалений

Просмотреть файл

@ -255,6 +255,41 @@ function waitForNEvents(target, eventName, numTimes, useCapture = false) {
return deferred.promise;
}
/**
* Wait for DOM change on target.
*
* @param {Object} target
* The Node on which to observe DOM mutations.
* @param {String} selector
* Given a selector to watch whether the expected element is changed
* on target.
* @param {Number} expectedLength
* Optional, default set to 1
* There may be more than one element match an array match the selector,
* give an expected length to wait for more elements.
* @return A promise that resolves when the event has been handled
*/
function waitForDOM(target, selector, expectedLength = 1) {
return new Promise((resolve) => {
let observer = new MutationObserver((mutations) => {
mutations.forEach((mutation) => {
let elements = mutation.target.querySelectorAll(selector);
if (elements.length === expectedLength) {
observer.disconnect();
resolve(elements);
}
});
});
observer.observe(target, {
attributes: true,
childList: true,
subtree: true,
});
});
}
/**
* Wait for eventName on target.
*

Просмотреть файл

@ -6,7 +6,7 @@
const general = {
CONTENT_SIZE_DECIMALS: 2,
FREETEXT_FILTER_SEARCH_DELAY: 200,
FILTER_SEARCH_DELAY: 200,
REQUEST_TIME_DECIMALS: 2,
};

Просмотреть файл

@ -21,14 +21,12 @@ const { Filters } = require("./filter-predicates");
const {
decodeUnicodeUrl,
formDataURI,
getFormDataSections,
getUrlBaseName,
getUrlQuery,
parseQueryString,
} = require("./request-utils");
const { createFactory } = require("devtools/client/shared/vendor/react");
const ReactDOM = require("devtools/client/shared/vendor/react-dom");
const Provider = createFactory(require("devtools/client/shared/vendor/react-redux").Provider);
const ParamsPanel = createFactory(require("./shared/components/params-panel"));
const PreviewPanel = createFactory(require("./shared/components/preview-panel"));
const SecurityPanel = createFactory(require("./shared/components/security-panel"));
const TimingsPanel = createFactory(require("./shared/components/timings-panel"));
@ -94,6 +92,13 @@ DetailsView.prototype = {
initialize: function (store) {
dumpn("Initializing the DetailsView");
this._paramsPanelNode = $("#react-params-tabpanel-hook");
ReactDOM.render(Provider(
{ store },
ParamsPanel()
), this._paramsPanelNode);
this._previewPanelNode = $("#react-preview-tabpanel-hook");
ReactDOM.render(Provider(
@ -131,11 +136,6 @@ DetailsView.prototype = {
emptyText: L10N.getStr("cookiesEmptyText"),
searchPlaceholder: L10N.getStr("cookiesFilterText")
}));
this._params = new VariablesView($("#request-params"),
Heritage.extend(GENERIC_VARIABLES_VIEW_SETTINGS, {
emptyText: L10N.getStr("paramsEmptyText"),
searchPlaceholder: L10N.getStr("paramsFilterText")
}));
this._json = new VariablesView($("#response-content-json"),
Heritage.extend(GENERIC_VARIABLES_VIEW_SETTINGS, {
onlyEnumVisible: true,
@ -143,9 +143,6 @@ DetailsView.prototype = {
}));
VariablesViewController.attach(this._json);
this._paramsQueryString = L10N.getStr("paramsQueryString");
this._paramsFormData = L10N.getStr("paramsFormData");
this._paramsPostPayload = L10N.getStr("paramsPostPayload");
this._requestHeaders = L10N.getStr("requestHeaders");
this._requestHeadersFromUpload = L10N.getStr("requestHeadersFromUpload");
this._responseHeaders = L10N.getStr("responseHeaders");
@ -160,6 +157,7 @@ DetailsView.prototype = {
*/
destroy: function () {
dumpn("Destroying the DetailsView");
ReactDOM.unmountComponentAtNode(this._paramsPanelNode);
ReactDOM.unmountComponentAtNode(this._previewPanelNode);
ReactDOM.unmountComponentAtNode(this._securityPanelNode);
ReactDOM.unmountComponentAtNode(this._timingsPanelNode);
@ -177,9 +175,6 @@ DetailsView.prototype = {
* Returns a promise that resolves upon population the view.
*/
populate: function (data) {
$("#request-params-box").setAttribute("flex", "1");
$("#request-params-box").hidden = false;
$("#request-post-data-textarea-box").hidden = true;
$("#response-content-info-header").hidden = true;
$("#response-content-json-box").hidden = true;
$("#response-content-textarea-box").hidden = true;
@ -210,7 +205,6 @@ DetailsView.prototype = {
this._headers.empty();
this._cookies.empty();
this._params.empty();
this._json.empty();
this._dataSrc = { src: data, populated: [] };
@ -260,14 +254,6 @@ DetailsView.prototype = {
yield view._setResponseCookies(src.responseCookies);
yield view._setRequestCookies(src.requestCookies);
break;
// "Params"
case 2:
yield view._setRequestGetParams(src.url);
yield view._setRequestPostParams(
src.requestHeaders,
src.requestHeadersFromUploadStream,
src.requestPostData);
break;
// "Response"
case 3:
yield view._setResponseBody(src.url, src.responseContent);
@ -485,108 +471,6 @@ DetailsView.prototype = {
}
}),
/**
* Sets the network request get params shown in this view.
*
* @param string url
* The request's url.
*/
_setRequestGetParams: function (url) {
let query = getUrlQuery(url);
if (query) {
this._addParams(this._paramsQueryString, query);
}
},
/**
* Sets the network request post params shown in this view.
*
* @param object headers
* The "requestHeaders" message received from the server.
* @param object uploadHeaders
* The "requestHeadersFromUploadStream" inferred from the POST payload.
* @param object postData
* The "requestPostData" message received from the server.
* @return object
* A promise that is resolved when the request post params are set.
*/
_setRequestPostParams: Task.async(function* (headers, uploadHeaders,
postData) {
if (!headers || !uploadHeaders || !postData) {
return;
}
let formDataSections = yield getFormDataSections(
headers,
uploadHeaders,
postData,
gNetwork.getString.bind(gNetwork));
this._params.onlyEnumVisible = false;
// Handle urlencoded form data sections (e.g. "?foo=bar&baz=42").
if (formDataSections.length > 0) {
formDataSections.forEach(section => {
this._addParams(this._paramsFormData, section);
});
} else {
// Handle JSON and actual forms ("multipart/form-data" content type).
let postDataLongString = postData.postData.text;
let text = yield gNetwork.getString(postDataLongString);
let jsonVal = null;
try {
jsonVal = JSON.parse(text);
} catch (ex) { // eslint-disable-line
}
if (jsonVal) {
this._params.onlyEnumVisible = true;
let jsonScopeName = L10N.getStr("jsonScopeName");
let jsonScope = this._params.addScope(jsonScopeName);
jsonScope.expanded = true;
let jsonItem = jsonScope.addItem(undefined, { enumerable: true });
jsonItem.populate(jsonVal, { sorted: true });
} else {
// This is really awkward, but hey, it works. Let's show an empty
// scope in the params view and place the source editor containing
// the raw post data directly underneath.
$("#request-params-box").removeAttribute("flex");
let paramsScope = this._params.addScope(this._paramsPostPayload);
paramsScope.expanded = true;
paramsScope.locked = true;
$("#request-post-data-textarea-box").hidden = false;
let editor = yield NetMonitorView.editor("#request-post-data-textarea");
editor.setMode(Editor.modes.text);
editor.setText(text);
}
}
window.emit(EVENTS.REQUEST_POST_PARAMS_DISPLAYED);
}),
/**
* Populates the params container in this view with the specified data.
*
* @param string name
* The type of params to populate (get or post).
* @param string queryString
* A query string of params (e.g. "?foo=bar&baz=42").
*/
_addParams: function (name, queryString) {
let paramsArray = parseQueryString(queryString);
if (!paramsArray) {
return;
}
let paramsScope = this._params.addScope(name);
paramsScope.expanded = true;
for (let param of paramsArray) {
let paramVar = paramsScope.addItem(param.name, {}, {relaxed: true});
paramVar.setGrip(param.value);
}
},
/**
* Sets the network response body shown in this view.
*
@ -705,11 +589,7 @@ DetailsView.prototype = {
_dataSrc: null,
_headers: null,
_cookies: null,
_params: null,
_json: null,
_paramsQueryString: "",
_paramsFormData: "",
_paramsPostPayload: "",
_requestHeaders: "",
_responseHeaders: "",
_requestCookies: "",

Просмотреть файл

@ -212,14 +212,8 @@
</tabpanel>
<tabpanel id="params-tabpanel"
class="tabpanel-content">
<vbox flex="1">
<vbox id="request-params-box" flex="1" hidden="true">
<vbox id="request-params" flex="1"/>
</vbox>
<vbox id="request-post-data-textarea-box" flex="1" hidden="true">
<vbox id="request-post-data-textarea" flex="1"/>
</vbox>
</vbox>
<html:div xmlns="http://www.w3.org/1999/xhtml"
id="react-params-tabpanel-hook"/>
</tabpanel>
<tabpanel id="response-tabpanel"
class="tabpanel-content">

Просмотреть файл

@ -14,7 +14,7 @@ const {
PRESELECT_REQUEST,
CLONE_SELECTED_REQUEST,
REMOVE_SELECTED_CUSTOM_REQUEST,
OPEN_SIDEBAR
OPEN_SIDEBAR,
} = require("../constants");
const Request = I.Record({
@ -37,7 +37,7 @@ const Request = I.Record({
httpVersion: undefined,
securityState: undefined,
securityInfo: undefined,
mimeType: undefined,
mimeType: "text/plain",
contentSize: undefined,
transferredSize: undefined,
totalTime: undefined,
@ -51,6 +51,7 @@ const Request = I.Record({
responseCookies: undefined,
responseContent: undefined,
responseContentDataUri: undefined,
formDataSections: undefined,
});
const Requests = I.Record({
@ -87,7 +88,8 @@ const UPDATE_PROPS = [
"responseHeaders",
"responseCookies",
"responseContent",
"responseContentDataUri"
"responseContentDataUri",
"formDataSections",
];
function requestsReducer(state = new Requests(), action) {
@ -139,13 +141,6 @@ function requestsReducer(state = new Requests(), action) {
// Compute the additional URL details
request.urlDetails = getUrlDetails(value);
break;
case "responseContent":
// If there's no mime type available when the response content
// is received, assume text/plain as a fallback.
if (!request.mimeType) {
request.mimeType = "text/plain";
}
break;
case "totalTime":
const endedMillis = request.startedMillis + value;
lastEndedMillis = Math.max(lastEndedMillis, endedMillis);

Просмотреть файл

@ -23,7 +23,8 @@ const { Prefs } = require("./prefs");
const {
formDataURI,
writeHeaderText,
loadCauseString
loadCauseString,
getFormDataSections,
} = require("./request-utils");
const {
@ -31,7 +32,7 @@ const {
getSortedRequests,
getDisplayedRequests,
getRequestById,
getSelectedRequest
getSelectedRequest,
} = require("./selectors/index");
// ms
@ -88,6 +89,57 @@ RequestsMenuView.prototype = {
() => this.onResize()
));
// Watch the requestHeaders, requestHeadersFromUploadStream and requestPostData
// in order to update formDataSections for composing form data
this.store.subscribe(storeWatcher(
false,
(currentRequest) => {
const request = getSelectedRequest(this.store.getState());
if (!request) {
return {};
}
const isChanged = request.requestHeaders !== currentRequest.requestHeaders ||
request.requestHeadersFromUploadStream !==
currentRequest.requestHeadersFromUploadStream ||
request.requestPostData !== currentRequest.requestPostData;
if (isChanged) {
return {
id: request.id,
requestHeaders: request.requestHeaders,
requestHeadersFromUploadStream: request.requestHeadersFromUploadStream,
requestPostData: request.requestPostData,
};
}
return currentRequest;
},
(newRequest) => {
const {
id,
requestHeaders,
requestHeadersFromUploadStream,
requestPostData,
} = newRequest;
if (requestHeaders && requestHeadersFromUploadStream && requestPostData) {
getFormDataSections(
requestHeaders,
requestHeadersFromUploadStream,
requestPostData,
gNetwork.getString.bind(gNetwork),
).then((formDataSections) => {
this.store.dispatch(Actions.updateRequest(
id,
{ formDataSections },
true,
));
});
}
},
));
this.sendCustomRequestEvent = this.sendCustomRequest.bind(this);
this.closeCustomRequestEvent = this.closeCustomRequest.bind(this);
this.cloneSelectedRequestEvent = this.cloneSelectedRequest.bind(this);

Просмотреть файл

@ -4,6 +4,7 @@
DevToolsModules(
'editor.js',
'params-panel.js',
'preview-panel.js',
'properties-view.js',
'security-panel.js',

Просмотреть файл

@ -0,0 +1,128 @@
/* 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 {
createFactory,
DOM,
PropTypes,
} = require("devtools/client/shared/vendor/react");
const { connect } = require("devtools/client/shared/vendor/react-redux");
const { L10N } = require("../../l10n");
const { getSelectedRequest } = require("../../selectors/index");
const { getUrlQuery, parseQueryString } = require("../../request-utils");
// Components
const PropertiesView = createFactory(require("./properties-view"));
const { div } = DOM;
const JSON_SCOPE_NAME = L10N.getStr("jsonScopeName");
const PARAMS_EMPTY_TEXT = L10N.getStr("paramsEmptyText");
const PARAMS_FILTER_TEXT = L10N.getStr("paramsFilterText");
const PARAMS_FORM_DATA = L10N.getStr("paramsFormData");
const PARAMS_POST_PAYLOAD = L10N.getStr("paramsPostPayload");
const PARAMS_QUERY_STRING = L10N.getStr("paramsQueryString");
const SECTION_NAMES = [
JSON_SCOPE_NAME,
PARAMS_FORM_DATA,
PARAMS_POST_PAYLOAD,
PARAMS_QUERY_STRING,
];
/*
* Params panel component
* Displays the GET parameters and POST data of a request
*/
function ParamsPanel({
formDataSections,
mimeType,
postData,
query,
}) {
if (!formDataSections && !postData && !query) {
return div({ className: "empty-notice" },
PARAMS_EMPTY_TEXT
);
}
let object = {};
let json;
// Query String section
if (query) {
object[PARAMS_QUERY_STRING] =
parseQueryString(query)
.reduce((acc, { name, value }) =>
name ? Object.assign(acc, { [name]: value }) : acc
, {});
}
// Form Data section
if (formDataSections && formDataSections.length > 0) {
let sections = formDataSections.filter((str) => /\S/.test(str)).join("&");
object[PARAMS_FORM_DATA] =
parseQueryString(sections)
.reduce((acc, { name, value }) =>
name ? Object.assign(acc, { [name]: value }) : acc
, {});
}
// Request payload section
if (formDataSections && formDataSections.length === 0 && postData) {
try {
json = JSON.parse(postData);
} catch (error) {
// Continue regardless of parsing error
}
if (json) {
object[JSON_SCOPE_NAME] = json;
} else {
object[PARAMS_POST_PAYLOAD] = {
EDITOR_CONFIG: {
text: postData,
mode: mimeType.replace(/;.+/, ""),
},
};
}
} else {
postData = "";
}
return (
PropertiesView({
object,
filterPlaceHolder: PARAMS_FILTER_TEXT,
sectionNames: SECTION_NAMES,
})
);
}
ParamsPanel.displayName = "ParamsPanel";
ParamsPanel.propTypes = {
formDataSections: PropTypes.array,
postData: PropTypes.string,
query: PropTypes.string,
};
module.exports = connect(
(state) => {
const selectedRequest = getSelectedRequest(state);
if (selectedRequest) {
const { formDataSections, mimeType, requestPostData, url } = selectedRequest;
return {
formDataSections,
mimeType,
postData: requestPostData ? requestPostData.postData.text : null,
query: getUrlQuery(url),
};
}
return {};
}
)(ParamsPanel);

Просмотреть файл

@ -22,6 +22,8 @@ const TreeRow = createFactory(require("devtools/client/shared/components/tree/tr
const { Rep } = createFactories(require("devtools/client/shared/components/reps/rep"));
const { div, tr, td } = DOM;
const AUTO_EXPAND_MAX_LEVEL = 7;
const EDITOR_CONFIG_ID = "EDITOR_CONFIG";
/*
* Properties View component
@ -30,7 +32,7 @@ const { div, tr, td } = DOM;
*
* Search filter - Set enableFilter to enable / disable SearchBox feature.
* Tree view - Default enabled.
* Source editor - Enable by specifying object level 1 property name to "editorText".
* Source editor - Enable by specifying object level 1 property name to EDITOR_CONFIG_ID.
* Rep - Default enabled.
*/
const PropertiesView = createClass({
@ -76,18 +78,24 @@ const PropertiesView = createClass({
},
renderRowWithEditor(props) {
const { level, name, value } = props.member;
// Display source editor when prop name specify to editorText
if (level === 1 && name === "editorText") {
const { level, name, value, path } = props.member;
// Display source editor when specifying to EDITOR_CONFIG_ID along with config
if (level === 1 && name === EDITOR_CONFIG_ID) {
return (
tr({},
td({ colSpan: 2 },
Editor({ text: value })
Editor(value)
)
)
);
}
// Skip for editor config
if (level >= 1 && path.includes(EDITOR_CONFIG_ID)) {
return null;
}
return TreeRow(props);
},
@ -106,18 +114,44 @@ const PropertiesView = createClass({
}));
},
shouldRenderSearchBox(object) {
return this.props.enableFilter && object && Object.keys(object)
.filter((section) => !object[section][EDITOR_CONFIG_ID]).length > 0;
},
updateFilterText(filterText) {
this.setState({
filterText,
});
},
getExpandedNodes: function (object, path = "", level = 0) {
if (typeof object != "object") {
return null;
}
if (level > AUTO_EXPAND_MAX_LEVEL) {
return null;
}
let expandedNodes = new Set();
for (let prop in object) {
let nodePath = path + "/" + prop;
expandedNodes.add(nodePath);
let nodes = this.getExpandedNodes(object[prop], nodePath, level + 1);
if (nodes) {
expandedNodes = new Set([...expandedNodes, ...nodes]);
}
}
return expandedNodes;
},
render() {
const {
object,
decorator,
enableInput,
enableFilter,
expandableStrings,
filterPlaceHolder,
renderRow,
@ -127,14 +161,15 @@ const PropertiesView = createClass({
return (
div({ className: "properties-view" },
enableFilter && div({ className: "searchbox-section" },
SearchBox({
delay: FILTER_SEARCH_DELAY,
type: "filter",
onChange: this.updateFilterText,
placeholder: filterPlaceHolder,
}),
),
this.shouldRenderSearchBox(object) &&
div({ className: "searchbox-section" },
SearchBox({
delay: FILTER_SEARCH_DELAY,
type: "filter",
onChange: this.updateFilterText,
placeholder: filterPlaceHolder,
}),
),
div({ className: "tree-container" },
TreeView({
object,
@ -147,7 +182,7 @@ const PropertiesView = createClass({
},
enableInput,
expandableStrings,
expandedNodes: new Set(sectionNames.map((sec) => "/" + sec)),
expandedNodes: this.getExpandedNodes(object),
onFilter: (props) => this.onFilter(props, sectionNames),
renderRow: renderRow || this.renderRowWithEditor,
renderValue: renderValue || this.renderValueWithRep,

Просмотреть файл

@ -15,7 +15,6 @@ add_task(function* () {
let { RequestsMenu, NetworkDetails } = NetMonitorView;
RequestsMenu.lazyUpdate = false;
NetworkDetails._params.lazyEmpty = false;
const REQUEST_DATA = [
{

Просмотреть файл

@ -14,11 +14,10 @@ add_task(function* () {
let { tab, monitor } = yield initNetMonitor(PARAMS_URL);
info("Starting test... ");
let { document, EVENTS, Editor, NetMonitorView } = monitor.panelWin;
let { RequestsMenu, NetworkDetails } = NetMonitorView;
let { document, NetMonitorView } = monitor.panelWin;
let { RequestsMenu } = NetMonitorView;
RequestsMenu.lazyUpdate = false;
NetworkDetails._params.lazyEmpty = false;
let wait = waitForNetworkEvents(monitor, 1, 6);
yield ContentTask.spawn(tab.linkedBrowser, {}, function* () {
@ -26,43 +25,47 @@ add_task(function* () {
});
yield wait;
let onEvent = monitor.panelWin.once(EVENTS.REQUEST_POST_PARAMS_DISPLAYED);
wait = waitForDOM(document, "#params-tabpanel .tree-section", 2);
EventUtils.sendMouseEvent({ type: "mousedown" },
document.getElementById("details-pane-toggle"));
EventUtils.sendMouseEvent({ type: "mousedown" },
document.querySelectorAll("#details-pane tab")[2]);
yield onEvent;
yield testParamsTab1("a", '""', '{ "foo": "bar" }', '""');
yield wait;
testParamsTab1("a", '""', '{ "foo": "bar" }', '""');
onEvent = monitor.panelWin.once(EVENTS.REQUEST_POST_PARAMS_DISPLAYED);
wait = waitForDOM(document, "#params-tabpanel .tree-section", 2);
RequestsMenu.selectedIndex = 1;
yield onEvent;
yield testParamsTab1("a", '"b"', '{ "foo": "bar" }', '""');
yield wait;
testParamsTab1("a", '"b"', '{ "foo": "bar" }', '""');
onEvent = monitor.panelWin.once(EVENTS.REQUEST_POST_PARAMS_DISPLAYED);
wait = waitForDOM(document, "#params-tabpanel .tree-section", 2);
RequestsMenu.selectedIndex = 2;
yield onEvent;
yield testParamsTab1("a", '"b"', "foo", '"bar"');
yield wait;
testParamsTab1("a", '"b"', "foo", '"bar"');
onEvent = monitor.panelWin.once(EVENTS.REQUEST_POST_PARAMS_DISPLAYED);
wait = waitForDOM(document, "#params-tabpanel tr:not(.tree-section).treeRow", 2);
RequestsMenu.selectedIndex = 3;
yield onEvent;
yield testParamsTab2("a", '""', '{ "foo": "bar" }', "js");
yield wait;
testParamsTab2("a", '""', '{ "foo": "bar" }', "js");
onEvent = monitor.panelWin.once(EVENTS.REQUEST_POST_PARAMS_DISPLAYED);
wait = waitForDOM(document, "#params-tabpanel tr:not(.tree-section).treeRow", 2);
RequestsMenu.selectedIndex = 4;
yield onEvent;
yield testParamsTab2("a", '"b"', '{ "foo": "bar" }', "js");
yield wait;
testParamsTab2("a", '"b"', '{ "foo": "bar" }', "js");
onEvent = monitor.panelWin.once(EVENTS.REQUEST_POST_PARAMS_DISPLAYED);
// Wait for all tree sections and editor updated by react
let waitSections = waitForDOM(document, "#params-tabpanel .tree-section", 2);
let waitEditor = waitForDOM(document, "#params-tabpanel .editor-mount iframe");
RequestsMenu.selectedIndex = 5;
yield onEvent;
yield testParamsTab2("a", '"b"', "?foo=bar", "text");
let [, editorFrames] = yield Promise.all([waitSections, waitEditor]);
yield once(editorFrames[0], "DOMContentLoaded");
yield waitForDOM(editorFrames[0].contentDocument, ".CodeMirror-code");
testParamsTab2("a", '"b"', "?foo=bar", "text");
onEvent = monitor.panelWin.once(EVENTS.SIDEBAR_POPULATED);
wait = waitForDOM(document, "#params-tabpanel .empty-notice");
RequestsMenu.selectedIndex = 6;
yield onEvent;
yield testParamsTab3("a", '"b"');
yield wait;
testParamsTab3();
yield teardown(monitor);
@ -70,126 +73,110 @@ add_task(function* () {
formDataParamName, formDataParamValue) {
let tabpanel = document.querySelectorAll("#details-pane tabpanel")[2];
is(tabpanel.querySelectorAll(".variables-view-scope").length, 2,
"The number of param scopes displayed in this tabpanel is incorrect.");
is(tabpanel.querySelectorAll(".variable-or-property").length, 2,
"The number of param values displayed in this tabpanel is incorrect.");
is(tabpanel.querySelectorAll(".variables-view-empty-notice").length, 0,
is(tabpanel.querySelectorAll(".tree-section").length, 2,
"The number of param tree sections displayed in this tabpanel is incorrect.");
is(tabpanel.querySelectorAll("tr:not(.tree-section).treeRow").length, 2,
"The number of param rows displayed in this tabpanel is incorrect.");
is(tabpanel.querySelectorAll(".empty-notice").length, 0,
"The empty notice should not be displayed in this tabpanel.");
is(tabpanel.querySelector("#request-params-box")
.hasAttribute("hidden"), false,
"The request params box should not be hidden.");
is(tabpanel.querySelector("#request-post-data-textarea-box")
.hasAttribute("hidden"), true,
"The request post data textarea box should be hidden.");
ok(tabpanel.querySelector(".treeTable"),
"The request params box should be displayed.");
ok(tabpanel.querySelector(".editor-mount") === null,
"The request post data editor should not be displayed.");
let paramsScope = tabpanel.querySelectorAll(".variables-view-scope")[0];
let formDataScope = tabpanel.querySelectorAll(".variables-view-scope")[1];
let treeSections = tabpanel.querySelectorAll(".tree-section");
let labels = tabpanel
.querySelectorAll("tr:not(.tree-section) .treeLabelCell .treeLabel");
let values = tabpanel
.querySelectorAll("tr:not(.tree-section) .treeValueCell .objectBox");
is(paramsScope.querySelector(".name").getAttribute("value"),
is(treeSections[0].querySelector(".treeLabel").textContent,
L10N.getStr("paramsQueryString"),
"The params scope doesn't have the correct title.");
is(formDataScope.querySelector(".name").getAttribute("value"),
"The params section doesn't have the correct title.");
is(treeSections[1].querySelector(".treeLabel").textContent,
L10N.getStr("paramsFormData"),
"The form data scope doesn't have the correct title.");
"The form data section doesn't have the correct title.");
is(paramsScope.querySelectorAll(".variables-view-variable .name")[0]
.getAttribute("value"),
queryStringParamName,
is(labels[0].textContent, queryStringParamName,
"The first query string param name was incorrect.");
is(paramsScope.querySelectorAll(".variables-view-variable .value")[0]
.getAttribute("value"),
queryStringParamValue,
is(values[0].textContent, queryStringParamValue,
"The first query string param value was incorrect.");
is(formDataScope.querySelectorAll(".variables-view-variable .name")[0]
.getAttribute("value"),
formDataParamName,
is(labels[1].textContent, formDataParamName,
"The first form data param name was incorrect.");
is(formDataScope.querySelectorAll(".variables-view-variable .value")[0]
.getAttribute("value"),
formDataParamValue,
is(values[1].textContent, formDataParamValue,
"The first form data param value was incorrect.");
}
function* testParamsTab2(queryStringParamName, queryStringParamValue,
function testParamsTab2(queryStringParamName, queryStringParamValue,
requestPayload, editorMode) {
let isJSON = editorMode == "js";
let isJSON = editorMode === "js";
let tabpanel = document.querySelectorAll("#details-pane tabpanel")[2];
is(tabpanel.querySelectorAll(".variables-view-scope").length, 2,
"The number of param scopes displayed in this tabpanel is incorrect.");
is(tabpanel.querySelectorAll(".variable-or-property").length, isJSON ? 4 : 1,
"The number of param values displayed in this tabpanel is incorrect.");
is(tabpanel.querySelectorAll(".variables-view-empty-notice").length, 0,
is(tabpanel.querySelectorAll(".tree-section").length, 2,
"The number of param tree sections displayed in this tabpanel is incorrect.");
is(tabpanel.querySelectorAll("tr:not(.tree-section).treeRow").length, isJSON ? 2 : 1,
"The number of param rows displayed in this tabpanel is incorrect.");
is(tabpanel.querySelectorAll(".empty-notice").length, 0,
"The empty notice should not be displayed in this tabpanel.");
is(tabpanel.querySelector("#request-params-box")
.hasAttribute("hidden"), false,
"The request params box should not be hidden.");
is(tabpanel.querySelector("#request-post-data-textarea-box")
.hasAttribute("hidden"), isJSON,
"The request post data textarea box should be hidden.");
ok(tabpanel.querySelector(".treeTable"),
"The request params box should be displayed.");
is(tabpanel.querySelector(".editor-mount") === null,
isJSON,
"The request post data editor should be not displayed.");
let paramsScope = tabpanel.querySelectorAll(".variables-view-scope")[0];
let payloadScope = tabpanel.querySelectorAll(".variables-view-scope")[1];
let treeSections = tabpanel.querySelectorAll(".tree-section");
is(paramsScope.querySelector(".name").getAttribute("value"),
is(treeSections[0].querySelector(".treeLabel").textContent,
L10N.getStr("paramsQueryString"),
"The params scope doesn't have the correct title.");
is(payloadScope.querySelector(".name").getAttribute("value"),
"The query section doesn't have the correct title.");
is(treeSections[1].querySelector(".treeLabel").textContent,
isJSON ? L10N.getStr("jsonScopeName") : L10N.getStr("paramsPostPayload"),
"The request payload scope doesn't have the correct title.");
"The post section doesn't have the correct title.");
is(paramsScope.querySelectorAll(".variables-view-variable .name")[0]
.getAttribute("value"),
queryStringParamName,
let labels = tabpanel
.querySelectorAll("tr:not(.tree-section) .treeLabelCell .treeLabel");
let values = tabpanel
.querySelectorAll("tr:not(.treeS-section) .treeValueCell .objectBox");
is(labels[0].textContent, queryStringParamName,
"The first query string param name was incorrect.");
is(paramsScope.querySelectorAll(".variables-view-variable .value")[0]
.getAttribute("value"),
queryStringParamValue,
is(values[0].textContent, queryStringParamValue,
"The first query string param value was incorrect.");
if (isJSON) {
let requestPayloadObject = JSON.parse(requestPayload);
let requestPairs = Object.keys(requestPayloadObject)
.map(k => [k, requestPayloadObject[k]]);
let displayedNames = payloadScope.querySelectorAll(
".variables-view-property.variable-or-property .name");
let displayedValues = payloadScope.querySelectorAll(
".variables-view-property.variable-or-property .value");
for (let i = 0; i < requestPairs.length; i++) {
for (let i = 1; i < requestPairs.length; i++) {
let [requestPayloadName, requestPayloadValue] = requestPairs[i];
is(requestPayloadName, displayedNames[i].getAttribute("value"),
is(requestPayloadName, labels[i].textContent,
"JSON property name " + i + " should be displayed correctly");
is('"' + requestPayloadValue + '"', displayedValues[i].getAttribute("value"),
is('"' + requestPayloadValue + '"', values[i].textContent,
"JSON property value " + i + " should be displayed correctly");
}
} else {
let editor = yield NetMonitorView.editor("#request-post-data-textarea");
is(editor.getText(), requestPayload,
let editor = editorFrames[0].contentDocument.querySelector(".CodeMirror-code");
ok(editor.textContent.includes(requestPayload),
"The text shown in the source editor is incorrect.");
is(editor.getMode(), Editor.modes[editorMode],
"The mode active in the source editor is incorrect.");
}
}
function testParamsTab3(queryStringParamName, queryStringParamValue) {
function testParamsTab3() {
let tabpanel = document.querySelectorAll("#details-pane tabpanel")[2];
is(tabpanel.querySelectorAll(".variables-view-scope").length, 0,
"The number of param scopes displayed in this tabpanel is incorrect.");
is(tabpanel.querySelectorAll(".variable-or-property").length, 0,
"The number of param values displayed in this tabpanel is incorrect.");
is(tabpanel.querySelectorAll(".variables-view-empty-notice").length, 1,
is(tabpanel.querySelectorAll(".tree-section").length, 0,
"The number of param tree sections displayed in this tabpanel is incorrect.");
is(tabpanel.querySelectorAll("tr:not(.tree-section).treeRow").length, 0,
"The number of param rows displayed in this tabpanel is incorrect.");
is(tabpanel.querySelectorAll(".empty-notice").length, 1,
"The empty notice should be displayed in this tabpanel.");
is(tabpanel.querySelector("#request-params-box")
.hasAttribute("hidden"), false,
"The request params box should not be hidden.");
is(tabpanel.querySelector("#request-post-data-textarea-box")
.hasAttribute("hidden"), true,
"The request post data textarea box should be hidden.");
ok(!tabpanel.querySelector(".treeTable"),
"The request params box should be hidden.");
ok(!tabpanel.querySelector(".editor-mount iframe"),
"The request post data editor should be hidden.");
}
});

Просмотреть файл

@ -13,11 +13,10 @@ add_task(function* () {
let { tab, monitor } = yield initNetMonitor(POST_DATA_URL);
info("Starting test... ");
let { document, EVENTS, Editor, NetMonitorView } = monitor.panelWin;
let { RequestsMenu, NetworkDetails } = NetMonitorView;
let { document, NetMonitorView } = monitor.panelWin;
let { RequestsMenu } = NetMonitorView;
RequestsMenu.lazyUpdate = false;
NetworkDetails._params.lazyEmpty = false;
let wait = waitForNetworkEvents(monitor, 0, 2);
yield ContentTask.spawn(tab.linkedBrowser, {}, function* () {
@ -44,17 +43,22 @@ add_task(function* () {
time: true
});
let onEvent = monitor.panelWin.once(EVENTS.TAB_UPDATED);
// Wait for all tree sections updated by react
wait = waitForDOM(document, "#params-tabpanel .tree-section", 2);
EventUtils.sendMouseEvent({ type: "mousedown" },
document.getElementById("details-pane-toggle"));
EventUtils.sendMouseEvent({ type: "mousedown" },
document.querySelectorAll("#details-pane tab")[2]);
yield onEvent;
yield wait;
yield testParamsTab("urlencoded");
onEvent = monitor.panelWin.once(EVENTS.TAB_UPDATED);
// Wait for all tree sections and editor updated by react
let waitForSections = waitForDOM(document, "#params-tabpanel .tree-section", 2);
let waitForEditor = waitForDOM(document, "#params-tabpanel .editor-mount iframe");
RequestsMenu.selectedIndex = 1;
yield onEvent;
let [, editorFrames] = yield Promise.all([waitForSections, waitForEditor]);
yield once(editorFrames[0], "DOMContentLoaded");
yield waitForDOM(editorFrames[0].contentDocument, ".CodeMirror-code");
yield testParamsTab("multipart");
return teardown(monitor);
@ -67,83 +71,51 @@ add_task(function* () {
"The params tab in the network details pane should be selected.");
function checkVisibility(box) {
is(tabpanel.querySelector("#request-params-box")
.hasAttribute("hidden"), !box.includes("params"),
"The request params box doesn't have the indended visibility.");
is(tabpanel.querySelector("#request-post-data-textarea-box")
.hasAttribute("hidden"), !box.includes("textarea"),
"The request post data textarea box doesn't have the indended visibility.");
is(!tabpanel.querySelector(".treeTable"), !box.includes("params"),
"The request params doesn't have the indended visibility.");
is(tabpanel.querySelector(".editor-mount") === null,
!box.includes("editor"),
"The request post data doesn't have the indended visibility.");
}
is(tabpanel.querySelectorAll(".variables-view-scope").length, 2,
"There should be 2 param scopes displayed in this tabpanel.");
is(tabpanel.querySelectorAll(".variables-view-empty-notice").length, 0,
is(tabpanel.querySelectorAll(".tree-section").length, 2,
"There should be 2 tree sections displayed in this tabpanel.");
is(tabpanel.querySelectorAll(".empty-notice").length, 0,
"The empty notice should not be displayed in this tabpanel.");
let queryScope = tabpanel.querySelectorAll(".variables-view-scope")[0];
let postScope = tabpanel.querySelectorAll(".variables-view-scope")[1];
let treeSections = tabpanel.querySelectorAll(".tree-section");
is(queryScope.querySelector(".name").getAttribute("value"),
is(treeSections[0].querySelector(".treeLabel").textContent,
L10N.getStr("paramsQueryString"),
"The query scope doesn't have the correct title.");
"The query section doesn't have the correct title.");
is(postScope.querySelector(".name").getAttribute("value"),
is(treeSections[1].querySelector(".treeLabel").textContent,
L10N.getStr(type == "urlencoded" ? "paramsFormData" : "paramsPostPayload"),
"The post scope doesn't have the correct title.");
"The post section doesn't have the correct title.");
is(queryScope.querySelectorAll(".variables-view-variable .name")[0]
.getAttribute("value"),
"foo", "The first query param name was incorrect.");
is(queryScope.querySelectorAll(".variables-view-variable .value")[0]
.getAttribute("value"),
"\"bar\"", "The first query param value was incorrect.");
is(queryScope.querySelectorAll(".variables-view-variable .name")[1]
.getAttribute("value"),
"baz", "The second query param name was incorrect.");
is(queryScope.querySelectorAll(".variables-view-variable .value")[1]
.getAttribute("value"),
"\"42\"", "The second query param value was incorrect.");
is(queryScope.querySelectorAll(".variables-view-variable .name")[2]
.getAttribute("value"),
"type", "The third query param name was incorrect.");
is(queryScope.querySelectorAll(".variables-view-variable .value")[2]
.getAttribute("value"),
"\"" + type + "\"", "The third query param value was incorrect.");
let labels = tabpanel.querySelectorAll("tr:not(.tree-section) .treeLabelCell .treeLabel");
let values = tabpanel.querySelectorAll("tr:not(.tree-section) .treeValueCell .objectBox");
is(labels[0].textContent, "foo", "The first query param name was incorrect.");
is(values[0].textContent, "\"bar\"", "The first query param value was incorrect.");
is(labels[1].textContent, "baz", "The second query param name was incorrect.");
is(values[1].textContent, "\"42\"", "The second query param value was incorrect.");
is(labels[2].textContent, "type", "The third query param name was incorrect.");
is(values[2].textContent, "\"" + type + "\"", "The third query param value was incorrect.");
if (type == "urlencoded") {
checkVisibility("params");
is(tabpanel.querySelectorAll(".variables-view-variable").length, 5,
"There should be 5 param values displayed in this tabpanel.");
is(queryScope.querySelectorAll(".variables-view-variable").length, 3,
"There should be 3 param values displayed in the query scope.");
is(postScope.querySelectorAll(".variables-view-variable").length, 2,
"There should be 2 param values displayed in the post scope.");
is(postScope.querySelectorAll(".variables-view-variable .name")[0]
.getAttribute("value"),
"foo", "The first post param name was incorrect.");
is(postScope.querySelectorAll(".variables-view-variable .value")[0]
.getAttribute("value"),
"\"bar\"", "The first post param value was incorrect.");
is(postScope.querySelectorAll(".variables-view-variable .name")[1]
.getAttribute("value"),
"baz", "The second post param name was incorrect.");
is(postScope.querySelectorAll(".variables-view-variable .value")[1]
.getAttribute("value"),
"\"123\"", "The second post param value was incorrect.");
is(labels.length, 5, "There should be 5 param values displayed in this tabpanel.");
is(labels[3].textContent, "foo", "The first post param name was incorrect.");
is(values[3].textContent, "\"bar\"", "The first post param value was incorrect.");
is(labels[4].textContent, "baz", "The second post param name was incorrect.");
is(values[4].textContent, "\"123\"", "The second post param value was incorrect.");
} else {
checkVisibility("params textarea");
checkVisibility("params editor");
is(tabpanel.querySelectorAll(".variables-view-variable").length, 3,
"There should be 3 param values displayed in this tabpanel.");
is(queryScope.querySelectorAll(".variables-view-variable").length, 3,
"There should be 3 param values displayed in the query scope.");
is(postScope.querySelectorAll(".variables-view-variable").length, 0,
"There should be 0 param values displayed in the post scope.");
is(labels.length, 3, "There should be 3 param values displayed in this tabpanel.");
let editor = yield NetMonitorView.editor("#request-post-data-textarea");
let text = editor.getText();
let text = editorFrames[0].contentDocument.querySelector(".CodeMirror-code").textContent;
ok(text.includes("Content-Disposition: form-data; name=\"text\""),
"The text shown in the source editor is incorrect (1.1).");
@ -159,8 +131,6 @@ add_task(function* () {
"The text shown in the source editor is incorrect (3.2).");
ok(text.includes("Extra data"),
"The text shown in the source editor is incorrect (4.2).");
is(editor.getMode(), Editor.modes.text,
"The mode active in the source editor is incorrect.");
}
}
});

Просмотреть файл

@ -14,11 +14,10 @@ add_task(function* () {
let { tab, monitor } = yield initNetMonitor(POST_RAW_URL);
info("Starting test... ");
let { document, EVENTS, NetMonitorView } = monitor.panelWin;
let { RequestsMenu, NetworkDetails } = NetMonitorView;
let { document, NetMonitorView } = monitor.panelWin;
let { RequestsMenu } = NetMonitorView;
RequestsMenu.lazyUpdate = false;
NetworkDetails._params.lazyEmpty = false;
let wait = waitForNetworkEvents(monitor, 0, 1);
yield ContentTask.spawn(tab.linkedBrowser, {}, function* () {
@ -26,48 +25,39 @@ add_task(function* () {
});
yield wait;
let onEvent = monitor.panelWin.once(EVENTS.TAB_UPDATED);
NetMonitorView.toggleDetailsPane({ visible: true }, 2);
RequestsMenu.selectedIndex = 0;
yield onEvent;
// Wait for all tree view updated by react
wait = waitForDOM(document, "#params-tabpanel .tree-section");
EventUtils.sendMouseEvent({ type: "mousedown" },
document.getElementById("details-pane-toggle"));
EventUtils.sendMouseEvent({ type: "mousedown" },
document.querySelectorAll("#details-pane tab")[2]);
yield wait;
let tabEl = document.querySelectorAll("#event-details-pane tab")[2];
let tabpanel = document.querySelectorAll("#event-details-pane tabpanel")[2];
let tabpanel = document.querySelectorAll("#details-pane tabpanel")[2];
is(tabEl.getAttribute("selected"), "true",
"The params tab in the network details pane should be selected.");
ok(tabpanel.querySelector(".treeTable"),
"The request params doesn't have the indended visibility.");
ok(tabpanel.querySelector(".editor-mount") === null,
"The request post data doesn't have the indended visibility.");
is(tabpanel.querySelector("#request-params-box")
.hasAttribute("hidden"), false,
"The request params box doesn't have the indended visibility.");
is(tabpanel.querySelector("#request-post-data-textarea-box")
.hasAttribute("hidden"), true,
"The request post data textarea box doesn't have the indended visibility.");
is(tabpanel.querySelectorAll(".variables-view-scope").length, 1,
"There should be 1 param scopes displayed in this tabpanel.");
is(tabpanel.querySelectorAll(".variables-view-empty-notice").length, 0,
is(tabpanel.querySelectorAll(".tree-section").length, 1,
"There should be 1 tree sections displayed in this tabpanel.");
is(tabpanel.querySelectorAll(".empty-notice").length, 0,
"The empty notice should not be displayed in this tabpanel.");
let postScope = tabpanel.querySelectorAll(".variables-view-scope")[0];
is(postScope.querySelector(".name").getAttribute("value"),
is(tabpanel.querySelector(".tree-section .treeLabel").textContent,
L10N.getStr("paramsFormData"),
"The post scope doesn't have the correct title.");
"The post section doesn't have the correct title.");
is(postScope.querySelectorAll(".variables-view-variable").length, 2,
"There should be 2 param values displayed in the post scope.");
is(postScope.querySelectorAll(".variables-view-variable .name")[0]
.getAttribute("value"),
"foo", "The first query param name was incorrect.");
is(postScope.querySelectorAll(".variables-view-variable .value")[0]
.getAttribute("value"),
"\"bar\"", "The first query param value was incorrect.");
is(postScope.querySelectorAll(".variables-view-variable .name")[1]
.getAttribute("value"),
"baz", "The second query param name was incorrect.");
is(postScope.querySelectorAll(".variables-view-variable .value")[1]
.getAttribute("value"),
"\"123\"", "The second query param value was incorrect.");
let labels = tabpanel
.querySelectorAll("tr:not(.tree-section) .treeLabelCell .treeLabel");
let values = tabpanel
.querySelectorAll("tr:not(.tree-section) .treeValueCell .objectBox");
is(labels[0].textContent, "foo", "The first query param name was incorrect.");
is(values[0].textContent, "\"bar\"", "The first query param value was incorrect.");
is(labels[1].textContent, "baz", "The second query param name was incorrect.");
is(values[1].textContent, "\"123\"", "The second query param value was incorrect.");
return teardown(monitor);
});

Просмотреть файл

@ -14,7 +14,7 @@ add_task(function* () {
let { tab, monitor } = yield initNetMonitor(POST_RAW_WITH_HEADERS_URL);
info("Starting test... ");
let { document, EVENTS, NetMonitorView } = monitor.panelWin;
let { document, NetMonitorView } = monitor.panelWin;
let { RequestsMenu } = NetMonitorView;
RequestsMenu.lazyUpdate = false;
@ -25,10 +25,13 @@ add_task(function* () {
});
yield wait;
let onEvent = monitor.panelWin.once(EVENTS.TAB_UPDATED);
NetMonitorView.toggleDetailsPane({ visible: true });
RequestsMenu.selectedIndex = 0;
yield onEvent;
// Wait for all tree view updated by react
wait = waitForDOM(document, "#headers-tabpanel .variables-view-scope", 3);
EventUtils.sendMouseEvent({ type: "mousedown" },
document.getElementById("details-pane-toggle"));
EventUtils.sendMouseEvent({ type: "mousedown" },
document.querySelectorAll("#details-pane tab")[0]);
yield wait;
let tabEl = document.querySelectorAll("#details-pane tab")[0];
let tabpanel = document.querySelectorAll("#details-pane tabpanel")[0];
@ -60,39 +63,32 @@ add_task(function* () {
.getAttribute("value"),
"\"hello world!\"", "The second request header value was incorrect.");
onEvent = monitor.panelWin.once(EVENTS.TAB_UPDATED);
// Wait for all tree sections updated by react
wait = waitForDOM(document, "#params-tabpanel .tree-section");
EventUtils.sendMouseEvent({ type: "mousedown" },
document.querySelectorAll("#details-pane tab")[2]);
yield onEvent;
yield wait;
tabEl = document.querySelectorAll("#details-pane tab")[2];
tabpanel = document.querySelectorAll("#details-pane tabpanel")[2];
let formDataScope = tabpanel.querySelectorAll(".variables-view-scope")[0];
is(tab.getAttribute("selected"), "true",
"The response tab in the network details pane should be selected.");
is(tabpanel.querySelectorAll(".variables-view-scope").length, 1,
"There should be 1 header scope displayed in this tabpanel.");
ok(tabpanel.querySelector(".treeTable"),
"The params tree view should be displayed.");
ok(tabpanel.querySelector(".editor-mount") === null,
"The post data shouldn't be displayed.");
is(formDataScope.querySelector(".name").getAttribute("value"),
is(tabpanel.querySelector(".tree-section .treeLabel").textContent,
L10N.getStr("paramsFormData"),
"The form data scope doesn't have the correct title.");
"The form data section doesn't have the correct title.");
is(formDataScope.querySelectorAll(".variables-view-variable").length, 2,
"There should be 2 payload values displayed in the form data scope.");
let labels = tabpanel
.querySelectorAll("tr:not(.tree-section) .treeLabelCell .treeLabel");
let values = tabpanel
.querySelectorAll("tr:not(.tree-section) .treeValueCell .objectBox");
is(formDataScope.querySelectorAll(".variables-view-variable .name")[0]
.getAttribute("value"),
"foo", "The first payload param name was incorrect.");
is(formDataScope.querySelectorAll(".variables-view-variable .value")[0]
.getAttribute("value"),
"\"bar\"", "The first payload param value was incorrect.");
is(formDataScope.querySelectorAll(".variables-view-variable .name")[1]
.getAttribute("value"),
"baz", "The second payload param name was incorrect.");
is(formDataScope.querySelectorAll(".variables-view-variable .value")[1]
.getAttribute("value"),
"\"123\"", "The second payload param value was incorrect.");
is(labels[0].textContent, "foo", "The first payload param name was incorrect.");
is(values[0].textContent, "\"bar\"", "The first payload param value was incorrect.");
is(labels[1].textContent, "baz", "The second payload param name was incorrect.");
is(values[1].textContent, "\"123\"", "The second payload param value was incorrect.");
return teardown(monitor);
});

Просмотреть файл

@ -14,11 +14,10 @@ add_task(function* () {
let { tab, monitor } = yield initNetMonitor(POST_JSON_URL);
info("Starting test... ");
let { document, EVENTS, NetMonitorView } = monitor.panelWin;
let { RequestsMenu, NetworkDetails } = NetMonitorView;
let { document, NetMonitorView } = monitor.panelWin;
let { RequestsMenu } = NetMonitorView;
RequestsMenu.lazyUpdate = false;
NetworkDetails._params.lazyEmpty = false;
let wait = waitForNetworkEvents(monitor, 0, 1);
yield ContentTask.spawn(tab.linkedBrowser, {}, function* () {
@ -26,49 +25,37 @@ add_task(function* () {
});
yield wait;
let onEvent = monitor.panelWin.once(EVENTS.TAB_UPDATED);
NetMonitorView.toggleDetailsPane({ visible: true }, 2);
RequestsMenu.selectedIndex = 0;
yield onEvent;
// Wait for all tree view updated by react
wait = waitForDOM(document, "#params-tabpanel .tree-section");
EventUtils.sendMouseEvent({ type: "mousedown" },
document.getElementById("details-pane-toggle"));
EventUtils.sendMouseEvent({ type: "mousedown" },
document.querySelectorAll("#details-pane tab")[2]);
yield wait;
let tabEl = document.querySelectorAll("#event-details-pane tab")[2];
let tabpanel = document.querySelectorAll("#event-details-pane tabpanel")[2];
is(tabEl.getAttribute("selected"), "true",
"The params tab in the network details pane should be selected.");
ok(tabpanel.querySelector(".treeTable"),
"The request params doesn't have the indended visibility.");
ok(tabpanel.querySelector(".editor-mount") === null,
"The request post data doesn't have the indended visibility.");
is(tabpanel.querySelector("#request-params-box")
.hasAttribute("hidden"), false,
"The request params box doesn't have the intended visibility.");
is(tabpanel.querySelector("#request-post-data-textarea-box")
.hasAttribute("hidden"), true,
"The request post data textarea box doesn't have the intended visibility.");
is(tabpanel.querySelectorAll(".variables-view-scope").length, 1,
"There should be 1 param scopes displayed in this tabpanel.");
is(tabpanel.querySelectorAll(".variables-view-empty-notice").length, 0,
is(tabpanel.querySelectorAll(".tree-section").length, 1,
"There should be 1 tree sections displayed in this tabpanel.");
is(tabpanel.querySelectorAll(".empty-notice").length, 0,
"The empty notice should not be displayed in this tabpanel.");
let jsonScope = tabpanel.querySelectorAll(".variables-view-scope")[0];
is(jsonScope.querySelector(".name").getAttribute("value"),
is(tabpanel.querySelector(".tree-section .treeLabel").textContent,
L10N.getStr("jsonScopeName"),
"The JSON scope doesn't have the correct title.");
"The JSON section doesn't have the correct title.");
let valueScope = tabpanel.querySelector(
".variables-view-scope > .variables-view-element-details");
let labels = tabpanel
.querySelectorAll("tr:not(.tree-section) .treeLabelCell .treeLabel");
let values = tabpanel
.querySelectorAll("tr:not(.tree-section) .treeValueCell .objectBox");
is(valueScope.querySelectorAll(".variables-view-variable").length, 1,
"There should be 1 value displayed in the JSON scope.");
is(valueScope.querySelector(".variables-view-property .name")
.getAttribute("value"),
"a", "The JSON var name was incorrect.");
is(valueScope.querySelector(".variables-view-property .value")
.getAttribute("value"),
"1", "The JSON var value was incorrect.");
let detailsParent = valueScope.querySelector(".variables-view-property .name")
.closest(".variables-view-element-details");
is(detailsParent.hasAttribute("open"), true, "The JSON value must be visible");
is(labels[0].textContent, "a", "The JSON var name was incorrect.");
is(values[0].textContent, "1", "The JSON var value was incorrect.");
return teardown(monitor);
});

Просмотреть файл

@ -19,7 +19,6 @@ add_task(function* () {
let requestItems = [];
RequestsMenu.lazyUpdate = false;
NetworkDetails._params.lazyEmpty = false;
const REQUEST_DATA = [
{
@ -173,33 +172,32 @@ add_task(function* () {
let tabpanel = document.querySelectorAll("#details-pane tabpanel")[2];
let statusParamValue = data.uri.split("=").pop();
let statusParamShownValue = "\"" + statusParamValue + "\"";
let treeSections = tabpanel.querySelectorAll(".tree-section");
is(tabpanel.querySelectorAll(".variables-view-scope").length, 1,
"There should be 1 param scope displayed in this tabpanel.");
is(tabpanel.querySelectorAll(".variable-or-property").length, 1,
"There should be 1 param value displayed in this tabpanel.");
is(tabpanel.querySelectorAll(".variables-view-empty-notice").length, 0,
is(treeSections.length, 1,
"There should be 1 param section displayed in this tabpanel.");
is(tabpanel.querySelectorAll("tr:not(.tree-section).treeRow").length, 1,
"There should be 1 param row displayed in this tabpanel.");
is(tabpanel.querySelectorAll(".empty-notice").length, 0,
"The empty notice should not be displayed in this tabpanel.");
let paramsScope = tabpanel.querySelectorAll(".variables-view-scope")[0];
let labels = tabpanel
.querySelectorAll("tr:not(.tree-section) .treeLabelCell .treeLabel");
let values = tabpanel
.querySelectorAll("tr:not(.tree-section) .treeValueCell .objectBox");
is(paramsScope.querySelector(".name").getAttribute("value"),
is(treeSections[0].querySelector(".treeLabel").textContent,
L10N.getStr("paramsQueryString"),
"The params scope doesn't have the correct title.");
is(paramsScope.querySelectorAll(".variables-view-variable .name")[0]
.getAttribute("value"),
"sts", "The param name was incorrect.");
is(paramsScope.querySelectorAll(".variables-view-variable .value")[0]
.getAttribute("value"),
statusParamShownValue, "The param value was incorrect.");
is(labels[0].textContent, "sts", "The param name was incorrect.");
is(values[0].textContent, statusParamShownValue, "The param value was incorrect.");
is(tabpanel.querySelector("#request-params-box")
.hasAttribute("hidden"), false,
"The request params box should not be hidden.");
is(tabpanel.querySelector("#request-post-data-textarea-box")
.hasAttribute("hidden"), true,
"The request post data textarea box should be hidden.");
ok(tabpanel.querySelector(".treeTable"),
"The request params tree view should be displayed.");
is(tabpanel.querySelector(".editor-mount") === null,
true,
"The request post data editor should be hidden.");
}
/**

Просмотреть файл

@ -1108,7 +1108,6 @@
background: none;
color: inherit;
width: 100%;
margin-inline-end: 2px;
}
.treeTable .textbox-input:focus {
@ -1116,10 +1115,6 @@
box-shadow: var(--theme-focus-box-shadow-textbox);
}
.treeTable .treeLabel {
font-weight: 600;
}
.properties-view {
/* FIXME: Minus 24px * 2 for toolbox height + panel height
* Give a fixed panel container height in order to force tree view scrollable */
@ -1162,6 +1157,11 @@
background-color: var(--theme-toolbar-background);
}
.properties-view .devtools-searchbox,
.tree-container .treeTable tr:not(:last-child) td:not([class=""]) {
border-bottom: 1px solid var(--theme-splitter-color);
}
.tree-container .treeTable .tree-section > * {
vertical-align: middle;
}
@ -1181,6 +1181,11 @@
white-space: nowrap;
}
.empty-notice {
color: var(--theme-body-color-alt);
padding: 3px 8px;
}
.editor-container,
.editor-mount,
.editor-mount iframe {
@ -1193,6 +1198,7 @@
* FIXME: normal html block element cannot fill outer XUL element
* This workaround should be removed after netmonitor is migrated to react
*/
#react-params-tabpanel-hook,
#react-preview-tabpanel-hook,
#react-security-tabpanel-hook,
#react-timings-tabpanel-hook,
@ -1204,6 +1210,7 @@
}
/* For vbox */
#react-params-tabpanel-hook,
#react-preview-tabpanel-hook,
#react-security-tabpanel-hook,
#react-timings-tabpanel-hook,