diff --git a/devtools/client/framework/toolbox.js b/devtools/client/framework/toolbox.js index fc492cc4c5fa..d46e6ac708ca 100644 --- a/devtools/client/framework/toolbox.js +++ b/devtools/client/framework/toolbox.js @@ -3496,20 +3496,23 @@ Toolbox.prototype = { }, inspectObjectActor: async function(objectActor, inspectFromAnnotation) { + const objectGrip = + objectActor && objectActor.getGrip ? objectActor.getGrip() : objectActor; + if ( this.currentToolId != "inspector" && - objectActor.preview && - objectActor.preview.nodeType === domNodeConstants.ELEMENT_NODE + objectGrip.preview && + objectGrip.preview.nodeType === domNodeConstants.ELEMENT_NODE ) { - return this.viewElementInInspector(objectActor, inspectFromAnnotation); + return this.viewElementInInspector(objectGrip, inspectFromAnnotation); } - if (objectActor.class == "Function") { - const { url, line } = objectActor.location; + if (objectGrip.class == "Function") { + const { url, line } = objectGrip.location; return this.viewSourceInDebugger(url, line); } - if (objectActor.type !== "null" && objectActor.type !== "undefined") { + if (objectGrip.type !== "null" && objectGrip.type !== "undefined") { // Open then split console and inspect the object in the variables view, // when the objectActor doesn't represent an undefined or null value. if (this.currentToolId != "webconsole") { diff --git a/devtools/client/webconsole/actions/messages.js b/devtools/client/webconsole/actions/messages.js index 4ea49cc44002..5d0c384caa35 100644 --- a/devtools/client/webconsole/actions/messages.js +++ b/devtools/client/webconsole/actions/messages.js @@ -119,16 +119,19 @@ function messageGetMatchingElements(id, cssSelectors) { }; } -function messageGetTableData(id, grip, dataType) { - return async ({ dispatch, client }) => { +function messageGetTableData(id, front, dataType) { + return async ({ dispatch }) => { const needEntries = ["Map", "WeakMap", "Set", "WeakSet"].includes(dataType); - const enumIndexedPropertiesOnly = getArrayTypeNames().includes(dataType); + const ignoreNonIndexedProperties = getArrayTypeNames().includes(dataType); - const results = await (needEntries - ? client.fetchObjectEntries(grip) - : client.fetchObjectProperties(grip, enumIndexedPropertiesOnly)); + const iteratorFront = await (needEntries + ? front.enumEntries() + : front.enumProperties({ + ignoreNonIndexedProperties, + })); - dispatch(messageUpdatePayload(id, results)); + const { ownProperties } = await iteratorFront.all(); + dispatch(messageUpdatePayload(id, ownProperties)); }; } diff --git a/devtools/client/webconsole/actions/ui.js b/devtools/client/webconsole/actions/ui.js index db6aa594c9f4..96cd32a14314 100644 --- a/devtools/client/webconsole/actions/ui.js +++ b/devtools/client/webconsole/actions/ui.js @@ -140,15 +140,15 @@ function setEditorWidth(width) { * Dispatches a SHOW_OBJECT_IN_SIDEBAR action, with a grip property corresponding to the * {actor} parameter in the {messageId} message. * - * @param {String} actor: Actor id of the object we want to place in the sidebar. + * @param {String} actorID: Actor id of the object we want to place in the sidebar. * @param {String} messageId: id of the message containing the {actor} parameter. */ -function showMessageObjectInSidebar(actor, messageId) { +function showMessageObjectInSidebar(actorID, messageId) { return ({ dispatch, getState }) => { const { parameters } = getMessage(getState(), messageId); if (Array.isArray(parameters)) { for (const parameter of parameters) { - if (parameter.actor === actor) { + if (parameter && parameter.actorID === actorID) { dispatch(showObjectInSidebar(parameter)); return; } @@ -157,10 +157,10 @@ function showMessageObjectInSidebar(actor, messageId) { }; } -function showObjectInSidebar(grip) { +function showObjectInSidebar(front) { return { type: SHOW_OBJECT_IN_SIDEBAR, - grip, + front, }; } diff --git a/devtools/client/webconsole/commands.js b/devtools/client/webconsole/commands.js index 5e294bc83761..54ffff499609 100644 --- a/devtools/client/webconsole/commands.js +++ b/devtools/client/webconsole/commands.js @@ -4,8 +4,6 @@ "use strict"; -const { ObjectFront } = require("devtools/shared/fronts/object"); - class ConsoleCommands { constructor({ debuggerClient, proxy, threadFront, currentTarget }) { this.debuggerClient = debuggerClient; @@ -32,44 +30,6 @@ class ConsoleCommands { return front.evaluateJSAsync(expression, options); } - createObjectFront(object) { - return new ObjectFront(this.debuggerClient, object); - } - - createLongStringFront(object) { - return this.proxy.webConsoleFront.longString(object); - } - - releaseActor(actor) { - if (!actor) { - return null; - } - - const objFront = this.debuggerClient.getFrontByID(actor); - if (objFront) { - return objFront.release(); - } - - // In case there's no object front, use the client's release method. - return this.debuggerClient.release(actor).catch(() => {}); - } - - async fetchObjectProperties(grip, ignoreNonIndexedProperties) { - const client = new ObjectFront(this.currentTarget.client, grip); - const iterator = await client.enumProperties({ - ignoreNonIndexedProperties, - }); - const { ownProperties } = await iterator.slice(0, iterator.count); - return ownProperties; - } - - async fetchObjectEntries(grip) { - const client = new ObjectFront(this.currentTarget.client, grip); - const iterator = await client.enumEntries(); - const { ownProperties } = await iterator.slice(0, iterator.count); - return ownProperties; - } - timeWarp(executionPoint) { return this.threadFront.timeWarp(executionPoint); } diff --git a/devtools/client/webconsole/components/Output/ConsoleTable.js b/devtools/client/webconsole/components/Output/ConsoleTable.js index 1a1d3a20bca9..7a0515cb1c34 100644 --- a/devtools/client/webconsole/components/Output/ConsoleTable.js +++ b/devtools/client/webconsole/components/Output/ConsoleTable.js @@ -54,9 +54,18 @@ class ConsoleTable extends Component { componentWillMount() { const { id, dispatch, parameters, tableData } = this.props; - const data = tableData || (parameters[0] && parameters[0].ownProperties); + const firstParam = Array.isArray(parameters) && parameters[0]; + if (!firstParam) { + return; + } - if (!Array.isArray(parameters) || parameters.length === 0 || data) { + const data = + tableData || + (firstParam.getGrip + ? firstParam.getGrip().ownProperties + : firstParam.ownProperties); + + if (data) { return; } @@ -125,7 +134,8 @@ class ConsoleTable extends Component { render() { const { parameters, tableData } = this.props; - const [valueGrip, headersGrip] = parameters; + const { valueGrip, headersGrip } = getValueAndHeadersGrip(parameters); + const headers = headersGrip && headersGrip.preview ? headersGrip.preview.items : null; @@ -163,11 +173,30 @@ class ConsoleTable extends Component { } } +function getValueAndHeadersGrip(parameters) { + const [valueFront, headersFront] = parameters; + + const headersGrip = + headersFront && headersFront.getGrip + ? headersFront.getGrip() + : headersFront; + + const valueGrip = + valueFront && valueFront.getGrip ? valueFront.getGrip() : valueFront; + + return { valueGrip, headersGrip }; +} + function getParametersDataType(parameters = null) { if (!Array.isArray(parameters) || parameters.length === 0) { return null; } - return parameters[0].class; + const [firstParam] = parameters; + if (!firstParam || !firstParam.getGrip) { + return null; + } + const grip = firstParam.getGrip(); + return grip.class; } const INDEX_NAME = "_index"; @@ -232,19 +261,23 @@ function getTableItems(data = {}, type, headers = null) { }; const propertyValue = getDescriptorValue(property); + const propertyValueGrip = + propertyValue && propertyValue.getGrip + ? propertyValue.getGrip() + : propertyValue; - if (propertyValue && propertyValue.ownProperties) { - const entries = propertyValue.ownProperties; + if (propertyValueGrip && propertyValueGrip.ownProperties) { + const entries = propertyValueGrip.ownProperties; for (const [key, entry] of Object.entries(entries)) { item[key] = getDescriptorValue(entry); } } else if ( - propertyValue && - propertyValue.preview && + propertyValueGrip && + propertyValueGrip.preview && (type === "Map" || type === "WeakMap") ) { - item.key = propertyValue.preview.key; - item[VALUE_NAME] = propertyValue.preview.value; + item.key = propertyValueGrip.preview.key; + item[VALUE_NAME] = propertyValueGrip.preview.value; } else { item[VALUE_NAME] = propertyValue; } @@ -324,9 +357,11 @@ function deprecatedGetTableItems(data = {}, type, headers = null) { }; const property = data[index] ? data[index].value : undefined; + const propertyGrip = + property && property.getGrip ? property.getGrip() : property; - if (property && property.preview) { - const { preview } = property; + if (propertyGrip && propertyGrip.preview) { + const { preview } = propertyGrip; const entries = preview.ownProperties || preview.items; if (entries) { for (const [key, entry] of Object.entries(entries)) { diff --git a/devtools/client/webconsole/components/Output/GripMessageBody.js b/devtools/client/webconsole/components/Output/GripMessageBody.js index 25f2e1cd5d0d..798674c7fae8 100644 --- a/devtools/client/webconsole/components/Output/GripMessageBody.js +++ b/devtools/client/webconsole/components/Output/GripMessageBody.js @@ -72,14 +72,18 @@ function GripMessageBody(props) { mode, maybeScrollToBottom, onCmdCtrlClick: (node, { depth, event, focused, expanded }) => { - const value = objectInspector.utils.node.getValue(node); - if (value) { - dispatch(actions.showObjectInSidebar(value)); + const front = objectInspector.utils.node.getFront(node); + if (front) { + dispatch(actions.showObjectInSidebar(front)); } }, }; - if (typeof grip === "string" || (grip && grip.type === "longString")) { + if ( + typeof grip === "string" || + (grip && grip.type === "longString") || + (grip && grip.getGrip && grip.getGrip().type === "longString") + ) { Object.assign(objectInspectorProps, { useQuotes, transformEmptyString: true, diff --git a/devtools/client/webconsole/components/Output/Message.js b/devtools/client/webconsole/components/Output/Message.js index 717874c8a4bf..2cc4f10da2d9 100644 --- a/devtools/client/webconsole/components/Output/Message.js +++ b/devtools/client/webconsole/components/Output/Message.js @@ -264,7 +264,17 @@ class Message extends Component { className: "devtools-button", onClick: () => navigator.clipboard.writeText( - JSON.stringify(this.props.message, null, 2) + JSON.stringify( + this.props.message, + function(key, value) { + // The message can hold one or multiple fronts that we need to serialize + if (value && value.getGrip) { + return value.getGrip(); + } + return value; + }, + 2 + ) ), }, l10n.getStr( diff --git a/devtools/client/webconsole/components/Output/message-types/EvaluationResult.js b/devtools/client/webconsole/components/Output/message-types/EvaluationResult.js index 867ad155b1db..015cabdae99e 100644 --- a/devtools/client/webconsole/components/Output/message-types/EvaluationResult.js +++ b/devtools/client/webconsole/components/Output/message-types/EvaluationResult.js @@ -57,13 +57,17 @@ function EvaluationResult(props) { typeof message.messageText !== "undefined" && message.messageText !== null ) { - if (typeof message.messageText === "string") { - messageBody = message.messageText; + const messageText = + message.messageText && message.messageText.getGrip + ? message.messageText.getGrip() + : message.messageText; + if (typeof messageText === "string") { + messageBody = messageText; } else if ( - typeof message.messageText === "object" && - message.messageText.type === "longString" + typeof messageText === "object" && + messageText.type === "longString" ) { - messageBody = `${message.messageText.initial}…`; + messageBody = `${messageText.initial}…`; } } else { messageBody = GripMessageBody({ diff --git a/devtools/client/webconsole/components/SideBar.js b/devtools/client/webconsole/components/SideBar.js index 26ae2386a999..c87a5b59e8c9 100644 --- a/devtools/client/webconsole/components/SideBar.js +++ b/devtools/client/webconsole/components/SideBar.js @@ -50,7 +50,7 @@ class SideBar extends Component { return { serviceContainer: PropTypes.object, dispatch: PropTypes.func.isRequired, - grip: PropTypes.object, + front: PropTypes.object, onResized: PropTypes.func, }; } @@ -61,8 +61,8 @@ class SideBar extends Component { } shouldComponentUpdate(nextProps) { - const { grip } = nextProps; - return grip !== this.props.grip; + const { front } = nextProps; + return front !== this.props.front; } onClickSidebarClose() { @@ -70,9 +70,9 @@ class SideBar extends Component { } render() { - const { grip, serviceContainer } = this.props; + const { front, serviceContainer } = this.props; - const objectInspector = getObjectInspector(grip, serviceContainer, { + const objectInspector = getObjectInspector(front, serviceContainer, { autoExpandDepth: 1, mode: reps.MODE.SHORT, autoFocusRoot: true, @@ -118,7 +118,7 @@ class SideBar extends Component { function mapStateToProps(state, props) { return { - grip: state.ui.gripInSidebar, + front: state.ui.frontInSidebar, }; } diff --git a/devtools/client/webconsole/constants.js b/devtools/client/webconsole/constants.js index 95863fbb0763..a9344badfbad 100644 --- a/devtools/client/webconsole/constants.js +++ b/devtools/client/webconsole/constants.js @@ -32,7 +32,7 @@ const actionTypes = { PERSIST_TOGGLE: "PERSIST_TOGGLE", PRIVATE_MESSAGES_CLEAR: "PRIVATE_MESSAGES_CLEAR", REMOVE_NOTIFICATION: "REMOVE_NOTIFICATION", - REMOVED_ACTORS_CLEAR: "REMOVED_ACTORS_CLEAR", + FRONTS_TO_RELEASE_CLEAR: "FRONTS_TO_RELEASE_CLEAR", REVERSE_SEARCH_INPUT_TOGGLE: "REVERSE_SEARCH_INPUT_TOGGLE", SELECT_NETWORK_MESSAGE_TAB: "SELECT_NETWORK_MESSAGE_TAB", SHOW_OBJECT_IN_SIDEBAR: "SHOW_OBJECT_IN_SIDEBAR", diff --git a/devtools/client/webconsole/enhancers/actor-releaser.js b/devtools/client/webconsole/enhancers/actor-releaser.js index 84061735d7e4..522d23e775e4 100644 --- a/devtools/client/webconsole/enhancers/actor-releaser.js +++ b/devtools/client/webconsole/enhancers/actor-releaser.js @@ -9,7 +9,7 @@ const { MESSAGES_CLEAR, PRIVATE_MESSAGES_CLEAR, MESSAGES_CLEAR_LOGPOINT, - REMOVED_ACTORS_CLEAR, + FRONTS_TO_RELEASE_CLEAR, } = require("devtools/client/webconsole/constants"); /** @@ -32,13 +32,26 @@ function enableActorReleaser(webConsoleUI) { MESSAGES_CLEAR_LOGPOINT, ].includes(type) ) { - state.messages.removedActors.forEach(actor => - webConsoleUI.releaseActor(actor) - ); + const promises = []; + state.messages.frontsToRelease.forEach(front => { + // We only release the front if it actually has a release method, + // and if it's not in the sidebar (where we might still need it). + if ( + front && + typeof front.release === "function" && + (!state.ui.frontInSidebar || + state.ui.frontInSidebar.actorID !== front.actorID) + ) { + promises.push(front.release()); + } + }); - // Reset `removedActors` in message reducer. + // Emit an event we can listen to to make sure all the fronts were released. + Promise.all(promises).then(() => webConsoleUI.emit("fronts-released")); + + // Reset `frontsToRelease` in message reducer. state = reducer(state, { - type: REMOVED_ACTORS_CLEAR, + type: FRONTS_TO_RELEASE_CLEAR, }); } diff --git a/devtools/client/webconsole/reducers/messages.js b/devtools/client/webconsole/reducers/messages.js index 75a2a667839e..2aee0f9d6ea4 100644 --- a/devtools/client/webconsole/reducers/messages.js +++ b/devtools/client/webconsole/reducers/messages.js @@ -101,10 +101,9 @@ const MessageState = overrides => currentGroup: null, // This group handles "warning groups" (Content Blocking, CORS, CSP, …) warningGroupsById: new Map(), - // Array of removed actors (i.e. actors logged in removed messages) we keep track of - // in order to properly release them. - // This array is not supposed to be consumed by any UI component. - removedActors: [], + // Array of fronts to release (i.e. fronts logged in removed messages). + // This array *should not* be consumed by any UI component. + frontsToRelease: [], // Map of the form {messageId : numberOfRepeat} repeatById: {}, // Map of the form {messageId : networkInformation} @@ -130,7 +129,7 @@ function cloneState(state) { messagesPayloadById: new Map(state.messagesPayloadById), groupsById: new Map(state.groupsById), currentGroup: state.currentGroup, - removedActors: [...state.removedActors], + frontsToRelease: [...state.frontsToRelease], repeatById: { ...state.repeatById }, networkMessagesUpdateById: { ...state.networkMessagesUpdateById }, removedLogpointIds: new Set(state.removedLogpointIds), @@ -439,8 +438,8 @@ function messages( return MessageState({ // Store all actors from removed messages. This array is used by // `releaseActorsEnhancer` to release all of those backend actors. - removedActors: [...state.messagesById.values()].reduce((res, msg) => { - res.push(...getAllActorsInMessage(msg)); + frontsToRelease: [...state.messagesById.values()].reduce((res, msg) => { + res.push(...getAllFrontsInMessage(msg)); return res; }, []), }); @@ -617,10 +616,10 @@ function messages( }; } - case constants.REMOVED_ACTORS_CLEAR: + case constants.FRONTS_TO_RELEASE_CLEAR: return { ...state, - removedActors: [], + frontsToRelease: [], }; case constants.WARNING_GROUPS_TOGGLE: @@ -856,7 +855,7 @@ function removeMessagesFromState(state, removedMessagesIds) { return state; } - const removedActors = []; + const frontsToRelease = []; const visibleMessages = [...state.visibleMessages]; removedMessagesIds.forEach(id => { const index = visibleMessages.indexOf(id); @@ -864,15 +863,15 @@ function removeMessagesFromState(state, removedMessagesIds) { visibleMessages.splice(index, 1); } - removedActors.push(...getAllActorsInMessage(state.messagesById.get(id))); + frontsToRelease.push(...getAllFrontsInMessage(state.messagesById.get(id))); }); if (state.visibleMessages.length > visibleMessages.length) { state.visibleMessages = visibleMessages; } - if (removedActors.length > 0) { - state.removedActors = state.removedActors.concat(removedActors); + if (frontsToRelease.length > 0) { + state.frontsToRelease = state.frontsToRelease.concat(frontsToRelease); } const isInRemovedId = id => removedMessagesIds.includes(id); @@ -933,28 +932,31 @@ function removeMessagesFromState(state, removedMessagesIds) { } /** - * Get an array of all the actors logged in a specific message. + * Get an array of all the fronts logged in a specific message. * * @param {Message} message: The message to get actors from. - * @return {Array} An array containing all the actors logged in a message. + * @return {Array} An array containing all the fronts logged + * in a message. */ -function getAllActorsInMessage(message) { +function getAllFrontsInMessage(message) { const { parameters, messageText } = message; - const actors = []; + const fronts = []; + const isFront = p => p && typeof p.release === "function"; + if (Array.isArray(parameters)) { message.parameters.forEach(parameter => { - if (parameter && parameter.actor) { - actors.push(parameter.actor); + if (isFront(parameter)) { + fronts.push(parameter); } }); } - if (messageText && messageText.actor) { - actors.push(messageText.actor); + if (isFront(messageText)) { + fronts.push(messageText); } - return actors; + return fronts; } /** @@ -1351,27 +1353,30 @@ function isTextInParameter(text, regex, parameter) { const matchStr = str => regex ? regex.test(str) : str.toLocaleLowerCase().includes(text); - if (parameter && parameter.class && matchStr(parameter.class)) { + const paramGrip = + parameter && parameter.getGrip ? parameter.getGrip() : parameter; + + if (paramGrip && paramGrip.class && matchStr(paramGrip.class)) { return true; } const parameterType = typeof parameter; if (parameterType !== "object" && parameterType !== "undefined") { - const str = parameter + ""; + const str = paramGrip + ""; if (matchStr(str)) { return true; } } - const previewItems = getGripPreviewItems(parameter); + const previewItems = getGripPreviewItems(paramGrip); for (const item of previewItems) { if (isTextInParameter(text, regex, item)) { return true; } } - if (parameter && parameter.ownProperties) { - for (const [key, desc] of Object.entries(parameter.ownProperties)) { + if (paramGrip && paramGrip.ownProperties) { + for (const [key, desc] of Object.entries(paramGrip.ownProperties)) { if (matchStr(key)) { return true; } @@ -1436,10 +1441,12 @@ function isTextInMessageText(text, regex, messageText) { : messageText.toLocaleLowerCase().includes(text); } - if (messageText.type === "longString") { + const grip = + messageText && messageText.getGrip ? messageText.getGrip() : messageText; + if (grip && grip.type === "longString") { return regex - ? regex.test(messageText.initial) - : messageText.initial.toLocaleLowerCase().includes(text); + ? regex.test(grip.initial) + : grip.initial.toLocaleLowerCase().includes(text); } return true; diff --git a/devtools/client/webconsole/reducers/ui.js b/devtools/client/webconsole/reducers/ui.js index 18a944fa06ea..fd559af20188 100644 --- a/devtools/client/webconsole/reducers/ui.js +++ b/devtools/client/webconsole/reducers/ui.js @@ -33,7 +33,7 @@ const UiState = overrides => showContentMessages: false, sidebarVisible: false, timestampsVisible: true, - gripInSidebar: null, + frontInSidebar: null, closeButtonVisible: false, reverseSearchInputVisible: false, reverseSearchInitialValue: "", @@ -60,17 +60,17 @@ function ui(state = UiState(), action) { return { ...state, sidebarVisible: false, - gripInSidebar: null, + frontInSidebar: null, }; case INITIALIZE: return { ...state, initialized: true }; case MESSAGES_CLEAR: - return { ...state, sidebarVisible: false, gripInSidebar: null }; + return { ...state, sidebarVisible: false, frontInSidebar: null }; case SHOW_OBJECT_IN_SIDEBAR: - if (action.grip === state.gripInSidebar) { + if (action.front === state.frontInSidebar) { return state; } - return { ...state, sidebarVisible: true, gripInSidebar: action.grip }; + return { ...state, sidebarVisible: true, frontInSidebar: action.front }; case SPLIT_CONSOLE_CLOSE_BUTTON_TOGGLE: return { ...state, closeButtonVisible: action.shouldDisplayButton }; case REVERSE_SEARCH_INPUT_TOGGLE: diff --git a/devtools/client/webconsole/test/browser/browser_console_cpow.js b/devtools/client/webconsole/test/browser/browser_console_cpow.js index d1682d740a0c..83a1b3fbf8b1 100644 --- a/devtools/client/webconsole/test/browser/browser_console_cpow.js +++ b/devtools/client/webconsole/test/browser/browser_console_cpow.js @@ -5,8 +5,6 @@ "use strict"; -const { ObjectFront } = require("devtools/shared/fronts/object"); - const { gDevToolsBrowser, } = require("devtools/client/framework/devtools-browser"); @@ -19,9 +17,10 @@ add_task(async function() { const hud = await BrowserConsoleManager.openBrowserConsoleOrFocus(); - const { message, actor } = await obtainObjectWithCPOW(hud); - await testFrontEnd(hud, message); - await testBackEnd(hud, actor); + const { message, objectFront } = await obtainObjectWithCPOW(hud); + await testFrontEnd(message); + await testBackEnd(objectFront); + await clearOutput(hud, true); }); async function obtainObjectWithCPOW(hud) { @@ -44,7 +43,7 @@ async function obtainObjectWithCPOW(hud) { info("Obtain the object with CPOW"); const message = await waitFor(() => findMessage(hud, "cpow")); const result = await hud.ui.evaluateJSAsync("result"); - const { actor } = result.result; + const objectFront = result.result; info("Cleanup"); await hud.ui.evaluateJSAsync("delete globalThis.result;"); @@ -52,10 +51,10 @@ async function obtainObjectWithCPOW(hud) { toolbox.topWindow.close(); await onToolboxDestroyed; - return { message, actor }; + return { message, objectFront }; } -async function testFrontEnd(hud, message) { +async function testFrontEnd(message) { const oi = message.querySelector(".tree"); const node = oi.querySelector(".tree-node"); is(node.textContent, "Object { cpow: CPOW }", "Got an object with a CPOW"); @@ -71,26 +70,22 @@ async function testFrontEnd(hud, message) { is(getObjectInspectorChildrenNodes(cpow).length, 0, "CPOW has no children"); } -async function testBackEnd(hud, actor) { +async function testBackEnd(objectFront) { // Check that inspecting an object with CPOW 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. - info("Creating an ObjectFront with: " + actor); - const objectFront = new ObjectFront(hud.ui.proxy.client, { actor }); // Before the fix for Bug 1382833, this wouldn't resolve due to a CPOW error // in the ObjectActor. const prototypeAndProperties = await objectFront.getPrototypeAndProperties(); // The CPOW is in the "cpow" property. - const cpow = prototypeAndProperties.ownProperties.cpow.value; + const cpowFront = prototypeAndProperties.ownProperties.cpow.value; - is(cpow.class, "CPOW", "The CPOW grip has the right class."); + is(cpowFront.getGrip().class, "CPOW", "The CPOW grip has the right class."); // Check that various protocol request methods work for the CPOW. - const objClient = new ObjectFront(hud.ui.proxy.client, cpow); - - let response = await objClient.getPrototypeAndProperties(); + let response = await cpowFront.getPrototypeAndProperties(); is( Reflect.ownKeys(response.ownProperties).length, 0, @@ -99,7 +94,7 @@ async function testBackEnd(hud, actor) { is(response.ownSymbols.length, 0, "No symbol property was retrieved."); is(response.prototype.type, "null", "The prototype is null."); - response = await objClient.enumProperties({ ignoreIndexedProperties: true }); + response = await cpowFront.enumProperties({ ignoreIndexedProperties: true }); let slice = await response.slice(0, response.count); is( Reflect.ownKeys(slice.ownProperties).length, @@ -107,7 +102,7 @@ async function testBackEnd(hud, actor) { "No property was retrieved." ); - response = await objClient.enumProperties({}); + response = await cpowFront.enumProperties({}); slice = await response.slice(0, response.count); is( Reflect.ownKeys(slice.ownProperties).length, @@ -115,20 +110,20 @@ async function testBackEnd(hud, actor) { "No property was retrieved." ); - response = await objClient.getOwnPropertyNames(); + response = await cpowFront.getOwnPropertyNames(); is(response.ownPropertyNames.length, 0, "No property was retrieved."); - response = await objClient.getProperty("x"); + response = await cpowFront.getProperty("x"); is(response.descriptor, undefined, "The property does not exist."); - response = await objClient.enumSymbols(); + response = await cpowFront.enumSymbols(); slice = await response.slice(0, response.count); is(slice.ownSymbols.length, 0, "No symbol property was retrieved."); - response = await objClient.getPrototype(); + response = await cpowFront.getPrototype(); is(response.prototype.type, "null", "The prototype is null."); - response = await objClient.getDisplayString(); + response = await cpowFront.getDisplayString(); is(response.displayString, "", "The CPOW stringifies to "); } diff --git a/devtools/client/webconsole/test/browser/browser_console_webconsole_iframe_messages.js b/devtools/client/webconsole/test/browser/browser_console_webconsole_iframe_messages.js index 8e0a527762d2..40d59f3a188b 100644 --- a/devtools/client/webconsole/test/browser/browser_console_webconsole_iframe_messages.js +++ b/devtools/client/webconsole/test/browser/browser_console_webconsole_iframe_messages.js @@ -29,7 +29,10 @@ add_task(async function() { hud = await BrowserConsoleManager.toggleBrowserConsole(); await testBrowserConsole(hud); - await closeConsole(); + + // clear and close the browser console. + await clearOutput(hud); + await BrowserConsoleManager.toggleBrowserConsole(); }); async function testMessages(hud) { diff --git a/devtools/client/webconsole/test/browser/browser_webconsole_stubs_console_api.js b/devtools/client/webconsole/test/browser/browser_webconsole_stubs_console_api.js index d48289d5caab..ae391ba40fb9 100644 --- a/devtools/client/webconsole/test/browser/browser_webconsole_stubs_console_api.js +++ b/devtools/client/webconsole/test/browser/browser_webconsole_stubs_console_api.js @@ -7,6 +7,7 @@ const { STUBS_UPDATE_ENV, getStubFilePath, getCleanedPacket, + getSerializedPacket, writeStubsToFile, } = require("devtools/client/webconsole/test/browser/stub-generator-helpers"); @@ -28,7 +29,6 @@ add_task(async function() { ok(true, `${STUB_FILE} was updated`); return; } - const existingStubs = require(getStubFilePath(STUB_FILE)); const FAILURE_MSG = "The consoleApi stubs file needs to be updated by running " + @@ -36,19 +36,18 @@ add_task(async function() { "browser_webconsole_stubs_console_api.js --headless " + "--setenv WEBCONSOLE_STUBS_UPDATE=true`"; - if (generatedStubs.size !== existingStubs.stubPackets.size) { + if (generatedStubs.size !== existingStubs.rawPackets.size) { ok(false, FAILURE_MSG); return; } let failed = false; for (const [key, packet] of generatedStubs) { - const packetStr = JSON.stringify(packet, null, 2); - const existingPacketStr = JSON.stringify( - existingStubs.stubPackets.get(key), - null, - 2 + const packetStr = getSerializedPacket(packet); + const existingPacketStr = getSerializedPacket( + existingStubs.rawPackets.get(key) ); + is(packetStr, existingPacketStr, `"${key}" packet has expected value`); failed = failed || packetStr !== existingPacketStr; } @@ -58,6 +57,8 @@ add_task(async function() { } else { ok(true, "Stubs are up to date"); } + + await closeTabAndToolbox().catch(() => {}); }); async function generateConsoleApiStubs() { @@ -100,7 +101,6 @@ async function generateConsoleApiStubs() { } Services.prefs.clearUserPref(PREFS.FILTER.LOG); - await closeTabAndToolbox().catch(() => {}); return stubs; } diff --git a/devtools/client/webconsole/test/browser/browser_webconsole_stubs_evaluation_result.js b/devtools/client/webconsole/test/browser/browser_webconsole_stubs_evaluation_result.js index ba501f5145e7..7756a8a94da1 100644 --- a/devtools/client/webconsole/test/browser/browser_webconsole_stubs_evaluation_result.js +++ b/devtools/client/webconsole/test/browser/browser_webconsole_stubs_evaluation_result.js @@ -6,6 +6,7 @@ const { STUBS_UPDATE_ENV, getCleanedPacket, + getSerializedPacket, getStubFilePath, writeStubsToFile, } = require("devtools/client/webconsole/test/browser/stub-generator-helpers"); @@ -35,18 +36,16 @@ add_task(async function() { "browser_webconsole_stubs_evaluation_result.js --headless " + "--setenv WEBCONSOLE_STUBS_UPDATE=true`"; - if (generatedStubs.size !== existingStubs.stubPackets.size) { + if (generatedStubs.size !== existingStubs.rawPackets.size) { ok(false, FAILURE_MSG); return; } let failed = false; for (const [key, packet] of generatedStubs) { - const packetStr = JSON.stringify(packet, null, 2); - const existingPacketStr = JSON.stringify( - existingStubs.stubPackets.get(key), - null, - 2 + const packetStr = getSerializedPacket(packet); + const existingPacketStr = getSerializedPacket( + existingStubs.rawPackets.get(key) ); is(packetStr, existingPacketStr, `"${key}" packet has expected value`); failed = failed || packetStr !== existingPacketStr; @@ -57,6 +56,8 @@ add_task(async function() { } else { ok(true, "Stubs are up to date"); } + + await closeTabAndToolbox(); }); async function generateEvaluationResultStubs() { @@ -68,7 +69,6 @@ async function generateEvaluationResultStubs() { stubs.set(key, getCleanedPacket(key, packet)); } - await closeTabAndToolbox(); return stubs; } diff --git a/devtools/client/webconsole/test/browser/browser_webconsole_stubs_page_error.js b/devtools/client/webconsole/test/browser/browser_webconsole_stubs_page_error.js index fbbcdeb98400..b1e17775c14a 100644 --- a/devtools/client/webconsole/test/browser/browser_webconsole_stubs_page_error.js +++ b/devtools/client/webconsole/test/browser/browser_webconsole_stubs_page_error.js @@ -6,6 +6,7 @@ const { STUBS_UPDATE_ENV, getCleanedPacket, + getSerializedPacket, getStubFilePath, writeStubsToFile, } = require("devtools/client/webconsole/test/browser/stub-generator-helpers"); @@ -36,18 +37,16 @@ add_task(async function() { "browser_webconsole_stubs_page_error.js --headless " + "--setenv WEBCONSOLE_STUBS_UPDATE=true`"; - if (generatedStubs.size !== existingStubs.stubPackets.size) { + if (generatedStubs.size !== existingStubs.rawPackets.size) { ok(false, FAILURE_MSG); return; } let failed = false; for (const [key, packet] of generatedStubs) { - const packetStr = JSON.stringify(packet, null, 2); - const existingPacketStr = JSON.stringify( - existingStubs.stubPackets.get(key), - null, - 2 + const packetStr = getSerializedPacket(packet); + const existingPacketStr = getSerializedPacket( + existingStubs.rawPackets.get(key) ); is(packetStr, existingPacketStr, `"${key}" packet has expected value`); failed = failed || packetStr !== existingPacketStr; @@ -58,6 +57,8 @@ add_task(async function() { } else { ok(true, "Stubs are up to date"); } + + await closeTabAndToolbox(); }); async function generatePageErrorStubs() { @@ -85,7 +86,6 @@ async function generatePageErrorStubs() { stubs.set(key, getCleanedPacket(key, packet)); } - await closeTabAndToolbox(); return stubs; } diff --git a/devtools/client/webconsole/test/browser/head.js b/devtools/client/webconsole/test/browser/head.js index 1f4712e9bc33..15380c1c7725 100644 --- a/devtools/client/webconsole/test/browser/head.js +++ b/devtools/client/webconsole/test/browser/head.js @@ -125,7 +125,15 @@ function logAllStoreChanges(hud) { return { id, type, parameters, messageText }; } ); - info("messages : " + JSON.stringify(debugMessages)); + info( + "messages : " + + JSON.stringify(debugMessages, function(key, value) { + if (value && value.getGrip) { + return value.getGrip(); + } + return value; + }) + ); }); } @@ -1578,13 +1586,21 @@ async function waitForLazyRequests(toolbox) { } /** - * Clear the console output and when for the "messages-cleared" event to be emitted. + * Clear the console output and wait for eventual object actors to be released. + * * @param {WebConsole} hud * @param {Object} An options object with the following properties: * - {Boolean} keepStorage: true to prevent clearing the messages storage. */ async function clearOutput(hud, { keepStorage = false } = {}) { - const onMessagesCleared = hud.ui.once("messages-cleared"); - hud.ui.clearOutput(!keepStorage); - await onMessagesCleared; + const { ui } = hud; + const promises = [ui.once("messages-cleared")]; + + // If there's an object inspector, we need to wait for the actors to be released. + if (ui.outputNode.querySelector(".object-inspector")) { + promises.push(ui.once("fronts-released")); + } + + ui.clearOutput(!keepStorage); + await Promise.all(promises); } diff --git a/devtools/client/webconsole/test/browser/stub-generator-helpers.js b/devtools/client/webconsole/test/browser/stub-generator-helpers.js index 3d29d1c13586..ca76bd3c281d 100644 --- a/devtools/client/webconsole/test/browser/stub-generator-helpers.js +++ b/devtools/client/webconsole/test/browser/stub-generator-helpers.js @@ -6,17 +6,21 @@ const ChromeUtils = require("ChromeUtils"); const { OS } = ChromeUtils.import("resource://gre/modules/osfile.jsm"); +const { + getAdHocFrontOrPrimitiveGrip, +} = require("devtools/shared/fronts/object"); + const STUBS_FOLDER = "devtools/client/webconsole/test/node/fixtures/stubs/"; const STUBS_UPDATE_ENV = "WEBCONSOLE_STUBS_UPDATE"; -const { - stubPackets, -} = require("devtools/client/webconsole/test/node/fixtures/stubs/index.js"); - const cachedPackets = {}; // eslint-disable-next-line complexity function getCleanedPacket(key, packet) { + const { + stubPackets, + } = require("devtools/client/webconsole/test/node/fixtures/stubs/index"); + if (Object.keys(cachedPackets).includes(key)) { return cachedPackets[key]; } @@ -90,17 +94,15 @@ function getCleanedPacket(key, packet) { const newArgument = Object.assign({}, argument); const existingArgument = existingPacket.message.arguments[i]; - if (existingArgument) { + if (existingArgument && newArgument._grip) { // Clean actor ids on each message.arguments item. - if (newArgument.actor) { - newArgument.actor = existingArgument.actor; - } + copyExistingActor(newArgument, existingArgument); // `window`'s properties count can vary from OS to OS, so we // clean the `ownPropertyLength` property from the grip. - if (newArgument.class === "Window") { - newArgument.ownPropertyLength = - existingArgument.ownPropertyLength; + if (newArgument._grip.class === "Window") { + newArgument._grip.ownPropertyLength = + existingArgument._grip.ownPropertyLength; } } return newArgument; @@ -122,45 +124,58 @@ function getCleanedPacket(key, packet) { } } - if (res.result && existingPacket.result) { + if (res.result && res.result._grip && existingPacket.result) { // Clean actor ids on evaluation result messages. - res.result.actor = existingPacket.result.actor; - if (res.result.preview) { - if (res.result.preview.timestamp) { + copyExistingActor(res.result, existingPacket.result); + + if (res.result._grip.preview) { + if (res.result._grip.preview.timestamp) { // Clean timestamp there too. - res.result.preview.timestamp = - existingPacket.result.preview.timestamp; + res.result._grip.preview.timestamp = + existingPacket.result._grip.preview.timestamp; } } } if (res.exception && existingPacket.exception) { // Clean actor ids on exception messages. - if (existingPacket.exception.actor) { - res.exception.actor = existingPacket.exception.actor; - } + copyExistingActor(res.exception, existingPacket.exception); - if (res.exception.preview) { - if (res.exception.preview.timestamp) { + if ( + res.exception._grip && + res.exception._grip.preview && + existingPacket.exception._grip && + existingPacket.exception._grip.preview + ) { + if (res.exception._grip.preview.timestamp) { // Clean timestamp there too. - res.exception.preview.timestamp = - existingPacket.exception.preview.timestamp; + res.exception._grip.preview.timestamp = + existingPacket.exception._grip.preview.timestamp; } if ( - typeof res.exception.preview.message === "object" && - res.exception.preview.message.type === "longString" + typeof res.exception._grip.preview.message === "object" && + res.exception._grip.preview.message._grip.type === "longString" && + typeof existingPacket.exception._grip.preview.message === "object" && + existingPacket.exception._grip.preview.message._grip.type === + "longString" ) { - res.exception.preview.message.actor = - existingPacket.exception.preview.message.actor; + copyExistingActor( + res.exception._grip.preview.message, + existingPacket.exception._grip.preview.message + ); } } if ( typeof res.exceptionMessage === "object" && - res.exceptionMessage.type === "longString" + res.exceptionMessage._grip && + res.exceptionMessage._grip.type === "longString" ) { - res.exceptionMessage.actor = existingPacket.exceptionMessage.actor; + copyExistingActor( + res.exceptionMessage, + existingPacket.exceptionMessage + ); } } @@ -179,10 +194,13 @@ function getCleanedPacket(key, packet) { if ( typeof res.pageError.errorMessage === "object" && - res.pageError.errorMessage.type === "longString" + res.pageError.errorMessage._grip && + res.pageError.errorMessage._grip.type === "longString" ) { - res.pageError.errorMessage.actor = - existingPacket.pageError.errorMessage.actor; + copyExistingActor( + res.pageError.errorMessage, + existingPacket.pageError.errorMessage + ); } if (res.pageError.sourceId) { @@ -276,10 +294,10 @@ function getCleanedPacket(key, packet) { } if (res.helperResult) { - if (res.helperResult.object) { - res.helperResult.object.actor = - existingPacket.helperResult.object.actor; - } + copyExistingActor( + res.helperResult.object, + existingPacket.helperResult.object + ); } } else { res = packet; @@ -289,6 +307,25 @@ function getCleanedPacket(key, packet) { return res; } +function copyExistingActor(front1, front2) { + if (!front1 || !front2) { + return; + } + + if (front1.actorID && front2.actorID) { + front1.actorID = front2.actorID; + } + + if ( + front1._grip && + front2._grip && + front1._grip.actor && + front2._grip.actor + ) { + front1._grip.actor = front2._grip.actor; + } +} + /** * Write stubs to a given file * @@ -298,8 +335,8 @@ function getCleanedPacket(key, packet) { async function writeStubsToFile(filePath, packets, isNetworkMessage) { const serializedPackets = Array.from(packets.entries()).map( ([key, packet]) => { - const stringifiedPacket = JSON.stringify(packet, null, 2); - return `stubPackets.set(\`${key}\`, ${stringifiedPacket});`; + const stringifiedPacket = getSerializedPacket(packet); + return `rawPackets.set(\`${key}\`, ${stringifiedPacket});`; } ); @@ -313,31 +350,32 @@ async function writeStubsToFile(filePath, packets, isNetworkMessage) { * THIS FILE IS AUTOGENERATED. DO NOT MODIFY BY HAND. RUN TESTS IN FIXTURES/ TO UPDATE. */ +const { + parsePacketsWithFronts, +} = require("devtools/client/webconsole/test/browser/stub-generator-helpers"); const { prepareMessage } = require("devtools/client/webconsole/utils/messages"); const { ConsoleMessage, NetworkEventMessage, } = require("devtools/client/webconsole/types"); -const stubPackets = new Map(); +const rawPackets = new Map(); ${serializedPackets.join("\n\n")} + +const stubPackets = parsePacketsWithFronts(rawPackets); + const stubPreparedMessages = new Map(); for (const [key, packet] of Array.from(stubPackets.entries())) { - const transformedPacket = prepareMessage(${ - isNetworkMessage ? "packet.networkInfo || packet" : "packet" - }, { + const transformedPacket = prepareMessage(packet, { getNextId: () => "1", }); - const message = ${ - isNetworkMessage - ? "NetworkEventMessage(transformedPacket);" - : "ConsoleMessage(transformedPacket);" - } + const message = ConsoleMessage(transformedPacket); stubPreparedMessages.set(key, message); } module.exports = { + rawPackets, stubPreparedMessages, stubPackets, }; @@ -351,9 +389,65 @@ function getStubFilePath(fileName, env, absolute = false) { return absolute ? `${env.get("MOZ_DEVELOPER_REPO_DIR")}/${path}` : path; } +function getSerializedPacket(packet) { + return JSON.stringify( + packet, + function(_, value) { + // The message can have fronts that we need to serialize + if (value && value._grip) { + return { _grip: value._grip, actorID: value.actorID }; + } + + return value; + }, + 2 + ); +} + +/** + * + * @param {Map} rawPackets + */ +function parsePacketsWithFronts(rawPackets) { + const packets = new Map(); + for (const [key, packet] of rawPackets.entries()) { + const newPacket = parsePacketAndCreateFronts(packet); + packets.set(key, newPacket); + } + return packets; +} + +function parsePacketAndCreateFronts(packet) { + if (!packet) { + return packet; + } + if (Array.isArray(packet)) { + packet.forEach(parsePacketAndCreateFronts); + } + if (typeof packet === "object") { + for (const [key, value] of Object.entries(packet)) { + if (value && value._grip) { + packet[key] = getAdHocFrontOrPrimitiveGrip(value._grip, { + conn: { + poolFor: () => {}, + addActorPool: () => {}, + }, + manage: () => {}, + }); + } else { + packet[key] = parsePacketAndCreateFronts(value); + } + } + } + + return packet; +} + module.exports = { STUBS_UPDATE_ENV, getStubFilePath, getCleanedPacket, + getSerializedPacket, + parsePacketsWithFronts, writeStubsToFile, }; diff --git a/devtools/client/webconsole/test/node/fixtures/stubs/consoleApi.js b/devtools/client/webconsole/test/node/fixtures/stubs/consoleApi.js index d64efe855f08..77ccec9c965c 100644 --- a/devtools/client/webconsole/test/node/fixtures/stubs/consoleApi.js +++ b/devtools/client/webconsole/test/node/fixtures/stubs/consoleApi.js @@ -8,14 +8,17 @@ * THIS FILE IS AUTOGENERATED. DO NOT MODIFY BY HAND. RUN TESTS IN FIXTURES/ TO UPDATE. */ +const { + parsePacketsWithFronts, +} = require("devtools/client/webconsole/test/browser/stub-generator-helpers"); const { prepareMessage } = require("devtools/client/webconsole/utils/messages"); const { ConsoleMessage, NetworkEventMessage, } = require("devtools/client/webconsole/types"); -const stubPackets = new Map(); -stubPackets.set(`console.log('foobar', 'test')`, { +const rawPackets = new Map(); +rawPackets.set(`console.log('foobar', 'test')`, { "message": { "addonId": "", "arguments": [ @@ -43,7 +46,7 @@ stubPackets.set(`console.log('foobar', 'test')`, { "type": "consoleAPICall" }); -stubPackets.set(`console.log(undefined)`, { +rawPackets.set(`console.log(undefined)`, { "message": { "addonId": "", "arguments": [ @@ -72,7 +75,7 @@ stubPackets.set(`console.log(undefined)`, { "type": "consoleAPICall" }); -stubPackets.set(`console.warn('danger, will robinson!')`, { +rawPackets.set(`console.warn('danger, will robinson!')`, { "message": { "addonId": "", "arguments": [ @@ -99,7 +102,7 @@ stubPackets.set(`console.warn('danger, will robinson!')`, { "type": "consoleAPICall" }); -stubPackets.set(`console.log(NaN)`, { +rawPackets.set(`console.log(NaN)`, { "message": { "addonId": "", "arguments": [ @@ -128,7 +131,7 @@ stubPackets.set(`console.log(NaN)`, { "type": "consoleAPICall" }); -stubPackets.set(`console.log(null)`, { +rawPackets.set(`console.log(null)`, { "message": { "addonId": "", "arguments": [ @@ -157,7 +160,7 @@ stubPackets.set(`console.log(null)`, { "type": "consoleAPICall" }); -stubPackets.set(`console.log('鼬')`, { +rawPackets.set(`console.log('鼬')`, { "message": { "addonId": "", "arguments": [ @@ -184,7 +187,7 @@ stubPackets.set(`console.log('鼬')`, { "type": "consoleAPICall" }); -stubPackets.set(`console.clear()`, { +rawPackets.set(`console.clear()`, { "message": { "addonId": "", "arguments": [], @@ -209,7 +212,7 @@ stubPackets.set(`console.clear()`, { "type": "consoleAPICall" }); -stubPackets.set(`console.count('bar')`, { +rawPackets.set(`console.count('bar')`, { "message": { "addonId": "", "arguments": [ @@ -239,33 +242,36 @@ stubPackets.set(`console.count('bar')`, { "type": "consoleAPICall" }); -stubPackets.set(`console.assert(false, {message: 'foobar'})`, { +rawPackets.set(`console.assert(false, {message: 'foobar'})`, { "message": { "addonId": "", "arguments": [ { - "type": "object", - "actor": "server0.conn0.child1/obj31", - "class": "Object", - "ownPropertyLength": 1, - "extensible": true, - "frozen": false, - "sealed": false, - "preview": { - "kind": "Object", - "ownProperties": { - "message": { - "configurable": true, - "enumerable": true, - "writable": true, - "value": "foobar" - } - }, - "ownSymbols": [], - "ownPropertiesLength": 1, - "ownSymbolsLength": 0, - "safeGetterValues": {} - } + "_grip": { + "type": "object", + "actor": "server0.conn0.child1/obj31", + "class": "Object", + "ownPropertyLength": 1, + "extensible": true, + "frozen": false, + "sealed": false, + "preview": { + "kind": "Object", + "ownProperties": { + "message": { + "configurable": true, + "enumerable": true, + "writable": true, + "value": "foobar" + } + }, + "ownSymbols": [], + "ownPropertiesLength": 1, + "ownSymbolsLength": 0, + "safeGetterValues": {} + } + }, + "actorID": "server0.conn0.child1/obj31" } ], "chromeContext": false, @@ -298,7 +304,7 @@ stubPackets.set(`console.assert(false, {message: 'foobar'})`, { "type": "consoleAPICall" }); -stubPackets.set(`console.log('úṇĩçödê țĕșť')`, { +rawPackets.set(`console.log('úṇĩçödê țĕșť')`, { "message": { "addonId": "", "arguments": [ @@ -325,22 +331,25 @@ stubPackets.set(`console.log('úṇĩçödê țĕșť')`, { "type": "consoleAPICall" }); -stubPackets.set(`console.dirxml(window)`, { +rawPackets.set(`console.dirxml(window)`, { "message": { "addonId": "", "arguments": [ { - "type": "object", - "actor": "server0.conn0.child1/obj34", - "class": "Window", - "ownPropertyLength": 811, - "extensible": true, - "frozen": false, - "sealed": false, - "preview": { - "kind": "ObjectWithURL", - "url": "http://example.com/browser/devtools/client/webconsole/test/browser/test-console-api.html" - } + "_grip": { + "type": "object", + "actor": "server0.conn0.child1/obj34", + "class": "Window", + "ownPropertyLength": 818, + "extensible": true, + "frozen": false, + "sealed": false, + "preview": { + "kind": "ObjectWithURL", + "url": "http://example.com/browser/devtools/client/webconsole/test/browser/test-console-api.html" + } + }, + "actorID": "server0.conn0.child1/obj34" } ], "chromeContext": false, @@ -364,28 +373,31 @@ stubPackets.set(`console.dirxml(window)`, { "type": "consoleAPICall" }); -stubPackets.set(`console.log('myarray', ['red', 'green', 'blue'])`, { +rawPackets.set(`console.log('myarray', ['red', 'green', 'blue'])`, { "message": { "addonId": "", "arguments": [ "myarray", { - "type": "object", - "actor": "server0.conn0.child1/obj36", - "class": "Array", - "ownPropertyLength": 4, - "extensible": true, - "frozen": false, - "sealed": false, - "preview": { - "kind": "ArrayLike", - "length": 3, - "items": [ - "red", - "green", - "blue" - ] - } + "_grip": { + "type": "object", + "actor": "server0.conn0.child1/obj36", + "class": "Array", + "ownPropertyLength": 4, + "extensible": true, + "frozen": false, + "sealed": false, + "preview": { + "kind": "ArrayLike", + "length": 3, + "items": [ + "red", + "green", + "blue" + ] + } + }, + "actorID": "server0.conn0.child1/obj36" } ], "chromeContext": false, @@ -409,20 +421,23 @@ stubPackets.set(`console.log('myarray', ['red', 'green', 'blue'])`, { "type": "consoleAPICall" }); -stubPackets.set(`console.log('myregex', /a.b.c/)`, { +rawPackets.set(`console.log('myregex', /a.b.c/)`, { "message": { "addonId": "", "arguments": [ "myregex", { - "type": "object", - "actor": "server0.conn0.child1/obj38", - "class": "RegExp", - "ownPropertyLength": 1, - "extensible": true, - "frozen": false, - "sealed": false, - "displayString": "/a.b.c/" + "_grip": { + "type": "object", + "actor": "server0.conn0.child1/obj38", + "class": "RegExp", + "ownPropertyLength": 1, + "extensible": true, + "frozen": false, + "sealed": false, + "displayString": "/a.b.c/" + }, + "actorID": "server0.conn0.child1/obj38" } ], "chromeContext": false, @@ -446,39 +461,42 @@ stubPackets.set(`console.log('myregex', /a.b.c/)`, { "type": "consoleAPICall" }); -stubPackets.set(`console.table(['red', 'green', 'blue']);`, { +rawPackets.set(`console.table(['red', 'green', 'blue']);`, { "message": { "addonId": "", "arguments": [ { - "type": "object", - "actor": "server0.conn0.child1/obj40", - "class": "Array", - "ownPropertyLength": 4, - "extensible": true, - "frozen": false, - "sealed": false, - "preview": null, - "ownProperties": { - "0": { - "configurable": true, - "enumerable": true, - "writable": true, - "value": "red" - }, - "1": { - "configurable": true, - "enumerable": true, - "writable": true, - "value": "green" - }, - "2": { - "configurable": true, - "enumerable": true, - "writable": true, - "value": "blue" + "_grip": { + "type": "object", + "actor": "server0.conn0.child1/obj40", + "class": "Array", + "ownPropertyLength": 4, + "extensible": true, + "frozen": false, + "sealed": false, + "preview": null, + "ownProperties": { + "0": { + "configurable": true, + "enumerable": true, + "writable": true, + "value": "red" + }, + "1": { + "configurable": true, + "enumerable": true, + "writable": true, + "value": "green" + }, + "2": { + "configurable": true, + "enumerable": true, + "writable": true, + "value": "blue" + } } - } + }, + "actorID": "server0.conn0.child1/obj40" } ], "chromeContext": false, @@ -502,46 +520,49 @@ stubPackets.set(`console.table(['red', 'green', 'blue']);`, { "type": "consoleAPICall" }); -stubPackets.set(`console.log('myobject', {red: 'redValue', green: 'greenValue', blue: 'blueValue'});`, { +rawPackets.set(`console.log('myobject', {red: 'redValue', green: 'greenValue', blue: 'blueValue'});`, { "message": { "addonId": "", "arguments": [ "myobject", { - "type": "object", - "actor": "server0.conn0.child1/obj42", - "class": "Object", - "ownPropertyLength": 3, - "extensible": true, - "frozen": false, - "sealed": false, - "preview": { - "kind": "Object", - "ownProperties": { - "red": { - "configurable": true, - "enumerable": true, - "writable": true, - "value": "redValue" + "_grip": { + "type": "object", + "actor": "server0.conn0.child1/obj42", + "class": "Object", + "ownPropertyLength": 3, + "extensible": true, + "frozen": false, + "sealed": false, + "preview": { + "kind": "Object", + "ownProperties": { + "red": { + "configurable": true, + "enumerable": true, + "writable": true, + "value": "redValue" + }, + "green": { + "configurable": true, + "enumerable": true, + "writable": true, + "value": "greenValue" + }, + "blue": { + "configurable": true, + "enumerable": true, + "writable": true, + "value": "blueValue" + } }, - "green": { - "configurable": true, - "enumerable": true, - "writable": true, - "value": "greenValue" - }, - "blue": { - "configurable": true, - "enumerable": true, - "writable": true, - "value": "blueValue" - } - }, - "ownSymbols": [], - "ownPropertiesLength": 3, - "ownSymbolsLength": 0, - "safeGetterValues": {} - } + "ownSymbols": [], + "ownPropertiesLength": 3, + "ownSymbolsLength": 0, + "safeGetterValues": {} + } + }, + "actorID": "server0.conn0.child1/obj42" } ], "chromeContext": false, @@ -565,7 +586,7 @@ stubPackets.set(`console.log('myobject', {red: 'redValue', green: 'greenValue', "type": "consoleAPICall" }); -stubPackets.set(`console.debug('debug message');`, { +rawPackets.set(`console.debug('debug message');`, { "message": { "addonId": "", "arguments": [ @@ -592,7 +613,7 @@ stubPackets.set(`console.debug('debug message');`, { "type": "consoleAPICall" }); -stubPackets.set(`console.info('info message');`, { +rawPackets.set(`console.info('info message');`, { "message": { "addonId": "", "arguments": [ @@ -619,7 +640,7 @@ stubPackets.set(`console.info('info message');`, { "type": "consoleAPICall" }); -stubPackets.set(`console.error('error message');`, { +rawPackets.set(`console.error('error message');`, { "message": { "addonId": "", "arguments": [ @@ -655,33 +676,36 @@ stubPackets.set(`console.error('error message');`, { "type": "consoleAPICall" }); -stubPackets.set(`console.log('mymap')`, { +rawPackets.set(`console.log('mymap')`, { "message": { "addonId": "", "arguments": [ "mymap", { - "type": "object", - "actor": "server0.conn0.child1/obj47", - "class": "Map", - "ownPropertyLength": 0, - "extensible": true, - "frozen": false, - "sealed": false, - "preview": { - "kind": "MapLike", - "size": 2, - "entries": [ - [ - "key1", - "value1" - ], - [ - "key2", - "value2" + "_grip": { + "type": "object", + "actor": "server0.conn0.child1/obj47", + "class": "Map", + "ownPropertyLength": 0, + "extensible": true, + "frozen": false, + "sealed": false, + "preview": { + "kind": "MapLike", + "size": 2, + "entries": [ + [ + "key1", + "value1" + ], + [ + "key2", + "value2" + ] ] - ] - } + } + }, + "actorID": "server0.conn0.child1/obj47" } ], "chromeContext": false, @@ -705,27 +729,30 @@ stubPackets.set(`console.log('mymap')`, { "type": "consoleAPICall" }); -stubPackets.set(`console.log('myset')`, { +rawPackets.set(`console.log('myset')`, { "message": { "addonId": "", "arguments": [ "myset", { - "type": "object", - "actor": "server0.conn0.child1/obj49", - "class": "Set", - "ownPropertyLength": 0, - "extensible": true, - "frozen": false, - "sealed": false, - "preview": { - "kind": "ArrayLike", - "length": 2, - "items": [ - "a", - "b" - ] - } + "_grip": { + "type": "object", + "actor": "server0.conn0.child1/obj49", + "class": "Set", + "ownPropertyLength": 0, + "extensible": true, + "frozen": false, + "sealed": false, + "preview": { + "kind": "ArrayLike", + "length": 2, + "items": [ + "a", + "b" + ] + } + }, + "actorID": "server0.conn0.child1/obj49" } ], "chromeContext": false, @@ -749,7 +776,7 @@ stubPackets.set(`console.log('myset')`, { "type": "consoleAPICall" }); -stubPackets.set(`console.trace()`, { +rawPackets.set(`console.trace()`, { "message": { "addonId": "", "arguments": [], @@ -797,52 +824,58 @@ stubPackets.set(`console.trace()`, { "type": "consoleAPICall" }); -stubPackets.set(`console.trace('bar', {'foo': 'bar'}, [1,2,3])`, { +rawPackets.set(`console.trace('bar', {'foo': 'bar'}, [1,2,3])`, { "message": { "addonId": "", "arguments": [ "bar", { - "type": "object", - "actor": "server0.conn0.child1/obj52", - "class": "Object", - "ownPropertyLength": 1, - "extensible": true, - "frozen": false, - "sealed": false, - "preview": { - "kind": "Object", - "ownProperties": { - "foo": { - "configurable": true, - "enumerable": true, - "writable": true, - "value": "bar" - } - }, - "ownSymbols": [], - "ownPropertiesLength": 1, - "ownSymbolsLength": 0, - "safeGetterValues": {} - } + "_grip": { + "type": "object", + "actor": "server0.conn0.child1/obj52", + "class": "Object", + "ownPropertyLength": 1, + "extensible": true, + "frozen": false, + "sealed": false, + "preview": { + "kind": "Object", + "ownProperties": { + "foo": { + "configurable": true, + "enumerable": true, + "writable": true, + "value": "bar" + } + }, + "ownSymbols": [], + "ownPropertiesLength": 1, + "ownSymbolsLength": 0, + "safeGetterValues": {} + } + }, + "actorID": "server0.conn0.child1/obj52" }, { - "type": "object", - "actor": "server0.conn0.child1/obj53", - "class": "Array", - "ownPropertyLength": 4, - "extensible": true, - "frozen": false, - "sealed": false, - "preview": { - "kind": "ArrayLike", - "length": 3, - "items": [ - 1, - 2, - 3 - ] - } + "_grip": { + "type": "object", + "actor": "server0.conn0.child1/obj53", + "class": "Array", + "ownPropertyLength": 4, + "extensible": true, + "frozen": false, + "sealed": false, + "preview": { + "kind": "ArrayLike", + "length": 3, + "items": [ + 1, + 2, + 3 + ] + } + }, + "actorID": "server0.conn0.child1/obj53" } ], "chromeContext": false, @@ -889,7 +922,7 @@ stubPackets.set(`console.trace('bar', {'foo': 'bar'}, [1,2,3])`, { "type": "consoleAPICall" }); -stubPackets.set(`console.time('bar')`, { +rawPackets.set(`console.time('bar')`, { "message": { "addonId": "", "arguments": [ @@ -918,7 +951,7 @@ stubPackets.set(`console.time('bar')`, { "type": "consoleAPICall" }); -stubPackets.set(`timerAlreadyExists`, { +rawPackets.set(`timerAlreadyExists`, { "message": { "addonId": "", "arguments": [ @@ -948,7 +981,7 @@ stubPackets.set(`timerAlreadyExists`, { "type": "consoleAPICall" }); -stubPackets.set(`console.timeLog('bar') - 1`, { +rawPackets.set(`console.timeLog('bar') - 1`, { "message": { "addonId": "", "arguments": [ @@ -978,35 +1011,38 @@ stubPackets.set(`console.timeLog('bar') - 1`, { "type": "consoleAPICall" }); -stubPackets.set(`console.timeLog('bar') - 2`, { +rawPackets.set(`console.timeLog('bar') - 2`, { "message": { "addonId": "", "arguments": [ "bar", "second call", { - "type": "object", - "actor": "server0.conn0.child1/obj55", - "class": "Object", - "ownPropertyLength": 1, - "extensible": true, - "frozen": false, - "sealed": false, - "preview": { - "kind": "Object", - "ownProperties": { - "state": { - "configurable": true, - "enumerable": true, - "writable": true, - "value": 1 - } - }, - "ownSymbols": [], - "ownPropertiesLength": 1, - "ownSymbolsLength": 0, - "safeGetterValues": {} - } + "_grip": { + "type": "object", + "actor": "server0.conn0.child1/obj55", + "class": "Object", + "ownPropertyLength": 1, + "extensible": true, + "frozen": false, + "sealed": false, + "preview": { + "kind": "Object", + "ownProperties": { + "state": { + "configurable": true, + "enumerable": true, + "writable": true, + "value": 1 + } + }, + "ownSymbols": [], + "ownPropertiesLength": 1, + "ownSymbolsLength": 0, + "safeGetterValues": {} + } + }, + "actorID": "server0.conn0.child1/obj55" } ], "chromeContext": false, @@ -1033,7 +1069,7 @@ stubPackets.set(`console.timeLog('bar') - 2`, { "type": "consoleAPICall" }); -stubPackets.set(`console.timeEnd('bar')`, { +rawPackets.set(`console.timeEnd('bar')`, { "message": { "addonId": "", "arguments": [ @@ -1063,7 +1099,7 @@ stubPackets.set(`console.timeEnd('bar')`, { "type": "consoleAPICall" }); -stubPackets.set(`timeEnd.timerDoesntExist`, { +rawPackets.set(`timeEnd.timerDoesntExist`, { "message": { "addonId": "", "arguments": [ @@ -1093,7 +1129,7 @@ stubPackets.set(`timeEnd.timerDoesntExist`, { "type": "consoleAPICall" }); -stubPackets.set(`timeLog.timerDoesntExist`, { +rawPackets.set(`timeLog.timerDoesntExist`, { "message": { "addonId": "", "arguments": [ @@ -1123,7 +1159,7 @@ stubPackets.set(`timeLog.timerDoesntExist`, { "type": "consoleAPICall" }); -stubPackets.set(`console.table('bar')`, { +rawPackets.set(`console.table('bar')`, { "message": { "addonId": "", "arguments": [ @@ -1150,39 +1186,42 @@ stubPackets.set(`console.table('bar')`, { "type": "consoleAPICall" }); -stubPackets.set(`console.table(['a', 'b', 'c'])`, { +rawPackets.set(`console.table(['a', 'b', 'c'])`, { "message": { "addonId": "", "arguments": [ { - "type": "object", - "actor": "server0.conn0.child1/obj58", - "class": "Array", - "ownPropertyLength": 4, - "extensible": true, - "frozen": false, - "sealed": false, - "preview": null, - "ownProperties": { - "0": { - "configurable": true, - "enumerable": true, - "writable": true, - "value": "a" - }, - "1": { - "configurable": true, - "enumerable": true, - "writable": true, - "value": "b" - }, - "2": { - "configurable": true, - "enumerable": true, - "writable": true, - "value": "c" + "_grip": { + "type": "object", + "actor": "server0.conn0.child1/obj58", + "class": "Array", + "ownPropertyLength": 4, + "extensible": true, + "frozen": false, + "sealed": false, + "preview": null, + "ownProperties": { + "0": { + "configurable": true, + "enumerable": true, + "writable": true, + "value": "a" + }, + "1": { + "configurable": true, + "enumerable": true, + "writable": true, + "value": "b" + }, + "2": { + "configurable": true, + "enumerable": true, + "writable": true, + "value": "c" + } } - } + }, + "actorID": "server0.conn0.child1/obj58" } ], "chromeContext": false, @@ -1206,7 +1245,7 @@ stubPackets.set(`console.table(['a', 'b', 'c'])`, { "type": "consoleAPICall" }); -stubPackets.set(`console.group('bar')`, { +rawPackets.set(`console.group('bar')`, { "message": { "addonId": "", "arguments": [ @@ -1233,7 +1272,7 @@ stubPackets.set(`console.group('bar')`, { "type": "consoleAPICall" }); -stubPackets.set(`console.groupEnd('bar')`, { +rawPackets.set(`console.groupEnd('bar')`, { "message": { "addonId": "", "arguments": [], @@ -1258,7 +1297,7 @@ stubPackets.set(`console.groupEnd('bar')`, { "type": "consoleAPICall" }); -stubPackets.set(`console.groupCollapsed('foo')`, { +rawPackets.set(`console.groupCollapsed('foo')`, { "message": { "addonId": "", "arguments": [ @@ -1285,7 +1324,7 @@ stubPackets.set(`console.groupCollapsed('foo')`, { "type": "consoleAPICall" }); -stubPackets.set(`console.groupEnd('foo')`, { +rawPackets.set(`console.groupEnd('foo')`, { "message": { "addonId": "", "arguments": [], @@ -1310,7 +1349,7 @@ stubPackets.set(`console.groupEnd('foo')`, { "type": "consoleAPICall" }); -stubPackets.set(`console.group()`, { +rawPackets.set(`console.group()`, { "message": { "addonId": "", "arguments": [], @@ -1335,7 +1374,7 @@ stubPackets.set(`console.group()`, { "type": "consoleAPICall" }); -stubPackets.set(`console.groupEnd()`, { +rawPackets.set(`console.groupEnd()`, { "message": { "addonId": "", "arguments": [], @@ -1360,7 +1399,7 @@ stubPackets.set(`console.groupEnd()`, { "type": "consoleAPICall" }); -stubPackets.set(`console.log(%cfoobar)`, { +rawPackets.set(`console.log(%cfoobar)`, { "message": { "addonId": "", "arguments": [ @@ -1391,7 +1430,7 @@ stubPackets.set(`console.log(%cfoobar)`, { "type": "consoleAPICall" }); -stubPackets.set(`console.log("%cHello%c|%cWorld")`, { +rawPackets.set(`console.log("%cHello%c|%cWorld")`, { "message": { "addonId": "", "arguments": [ @@ -1424,7 +1463,7 @@ stubPackets.set(`console.log("%cHello%c|%cWorld")`, { "type": "consoleAPICall" }); -stubPackets.set(`console.group(%cfoo%cbar)`, { +rawPackets.set(`console.group(%cfoo%cbar)`, { "message": { "addonId": "", "arguments": [ @@ -1455,7 +1494,7 @@ stubPackets.set(`console.group(%cfoo%cbar)`, { "type": "consoleAPICall" }); -stubPackets.set(`console.groupEnd(%cfoo%cbar)`, { +rawPackets.set(`console.groupEnd(%cfoo%cbar)`, { "message": { "addonId": "", "arguments": [], @@ -1480,7 +1519,7 @@ stubPackets.set(`console.groupEnd(%cfoo%cbar)`, { "type": "consoleAPICall" }); -stubPackets.set(`console.groupCollapsed(%cfoo%cbaz)`, { +rawPackets.set(`console.groupCollapsed(%cfoo%cbaz)`, { "message": { "addonId": "", "arguments": [ @@ -1511,7 +1550,7 @@ stubPackets.set(`console.groupCollapsed(%cfoo%cbaz)`, { "type": "consoleAPICall" }); -stubPackets.set(`console.groupEnd(%cfoo%cbaz)`, { +rawPackets.set(`console.groupEnd(%cfoo%cbaz)`, { "message": { "addonId": "", "arguments": [], @@ -1536,51 +1575,54 @@ stubPackets.set(`console.groupEnd(%cfoo%cbaz)`, { "type": "consoleAPICall" }); -stubPackets.set(`console.dir({C, M, Y, K})`, { +rawPackets.set(`console.dir({C, M, Y, K})`, { "message": { "addonId": "", "arguments": [ { - "type": "object", - "actor": "server0.conn0.child1/obj67", - "class": "Object", - "ownPropertyLength": 4, - "extensible": true, - "frozen": false, - "sealed": false, - "preview": { - "kind": "Object", - "ownProperties": { - "cyan": { - "configurable": true, - "enumerable": true, - "writable": true, - "value": "C" + "_grip": { + "type": "object", + "actor": "server0.conn0.child1/obj67", + "class": "Object", + "ownPropertyLength": 4, + "extensible": true, + "frozen": false, + "sealed": false, + "preview": { + "kind": "Object", + "ownProperties": { + "cyan": { + "configurable": true, + "enumerable": true, + "writable": true, + "value": "C" + }, + "magenta": { + "configurable": true, + "enumerable": true, + "writable": true, + "value": "M" + }, + "yellow": { + "configurable": true, + "enumerable": true, + "writable": true, + "value": "Y" + }, + "black": { + "configurable": true, + "enumerable": true, + "writable": true, + "value": "K" + } }, - "magenta": { - "configurable": true, - "enumerable": true, - "writable": true, - "value": "M" - }, - "yellow": { - "configurable": true, - "enumerable": true, - "writable": true, - "value": "Y" - }, - "black": { - "configurable": true, - "enumerable": true, - "writable": true, - "value": "K" - } - }, - "ownSymbols": [], - "ownPropertiesLength": 4, - "ownSymbolsLength": 0, - "safeGetterValues": {} - } + "ownSymbols": [], + "ownPropertiesLength": 4, + "ownSymbolsLength": 0, + "safeGetterValues": {} + } + }, + "actorID": "server0.conn0.child1/obj67" } ], "chromeContext": false, @@ -1604,7 +1646,7 @@ stubPackets.set(`console.dir({C, M, Y, K})`, { "type": "consoleAPICall" }); -stubPackets.set(`console.count | default: 1`, { +rawPackets.set(`console.count | default: 1`, { "message": { "addonId": "", "arguments": [ @@ -1634,7 +1676,7 @@ stubPackets.set(`console.count | default: 1`, { "type": "consoleAPICall" }); -stubPackets.set(`console.count | default: 2`, { +rawPackets.set(`console.count | default: 2`, { "message": { "addonId": "", "arguments": [ @@ -1664,7 +1706,7 @@ stubPackets.set(`console.count | default: 2`, { "type": "consoleAPICall" }); -stubPackets.set(`console.count | test counter: 1`, { +rawPackets.set(`console.count | test counter: 1`, { "message": { "addonId": "", "arguments": [ @@ -1694,7 +1736,7 @@ stubPackets.set(`console.count | test counter: 1`, { "type": "consoleAPICall" }); -stubPackets.set(`console.count | test counter: 2`, { +rawPackets.set(`console.count | test counter: 2`, { "message": { "addonId": "", "arguments": [ @@ -1724,7 +1766,7 @@ stubPackets.set(`console.count | test counter: 2`, { "type": "consoleAPICall" }); -stubPackets.set(`console.count | default: 3`, { +rawPackets.set(`console.count | default: 3`, { "message": { "addonId": "", "arguments": [ @@ -1754,7 +1796,7 @@ stubPackets.set(`console.count | default: 3`, { "type": "consoleAPICall" }); -stubPackets.set(`console.count | clear`, { +rawPackets.set(`console.count | clear`, { "message": { "addonId": "", "arguments": [], @@ -1779,7 +1821,7 @@ stubPackets.set(`console.count | clear`, { "type": "consoleAPICall" }); -stubPackets.set(`console.count | default: 4`, { +rawPackets.set(`console.count | default: 4`, { "message": { "addonId": "", "arguments": [ @@ -1809,7 +1851,7 @@ stubPackets.set(`console.count | default: 4`, { "type": "consoleAPICall" }); -stubPackets.set(`console.count | test counter: 3`, { +rawPackets.set(`console.count | test counter: 3`, { "message": { "addonId": "", "arguments": [ @@ -1839,7 +1881,7 @@ stubPackets.set(`console.count | test counter: 3`, { "type": "consoleAPICall" }); -stubPackets.set(`console.countReset | test counter: 0`, { +rawPackets.set(`console.countReset | test counter: 0`, { "message": { "addonId": "", "arguments": [ @@ -1869,7 +1911,7 @@ stubPackets.set(`console.countReset | test counter: 0`, { "type": "consoleAPICall" }); -stubPackets.set(`console.countReset | counterDoesntExist`, { +rawPackets.set(`console.countReset | counterDoesntExist`, { "message": { "addonId": "", "arguments": [ @@ -1899,7 +1941,7 @@ stubPackets.set(`console.countReset | counterDoesntExist`, { "type": "consoleAPICall" }); -stubPackets.set(`console.log escaped characters`, { +rawPackets.set(`console.log escaped characters`, { "message": { "addonId": "", "arguments": [ @@ -1926,6 +1968,9 @@ stubPackets.set(`console.log escaped characters`, { "type": "consoleAPICall" }); + +const stubPackets = parsePacketsWithFronts(rawPackets); + const stubPreparedMessages = new Map(); for (const [key, packet] of Array.from(stubPackets.entries())) { const transformedPacket = prepareMessage(packet, { @@ -1936,6 +1981,7 @@ for (const [key, packet] of Array.from(stubPackets.entries())) { } module.exports = { + rawPackets, stubPreparedMessages, stubPackets, }; diff --git a/devtools/client/webconsole/test/node/fixtures/stubs/evaluationResult.js b/devtools/client/webconsole/test/node/fixtures/stubs/evaluationResult.js index 04a8e09eef99..24d0260c8952 100644 --- a/devtools/client/webconsole/test/node/fixtures/stubs/evaluationResult.js +++ b/devtools/client/webconsole/test/node/fixtures/stubs/evaluationResult.js @@ -8,52 +8,60 @@ * THIS FILE IS AUTOGENERATED. DO NOT MODIFY BY HAND. RUN TESTS IN FIXTURES/ TO UPDATE. */ +const { + parsePacketsWithFronts, +} = require("devtools/client/webconsole/test/browser/stub-generator-helpers"); const { prepareMessage } = require("devtools/client/webconsole/utils/messages"); const { ConsoleMessage, NetworkEventMessage, } = require("devtools/client/webconsole/types"); -const stubPackets = new Map(); -stubPackets.set(`new Date(0)`, { - "resultID": "1573385647471-0", +const rawPackets = new Map(); +rawPackets.set(`new Date(0)`, { + "resultID": "1573832025018-0", "input": "new Date(0)", "result": { - "type": "object", - "actor": "server0.conn0.child1/obj23", - "class": "Date", - "ownPropertyLength": 0, - "extensible": true, - "frozen": false, - "sealed": false, - "preview": { - "timestamp": 0 - } + "_grip": { + "type": "object", + "actor": "server0.conn0.child1/obj23", + "class": "Date", + "ownPropertyLength": 0, + "extensible": true, + "frozen": false, + "sealed": false, + "preview": { + "timestamp": 0 + } + }, + "actorID": "server0.conn0.child1/obj23" }, - "timestamp": 1572868073590, - "from": "server0.conn0.child1/consoleActor2" + "timestamp": 1573832025019 }); -stubPackets.set(`asdf()`, { - "resultID": "1573385647554-1", +rawPackets.set(`asdf()`, { + "resultID": "1573832025112-1", "errorMessageName": "JSMSG_NOT_DEFINED", "exception": { - "type": "object", - "actor": "server0.conn0.child1/obj25", - "class": "Error", - "ownPropertyLength": 4, - "extensible": true, - "frozen": false, - "sealed": false, - "preview": { - "kind": "Error", - "name": "ReferenceError", - "message": "asdf is not defined", - "stack": "@debugger eval code:1:1\n", - "fileName": "debugger eval code", - "lineNumber": 1, - "columnNumber": 1 - } + "_grip": { + "type": "object", + "actor": "server0.conn0.child1/obj25", + "class": "Error", + "ownPropertyLength": 4, + "extensible": true, + "frozen": false, + "sealed": false, + "preview": { + "kind": "Error", + "name": "ReferenceError", + "message": "asdf is not defined", + "stack": "@debugger eval code:1:1\n", + "fileName": "debugger eval code", + "lineNumber": 1, + "columnNumber": 1 + } + }, + "actorID": "server0.conn0.child1/obj25" }, "exceptionMessage": "ReferenceError: asdf is not defined", "exceptionDocURL": "https://developer.mozilla.org/docs/Web/JavaScript/Reference/Errors/Not_defined?utm_source=mozilla&utm_medium=firefox-console-errors&utm_campaign=default", @@ -75,30 +83,32 @@ stubPackets.set(`asdf()`, { "result": { "type": "undefined" }, - "timestamp": 1572868073933, - "from": "server0.conn0.child1/consoleActor2" + "timestamp": 1573832025112 }); -stubPackets.set(`1 + @`, { - "resultID": "1573385647562-2", +rawPackets.set(`1 + @`, { + "resultID": "1573832025117-2", "errorMessageName": "JSMSG_ILLEGAL_CHARACTER", "exception": { - "type": "object", - "actor": "server0.conn0.child1/obj26", - "class": "Error", - "ownPropertyLength": 4, - "extensible": true, - "frozen": false, - "sealed": false, - "preview": { - "kind": "Error", - "name": "SyntaxError", - "message": "illegal character", - "stack": "", - "fileName": "debugger eval code", - "lineNumber": 1, - "columnNumber": 4 - } + "_grip": { + "type": "object", + "actor": "server0.conn0.child1/obj26", + "class": "Error", + "ownPropertyLength": 4, + "extensible": true, + "frozen": false, + "sealed": false, + "preview": { + "kind": "Error", + "name": "SyntaxError", + "message": "illegal character", + "stack": "", + "fileName": "debugger eval code", + "lineNumber": 1, + "columnNumber": 4 + } + }, + "actorID": "server0.conn0.child1/obj26" }, "exceptionMessage": "SyntaxError: illegal character", "exceptionDocURL": "https://developer.mozilla.org/docs/Web/JavaScript/Reference/Errors/Illegal_character?utm_source=mozilla&utm_medium=firefox-console-errors&utm_campaign=default", @@ -111,50 +121,51 @@ stubPackets.set(`1 + @`, { "result": { "type": "undefined" }, - "timestamp": 1572868073955, - "from": "server0.conn0.child1/consoleActor2" + "timestamp": 1573832025117 }); -stubPackets.set(`inspect({a: 1})`, { - "resultID": "1573385647565-3", +rawPackets.set(`inspect({a: 1})`, { + "resultID": "1573832025122-3", "helperResult": { "type": "inspectObject", "input": "inspect({a: 1})", "object": { - "type": "object", - "actor": "server0.conn0.child1/obj28", - "class": "Object", - "ownPropertyLength": 1, - "extensible": true, - "frozen": false, - "sealed": false, - "preview": { - "kind": "Object", - "ownProperties": { - "a": { - "configurable": true, - "enumerable": true, - "writable": true, - "value": 1 - } - }, - "ownSymbols": [], - "ownPropertiesLength": 1, - "ownSymbolsLength": 0, - "safeGetterValues": {} - } + "_grip": { + "type": "object", + "actor": "server0.conn0.child1/obj28", + "class": "Object", + "ownPropertyLength": 1, + "extensible": true, + "frozen": false, + "sealed": false, + "preview": { + "kind": "Object", + "ownProperties": { + "a": { + "configurable": true, + "enumerable": true, + "writable": true, + "value": 1 + } + }, + "ownSymbols": [], + "ownPropertiesLength": 1, + "ownSymbolsLength": 0, + "safeGetterValues": {} + } + }, + "actorID": "server0.conn0.child1/obj28" } }, "input": "inspect({a: 1})", "result": { "type": "undefined" }, - "timestamp": 1572868073976, - "from": "server0.conn0.child1/consoleActor2" + "timestamp": 1573832025123 }); -stubPackets.set(`cd(document)`, { - "resultID": "1573385647570-4", +rawPackets.set(`cd(document)`, { + "resultID": "1573832025125-4", "helperResult": { "type": "error", "message": "cdFunctionInvalidArgument" @@ -163,50 +174,57 @@ stubPackets.set(`cd(document)`, { "result": { "type": "undefined" }, - "timestamp": 1572868074010, - "from": "server0.conn0.child1/consoleActor2" + "timestamp": 1573832025126 }); -stubPackets.set(`undefined`, { - "resultID": "1573385647572-5", +rawPackets.set(`undefined`, { + "resultID": "1573832025127-5", "input": "undefined", "result": { "type": "undefined" }, - "timestamp": 1572868074023, - "from": "server0.conn0.child1/consoleActor2" + "timestamp": 1573832025128 }); -stubPackets.set(`longString message Error`, { - "resultID": "1573385647576-6", +rawPackets.set(`longString message Error`, { + "resultID": "1573832025130-6", "exception": { - "type": "object", - "actor": "server0.conn0.child1/obj32", - "class": "Error", - "ownPropertyLength": 4, - "extensible": true, - "frozen": false, - "sealed": false, - "preview": { - "kind": "Error", - "name": "Error", - "message": { - "type": "longString", - "actor": "server0.conn0.child1/longstractor33", - "length": 110000, - "initial": "Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error" - }, - "stack": "@debugger eval code:1:7\n", - "fileName": "debugger eval code", - "lineNumber": 1, - "columnNumber": 7 - } + "_grip": { + "type": "object", + "actor": "server0.conn0.child1/obj32", + "class": "Error", + "ownPropertyLength": 4, + "extensible": true, + "frozen": false, + "sealed": false, + "preview": { + "kind": "Error", + "name": "Error", + "message": { + "_grip": { + "type": "longString", + "actor": "server0.conn0.child1/longstractor33", + "length": 110000, + "initial": "Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error" + }, + "actorID": "server0.conn0.child1/longstractor33" + }, + "stack": "@debugger eval code:1:7\n", + "fileName": "debugger eval code", + "lineNumber": 1, + "columnNumber": 7 + } + }, + "actorID": "server0.conn0.child1/obj32" }, "exceptionMessage": { - "type": "longString", - "actor": "server0.conn0.child1/longstractor34", - "length": 110007, - "initial": "Error: Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Lon" + "_grip": { + "type": "longString", + "actor": "server0.conn0.child1/longstractor34", + "length": 110007, + "initial": "Error: Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Lon" + }, + "actorID": "server0.conn0.child1/longstractor34" }, "exceptionStack": [ { @@ -227,12 +245,11 @@ stubPackets.set(`longString message Error`, { "result": { "type": "undefined" }, - "timestamp": 1572868074038, - "from": "server0.conn0.child1/consoleActor2" + "timestamp": 1573832025130 }); -stubPackets.set(`eval throw ""`, { - "resultID": "1573385647580-7", +rawPackets.set(`eval throw ""`, { + "resultID": "1573832025134-7", "exception": "", "exceptionMessage": "", "exceptionStack": [ @@ -254,12 +271,11 @@ stubPackets.set(`eval throw ""`, { "result": { "type": "undefined" }, - "timestamp": 1572868074059, - "from": "server0.conn0.child1/consoleActor2" + "timestamp": 1573832025134 }); -stubPackets.set(`eval throw "tomato"`, { - "resultID": "1573385647583-8", +rawPackets.set(`eval throw "tomato"`, { + "resultID": "1573832025137-8", "exception": "tomato", "exceptionMessage": "tomato", "exceptionStack": [ @@ -281,10 +297,12 @@ stubPackets.set(`eval throw "tomato"`, { "result": { "type": "undefined" }, - "timestamp": 1572868074071, - "from": "server0.conn0.child1/consoleActor2" + "timestamp": 1573832025138 }); + +const stubPackets = parsePacketsWithFronts(rawPackets); + const stubPreparedMessages = new Map(); for (const [key, packet] of Array.from(stubPackets.entries())) { const transformedPacket = prepareMessage(packet, { @@ -295,6 +313,7 @@ for (const [key, packet] of Array.from(stubPackets.entries())) { } module.exports = { + rawPackets, stubPreparedMessages, stubPackets, }; diff --git a/devtools/client/webconsole/test/node/fixtures/stubs/pageError.js b/devtools/client/webconsole/test/node/fixtures/stubs/pageError.js index b00f02ac2ef9..bb1cfdf700f9 100644 --- a/devtools/client/webconsole/test/node/fixtures/stubs/pageError.js +++ b/devtools/client/webconsole/test/node/fixtures/stubs/pageError.js @@ -8,14 +8,17 @@ * THIS FILE IS AUTOGENERATED. DO NOT MODIFY BY HAND. RUN TESTS IN FIXTURES/ TO UPDATE. */ +const { + parsePacketsWithFronts, +} = require("devtools/client/webconsole/test/browser/stub-generator-helpers"); const { prepareMessage } = require("devtools/client/webconsole/utils/messages"); const { ConsoleMessage, NetworkEventMessage, } = require("devtools/client/webconsole/types"); -const stubPackets = new Map(); -stubPackets.set(`ReferenceError: asdf is not defined`, { +const rawPackets = new Map(); +rawPackets.set(`ReferenceError: asdf is not defined`, { "pageError": { "errorMessage": "ReferenceError: asdf is not defined", "errorMessageName": "JSMSG_NOT_DEFINED", @@ -27,7 +30,7 @@ stubPackets.set(`ReferenceError: asdf is not defined`, { "columnNumber": 5, "category": "content javascript", "innerWindowID": 8589934593, - "timeStamp": 1572868283535, + "timeStamp": 1573832650066, "warning": false, "error": false, "exception": true, @@ -78,7 +81,7 @@ stubPackets.set(`ReferenceError: asdf is not defined`, { "type": "pageError" }); -stubPackets.set(`SyntaxError: redeclaration of let a`, { +rawPackets.set(`SyntaxError: redeclaration of let a`, { "pageError": { "errorMessage": "SyntaxError: redeclaration of let a", "errorMessageName": "JSMSG_REDECLARED_VAR", @@ -90,7 +93,7 @@ stubPackets.set(`SyntaxError: redeclaration of let a`, { "columnNumber": 9, "category": "content javascript", "innerWindowID": 8589934593, - "timeStamp": 1572868283903, + "timeStamp": 1573832650228, "warning": false, "error": false, "exception": true, @@ -130,13 +133,16 @@ stubPackets.set(`SyntaxError: redeclaration of let a`, { "type": "pageError" }); -stubPackets.set(`TypeError longString message`, { +rawPackets.set(`TypeError longString message`, { "pageError": { "errorMessage": { - "type": "longString", - "actor": "server0.conn0.child1/longstractor24", - "length": 110007, - "initial": "Error: Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Lon" + "_grip": { + "type": "longString", + "actor": "server0.conn0.child1/longstractor24", + "length": 110007, + "initial": "Error: Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Lon" + }, + "actorID": "server0.conn0.child1/longstractor24" }, "errorMessageName": "", "sourceName": "http://example.com/browser/devtools/client/webconsole/test/browser/test-console-api.html", @@ -146,7 +152,7 @@ stubPackets.set(`TypeError longString message`, { "columnNumber": 7, "category": "content javascript", "innerWindowID": 8589934593, - "timeStamp": 1572868284293, + "timeStamp": 1573832650682, "warning": false, "error": false, "exception": true, @@ -183,7 +189,7 @@ stubPackets.set(`TypeError longString message`, { "type": "pageError" }); -stubPackets.set(`throw ""`, { +rawPackets.set(`throw ""`, { "pageError": { "errorMessage": "uncaught exception: ", "errorMessageName": "JSMSG_UNCAUGHT_EXCEPTION", @@ -194,7 +200,7 @@ stubPackets.set(`throw ""`, { "columnNumber": 1, "category": "content javascript", "innerWindowID": 8589934593, - "timeStamp": 1572868284458, + "timeStamp": 1573832650688, "warning": false, "error": false, "exception": false, @@ -231,7 +237,7 @@ stubPackets.set(`throw ""`, { "type": "pageError" }); -stubPackets.set(`throw "tomato"`, { +rawPackets.set(`throw "tomato"`, { "pageError": { "errorMessage": "uncaught exception: tomato", "errorMessageName": "JSMSG_UNCAUGHT_EXCEPTION", @@ -242,7 +248,7 @@ stubPackets.set(`throw "tomato"`, { "columnNumber": 1, "category": "content javascript", "innerWindowID": 8589934593, - "timeStamp": 1572868284565, + "timeStamp": 1573832650692, "warning": false, "error": false, "exception": false, @@ -279,6 +285,9 @@ stubPackets.set(`throw "tomato"`, { "type": "pageError" }); + +const stubPackets = parsePacketsWithFronts(rawPackets); + const stubPreparedMessages = new Map(); for (const [key, packet] of Array.from(stubPackets.entries())) { const transformedPacket = prepareMessage(packet, { @@ -289,6 +298,7 @@ for (const [key, packet] of Array.from(stubPackets.entries())) { } module.exports = { + rawPackets, stubPreparedMessages, stubPackets, }; diff --git a/devtools/client/webconsole/test/node/mocha-test-setup.js b/devtools/client/webconsole/test/node/mocha-test-setup.js index 302e6e90d567..9af0821c3f8b 100644 --- a/devtools/client/webconsole/test/node/mocha-test-setup.js +++ b/devtools/client/webconsole/test/node/mocha-test-setup.js @@ -103,7 +103,9 @@ requireHacker.global_hook("default", (path, module) => { react: () => getModule("devtools/client/shared/vendor/react-dev"), "devtools/client/shared/vendor/react": () => getModule("devtools/client/shared/vendor/react-dev"), - chrome: () => `module.exports = { Cc: {}, Ci: {}, Cu: {} }`, + chrome: () => + `module.exports = { Cc: {}, Ci: {}, Cu: {}, components: {stack: {caller: ""}} }`, + ChromeUtils: () => `module.exports = { import: () => ({}) }`, // Some modules depend on Chrome APIs which don't work in mocha. When such a module // is required, replace it with a mock version. "devtools/shared/l10n": () => @@ -113,9 +115,8 @@ requireHacker.global_hook("default", (path, module) => { "devtools/shared/plural-form": () => getModule("devtools/client/webconsole/test/node/fixtures/PluralForm"), Services: () => `module.exports = require("devtools-services")`, - "devtools/shared/fronts/object": () => `() => {}`, - "devtools/shared/fronts/string": () => - `() => ({LongStringFront: () => {}})`, + "devtools/server/debugger-server": () => + `module.exports = {DebuggerServer: {}}`, "devtools/client/shared/components/SmartTrace": () => "{}", "devtools/client/netmonitor/src/components/TabboxPanel": () => "{}", "devtools/client/webconsole/utils/context-menu": () => "{}", diff --git a/devtools/client/webconsole/test/node/store/private-messages.test.js b/devtools/client/webconsole/test/node/store/private-messages.test.js index c2e5c03843a7..bf99b8578b5f 100644 --- a/devtools/client/webconsole/test/node/store/private-messages.test.js +++ b/devtools/client/webconsole/test/node/store/private-messages.test.js @@ -18,7 +18,6 @@ const { getFirstMessage, getLastMessage, getPrivatePacket, - getWebConsoleUiMock, setupActions, setupStore, } = require("devtools/client/webconsole/test/node/helpers"); @@ -190,27 +189,27 @@ describe("private messages", () => { it("releases private backend actors on PRIVATE_MESSAGES_CLEAR action", () => { const releasedActors = []; - const { dispatch, getState } = setupStore([], { - webConsoleUI: getWebConsoleUiMock(null, { - releaseActor: actor => { - releasedActors.push(actor); - }, - }), - }); + const { dispatch, getState } = setupStore([]); + const mockFrontRelease = function() { + releasedActors.push(this.actorID); + }; + + const publicPacket = stubPackets.get( + "console.log('myarray', ['red', 'green', 'blue'])" + ); + const privatePacket = getPrivatePacket("console.log('mymap')"); + + publicPacket.message.arguments[1].release = mockFrontRelease; + privatePacket.message.arguments[1].release = mockFrontRelease; // Add a log message. - dispatch( - actions.messagesAdd([ - stubPackets.get("console.log('myarray', ['red', 'green', 'blue'])"), - getPrivatePacket("console.log('mymap')"), - ]) - ); + dispatch(actions.messagesAdd([publicPacket, privatePacket])); const firstMessage = getFirstMessage(getState()); - const firstMessageActor = firstMessage.parameters[1].actor; + const firstMessageActor = firstMessage.parameters[1].actorID; const lastMessage = getLastMessage(getState()); - const lastMessageActor = lastMessage.parameters[1].actor; + const lastMessageActor = lastMessage.parameters[1].actorID; // Kick-off the actor release. dispatch(actions.privateMessagesClear()); diff --git a/devtools/client/webconsole/test/node/store/release-actors.test.js b/devtools/client/webconsole/test/node/store/release-actors.test.js index 48e061854143..f1bc6d073ec6 100644 --- a/devtools/client/webconsole/test/node/store/release-actors.test.js +++ b/devtools/client/webconsole/test/node/store/release-actors.test.js @@ -3,9 +3,7 @@ "use strict"; const { - clonePacket, getFirstMessage, - getWebConsoleUiMock, setupActions, setupStore, } = require("devtools/client/webconsole/test/node/helpers"); @@ -26,39 +24,40 @@ describe("Release actor enhancer:", () => { it("releases backend actors when limit reached adding a single message", () => { const logLimit = 100; const releasedActors = []; + const mockFrontRelease = function() { + releasedActors.push(this.actorID); + }; + const { dispatch, getState } = setupStore([], { storeOptions: { logLimit }, - webConsoleUI: getWebConsoleUiMock(null, { - releaseActor: actor => { - releasedActors.push(actor); - }, - }), }); // Add a log message. - dispatch( - actions.messagesAdd([ - stubPackets.get("console.log('myarray', ['red', 'green', 'blue'])"), - ]) + const packet = stubPackets.get( + "console.log('myarray', ['red', 'green', 'blue'])" ); + packet.message.arguments[1].release = mockFrontRelease; + dispatch(actions.messagesAdd([packet])); const firstMessage = getFirstMessage(getState()); - const firstMessageActor = firstMessage.parameters[1].actor; + const firstMessageActor = firstMessage.parameters[1].actorID; // Add an evaluation result message (see Bug 1408321). const evaluationResultPacket = stubPackets.get("new Date(0)"); + evaluationResultPacket.result.release = mockFrontRelease; dispatch(actions.messagesAdd([evaluationResultPacket])); - const secondMessageActor = evaluationResultPacket.result.actor; + const secondMessageActor = evaluationResultPacket.result.actorID; const logCount = logLimit + 1; - const packet = clonePacket( - stubPackets.get("console.assert(false, {message: 'foobar'})") + const assertPacket = stubPackets.get( + "console.assert(false, {message: 'foobar'})" ); - const thirdMessageActor = packet.message.arguments[0].actor; + assertPacket.message.arguments[0].release = mockFrontRelease; + const thirdMessageActor = assertPacket.message.arguments[0].actorID; for (let i = 1; i <= logCount; i++) { - packet.message.arguments.push(`message num ${i}`); - dispatch(actions.messagesAdd([packet])); + assertPacket.message.arguments.push(`message num ${i}`); + dispatch(actions.messagesAdd([assertPacket])); } expect(releasedActors.length).toBe(3); @@ -72,34 +71,35 @@ describe("Release actor enhancer:", () => { const releasedActors = []; const { dispatch, getState } = setupStore([], { storeOptions: { logLimit }, - webConsoleUI: getWebConsoleUiMock(null, { - releaseActor: actor => { - releasedActors.push(actor); - }, - }), }); + const mockFrontRelease = function() { + releasedActors.push(this.actorID); + }; + // Add a log message. - dispatch( - actions.messagesAdd([ - stubPackets.get("console.log('myarray', ['red', 'green', 'blue'])"), - ]) + const logPacket = stubPackets.get( + "console.log('myarray', ['red', 'green', 'blue'])" ); + logPacket.message.arguments[1].release = mockFrontRelease; + dispatch(actions.messagesAdd([logPacket])); const firstMessage = getFirstMessage(getState()); - const firstMessageActor = firstMessage.parameters[1].actor; + const firstMessageActor = firstMessage.parameters[1].actorID; // Add an evaluation result message (see Bug 1408321). const evaluationResultPacket = stubPackets.get("new Date(0)"); + evaluationResultPacket.result.release = mockFrontRelease; dispatch(actions.messagesAdd([evaluationResultPacket])); - const secondMessageActor = evaluationResultPacket.result.actor; + const secondMessageActor = evaluationResultPacket.result.actorID; // Add an assertion message. const assertPacket = stubPackets.get( "console.assert(false, {message: 'foobar'})" ); + assertPacket.message.arguments[0].release = mockFrontRelease; dispatch(actions.messagesAdd([assertPacket])); - const thirdMessageActor = assertPacket.message.arguments[0].actor; + const thirdMessageActor = assertPacket.message.arguments[0].actorID; // Add ${logLimit} messages so we prune the ones we added before. const packets = []; @@ -122,39 +122,42 @@ describe("Release actor enhancer:", () => { it("properly releases backend actors after clear", () => { const releasedActors = []; - const { dispatch, getState } = setupStore([], { - webConsoleUI: getWebConsoleUiMock(null, { - releaseActor: actor => { - releasedActors.push(actor); - }, - }), - }); + const { dispatch, getState } = setupStore([]); + + const mockFrontRelease = function() { + releasedActors.push(this.actorID); + }; // Add a log message. - dispatch( - actions.messagesAdd([ - stubPackets.get("console.log('myarray', ['red', 'green', 'blue'])"), - ]) + const logPacket = stubPackets.get( + "console.log('myarray', ['red', 'green', 'blue'])" ); + logPacket.message.arguments[1].release = mockFrontRelease; + dispatch(actions.messagesAdd([logPacket])); const firstMessage = getFirstMessage(getState()); - const firstMessageActor = firstMessage.parameters[1].actor; + const firstMessageActor = firstMessage.parameters[1].actorID; - const packet = clonePacket( - stubPackets.get("console.assert(false, {message: 'foobar'})") + // Add an assertion message. + const assertPacket = stubPackets.get( + "console.assert(false, {message: 'foobar'})" ); - const secondMessageActor = packet.message.arguments[0].actor; - dispatch(actions.messagesAdd([packet])); + assertPacket.message.arguments[0].release = mockFrontRelease; + dispatch(actions.messagesAdd([assertPacket])); + const secondMessageActor = assertPacket.message.arguments[0].actorID; // Add an evaluation result message (see Bug 1408321). const evaluationResultPacket = stubPackets.get("new Date(0)"); + evaluationResultPacket.result.release = mockFrontRelease; dispatch(actions.messagesAdd([evaluationResultPacket])); - const thirdMessageActor = evaluationResultPacket.result.actor; + const thirdMessageActor = evaluationResultPacket.result.actorID; // Add a message with a long string messageText property. const longStringPacket = stubPackets.get("TypeError longString message"); + longStringPacket.pageError.errorMessage.release = mockFrontRelease; dispatch(actions.messagesAdd([longStringPacket])); - const fourthMessageActor = longStringPacket.pageError.errorMessage.actor; + const fourthMessageActor = + longStringPacket.pageError.errorMessage.actorID; // Kick-off the actor release. dispatch(actions.messagesClear()); diff --git a/devtools/client/webconsole/test/node/store/ui.test.js b/devtools/client/webconsole/test/node/store/ui.test.js index ab6015000184..8b4315a465fe 100644 --- a/devtools/client/webconsole/test/node/store/ui.test.js +++ b/devtools/client/webconsole/test/node/store/ui.test.js @@ -29,9 +29,9 @@ describe("Testing UI", () => { const message = stubPreparedMessages.get("inspect({a: 1})"); store.dispatch(actions.messagesAdd([packet])); - const actorId = message.parameters[0].actor; + const { actorID } = message.parameters[0]; const messageId = getFirstMessage(store.getState()).id; - store.dispatch(actions.showMessageObjectInSidebar(actorId, messageId)); + store.dispatch(actions.showMessageObjectInSidebar(actorID, messageId)); expect(store.getState().ui.sidebarVisible).toEqual(true); store.dispatch(actions.sidebarClose()); @@ -45,9 +45,9 @@ describe("Testing UI", () => { const message = stubPreparedMessages.get("inspect({a: 1})"); store.dispatch(actions.messagesAdd([packet])); - const actorId = message.parameters[0].actor; + const { actorID } = message.parameters[0]; const messageId = getFirstMessage(store.getState()).id; - store.dispatch(actions.showMessageObjectInSidebar(actorId, messageId)); + store.dispatch(actions.showMessageObjectInSidebar(actorID, messageId)); expect(store.getState().ui.sidebarVisible).toEqual(true); store.dispatch(actions.messagesClear()); @@ -63,12 +63,12 @@ describe("Testing UI", () => { const message = stubPreparedMessages.get("inspect({a: 1})"); store.dispatch(actions.messagesAdd([packet])); - const actorId = message.parameters[0].actor; + const { actorID } = message.parameters[0]; const messageId = getFirstMessage(store.getState()).id; - store.dispatch(actions.showMessageObjectInSidebar(actorId, messageId)); + store.dispatch(actions.showMessageObjectInSidebar(actorID, messageId)); expect(store.getState().ui.sidebarVisible).toEqual(true); - expect(store.getState().ui.gripInSidebar).toEqual(message.parameters[0]); + expect(store.getState().ui.frontInSidebar).toEqual(message.parameters[0]); }); it("sidebar is not updated for the same object", () => { @@ -76,15 +76,15 @@ describe("Testing UI", () => { const message = stubPreparedMessages.get("inspect({a: 1})"); store.dispatch(actions.messagesAdd([packet])); - const actorId = message.parameters[0].actor; + const { actorID } = message.parameters[0]; const messageId = getFirstMessage(store.getState()).id; - store.dispatch(actions.showMessageObjectInSidebar(actorId, messageId)); + store.dispatch(actions.showMessageObjectInSidebar(actorID, messageId)); expect(store.getState().ui.sidebarVisible).toEqual(true); - expect(store.getState().ui.gripInSidebar).toEqual(message.parameters[0]); + expect(store.getState().ui.frontInSidebar).toEqual(message.parameters[0]); const state = store.getState().ui; - store.dispatch(actions.showMessageObjectInSidebar(actorId, messageId)); + store.dispatch(actions.showMessageObjectInSidebar(actorID, messageId)); expect(store.getState().ui).toEqual(state); }); @@ -93,25 +93,25 @@ describe("Testing UI", () => { const message = stubPreparedMessages.get("inspect({a: 1})"); store.dispatch(actions.messagesAdd([packet])); - const actorId = message.parameters[0].actor; + const { actorID } = message.parameters[0]; const messageId = getFirstMessage(store.getState()).id; - store.dispatch(actions.showMessageObjectInSidebar(actorId, messageId)); + store.dispatch(actions.showMessageObjectInSidebar(actorID, messageId)); expect(store.getState().ui.sidebarVisible).toEqual(true); - expect(store.getState().ui.gripInSidebar).toEqual(message.parameters[0]); + expect(store.getState().ui.frontInSidebar).toEqual(message.parameters[0]); const newPacket = stubPackets.get("new Date(0)"); const newMessage = stubPreparedMessages.get("new Date(0)"); store.dispatch(actions.messagesAdd([newPacket])); - const newActorId = newMessage.parameters[0].actor; + const newActorID = newMessage.parameters[0].actorID; const newMessageId = getLastMessage(store.getState()).id; store.dispatch( - actions.showMessageObjectInSidebar(newActorId, newMessageId) + actions.showMessageObjectInSidebar(newActorID, newMessageId) ); expect(store.getState().ui.sidebarVisible).toEqual(true); - expect(store.getState().ui.gripInSidebar).toEqual( + expect(store.getState().ui.frontInSidebar).toEqual( newMessage.parameters[0] ); }); diff --git a/devtools/client/webconsole/utils/object-inspector.js b/devtools/client/webconsole/utils/object-inspector.js index 322ab6ac8bdf..ef20b4ba45a8 100644 --- a/devtools/client/webconsole/utils/object-inspector.js +++ b/devtools/client/webconsole/utils/object-inspector.js @@ -26,8 +26,22 @@ loader.lazyRequireGetter( "devtools/client/shared/components/SmartTrace" ); +loader.lazyRequireGetter( + this, + "LongStringFront", + "devtools/shared/fronts/string", + true +); + +loader.lazyRequireGetter( + this, + "ObjectFront", + "devtools/shared/fronts/object", + true +); + /** - * Create and return an ObjectInspector for the given grip. + * Create and return an ObjectInspector for the given front. * * @param {Object} grip * The object grip to create an ObjectInspector for. @@ -39,7 +53,11 @@ loader.lazyRequireGetter( * @returns {ObjectInspector} * An ObjectInspector for the given grip. */ -function getObjectInspector(grip, serviceContainer, override = {}) { +function getObjectInspector( + frontOrPrimitiveGrip, + serviceContainer, + override = {} +) { let onDOMNodeMouseOver; let onDOMNodeMouseOut; let onInspectIconClick; @@ -60,7 +78,7 @@ function getObjectInspector(grip, serviceContainer, override = {}) { : null; } - const roots = createRootsFromGrip(grip, override.pathPrefix); + const roots = createRoots(frontOrPrimitiveGrip, override.pathPrefix); const objectInspectorProps = { autoExpandDepth: 0, @@ -86,29 +104,36 @@ function getObjectInspector(grip, serviceContainer, override = {}) { }), }; - if (!(typeof grip === "string" || (grip && grip.type === "longString"))) { - Object.assign(objectInspectorProps, { - onDOMNodeMouseOver, - onDOMNodeMouseOut, - onInspectIconClick, - defaultRep: REPS.Grip, - }); - } + Object.assign(objectInspectorProps, { + onDOMNodeMouseOver, + onDOMNodeMouseOut, + onInspectIconClick, + defaultRep: REPS.Grip, + }); if (override.autoFocusRoot) { Object.assign(objectInspectorProps, { - focusedItem: roots[0], + focusedItem: objectInspectorProps.roots[0], }); } return ObjectInspector({ ...objectInspectorProps, ...override }); } -function createRootsFromGrip(grip, pathPrefix = "") { +function createRoots(frontOrPrimitiveGrip, pathPrefix = "") { + const isFront = + frontOrPrimitiveGrip instanceof ObjectFront || + frontOrPrimitiveGrip instanceof LongStringFront; + const grip = isFront ? frontOrPrimitiveGrip.getGrip() : frontOrPrimitiveGrip; + return [ { - path: `${pathPrefix}${(grip && grip.actor) || JSON.stringify(grip)}`, - contents: { value: grip }, + path: `${pathPrefix}${ + frontOrPrimitiveGrip + ? frontOrPrimitiveGrip.actorID || frontOrPrimitiveGrip.actor + : null + }`, + contents: { value: grip, front: isFront ? frontOrPrimitiveGrip : null }, }, ]; } diff --git a/devtools/client/webconsole/webconsole-connection-proxy.js b/devtools/client/webconsole/webconsole-connection-proxy.js index 64d78987de55..a8ab013c29d7 100644 --- a/devtools/client/webconsole/webconsole-connection-proxy.js +++ b/devtools/client/webconsole/webconsole-connection-proxy.js @@ -356,24 +356,6 @@ class WebConsoleConnectionProxy { this.webConsoleUI.wrapper.dispatchMessageUpdate(networkInfo, response); } - /** - * Release an object actor. - * - * @param string actor - * The actor ID to send the request to. - */ - releaseActor(actor) { - if (this.client) { - const objFront = this.client.getFrontByID(actor); - if (objFront) { - objFront.release().catch(() => {}); - return; - } - // In case there's no object front, use the client's release method. - this.client.release(actor).catch(() => {}); - } - } - /** * Disconnect the Web Console from the remote server. * diff --git a/devtools/client/webconsole/webconsole-ui.js b/devtools/client/webconsole/webconsole-ui.js index 54c44c1ffe23..3a397ffb9654 100644 --- a/devtools/client/webconsole/webconsole-ui.js +++ b/devtools/client/webconsole/webconsole-ui.js @@ -17,6 +17,9 @@ var ChromeUtils = require("ChromeUtils"); const { BrowserLoader } = ChromeUtils.import( "resource://devtools/client/shared/browser-loader.js" ); +const { + getAdHocFrontOrPrimitiveGrip, +} = require("devtools/shared/fronts/object"); loader.lazyRequireGetter( this, @@ -245,11 +248,15 @@ class WebConsoleUI { } inspectObjectActor(objectActor) { + const webConsoleFront = this.webConsoleFront; this.wrapper.dispatchMessageAdd( { helperResult: { type: "inspectObject", - object: objectActor, + object: + objectActor && objectActor.getGrip + ? objectActor + : getAdHocFrontOrPrimitiveGrip(objectActor, webConsoleFront), }, }, true @@ -478,22 +485,6 @@ class WebConsoleUI { } } - /** - * Release an actor. - * - * @private - * @param string actor - * The actor ID you want to release. - */ - releaseActor(actor) { - const proxy = this.getProxy(); - if (!proxy) { - return null; - } - - return proxy.releaseActor(actor); - } - /** * @param {String} expression * @param {Object} options