diff --git a/devtools/client/webconsole/new-console-output/constants.js b/devtools/client/webconsole/new-console-output/constants.js index edcdd7d381da..7a3ea2ab7af4 100644 --- a/devtools/client/webconsole/new-console-output/constants.js +++ b/devtools/client/webconsole/new-console-output/constants.js @@ -44,7 +44,10 @@ const chromeRDPEnums = { // Undocumented in Chrome RDP, but is used for evaluation results. RESULT: "result", // Undocumented in Chrome RDP, but is used for input. - COMMAND: "command" + COMMAND: "command", + // Undocumented in Chrome RDP, but is used for messages that should not + // output anything (e.g. `console.time()` calls). + NULL_MESSAGE: "nullMessage", }, MESSAGE_LEVEL: { LOG: "log", diff --git a/devtools/client/webconsole/new-console-output/reducers/messages.js b/devtools/client/webconsole/new-console-output/reducers/messages.js index 428905059dfb..622096c9ba58 100644 --- a/devtools/client/webconsole/new-console-output/reducers/messages.js +++ b/devtools/client/webconsole/new-console-output/reducers/messages.js @@ -21,7 +21,11 @@ function messages(state = new MessageState(), action) { case constants.MESSAGE_ADD: let newMessage = action.message; - if (newMessage.type === "clear") { + if (newMessage.type === constants.MESSAGE_TYPE.NULL_MESSAGE) { + return state; + } + + if (newMessage.type === constants.MESSAGE_TYPE.CLEAR) { return state.set("messagesById", Immutable.List([newMessage])); } diff --git a/devtools/client/webconsole/new-console-output/test/components/console-api-call.test.js b/devtools/client/webconsole/new-console-output/test/components/console-api-call.test.js index 5da278a9248d..282bc39355e4 100644 --- a/devtools/client/webconsole/new-console-output/test/components/console-api-call.test.js +++ b/devtools/client/webconsole/new-console-output/test/components/console-api-call.test.js @@ -46,6 +46,27 @@ describe("ConsoleAPICall component:", () => { expect(messageBody.textContent).toBe(message.messageText); }); }); + + describe("console.time", () => { + it("does not show anything", () => { + const message = stubConsoleMessages.get("console.time('bar')"); + const rendered = renderComponent(ConsoleApiCall, {message, onViewSourceInDebugger}); + + const messageBody = getMessageBody(rendered); + expect(messageBody.textContent).toBe(""); + }); + }); + + describe("console.timeEnd", () => { + it("renders as expected", () => { + const message = stubConsoleMessages.get("console.timeEnd('bar')"); + const rendered = renderComponent(ConsoleApiCall, {message, onViewSourceInDebugger}); + + const messageBody = getMessageBody(rendered); + expect(messageBody.textContent).toBe(message.messageText); + expect(messageBody.textContent).toMatch(/^bar: \d+(\.\d+)?ms$/); + }); + }); }); function getMessageBody(rendered) { @@ -56,4 +77,4 @@ function getMessageBody(rendered) { function getRepeatNode(rendered) { const repeatPath = "span > span.message-flex-body > span.message-body.devtools-monospace + span.message-repeats"; return rendered.querySelectorAll(repeatPath); -} \ No newline at end of file +} diff --git a/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/browser_webconsole_update_stubs_console_api.js b/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/browser_webconsole_update_stubs_console_api.js index 4e73c760eb7c..08261822970e 100644 --- a/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/browser_webconsole_update_stubs_console_api.js +++ b/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/browser_webconsole_update_stubs_console_api.js @@ -12,11 +12,10 @@ const TEST_URI = "http://example.com/browser/devtools/client/webconsole/new-cons let stubs = []; -snippets.forEach((code, key) => { - add_task(function* () { - let tempFilePath = OS.Path.join(`${BASE_PATH}/stub-generators`, "test-tempfile.js"); +add_task(function* () { + let tempFilePath = OS.Path.join(`${BASE_PATH}/stub-generators`, "test-tempfile.js"); + for (var [key, {keys, code}] of snippets) { OS.File.writeAtomic(tempFilePath, `function triggerPacket() {${code}}`); - let toolbox = yield openNewTabAndToolbox(TEST_URI, "webconsole"); let hud = toolbox.getCurrentPanel().hud; let {ui} = hud; @@ -24,17 +23,23 @@ snippets.forEach((code, key) => { ok(ui.jsterm, "jsterm exists"); ok(ui.newConsoleOutput, "newConsoleOutput exists"); - toolbox.target.client.addListener("consoleAPICall", (type, res) => { - stubs.push(formatStub(key, res)); - if (stubs.length == snippets.size) { - let filePath = OS.Path.join(`${BASE_PATH}/stubs`, "consoleApi.js"); - OS.File.writeAtomic(filePath, formatFile(stubs)); - OS.File.writeAtomic(tempFilePath, ""); - } + let received = new Promise(resolve => { + let i = 0; + toolbox.target.client.addListener("consoleAPICall", (type, res) => { + stubs.push(formatStub(keys[i], res)); + if(++i === keys.length ){ + resolve(); + } + }); }); yield ContentTask.spawn(gBrowser.selectedBrowser, {}, function() { content.wrappedJSObject.triggerPacket(); }); - }); + + yield received; + } + let filePath = OS.Path.join(`${BASE_PATH}/stubs`, "consoleApi.js"); + OS.File.writeAtomic(filePath, formatFile(stubs)); + OS.File.writeAtomic(tempFilePath, ""); }); diff --git a/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/stub-snippets.js b/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/stub-snippets.js index 73988352096e..92b2df4d41ff 100644 --- a/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/stub-snippets.js +++ b/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/stub-snippets.js @@ -15,10 +15,12 @@ const consoleApiCommands = [ "console.count('bar')", ]; -let consoleApi = new Map(consoleApiCommands.map(cmd => [cmd, cmd])); +let consoleApi = new Map(consoleApiCommands.map( + cmd => [cmd, {keys: [cmd], code: cmd}])); -consoleApi.set("console.trace()", -` +consoleApi.set("console.trace()", { + keys: ["console.trace()"], + code: ` function bar() { console.trace() } @@ -27,13 +29,14 @@ function foo() { } foo() -`); +`}); -consoleApi.set("console.time()", -` -console.time() -console.timeEnd() -`); +consoleApi.set("console.time('bar')", { + keys: ["console.time('bar')", "console.timeEnd('bar')"], + code: ` +console.time("bar"); +console.timeEnd("bar"); +`}); // Evaluation Result diff --git a/devtools/client/webconsole/new-console-output/test/fixtures/stubs/consoleApi.js b/devtools/client/webconsole/new-console-output/test/fixtures/stubs/consoleApi.js index 96fa5b71c275..bd959ff1c9d0 100644 --- a/devtools/client/webconsole/new-console-output/test/fixtures/stubs/consoleApi.js +++ b/devtools/client/webconsole/new-console-output/test/fixtures/stubs/consoleApi.js @@ -196,5 +196,41 @@ stubConsoleMessages.set("console.trace()", new ConsoleMessage({ } })); +stubConsoleMessages.set("console.time('bar')", new ConsoleMessage({ + "id": "1", + "allowRepeating": true, + "source": "console-api", + "type": "nullMessage", + "level": "log", + "messageText": null, + "parameters": null, + "repeat": 1, + "repeatId": "{\"id\":null,\"allowRepeating\":true,\"source\":\"console-api\",\"type\":\"nullMessage\",\"level\":\"log\",\"messageText\":null,\"parameters\":null,\"repeatId\":null,\"stacktrace\":null,\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js\",\"line\":2,\"column\":1}}", + "stacktrace": null, + "frame": { + "source": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js", + "line": 2, + "column": 1 + } +})); + +stubConsoleMessages.set("console.timeEnd('bar')", new ConsoleMessage({ + "id": "1", + "allowRepeating": true, + "source": "console-api", + "type": "timeEnd", + "level": "log", + "messageText": "bar: 3.87ms", + "parameters": null, + "repeat": 1, + "repeatId": "{\"id\":null,\"allowRepeating\":true,\"source\":\"console-api\",\"type\":\"timeEnd\",\"level\":\"log\",\"messageText\":\"bar: 3.87ms\",\"parameters\":null,\"repeatId\":null,\"stacktrace\":null,\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js\",\"line\":3,\"column\":1}}", + "stacktrace": null, + "frame": { + "source": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js", + "line": 3, + "column": 1 + } +})); + module.exports = stubConsoleMessages \ No newline at end of file diff --git a/devtools/client/webconsole/new-console-output/test/store/messages.test.js b/devtools/client/webconsole/new-console-output/test/store/messages.test.js index 44d26114a415..81644bf9194d 100644 --- a/devtools/client/webconsole/new-console-output/test/store/messages.test.js +++ b/devtools/client/webconsole/new-console-output/test/store/messages.test.js @@ -96,4 +96,14 @@ describe("Message reducer:", () => { expect(messages.first().parameters[0]).toBe(`message num 2`); expect(messages.last().parameters[0]).toBe(`message num ${logLimit + 1}`); }); + + it("does not add null messages to the store", () => { + const { dispatch, getState } = setupStore([]); + + const message = stubConsoleMessages.get("console.time('bar')"); + dispatch(actions.messageAdd(message)); + + const messages = getAllMessages(getState()); + expect(messages.size).toBe(0); + }); }); diff --git a/devtools/client/webconsole/new-console-output/utils/messages.js b/devtools/client/webconsole/new-console-output/utils/messages.js index bbc022344de1..b6a8b292b24e 100644 --- a/devtools/client/webconsole/new-console-output/utils/messages.js +++ b/devtools/client/webconsole/new-console-output/utils/messages.js @@ -45,6 +45,7 @@ function transformPacket(packet) { let type = message.level; let level = getLevelFromType(type); let messageText = null; + const timer = message.timer; // Special per-type conversion. switch (type) { @@ -60,6 +61,23 @@ function transformPacket(packet) { messageText = `${label}: ${counter.count}`; parameters = null; break; + case "time": + // We don't show anything for console.time calls to match Chrome's behaviour. + parameters = null; + type = MESSAGE_TYPE.NULL_MESSAGE; + break; + case "timeEnd": + parameters = null; + if (timer) { + // We show the duration to users when calls console.timeEnd() is called, + // if corresponding console.time() was called before. + let duration = Math.round(timer.duration * 100) / 100; + messageText = l10n.getFormatStr("timeEnd", [timer.name, duration]); + } else { + // If the `timer` property does not exists, we don't output anything. + type = MESSAGE_TYPE.NULL_MESSAGE; + } + break; } const frame = {