Source code
Revision control
Copy as Markdown
Other Tools
/* Any copyright is dedicated to the Public Domain.
"use strict";
const reduxActions = require("resource://devtools/client/webconsole/actions/index.js");
const {
configureStore,
} = require("resource://devtools/client/webconsole/store.js");
const {
IdGenerator,
} = require("resource://devtools/client/webconsole/utils/id-generator.js");
const {
stubPackets,
const {
getMutableMessagesById,
} = require("resource://devtools/client/webconsole/selectors/messages.js");
const {
getPrefsService,
} = require("resource://devtools/client/webconsole/utils/prefs.js");
const prefsService = getPrefsService({});
const { PREFS } = require("resource://devtools/client/webconsole/constants.js");
const Telemetry = require("resource://devtools/client/shared/test-helpers/jest-fixtures/telemetry.js");
const {
getSerializedPacket,
parsePacketAndCreateFronts,
/**
* Prepare actions for use in testing.
*/
function setupActions() {
// Some actions use dependency injection. This helps them avoid using state in
// a hard-to-test way. We need to inject stubbed versions of these dependencies.
const wrappedActions = Object.assign({}, reduxActions);
const idGenerator = new IdGenerator();
wrappedActions.messagesAdd = packets => {
return reduxActions.messagesAdd(packets, idGenerator);
};
return {
...reduxActions,
messagesAdd: packets => reduxActions.messagesAdd(packets, idGenerator),
};
}
/**
* Prepare the store for use in testing.
*/
function setupStore(
input = [],
{ storeOptions = {}, actions, webConsoleUI } = {}
) {
if (!webConsoleUI) {
webConsoleUI = getWebConsoleUiMock();
}
const store = configureStore(webConsoleUI, {
...storeOptions,
thunkArgs: { toolbox: {}, webConsoleUI },
telemetry: new Telemetry(),
});
// Add the messages from the input commands to the store.
const messagesAdd = actions ? actions.messagesAdd : reduxActions.messagesAdd;
store.dispatch(messagesAdd(input.map(cmd => stubPackets.get(cmd))));
return store;
}
/**
* Create deep copy of given packet object.
*/
function clonePacket(packet) {
const strPacket = getSerializedPacket(packet);
return parsePacketAndCreateFronts(JSON.parse(strPacket));
}
/**
* Return the message in the store at the given index.
*
* @param {object} state - The redux state of the console.
* @param {int} index - The index of the message in the map.
* @return {Message} - The message, or undefined if the index does not exists in the map.
*/
function getMessageAt(state, index) {
const messageMap = getMutableMessagesById(state);
return messageMap.get(state.messages.mutableMessagesOrder[index]);
}
/**
* Return the first message in the store.
*
* @param {object} state - The redux state of the console.
* @return {Message} - The last message, or undefined if there are no message in store.
*/
function getFirstMessage(state) {
return getMessageAt(state, 0);
}
/**
* Return the last message in the store.
*
* @param {object} state - The redux state of the console.
* @return {Message} - The last message, or undefined if there are no message in store.
*/
function getLastMessage(state) {
const lastIndex = state.messages.mutableMessagesOrder.length - 1;
return getMessageAt(state, lastIndex);
}
function getFiltersPrefs() {
return Object.values(PREFS.FILTER).reduce((res, pref) => {
res[pref] = prefsService.getBoolPref(pref);
return res;
}, {});
}
function clearPrefs() {
[
"devtools.hud.loglimit",
...Object.values(PREFS.FILTER),
...Object.values(PREFS.UI),
].forEach(prefsService.clearUserPref);
}
function getPrivatePacket(key) {
const packet = clonePacket(stubPackets.get(key));
packet.private = true;
if (packet.pageError) {
packet.pageError.private = true;
}
if (Object.getOwnPropertyNames(packet).includes("private")) {
packet.private = true;
}
return packet;
}
function getWebConsoleUiMock(hud) {
return {
emit: () => {},
emitForTests: () => {},
hud: {
commands: {
client: {
mainRoot: {},
},
objectCommand: {
releaseObjects: async () => {},
},
},
...hud,
},
clearNetworkRequests: () => {},
clearMessagesCache: () => {},
inspectObjectActor: () => {},
toolbox: {},
watchCssMessages: () => {},
};
}
function formatErrorTextWithCausedBy(text) {
// The component text does not append new line character before
// the "Caused by" label, so add it here to make the assertions
// look more legible
return text.replace(/Caused by/g, "\nCaused by");
}
module.exports = {
clearPrefs,
clonePacket,
formatErrorTextWithCausedBy,
getFiltersPrefs,
getFirstMessage,
getLastMessage,
getMessageAt,
getPrivatePacket,
getWebConsoleUiMock,
prefsService,
setupActions,
setupStore,
};