diff options
Diffstat (limited to 'devtools/client/webconsole/new-console-output/test')
60 files changed, 5203 insertions, 0 deletions
diff --git a/devtools/client/webconsole/new-console-output/test/.eslintrc.js b/devtools/client/webconsole/new-console-output/test/.eslintrc.js new file mode 100644 index 000000000..e010df386 --- /dev/null +++ b/devtools/client/webconsole/new-console-output/test/.eslintrc.js @@ -0,0 +1,5 @@ +"use strict"; + +module.exports = { + "extends": ["../../../../.eslintrc.xpcshell.js"] +}; diff --git a/devtools/client/webconsole/new-console-output/test/chrome/chrome.ini b/devtools/client/webconsole/new-console-output/test/chrome/chrome.ini new file mode 100644 index 000000000..0543ae5c6 --- /dev/null +++ b/devtools/client/webconsole/new-console-output/test/chrome/chrome.ini @@ -0,0 +1,7 @@ +[DEFAULT] + +support-files = + head.js + +[test_render_perf.html] +skip-if = true # Bug 1306783 diff --git a/devtools/client/webconsole/new-console-output/test/chrome/head.js b/devtools/client/webconsole/new-console-output/test/chrome/head.js new file mode 100644 index 000000000..e8a5fd22e --- /dev/null +++ b/devtools/client/webconsole/new-console-output/test/chrome/head.js @@ -0,0 +1,16 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +var { utils: Cu } = Components; + +var { require } = Cu.import("resource://devtools/shared/Loader.jsm", {}); +var { Assert } = require("resource://testing-common/Assert.jsm"); +var { BrowserLoader } = Cu.import("resource://devtools/client/shared/browser-loader.js", {}); +var { Task } = require("devtools/shared/task"); + +var { require: browserRequire } = BrowserLoader({ + baseURI: "resource://devtools/client/webconsole/", + window +}); diff --git a/devtools/client/webconsole/new-console-output/test/chrome/test_render_perf.html b/devtools/client/webconsole/new-console-output/test/chrome/test_render_perf.html new file mode 100644 index 000000000..d22819a2b --- /dev/null +++ b/devtools/client/webconsole/new-console-output/test/chrome/test_render_perf.html @@ -0,0 +1,90 @@ +<!DOCTYPE HTML> +<html lang="en"> +<head> + <meta charset="utf8"> + <title>Test for getRepeatId()</title> + <script type="text/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> + <script type="application/javascript;version=1.8" src="head.js"></script> + <!-- Any copyright is dedicated to the Public Domain. + - http://creativecommons.org/publicdomain/zero/1.0/ --> +</head> +<body> +<p>Test for render perf</p> +<div id="output"></div> + +<script type="text/javascript;version=1.8"> +const testPackets = []; +const numMessages = 1000; +for (let id = 0; id < numMessages; id++) { + let message = "Odd text"; + if (id % 2 === 0) { + message = "Even text"; + } + testPackets.push({ + "from": "server1.conn4.child1/consoleActor2", + "type": "consoleAPICall", + "message": { + "arguments": [ + "foobar", + message, + id + ], + "columnNumber": 1, + "counter": null, + "filename": "file:///test.html", + "functionName": "", + "groupName": "", + "level": "log", + "lineNumber": 1, + "private": false, + "styles": [], + "timeStamp": 1455064271115 + id, + "timer": null, + "workerType": "none", + "category": "webdev" + } + }); +} + +function timeit(cb) { + // Return a Promise that resolves the number of seconds cb takes. + return new Promise(resolve => { + let start = performance.now(); + cb(); + let elapsed = performance.now() - start; + resolve(elapsed / 1000); + }); +} + +window.onload = Task.async(function* () { + const { configureStore } = browserRequire("devtools/client/webconsole/new-console-output/store"); + const { filterTextSet, filtersClear } = browserRequire("devtools/client/webconsole/new-console-output/actions/index"); + const NewConsoleOutputWrapper = browserRequire("devtools/client/webconsole/new-console-output/new-console-output-wrapper"); + const wrapper = new NewConsoleOutputWrapper(document.querySelector("#output"), {}); + + const store = configureStore(); + + let time = yield timeit(() => { + testPackets.forEach((message) => { + wrapper.dispatchMessageAdd(message); + }); + }); + info("took " + time + " seconds to render messages"); + + time = yield timeit(() => { + store.dispatch(filterTextSet("Odd text")); + }); + info("took " + time + " seconds to search filter half the messages"); + + time = yield timeit(() => { + store.dispatch(filtersClear()); + }); + info("took " + time + " seconds to clear the filter"); + + ok(true, "Yay, it didn't time out!"); + + SimpleTest.finish(); +}); +</script> +</body> +</html> 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 new file mode 100644 index 000000000..3b4e2b196 --- /dev/null +++ b/devtools/client/webconsole/new-console-output/test/components/console-api-call.test.js @@ -0,0 +1,230 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ +"use strict"; + +// Test utils. +const expect = require("expect"); +const { render, mount } = require("enzyme"); +const sinon = require("sinon"); + +// React +const { createFactory } = require("devtools/client/shared/vendor/react"); +const Provider = createFactory(require("react-redux").Provider); +const { setupStore } = require("devtools/client/webconsole/new-console-output/test/helpers"); + +// Components under test. +const ConsoleApiCall = createFactory(require("devtools/client/webconsole/new-console-output/components/message-types/console-api-call")); +const { + MESSAGE_OPEN, + MESSAGE_CLOSE, +} = require("devtools/client/webconsole/new-console-output/constants"); +const { INDENT_WIDTH } = require("devtools/client/webconsole/new-console-output/components/message-indent"); + +// Test fakes. +const { stubPreparedMessages } = require("devtools/client/webconsole/new-console-output/test/fixtures/stubs/index"); +const serviceContainer = require("devtools/client/webconsole/new-console-output/test/fixtures/serviceContainer"); + +const tempfilePath = "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js"; + +describe("ConsoleAPICall component:", () => { + describe("console.log", () => { + it("renders string grips", () => { + const message = stubPreparedMessages.get("console.log('foobar', 'test')"); + const wrapper = render(ConsoleApiCall({ message, serviceContainer })); + + expect(wrapper.find(".message-body").text()).toBe("foobar test"); + expect(wrapper.find(".objectBox-string").length).toBe(2); + expect(wrapper.find("div.message.cm-s-mozilla span span.message-flex-body span.message-body.devtools-monospace").length).toBe(1); + + // There should be the location + const locationLink = wrapper.find(`.message-location`); + expect(locationLink.length).toBe(1); + expect(locationLink.text()).toBe("test-tempfile.js:1:27"); + }); + + it("renders string grips with custom style", () => { + const message = stubPreparedMessages.get("console.log(%cfoobar)"); + const wrapper = render(ConsoleApiCall({ message, serviceContainer })); + + const elements = wrapper.find(".objectBox-string"); + expect(elements.text()).toBe("foobar"); + expect(elements.length).toBe(2); + + const firstElementStyle = elements.eq(0).prop("style"); + // Allowed styles are applied accordingly on the first element. + expect(firstElementStyle.color).toBe(`blue`); + expect(firstElementStyle["font-size"]).toBe(`1.3em`); + // Forbidden styles are not applied. + expect(firstElementStyle["background-image"]).toBe(undefined); + expect(firstElementStyle.position).toBe(undefined); + expect(firstElementStyle.top).toBe(undefined); + + const secondElementStyle = elements.eq(1).prop("style"); + // Allowed styles are applied accordingly on the second element. + expect(secondElementStyle.color).toBe(`red`); + // Forbidden styles are not applied. + expect(secondElementStyle.background).toBe(undefined); + }); + + it("renders repeat node", () => { + const message = + stubPreparedMessages.get("console.log('foobar', 'test')") + .set("repeat", 107); + const wrapper = render(ConsoleApiCall({ message, serviceContainer })); + + expect(wrapper.find(".message-repeats").text()).toBe("107"); + expect(wrapper.find(".message-repeats").prop("title")).toBe("107 repeats"); + + expect(wrapper.find("span > span.message-flex-body > span.message-body.devtools-monospace + span.message-repeats").length).toBe(1); + }); + + it("has the expected indent", () => { + const message = stubPreparedMessages.get("console.log('foobar', 'test')"); + + const indent = 10; + let wrapper = render(ConsoleApiCall({ message, serviceContainer, indent })); + expect(wrapper.find(".indent").prop("style").width) + .toBe(`${indent * INDENT_WIDTH}px`); + + wrapper = render(ConsoleApiCall({ message, serviceContainer})); + expect(wrapper.find(".indent").prop("style").width).toBe(`0`); + }); + }); + + describe("console.count", () => { + it("renders", () => { + const message = stubPreparedMessages.get("console.count('bar')"); + const wrapper = render(ConsoleApiCall({ message, serviceContainer })); + + expect(wrapper.find(".message-body").text()).toBe("bar: 1"); + }); + }); + + describe("console.assert", () => { + it("renders", () => { + const message = stubPreparedMessages.get("console.assert(false, {message: 'foobar'})"); + const wrapper = render(ConsoleApiCall({ message, serviceContainer })); + + expect(wrapper.find(".message-body").text()).toBe("Assertion failed: Object { message: \"foobar\" }"); + }); + }); + + describe("console.time", () => { + it("does not show anything", () => { + const message = stubPreparedMessages.get("console.time('bar')"); + const wrapper = render(ConsoleApiCall({ message, serviceContainer })); + + expect(wrapper.find(".message-body").text()).toBe(""); + }); + }); + + describe("console.timeEnd", () => { + it("renders as expected", () => { + const message = stubPreparedMessages.get("console.timeEnd('bar')"); + const wrapper = render(ConsoleApiCall({ message, serviceContainer })); + + expect(wrapper.find(".message-body").text()).toBe(message.messageText); + expect(wrapper.find(".message-body").text()).toMatch(/^bar: \d+(\.\d+)?ms$/); + }); + }); + + describe("console.trace", () => { + it("renders", () => { + const message = stubPreparedMessages.get("console.trace()"); + const wrapper = render(ConsoleApiCall({ message, serviceContainer, open: true })); + const filepath = `${tempfilePath}`; + + expect(wrapper.find(".message-body").text()).toBe("console.trace()"); + + const frameLinks = wrapper.find(`.stack-trace span.frame-link[data-url='${filepath}']`); + expect(frameLinks.length).toBe(3); + + expect(frameLinks.eq(0).find(".frame-link-function-display-name").text()).toBe("testStacktraceFiltering"); + expect(frameLinks.eq(0).find(".frame-link-filename").text()).toBe(filepath); + + expect(frameLinks.eq(1).find(".frame-link-function-display-name").text()).toBe("foo"); + expect(frameLinks.eq(1).find(".frame-link-filename").text()).toBe(filepath); + + expect(frameLinks.eq(2).find(".frame-link-function-display-name").text()).toBe("triggerPacket"); + expect(frameLinks.eq(2).find(".frame-link-filename").text()).toBe(filepath); + + //it should not be collapsible. + expect(wrapper.find(`.theme-twisty`).length).toBe(0); + }); + }); + + describe("console.group", () => { + it("renders", () => { + const message = stubPreparedMessages.get("console.group('bar')"); + const wrapper = render(ConsoleApiCall({ message, serviceContainer, open: true })); + + expect(wrapper.find(".message-body").text()).toBe(message.messageText); + expect(wrapper.find(".theme-twisty.open").length).toBe(1); + }); + + it("toggle the group when the collapse button is clicked", () => { + const store = setupStore([]); + store.dispatch = sinon.spy(); + const message = stubPreparedMessages.get("console.group('bar')"); + + let wrapper = mount(Provider({store}, + ConsoleApiCall({ + message, + open: true, + dispatch: store.dispatch, + serviceContainer, + }) + )); + wrapper.find(".theme-twisty.open").simulate("click"); + let call = store.dispatch.getCall(0); + expect(call.args[0]).toEqual({ + id: message.id, + type: MESSAGE_CLOSE + }); + + wrapper = mount(Provider({store}, + ConsoleApiCall({ + message, + open: false, + dispatch: store.dispatch, + serviceContainer, + }) + )); + wrapper.find(".theme-twisty").simulate("click"); + call = store.dispatch.getCall(1); + expect(call.args[0]).toEqual({ + id: message.id, + type: MESSAGE_OPEN + }); + }); + }); + + describe("console.groupEnd", () => { + it("does not show anything", () => { + const message = stubPreparedMessages.get("console.groupEnd('bar')"); + const wrapper = render(ConsoleApiCall({ message, serviceContainer })); + + expect(wrapper.find(".message-body").text()).toBe(""); + }); + }); + + describe("console.groupCollapsed", () => { + it("renders", () => { + const message = stubPreparedMessages.get("console.groupCollapsed('foo')"); + const wrapper = render(ConsoleApiCall({ message, serviceContainer, open: false})); + + expect(wrapper.find(".message-body").text()).toBe(message.messageText); + expect(wrapper.find(".theme-twisty:not(.open)").length).toBe(1); + }); + }); + + describe("console.dirxml", () => { + it("renders", () => { + const message = stubPreparedMessages.get("console.dirxml(window)"); + const wrapper = render(ConsoleApiCall({ message, serviceContainer })); + + expect(wrapper.find(".message-body").text()) + .toBe("Window http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-console-api.html"); + }); + }); +}); diff --git a/devtools/client/webconsole/new-console-output/test/components/evaluation-result.test.js b/devtools/client/webconsole/new-console-output/test/components/evaluation-result.test.js new file mode 100644 index 000000000..4d7890807 --- /dev/null +++ b/devtools/client/webconsole/new-console-output/test/components/evaluation-result.test.js @@ -0,0 +1,84 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ +"use strict"; + +// Test utils. +const expect = require("expect"); +const { render, mount } = require("enzyme"); +const sinon = require("sinon"); + +// React +const { createFactory } = require("devtools/client/shared/vendor/react"); +const Provider = createFactory(require("react-redux").Provider); +const { setupStore } = require("devtools/client/webconsole/new-console-output/test/helpers"); + +// Components under test. +const EvaluationResult = createFactory(require("devtools/client/webconsole/new-console-output/components/message-types/evaluation-result")); +const { INDENT_WIDTH } = require("devtools/client/webconsole/new-console-output/components/message-indent"); + +// Test fakes. +const { stubPreparedMessages } = require("devtools/client/webconsole/new-console-output/test/fixtures/stubs/index"); +const serviceContainer = require("devtools/client/webconsole/new-console-output/test/fixtures/serviceContainer"); + +describe("EvaluationResult component:", () => { + it("renders a grip result", () => { + const message = stubPreparedMessages.get("new Date(0)"); + const wrapper = render(EvaluationResult({ message })); + + expect(wrapper.find(".message-body").text()).toBe("Date 1970-01-01T00:00:00.000Z"); + + expect(wrapper.find(".message.log").length).toBe(1); + }); + + it("renders an error", () => { + const message = stubPreparedMessages.get("asdf()"); + const wrapper = render(EvaluationResult({ message })); + + expect(wrapper.find(".message-body").text()) + .toBe("ReferenceError: asdf is not defined[Learn More]"); + + expect(wrapper.find(".message.error").length).toBe(1); + }); + + it("displays a [Learn more] link", () => { + const store = setupStore([]); + + const message = stubPreparedMessages.get("asdf()"); + + serviceContainer.openLink = sinon.spy(); + const wrapper = mount(Provider({store}, + EvaluationResult({message, serviceContainer}) + )); + + const url = + "https://developer.mozilla.org/docs/Web/JavaScript/Reference/Errors/Not_defined"; + const learnMore = wrapper.find(".learn-more-link"); + expect(learnMore.length).toBe(1); + expect(learnMore.prop("title")).toBe(url); + + learnMore.simulate("click"); + let call = serviceContainer.openLink.getCall(0); + expect(call.args[0]).toEqual(message.exceptionDocURL); + }); + + it("has the expected indent", () => { + const message = stubPreparedMessages.get("new Date(0)"); + + const indent = 10; + let wrapper = render(EvaluationResult({ message, indent})); + expect(wrapper.find(".indent").prop("style").width) + .toBe(`${indent * INDENT_WIDTH}px`); + + wrapper = render(EvaluationResult({ message})); + expect(wrapper.find(".indent").prop("style").width).toBe(`0`); + }); + + it("has location information", () => { + const message = stubPreparedMessages.get("1 + @"); + const wrapper = render(EvaluationResult({ message })); + + const locationLink = wrapper.find(`.message-location`); + expect(locationLink.length).toBe(1); + expect(locationLink.text()).toBe("debugger eval code:1:4"); + }); +}); diff --git a/devtools/client/webconsole/new-console-output/test/components/filter-bar.test.js b/devtools/client/webconsole/new-console-output/test/components/filter-bar.test.js new file mode 100644 index 000000000..23f958cd9 --- /dev/null +++ b/devtools/client/webconsole/new-console-output/test/components/filter-bar.test.js @@ -0,0 +1,96 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ +"use strict"; + +const expect = require("expect"); +const sinon = require("sinon"); +const { render, mount } = require("enzyme"); + +const { createFactory } = require("devtools/client/shared/vendor/react"); +const Provider = createFactory(require("react-redux").Provider); + +const FilterButton = createFactory(require("devtools/client/webconsole/new-console-output/components/filter-button")); +const FilterBar = createFactory(require("devtools/client/webconsole/new-console-output/components/filter-bar")); +const { getAllUi } = require("devtools/client/webconsole/new-console-output/selectors/ui"); +const { + MESSAGES_CLEAR, + MESSAGE_LEVEL +} = require("devtools/client/webconsole/new-console-output/constants"); + +const { setupStore } = require("devtools/client/webconsole/new-console-output/test/helpers"); +const serviceContainer = require("devtools/client/webconsole/new-console-output/test/fixtures/serviceContainer"); + +describe("FilterBar component:", () => { + it("initial render", () => { + const store = setupStore([]); + + const wrapper = render(Provider({store}, FilterBar({ serviceContainer }))); + const toolbar = wrapper.find( + ".devtools-toolbar.webconsole-filterbar-primary" + ); + + // Clear button + expect(toolbar.children().eq(0).attr("class")) + .toBe("devtools-button devtools-clear-icon"); + expect(toolbar.children().eq(0).attr("title")).toBe("Clear output"); + + // Filter bar toggle + expect(toolbar.children().eq(1).attr("class")) + .toBe("devtools-button devtools-filter-icon"); + expect(toolbar.children().eq(1).attr("title")).toBe("Toggle filter bar"); + + // Text filter + expect(toolbar.children().eq(2).attr("class")).toBe("devtools-plaininput text-filter"); + expect(toolbar.children().eq(2).attr("placeholder")).toBe("Filter output"); + expect(toolbar.children().eq(2).attr("type")).toBe("search"); + expect(toolbar.children().eq(2).attr("value")).toBe(""); + }); + + it("displays filter bar when button is clicked", () => { + const store = setupStore([]); + + expect(getAllUi(store.getState()).filterBarVisible).toBe(false); + + const wrapper = mount(Provider({store}, FilterBar({ serviceContainer }))); + wrapper.find(".devtools-filter-icon").simulate("click"); + + expect(getAllUi(store.getState()).filterBarVisible).toBe(true); + + // Buttons are displayed + const buttonProps = { + active: true, + dispatch: store.dispatch + }; + const logButton = FilterButton(Object.assign({}, buttonProps, + { label: "Logs", filterKey: MESSAGE_LEVEL.LOG })); + const debugButton = FilterButton(Object.assign({}, buttonProps, + { label: "Debug", filterKey: MESSAGE_LEVEL.DEBUG })); + const infoButton = FilterButton(Object.assign({}, buttonProps, + { label: "Info", filterKey: MESSAGE_LEVEL.INFO })); + const warnButton = FilterButton(Object.assign({}, buttonProps, + { label: "Warnings", filterKey: MESSAGE_LEVEL.WARN })); + const errorButton = FilterButton(Object.assign({}, buttonProps, + { label: "Errors", filterKey: MESSAGE_LEVEL.ERROR })); + expect(wrapper.contains([errorButton, warnButton, logButton, infoButton, debugButton])).toBe(true); + }); + + it("fires MESSAGES_CLEAR action when clear button is clicked", () => { + const store = setupStore([]); + store.dispatch = sinon.spy(); + + const wrapper = mount(Provider({store}, FilterBar({ serviceContainer }))); + wrapper.find(".devtools-clear-icon").simulate("click"); + const call = store.dispatch.getCall(0); + expect(call.args[0]).toEqual({ + type: MESSAGES_CLEAR + }); + }); + + it("sets filter text when text is typed", () => { + const store = setupStore([]); + + const wrapper = mount(Provider({store}, FilterBar({ serviceContainer }))); + wrapper.find(".devtools-plaininput").simulate("input", { target: { value: "a" } }); + expect(store.getState().filters.text).toBe("a"); + }); +}); diff --git a/devtools/client/webconsole/new-console-output/test/components/filter-button.test.js b/devtools/client/webconsole/new-console-output/test/components/filter-button.test.js new file mode 100644 index 000000000..3774da0b8 --- /dev/null +++ b/devtools/client/webconsole/new-console-output/test/components/filter-button.test.js @@ -0,0 +1,34 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ +"use strict"; + +const expect = require("expect"); +const { render } = require("enzyme"); + +const { createFactory } = require("devtools/client/shared/vendor/react"); + +const FilterButton = createFactory(require("devtools/client/webconsole/new-console-output/components/filter-button")); +const { MESSAGE_LEVEL } = require("devtools/client/webconsole/new-console-output/constants"); + +describe("FilterButton component:", () => { + const props = { + active: true, + label: "Error", + filterKey: MESSAGE_LEVEL.ERROR, + }; + + it("displays as active when turned on", () => { + const wrapper = render(FilterButton(props)); + expect(wrapper.html()).toBe( + "<button class=\"menu-filter-button error checked\">Error</button>" + ); + }); + + it("displays as inactive when turned off", () => { + const inactiveProps = Object.assign({}, props, { active: false }); + const wrapper = render(FilterButton(inactiveProps)); + expect(wrapper.html()).toBe( + "<button class=\"menu-filter-button error\">Error</button>" + ); + }); +}); diff --git a/devtools/client/webconsole/new-console-output/test/components/message-container.test.js b/devtools/client/webconsole/new-console-output/test/components/message-container.test.js new file mode 100644 index 000000000..2377af906 --- /dev/null +++ b/devtools/client/webconsole/new-console-output/test/components/message-container.test.js @@ -0,0 +1,54 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ +"use strict"; + +// Test utils. +const expect = require("expect"); +const { + renderComponent, + shallowRenderComponent +} = require("devtools/client/webconsole/new-console-output/test/helpers"); + +// Components under test. +const { MessageContainer } = require("devtools/client/webconsole/new-console-output/components/message-container"); +const ConsoleApiCall = require("devtools/client/webconsole/new-console-output/components/message-types/console-api-call"); +const EvaluationResult = require("devtools/client/webconsole/new-console-output/components/message-types/evaluation-result"); +const PageError = require("devtools/client/webconsole/new-console-output/components/message-types/page-error"); + +// Test fakes. +const { stubPreparedMessages } = require("devtools/client/webconsole/new-console-output/test/fixtures/stubs/index"); +const serviceContainer = require("devtools/client/webconsole/new-console-output/test/fixtures/serviceContainer"); + +describe("MessageContainer component:", () => { + it("pipes data to children as expected", () => { + const message = stubPreparedMessages.get("console.log('foobar', 'test')"); + const rendered = renderComponent(MessageContainer, {message, serviceContainer}); + + expect(rendered.textContent.includes("foobar")).toBe(true); + }); + it("picks correct child component", () => { + const messageTypes = [ + { + component: ConsoleApiCall, + message: stubPreparedMessages.get("console.log('foobar', 'test')") + }, + { + component: EvaluationResult, + message: stubPreparedMessages.get("new Date(0)") + }, + { + component: PageError, + message: stubPreparedMessages.get("ReferenceError: asdf is not defined") + } + ]; + + messageTypes.forEach(info => { + const { component, message } = info; + const rendered = shallowRenderComponent(MessageContainer, { + message, + serviceContainer, + }); + expect(rendered.type).toBe(component); + }); + }); +}); diff --git a/devtools/client/webconsole/new-console-output/test/components/message-icon.test.js b/devtools/client/webconsole/new-console-output/test/components/message-icon.test.js new file mode 100644 index 000000000..0244f08cf --- /dev/null +++ b/devtools/client/webconsole/new-console-output/test/components/message-icon.test.js @@ -0,0 +1,23 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ +"use strict"; + +const { + MESSAGE_LEVEL, +} = require("devtools/client/webconsole/new-console-output/constants"); +const MessageIcon = require("devtools/client/webconsole/new-console-output/components/message-icon"); + +const expect = require("expect"); + +const { + renderComponent +} = require("devtools/client/webconsole/new-console-output/test/helpers"); + +describe("MessageIcon component:", () => { + it("renders icon based on level", () => { + const rendered = renderComponent(MessageIcon, { level: MESSAGE_LEVEL.ERROR }); + + expect(rendered.classList.contains("icon")).toBe(true); + expect(rendered.getAttribute("title")).toBe("Error"); + }); +}); diff --git a/devtools/client/webconsole/new-console-output/test/components/message-repeat.test.js b/devtools/client/webconsole/new-console-output/test/components/message-repeat.test.js new file mode 100644 index 000000000..0257a3aad --- /dev/null +++ b/devtools/client/webconsole/new-console-output/test/components/message-repeat.test.js @@ -0,0 +1,25 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ +"use strict"; + +const MessageRepeat = require("devtools/client/webconsole/new-console-output/components/message-repeat"); + +const expect = require("expect"); + +const { + renderComponent +} = require("devtools/client/webconsole/new-console-output/test/helpers"); + +describe("MessageRepeat component:", () => { + it("renders repeated value correctly", () => { + const rendered = renderComponent(MessageRepeat, { repeat: 99 }); + expect(rendered.classList.contains("message-repeats")).toBe(true); + expect(rendered.style.visibility).toBe("visible"); + expect(rendered.textContent).toBe("99"); + }); + + it("renders an un-repeated value correctly", () => { + const rendered = renderComponent(MessageRepeat, { repeat: 1 }); + expect(rendered.style.visibility).toBe("hidden"); + }); +}); diff --git a/devtools/client/webconsole/new-console-output/test/components/network-event-message.test.js b/devtools/client/webconsole/new-console-output/test/components/network-event-message.test.js new file mode 100644 index 000000000..8d0c5307e --- /dev/null +++ b/devtools/client/webconsole/new-console-output/test/components/network-event-message.test.js @@ -0,0 +1,74 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ +"use strict"; + +// Test utils. +const expect = require("expect"); +const { render } = require("enzyme"); + +// React +const { createFactory } = require("devtools/client/shared/vendor/react"); + +// Components under test. +const NetworkEventMessage = createFactory(require("devtools/client/webconsole/new-console-output/components/message-types/network-event-message")); +const { INDENT_WIDTH } = require("devtools/client/webconsole/new-console-output/components/message-indent"); + +// Test fakes. +const { stubPreparedMessages } = require("devtools/client/webconsole/new-console-output/test/fixtures/stubs/index"); +const serviceContainer = require("devtools/client/webconsole/new-console-output/test/fixtures/serviceContainer"); + +const EXPECTED_URL = "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/inexistent.html"; + +describe("NetworkEventMessage component:", () => { + describe("GET request", () => { + it("renders as expected", () => { + const message = stubPreparedMessages.get("GET request"); + const wrapper = render(NetworkEventMessage({ message, serviceContainer })); + + expect(wrapper.find(".message-body .method").text()).toBe("GET"); + expect(wrapper.find(".message-body .xhr").length).toBe(0); + expect(wrapper.find(".message-body .url").length).toBe(1); + expect(wrapper.find(".message-body .url").text()).toBe(EXPECTED_URL); + expect(wrapper.find("div.message.cm-s-mozilla span.message-body.devtools-monospace").length).toBe(1); + }); + + it("has the expected indent", () => { + const message = stubPreparedMessages.get("GET request"); + + const indent = 10; + let wrapper = render(NetworkEventMessage({ message, serviceContainer, indent})); + expect(wrapper.find(".indent").prop("style").width) + .toBe(`${indent * INDENT_WIDTH}px`); + + wrapper = render(NetworkEventMessage({ message, serviceContainer })); + expect(wrapper.find(".indent").prop("style").width).toBe(`0`); + }); + }); + + describe("XHR GET request", () => { + it("renders as expected", () => { + const message = stubPreparedMessages.get("XHR GET request"); + const wrapper = render(NetworkEventMessage({ message, serviceContainer })); + + expect(wrapper.find(".message-body .method").text()).toBe("GET"); + expect(wrapper.find(".message-body .xhr").length).toBe(1); + expect(wrapper.find(".message-body .xhr").text()).toBe("XHR"); + expect(wrapper.find(".message-body .url").text()).toBe(EXPECTED_URL); + expect(wrapper.find("div.message.cm-s-mozilla span.message-body.devtools-monospace").length).toBe(1); + }); + }); + + describe("XHR POST request", () => { + it("renders as expected", () => { + const message = stubPreparedMessages.get("XHR POST request"); + const wrapper = render(NetworkEventMessage({ message, serviceContainer })); + + expect(wrapper.find(".message-body .method").text()).toBe("POST"); + expect(wrapper.find(".message-body .xhr").length).toBe(1); + expect(wrapper.find(".message-body .xhr").text()).toBe("XHR"); + expect(wrapper.find(".message-body .url").length).toBe(1); + expect(wrapper.find(".message-body .url").text()).toBe(EXPECTED_URL); + expect(wrapper.find("div.message.cm-s-mozilla span.message-body.devtools-monospace").length).toBe(1); + }); + }); +}); diff --git a/devtools/client/webconsole/new-console-output/test/components/page-error.test.js b/devtools/client/webconsole/new-console-output/test/components/page-error.test.js new file mode 100644 index 000000000..93f3a9ea5 --- /dev/null +++ b/devtools/client/webconsole/new-console-output/test/components/page-error.test.js @@ -0,0 +1,126 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ +"use strict"; + +// Test utils. +const expect = require("expect"); +const { render, mount } = require("enzyme"); +const sinon = require("sinon"); + +// React +const { createFactory } = require("devtools/client/shared/vendor/react"); +const Provider = createFactory(require("react-redux").Provider); +const { setupStore } = require("devtools/client/webconsole/new-console-output/test/helpers"); + +// Components under test. +const PageError = require("devtools/client/webconsole/new-console-output/components/message-types/page-error"); +const { + MESSAGE_OPEN, + MESSAGE_CLOSE, +} = require("devtools/client/webconsole/new-console-output/constants"); +const { INDENT_WIDTH } = require("devtools/client/webconsole/new-console-output/components/message-indent"); + +// Test fakes. +const { stubPreparedMessages } = require("devtools/client/webconsole/new-console-output/test/fixtures/stubs/index"); +const serviceContainer = require("devtools/client/webconsole/new-console-output/test/fixtures/serviceContainer"); + +describe("PageError component:", () => { + it("renders", () => { + const message = stubPreparedMessages.get("ReferenceError: asdf is not defined"); + const wrapper = render(PageError({ message, serviceContainer })); + + expect(wrapper.find(".message-body").text()) + .toBe("ReferenceError: asdf is not defined[Learn More]"); + + // The stacktrace should be closed by default. + const frameLinks = wrapper.find(`.stack-trace`); + expect(frameLinks.length).toBe(0); + + // There should be the location. + const locationLink = wrapper.find(`.message-location`); + expect(locationLink.length).toBe(1); + // @TODO Will likely change. See https://github.com/devtools-html/gecko-dev/issues/285 + expect(locationLink.text()).toBe("test-tempfile.js:3:5"); + }); + + it("displays a [Learn more] link", () => { + const store = setupStore([]); + + const message = stubPreparedMessages.get("ReferenceError: asdf is not defined"); + + serviceContainer.openLink = sinon.spy(); + const wrapper = mount(Provider({store}, + PageError({message, serviceContainer}) + )); + + // There should be a [Learn more] link. + const url = + "https://developer.mozilla.org/docs/Web/JavaScript/Reference/Errors/Not_defined"; + const learnMore = wrapper.find(".learn-more-link"); + expect(learnMore.length).toBe(1); + expect(learnMore.prop("title")).toBe(url); + + learnMore.simulate("click"); + let call = serviceContainer.openLink.getCall(0); + expect(call.args[0]).toEqual(message.exceptionDocURL); + }); + + it("has a stacktrace which can be openned", () => { + const message = stubPreparedMessages.get("ReferenceError: asdf is not defined"); + const wrapper = render(PageError({ message, serviceContainer, open: true })); + + // There should be a collapse button. + expect(wrapper.find(".theme-twisty.open").length).toBe(1); + + // There should be three stacktrace items. + const frameLinks = wrapper.find(`.stack-trace span.frame-link`); + expect(frameLinks.length).toBe(3); + }); + + it("toggle the stacktrace when the collapse button is clicked", () => { + const store = setupStore([]); + store.dispatch = sinon.spy(); + const message = stubPreparedMessages.get("ReferenceError: asdf is not defined"); + + let wrapper = mount(Provider({store}, + PageError({ + message, + open: true, + dispatch: store.dispatch, + serviceContainer, + }) + )); + wrapper.find(".theme-twisty.open").simulate("click"); + let call = store.dispatch.getCall(0); + expect(call.args[0]).toEqual({ + id: message.id, + type: MESSAGE_CLOSE + }); + + wrapper = mount(Provider({store}, + PageError({ + message, + open: false, + dispatch: store.dispatch, + serviceContainer, + }) + )); + wrapper.find(".theme-twisty").simulate("click"); + call = store.dispatch.getCall(1); + expect(call.args[0]).toEqual({ + id: message.id, + type: MESSAGE_OPEN + }); + }); + + it("has the expected indent", () => { + const message = stubPreparedMessages.get("ReferenceError: asdf is not defined"); + const indent = 10; + let wrapper = render(PageError({ message, serviceContainer, indent})); + expect(wrapper.find(".indent").prop("style").width) + .toBe(`${indent * INDENT_WIDTH}px`); + + wrapper = render(PageError({ message, serviceContainer})); + expect(wrapper.find(".indent").prop("style").width).toBe(`0`); + }); +}); diff --git a/devtools/client/webconsole/new-console-output/test/fixtures/L10n.js b/devtools/client/webconsole/new-console-output/test/fixtures/L10n.js new file mode 100644 index 000000000..bb34bb477 --- /dev/null +++ b/devtools/client/webconsole/new-console-output/test/fixtures/L10n.js @@ -0,0 +1,27 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +// @TODO Load the actual strings from webconsole.properties instead. +class L10n { + getStr(str) { + switch (str) { + case "level.error": + return "Error"; + case "consoleCleared": + return "Console was cleared."; + case "webConsoleXhrIndicator": + return "XHR"; + case "webConsoleMoreInfoLabel": + return "Learn More"; + } + return str; + } + + getFormatStr(str) { + return this.getStr(str); + } +} + +module.exports = L10n; diff --git a/devtools/client/webconsole/new-console-output/test/fixtures/LocalizationHelper.js b/devtools/client/webconsole/new-console-output/test/fixtures/LocalizationHelper.js new file mode 100644 index 000000000..8e6e9428c --- /dev/null +++ b/devtools/client/webconsole/new-console-output/test/fixtures/LocalizationHelper.js @@ -0,0 +1,10 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +const LocalizationHelper = require("devtools/client/webconsole/new-console-output/test/fixtures/L10n"); + +module.exports = { + LocalizationHelper +}; diff --git a/devtools/client/webconsole/new-console-output/test/fixtures/ObjectClient.js b/devtools/client/webconsole/new-console-output/test/fixtures/ObjectClient.js new file mode 100644 index 000000000..87a058d5c --- /dev/null +++ b/devtools/client/webconsole/new-console-output/test/fixtures/ObjectClient.js @@ -0,0 +1,9 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +class ObjectClient { +} + +module.exports = ObjectClient; diff --git a/devtools/client/webconsole/new-console-output/test/fixtures/PluralForm.js b/devtools/client/webconsole/new-console-output/test/fixtures/PluralForm.js new file mode 100644 index 000000000..9ab3ad3ec --- /dev/null +++ b/devtools/client/webconsole/new-console-output/test/fixtures/PluralForm.js @@ -0,0 +1,18 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +module.exports = { + PluralForm: { + get: function (occurence, str) { + // @TODO Remove when loading the actual strings from webconsole.properties + // is done in the L10n fixture. + if (str === "messageRepeats.tooltip2") { + return `${occurence} repeats`; + } + + return str; + } + } +}; diff --git a/devtools/client/webconsole/new-console-output/test/fixtures/Services.js b/devtools/client/webconsole/new-console-output/test/fixtures/Services.js new file mode 100644 index 000000000..61b3d5e13 --- /dev/null +++ b/devtools/client/webconsole/new-console-output/test/fixtures/Services.js @@ -0,0 +1,27 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +const { PREFS } = require("devtools/client/webconsole/new-console-output/constants"); + +module.exports = { + prefs: { + getIntPref: pref => { + switch (pref) { + case "devtools.hud.loglimit": + return 1000; + } + }, + getBoolPref: pref => { + const falsey = [ + PREFS.FILTER.NET, + PREFS.FILTER.NETXHR, + PREFS.UI.FILTER_BAR, + ]; + return !falsey.includes(pref); + }, + setBoolPref: () => {}, + clearUserPref: () => {}, + } +}; diff --git a/devtools/client/webconsole/new-console-output/test/fixtures/WebConsoleUtils.js b/devtools/client/webconsole/new-console-output/test/fixtures/WebConsoleUtils.js new file mode 100644 index 000000000..5ab1c0bb4 --- /dev/null +++ b/devtools/client/webconsole/new-console-output/test/fixtures/WebConsoleUtils.js @@ -0,0 +1,14 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +const L10n = require("devtools/client/webconsole/new-console-output/test/fixtures/L10n"); + +const Utils = { + L10n +}; + +module.exports = { + Utils +}; diff --git a/devtools/client/webconsole/new-console-output/test/fixtures/moz.build b/devtools/client/webconsole/new-console-output/test/fixtures/moz.build new file mode 100644 index 000000000..ff41d6c80 --- /dev/null +++ b/devtools/client/webconsole/new-console-output/test/fixtures/moz.build @@ -0,0 +1,9 @@ +# vim: set filetype=python: +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +DIRS += [ + 'stub-generators', + 'stubs' +] diff --git a/devtools/client/webconsole/new-console-output/test/fixtures/serviceContainer.js b/devtools/client/webconsole/new-console-output/test/fixtures/serviceContainer.js new file mode 100644 index 000000000..04b15c88b --- /dev/null +++ b/devtools/client/webconsole/new-console-output/test/fixtures/serviceContainer.js @@ -0,0 +1,17 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +module.exports = { + attachRefToHud: () => {}, + emitNewMessage: () => {}, + hudProxyClient: {}, + onViewSourceInDebugger: () => {}, + openNetworkPanel: () => {}, + sourceMapService: { + subscribe: () => {}, + }, + openLink: () => {}, + createElement: tagName => document.createElement(tagName) +}; diff --git a/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/browser.ini b/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/browser.ini new file mode 100644 index 000000000..9f348544f --- /dev/null +++ b/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/browser.ini @@ -0,0 +1,18 @@ +[DEFAULT] +tags = devtools +subsuite = devtools +support-files = + head.js + !/devtools/client/framework/test/shared-head.js + test-console-api.html + test-network-event.html + test-tempfile.js + +[browser_webconsole_update_stubs_console_api.js] +skip-if=true # This is only used to update stubs. It is not an actual test. +[browser_webconsole_update_stubs_evaluation_result.js] +skip-if=true # This is only used to update stubs. It is not an actual test. +[browser_webconsole_update_stubs_network_event.js] +skip-if=true # This is only used to update stubs. It is not an actual test. +[browser_webconsole_update_stubs_page_error.js] +skip-if=true # This is only used to update stubs. It is not an actual test. 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 new file mode 100644 index 000000000..fc859a002 --- /dev/null +++ b/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/browser_webconsole_update_stubs_console_api.js @@ -0,0 +1,56 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ +/* vim: set ft=javascript ts=2 et sw=2 tw=80: */ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; +requestLongerTimeout(2) + +Cu.import("resource://gre/modules/osfile.jsm"); +const { consoleApi: snippets } = require("devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/stub-snippets.js"); + +const TEST_URI = "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-console-api.html"; + +let stubs = { + preparedMessages: [], + packets: [], +}; + +add_task(function* () { + for (var [key, {keys, code}] of snippets) { + yield OS.File.writeAtomic(TEMP_FILE_PATH, `function triggerPacket() {${code}}`); + + let toolbox = yield openNewTabAndToolbox(TEST_URI, "webconsole"); + let {ui} = toolbox.getCurrentPanel().hud; + + ok(ui.jsterm, "jsterm exists"); + ok(ui.newConsoleOutput, "newConsoleOutput exists"); + + let received = new Promise(resolve => { + let i = 0; + let listener = (type, res) => { + stubs.packets.push(formatPacket(keys[i], res)); + stubs.preparedMessages.push(formatStub(keys[i], res)); + if(++i === keys.length ){ + toolbox.target.client.removeListener("consoleAPICall", listener); + resolve(); + } + }; + toolbox.target.client.addListener("consoleAPICall", listener); + }); + + yield ContentTask.spawn(gBrowser.selectedBrowser, key, function(key) { + var script = content.document.createElement("script"); + script.src = "test-tempfile.js?key=" + encodeURIComponent(key); + script.onload = function() { content.wrappedJSObject.triggerPacket(); } + content.document.body.appendChild(script); + }); + + yield received; + + yield closeTabAndToolbox(); + } + let filePath = OS.Path.join(`${BASE_PATH}/stubs`, "consoleApi.js"); + OS.File.writeAtomic(filePath, formatFile(stubs)); + OS.File.writeAtomic(TEMP_FILE_PATH, ""); +}); diff --git a/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/browser_webconsole_update_stubs_evaluation_result.js b/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/browser_webconsole_update_stubs_evaluation_result.js new file mode 100644 index 000000000..507201a24 --- /dev/null +++ b/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/browser_webconsole_update_stubs_evaluation_result.js @@ -0,0 +1,32 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ +/* vim: set ft=javascript ts=2 et sw=2 tw=80: */ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +Cu.import("resource://gre/modules/osfile.jsm"); +const TEST_URI = "data:text/html;charset=utf-8,stub generation"; + +const { evaluationResult: snippets} = require("devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/stub-snippets.js"); + +let stubs = { + preparedMessages: [], + packets: [], +}; + +add_task(function* () { + let toolbox = yield openNewTabAndToolbox(TEST_URI, "webconsole"); + ok(true, "make the test not fail"); + + for (var [code,key] of snippets) { + const packet = yield new Promise(resolve => { + toolbox.target.activeConsole.evaluateJS(code, resolve); + }); + stubs.packets.push(formatPacket(key, packet)); + stubs.preparedMessages.push(formatStub(key, packet)); + } + + let filePath = OS.Path.join(`${BASE_PATH}/stubs`, "evaluationResult.js"); + OS.File.writeAtomic(filePath, formatFile(stubs)); +}); diff --git a/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/browser_webconsole_update_stubs_network_event.js b/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/browser_webconsole_update_stubs_network_event.js new file mode 100644 index 000000000..cc018f634 --- /dev/null +++ b/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/browser_webconsole_update_stubs_network_event.js @@ -0,0 +1,47 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ +/* vim: set ft=javascript ts=2 et sw=2 tw=80: */ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +Cu.import("resource://gre/modules/osfile.jsm"); +const TARGET = "networkEvent"; +const { [TARGET]: snippets } = require("devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/stub-snippets.js"); +const TEST_URI = "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-network-event.html"; + +let stubs = { + preparedMessages: [], + packets: [], +}; + +add_task(function* () { + for (var [key, {keys, code}] of snippets) { + OS.File.writeAtomic(TEMP_FILE_PATH, `function triggerPacket() {${code}}`); + let toolbox = yield openNewTabAndToolbox(TEST_URI, "webconsole"); + let {ui} = toolbox.getCurrentPanel().hud; + + ok(ui.jsterm, "jsterm exists"); + ok(ui.newConsoleOutput, "newConsoleOutput exists"); + + let received = new Promise(resolve => { + let i = 0; + toolbox.target.client.addListener(TARGET, (type, res) => { + stubs.packets.push(formatPacket(keys[i], res)); + stubs.preparedMessages.push(formatNetworkStub(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/${TARGET}.js`); + OS.File.writeAtomic(filePath, formatFile(stubs)); + OS.File.writeAtomic(TEMP_FILE_PATH, ""); +}); diff --git a/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/browser_webconsole_update_stubs_page_error.js b/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/browser_webconsole_update_stubs_page_error.js new file mode 100644 index 000000000..9323e0031 --- /dev/null +++ b/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/browser_webconsole_update_stubs_page_error.js @@ -0,0 +1,48 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ +/* vim: set ft=javascript ts=2 et sw=2 tw=80: */ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +Cu.import("resource://gre/modules/osfile.jsm"); +const TEST_URI = "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-console-api.html"; + +const { pageError: snippets} = require("devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/stub-snippets.js"); + +let stubs = { + preparedMessages: [], + packets: [], +}; + +add_task(function* () { + let toolbox = yield openNewTabAndToolbox(TEST_URI, "webconsole"); + ok(true, "make the test not fail"); + + for (var [key,code] of snippets) { + OS.File.writeAtomic(TEMP_FILE_PATH, `${code}`); + let received = new Promise(resolve => { + toolbox.target.client.addListener("pageError", function onPacket(e, packet) { + toolbox.target.client.removeListener("pageError", onPacket); + info("Received page error:" + e + " " + JSON.stringify(packet, null, "\t")); + + let message = prepareMessage(packet, {getNextId: () => 1}); + stubs.packets.push(formatPacket(message.messageText, packet)); + stubs.preparedMessages.push(formatStub(message.messageText, packet)); + resolve(); + }); + }); + + yield ContentTask.spawn(gBrowser.selectedBrowser, key, function(key) { + var script = content.document.createElement("script"); + script.src = "test-tempfile.js?key=" + encodeURIComponent(key); + content.document.body.appendChild(script); + }); + + yield received; + } + + let filePath = OS.Path.join(`${BASE_PATH}/stubs`, "pageError.js"); + OS.File.writeAtomic(filePath, formatFile(stubs)); + OS.File.writeAtomic(TEMP_FILE_PATH, ""); +}); diff --git a/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/head.js b/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/head.js new file mode 100644 index 000000000..be988b9d8 --- /dev/null +++ b/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/head.js @@ -0,0 +1,192 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ +/* vim: set ft=javascript ts=2 et sw=2 tw=80: */ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ */ +/* import-globals-from ../../../../framework/test/shared-head.js */ + +"use strict"; + +// shared-head.js handles imports, constants, and utility functions +// Load the shared-head file first. +Services.scriptloader.loadSubScript( + "chrome://mochitests/content/browser/devtools/client/framework/test/shared-head.js", + this); + +Services.prefs.setBoolPref("devtools.webconsole.new-frontend-enabled", true); +registerCleanupFunction(() => { + Services.prefs.clearUserPref("devtools.webconsole.new-frontend-enabled"); +}); + +const { prepareMessage } = require("devtools/client/webconsole/new-console-output/utils/messages"); +const { stubPackets } = require("devtools/client/webconsole/new-console-output/test/fixtures/stubs/index.js"); + +const BASE_PATH = "../../../../devtools/client/webconsole/new-console-output/test/fixtures"; +const TEMP_FILE_PATH = OS.Path.join(`${BASE_PATH}/stub-generators`, "test-tempfile.js"); + +let cachedPackets = {}; + +function getCleanedPacket(key, packet) { + if(Object.keys(cachedPackets).includes(key)) { + return cachedPackets[key]; + } + + // Strip escaped characters. + let safeKey = key + .replace(/\\n/g, "\n") + .replace(/\\r/g, "\r") + .replace(/\\\"/g, `\"`) + .replace(/\\\'/g, `\'`); + + // If the stub already exist, we want to ignore irrelevant properties + // (actor, timeStamp, timer, ...) that might changed and "pollute" + // the diff resulting from this stub generation. + let res; + if(stubPackets.has(safeKey)) { + + let existingPacket = stubPackets.get(safeKey); + res = Object.assign({}, packet, { + from: existingPacket.from + }); + + // Clean root timestamp. + if(res.timestamp) { + res.timestamp = existingPacket.timestamp; + } + + if (res.message) { + // Clean timeStamp on the message prop. + res.message.timeStamp = existingPacket.message.timeStamp; + if (res.message.timer) { + // Clean timer properties on the message. + // Those properties are found on console.time and console.timeEnd calls, + // and those time can vary, which is why we need to clean them. + if (res.message.timer.started) { + res.message.timer.started = existingPacket.message.timer.started; + } + if (res.message.timer.duration) { + res.message.timer.duration = existingPacket.message.timer.duration; + } + } + + if(Array.isArray(res.message.arguments)) { + // Clean actor ids on each message.arguments item. + res.message.arguments.forEach((argument, i) => { + if (argument && argument.actor) { + argument.actor = existingPacket.message.arguments[i].actor; + } + }); + } + } + + if (res.result) { + // Clean actor ids on evaluation result messages. + res.result.actor = existingPacket.result.actor; + if (res.result.preview) { + if(res.result.preview.timestamp) { + // Clean timestamp there too. + res.result.preview.timestamp = existingPacket.result.preview.timestamp; + } + } + } + + if (res.exception) { + // Clean actor ids on exception messages. + res.exception.actor = existingPacket.exception.actor; + if (res.exception.preview) { + if(res.exception.preview.timestamp) { + // Clean timestamp there too. + res.exception.preview.timestamp = existingPacket.exception.preview.timestamp; + } + } + } + + if (res.eventActor) { + // Clean actor ids, timeStamp and startedDateTime on network messages. + res.eventActor.actor = existingPacket.eventActor.actor; + res.eventActor.startedDateTime = existingPacket.eventActor.startedDateTime; + res.eventActor.timeStamp = existingPacket.eventActor.timeStamp; + } + + if (res.pageError) { + // Clean timeStamp on pageError messages. + res.pageError.timeStamp = existingPacket.pageError.timeStamp; + } + + } else { + res = packet; + } + + cachedPackets[key] = res; + return res; +} + +function formatPacket(key, packet) { + return ` +stubPackets.set("${key}", ${JSON.stringify(getCleanedPacket(key, packet), null, "\t")}); +`; +} + +function formatStub(key, packet) { + let prepared = prepareMessage( + getCleanedPacket(key, packet), + {getNextId: () => "1"} + ); + + return ` +stubPreparedMessages.set("${key}", new ConsoleMessage(${JSON.stringify(prepared, null, "\t")})); +`; +} + +function formatNetworkStub(key, packet) { + let actor = packet.eventActor; + let networkInfo = { + _type: "NetworkEvent", + timeStamp: actor.timeStamp, + node: null, + actor: actor.actor, + discardRequestBody: true, + discardResponseBody: true, + startedDateTime: actor.startedDateTime, + request: { + url: actor.url, + method: actor.method, + }, + isXHR: actor.isXHR, + cause: actor.cause, + response: {}, + timings: {}, + // track the list of network event updates + updates: [], + private: actor.private, + fromCache: actor.fromCache, + fromServiceWorker: actor.fromServiceWorker + }; + let prepared = prepareMessage(networkInfo, {getNextId: () => "1"}); + return ` +stubPreparedMessages.set("${key}", new NetworkEventMessage(${JSON.stringify(prepared, null, "\t")})); +`; +} + +function formatFile(stubs) { + return `/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +/* + * THIS FILE IS AUTOGENERATED. DO NOT MODIFY BY HAND. RUN TESTS IN FIXTURES/ TO UPDATE. + */ + +const { ConsoleMessage, NetworkEventMessage } = require("devtools/client/webconsole/new-console-output/types"); + +let stubPreparedMessages = new Map(); +let stubPackets = new Map(); + +${stubs.preparedMessages.join("")} +${stubs.packets.join("")} + +module.exports = { + stubPreparedMessages, + stubPackets, +}`; +} diff --git a/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/moz.build b/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/moz.build new file mode 100644 index 000000000..4b4e8a1d8 --- /dev/null +++ b/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/moz.build @@ -0,0 +1,8 @@ +# vim: set filetype=python: +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +DevToolsModules( + 'stub-snippets.js', +) 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 new file mode 100644 index 000000000..f79548e7b --- /dev/null +++ b/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/stub-snippets.js @@ -0,0 +1,148 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +var {DebuggerServer} = require("devtools/server/main"); +var longString = (new Array(DebuggerServer.LONG_STRING_LENGTH + 4)).join("a"); +var initialString = longString.substring(0, DebuggerServer.LONG_STRING_INITIAL_LENGTH); + +// Console API + +const consoleApiCommands = [ + "console.log('foobar', 'test')", + "console.log(undefined)", + "console.warn('danger, will robinson!')", + "console.log(NaN)", + "console.log(null)", + "console.log('\u9f2c')", + "console.clear()", + "console.count('bar')", + "console.assert(false, {message: 'foobar'})", + "console.log('hello \\nfrom \\rthe \\\"string world!')", + "console.log('\xFA\u1E47\u0129\xE7\xF6d\xEA \u021B\u0115\u0219\u0165')", + "console.dirxml(window)", +]; + +let consoleApi = new Map(consoleApiCommands.map( + cmd => [cmd, {keys: [cmd], code: cmd}])); + +consoleApi.set("console.trace()", { + keys: ["console.trace()"], + code: ` +function testStacktraceFiltering() { + console.trace() +} +function foo() { + testStacktraceFiltering() +} + +foo() +`}); + +consoleApi.set("console.time('bar')", { + keys: ["console.time('bar')", "console.timeEnd('bar')"], + code: ` +console.time("bar"); +console.timeEnd("bar"); +`}); + +consoleApi.set("console.table('bar')", { + keys: ["console.table('bar')"], + code: ` +console.table('bar'); +`}); + +consoleApi.set("console.table(['a', 'b', 'c'])", { + keys: ["console.table(['a', 'b', 'c'])"], + code: ` +console.table(['a', 'b', 'c']); +`}); + +consoleApi.set("console.group('bar')", { + keys: ["console.group('bar')", "console.groupEnd('bar')"], + code: ` +console.group("bar"); +console.groupEnd("bar"); +`}); + +consoleApi.set("console.groupCollapsed('foo')", { + keys: ["console.groupCollapsed('foo')", "console.groupEnd('foo')"], + code: ` +console.groupCollapsed("foo"); +console.groupEnd("foo"); +`}); + +consoleApi.set("console.group()", { + keys: ["console.group()", "console.groupEnd()"], + code: ` +console.group(); +console.groupEnd(); +`}); + +consoleApi.set("console.log(%cfoobar)", { + keys: ["console.log(%cfoobar)"], + code: ` +console.log( + "%cfoo%cbar", + "color:blue;font-size:1.3em;background:url('http://example.com/test');position:absolute;top:10px", + "color:red;background:\\165rl('http://example.com/test')"); +`}); + +// Evaluation Result +const evaluationResultCommands = [ + "new Date(0)", + "asdf()", + "1 + @" +]; + +let evaluationResult = new Map(evaluationResultCommands.map(cmd => [cmd, cmd])); + +// Network Event + +let networkEvent = new Map(); + +networkEvent.set("GET request", { + keys: ["GET request"], + code: ` +let i = document.createElement("img"); +i.src = "inexistent.html"; +`}); + +networkEvent.set("XHR GET request", { + keys: ["XHR GET request"], + code: ` +const xhr = new XMLHttpRequest(); +xhr.open("GET", "inexistent.html"); +xhr.send(); +`}); + +networkEvent.set("XHR POST request", { + keys: ["XHR POST request"], + code: ` +const xhr = new XMLHttpRequest(); +xhr.open("POST", "inexistent.html"); +xhr.send(); +`}); + +// Page Error + +let pageError = new Map(); + +pageError.set("Reference Error", ` + function bar() { + asdf() + } + function foo() { + bar() + } + + foo() +`); + +module.exports = { + consoleApi, + evaluationResult, + networkEvent, + pageError, +}; diff --git a/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-console-api.html b/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-console-api.html new file mode 100644 index 000000000..3246cff15 --- /dev/null +++ b/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-console-api.html @@ -0,0 +1,11 @@ +<!DOCTYPE html> +<html lang="en"> + <head> + <meta charset="utf-8"> + <title>Stub generator</title> + </head> + <body> + <p>Stub generator</p> + <script src="test-tempfile.js"></script> + </body> +</html> diff --git a/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-network-event.html b/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-network-event.html new file mode 100644 index 000000000..c234acea6 --- /dev/null +++ b/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-network-event.html @@ -0,0 +1,11 @@ +<!DOCTYPE html> +<html lang="en"> + <head> + <meta charset="utf-8"> + <title>Stub generator for network event</title> + </head> + <body> + <p>Stub generator for network event</p> + <script src="test-tempfile.js"></script> + </body> +</html> diff --git a/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js b/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js 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 new file mode 100644 index 000000000..26e95fe39 --- /dev/null +++ b/devtools/client/webconsole/new-console-output/test/fixtures/stubs/consoleApi.js @@ -0,0 +1,1482 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +/* + * THIS FILE IS AUTOGENERATED. DO NOT MODIFY BY HAND. RUN TESTS IN FIXTURES/ TO UPDATE. + */ + +const { ConsoleMessage, NetworkEventMessage } = require("devtools/client/webconsole/new-console-output/types"); + +let stubPreparedMessages = new Map(); +let stubPackets = new Map(); + + +stubPreparedMessages.set("console.log('foobar', 'test')", new ConsoleMessage({ + "id": "1", + "allowRepeating": true, + "source": "console-api", + "type": "log", + "level": "log", + "messageText": null, + "parameters": [ + "foobar", + "test" + ], + "repeat": 1, + "repeatId": "{\"id\":null,\"allowRepeating\":true,\"source\":\"console-api\",\"type\":\"log\",\"level\":\"log\",\"messageText\":null,\"parameters\":[\"foobar\",\"test\"],\"repeatId\":null,\"stacktrace\":null,\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.log(%27foobar%27%2C%20%27test%27)\",\"line\":1,\"column\":27},\"groupId\":null,\"exceptionDocURL\":null,\"userProvidedStyles\":[]}", + "stacktrace": null, + "frame": { + "source": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.log(%27foobar%27%2C%20%27test%27)", + "line": 1, + "column": 27 + }, + "groupId": null, + "exceptionDocURL": null, + "userProvidedStyles": [] +})); + +stubPreparedMessages.set("console.log(undefined)", new ConsoleMessage({ + "id": "1", + "allowRepeating": true, + "source": "console-api", + "type": "log", + "level": "log", + "messageText": null, + "parameters": [ + { + "type": "undefined" + } + ], + "repeat": 1, + "repeatId": "{\"id\":null,\"allowRepeating\":true,\"source\":\"console-api\",\"type\":\"log\",\"level\":\"log\",\"messageText\":null,\"parameters\":[{\"type\":\"undefined\"}],\"repeatId\":null,\"stacktrace\":null,\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.log(undefined)\",\"line\":1,\"column\":27},\"groupId\":null,\"exceptionDocURL\":null,\"userProvidedStyles\":[]}", + "stacktrace": null, + "frame": { + "source": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.log(undefined)", + "line": 1, + "column": 27 + }, + "groupId": null, + "exceptionDocURL": null, + "userProvidedStyles": [] +})); + +stubPreparedMessages.set("console.warn('danger, will robinson!')", new ConsoleMessage({ + "id": "1", + "allowRepeating": true, + "source": "console-api", + "type": "warn", + "level": "warn", + "messageText": null, + "parameters": [ + "danger, will robinson!" + ], + "repeat": 1, + "repeatId": "{\"id\":null,\"allowRepeating\":true,\"source\":\"console-api\",\"type\":\"warn\",\"level\":\"warn\",\"messageText\":null,\"parameters\":[\"danger, will robinson!\"],\"repeatId\":null,\"stacktrace\":null,\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.warn(%27danger%2C%20will%20robinson!%27)\",\"line\":1,\"column\":27},\"groupId\":null,\"exceptionDocURL\":null,\"userProvidedStyles\":[]}", + "stacktrace": null, + "frame": { + "source": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.warn(%27danger%2C%20will%20robinson!%27)", + "line": 1, + "column": 27 + }, + "groupId": null, + "exceptionDocURL": null, + "userProvidedStyles": [] +})); + +stubPreparedMessages.set("console.log(NaN)", new ConsoleMessage({ + "id": "1", + "allowRepeating": true, + "source": "console-api", + "type": "log", + "level": "log", + "messageText": null, + "parameters": [ + { + "type": "NaN" + } + ], + "repeat": 1, + "repeatId": "{\"id\":null,\"allowRepeating\":true,\"source\":\"console-api\",\"type\":\"log\",\"level\":\"log\",\"messageText\":null,\"parameters\":[{\"type\":\"NaN\"}],\"repeatId\":null,\"stacktrace\":null,\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.log(NaN)\",\"line\":1,\"column\":27},\"groupId\":null,\"exceptionDocURL\":null,\"userProvidedStyles\":[]}", + "stacktrace": null, + "frame": { + "source": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.log(NaN)", + "line": 1, + "column": 27 + }, + "groupId": null, + "exceptionDocURL": null, + "userProvidedStyles": [] +})); + +stubPreparedMessages.set("console.log(null)", new ConsoleMessage({ + "id": "1", + "allowRepeating": true, + "source": "console-api", + "type": "log", + "level": "log", + "messageText": null, + "parameters": [ + { + "type": "null" + } + ], + "repeat": 1, + "repeatId": "{\"id\":null,\"allowRepeating\":true,\"source\":\"console-api\",\"type\":\"log\",\"level\":\"log\",\"messageText\":null,\"parameters\":[{\"type\":\"null\"}],\"repeatId\":null,\"stacktrace\":null,\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.log(null)\",\"line\":1,\"column\":27},\"groupId\":null,\"exceptionDocURL\":null,\"userProvidedStyles\":[]}", + "stacktrace": null, + "frame": { + "source": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.log(null)", + "line": 1, + "column": 27 + }, + "groupId": null, + "exceptionDocURL": null, + "userProvidedStyles": [] +})); + +stubPreparedMessages.set("console.log('鼬')", new ConsoleMessage({ + "id": "1", + "allowRepeating": true, + "source": "console-api", + "type": "log", + "level": "log", + "messageText": null, + "parameters": [ + "鼬" + ], + "repeat": 1, + "repeatId": "{\"id\":null,\"allowRepeating\":true,\"source\":\"console-api\",\"type\":\"log\",\"level\":\"log\",\"messageText\":null,\"parameters\":[\"鼬\"],\"repeatId\":null,\"stacktrace\":null,\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.log(%27%E9%BC%AC%27)\",\"line\":1,\"column\":27},\"groupId\":null,\"exceptionDocURL\":null,\"userProvidedStyles\":[]}", + "stacktrace": null, + "frame": { + "source": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.log(%27%E9%BC%AC%27)", + "line": 1, + "column": 27 + }, + "groupId": null, + "exceptionDocURL": null, + "userProvidedStyles": [] +})); + +stubPreparedMessages.set("console.clear()", new ConsoleMessage({ + "id": "1", + "allowRepeating": true, + "source": "console-api", + "type": "clear", + "level": "log", + "messageText": null, + "parameters": [ + "Console was cleared." + ], + "repeat": 1, + "repeatId": "{\"id\":null,\"allowRepeating\":true,\"source\":\"console-api\",\"type\":\"clear\",\"level\":\"log\",\"messageText\":null,\"parameters\":[\"Console was cleared.\"],\"repeatId\":null,\"stacktrace\":null,\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.clear()\",\"line\":1,\"column\":27},\"groupId\":null,\"exceptionDocURL\":null,\"userProvidedStyles\":[]}", + "stacktrace": null, + "frame": { + "source": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.clear()", + "line": 1, + "column": 27 + }, + "groupId": null, + "exceptionDocURL": null, + "userProvidedStyles": [] +})); + +stubPreparedMessages.set("console.count('bar')", new ConsoleMessage({ + "id": "1", + "allowRepeating": true, + "source": "console-api", + "type": "log", + "level": "debug", + "messageText": "bar: 1", + "parameters": null, + "repeat": 1, + "repeatId": "{\"id\":null,\"allowRepeating\":true,\"source\":\"console-api\",\"type\":\"log\",\"level\":\"debug\",\"messageText\":\"bar: 1\",\"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?key=console.count(%27bar%27)\",\"line\":1,\"column\":27},\"groupId\":null,\"exceptionDocURL\":null,\"userProvidedStyles\":[]}", + "stacktrace": null, + "frame": { + "source": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.count(%27bar%27)", + "line": 1, + "column": 27 + }, + "groupId": null, + "exceptionDocURL": null, + "userProvidedStyles": [] +})); + +stubPreparedMessages.set("console.assert(false, {message: 'foobar'})", new ConsoleMessage({ + "id": "1", + "allowRepeating": true, + "source": "console-api", + "type": "assert", + "level": "error", + "messageText": null, + "parameters": [ + { + "type": "object", + "actor": "server1.conn8.child1/obj31", + "class": "Object", + "extensible": true, + "frozen": false, + "sealed": false, + "ownPropertyLength": 1, + "preview": { + "kind": "Object", + "ownProperties": { + "message": { + "configurable": true, + "enumerable": true, + "writable": true, + "value": "foobar" + } + }, + "ownPropertiesLength": 1, + "safeGetterValues": {} + } + } + ], + "repeat": 1, + "repeatId": "{\"id\":null,\"allowRepeating\":true,\"source\":\"console-api\",\"type\":\"assert\",\"level\":\"error\",\"messageText\":null,\"parameters\":[{\"type\":\"object\",\"actor\":\"server1.conn8.child1/obj31\",\"class\":\"Object\",\"extensible\":true,\"frozen\":false,\"sealed\":false,\"ownPropertyLength\":1,\"preview\":{\"kind\":\"Object\",\"ownProperties\":{\"message\":{\"configurable\":true,\"enumerable\":true,\"writable\":true,\"value\":\"foobar\"}},\"ownPropertiesLength\":1,\"safeGetterValues\":{}}}],\"repeatId\":null,\"stacktrace\":[{\"columnNumber\":27,\"filename\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.assert(false%2C%20%7Bmessage%3A%20%27foobar%27%7D)\",\"functionName\":\"triggerPacket\",\"language\":2,\"lineNumber\":1}],\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.assert(false%2C%20%7Bmessage%3A%20%27foobar%27%7D)\",\"line\":1,\"column\":27},\"groupId\":null,\"exceptionDocURL\":null,\"userProvidedStyles\":[]}", + "stacktrace": [ + { + "columnNumber": 27, + "filename": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.assert(false%2C%20%7Bmessage%3A%20%27foobar%27%7D)", + "functionName": "triggerPacket", + "language": 2, + "lineNumber": 1 + } + ], + "frame": { + "source": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.assert(false%2C%20%7Bmessage%3A%20%27foobar%27%7D)", + "line": 1, + "column": 27 + }, + "groupId": null, + "exceptionDocURL": null, + "userProvidedStyles": [] +})); + +stubPreparedMessages.set("console.log('hello \nfrom \rthe \"string world!')", new ConsoleMessage({ + "id": "1", + "allowRepeating": true, + "source": "console-api", + "type": "log", + "level": "log", + "messageText": null, + "parameters": [ + "hello \nfrom \rthe \"string world!" + ], + "repeat": 1, + "repeatId": "{\"id\":null,\"allowRepeating\":true,\"source\":\"console-api\",\"type\":\"log\",\"level\":\"log\",\"messageText\":null,\"parameters\":[\"hello \\nfrom \\rthe \\\"string world!\"],\"repeatId\":null,\"stacktrace\":null,\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.log(%27hello%20%5Cnfrom%20%5Crthe%20%5C%22string%20world!%27)\",\"line\":1,\"column\":27},\"groupId\":null,\"exceptionDocURL\":null,\"userProvidedStyles\":[]}", + "stacktrace": null, + "frame": { + "source": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.log(%27hello%20%5Cnfrom%20%5Crthe%20%5C%22string%20world!%27)", + "line": 1, + "column": 27 + }, + "groupId": null, + "exceptionDocURL": null, + "userProvidedStyles": [] +})); + +stubPreparedMessages.set("console.log('úṇĩçödê țĕșť')", new ConsoleMessage({ + "id": "1", + "allowRepeating": true, + "source": "console-api", + "type": "log", + "level": "log", + "messageText": null, + "parameters": [ + "úṇĩçödê țĕșť" + ], + "repeat": 1, + "repeatId": "{\"id\":null,\"allowRepeating\":true,\"source\":\"console-api\",\"type\":\"log\",\"level\":\"log\",\"messageText\":null,\"parameters\":[\"úṇĩçödê țĕșť\"],\"repeatId\":null,\"stacktrace\":null,\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.log(%27%C3%BA%E1%B9%87%C4%A9%C3%A7%C3%B6d%C3%AA%20%C8%9B%C4%95%C8%99%C5%A5%27)\",\"line\":1,\"column\":27},\"groupId\":null,\"exceptionDocURL\":null,\"userProvidedStyles\":[]}", + "stacktrace": null, + "frame": { + "source": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.log(%27%C3%BA%E1%B9%87%C4%A9%C3%A7%C3%B6d%C3%AA%20%C8%9B%C4%95%C8%99%C5%A5%27)", + "line": 1, + "column": 27 + }, + "groupId": null, + "exceptionDocURL": null, + "userProvidedStyles": [] +})); + +stubPreparedMessages.set("console.dirxml(window)", new ConsoleMessage({ + "id": "1", + "allowRepeating": true, + "source": "console-api", + "type": "log", + "level": "log", + "messageText": null, + "parameters": [ + { + "type": "object", + "actor": "server1.conn11.child1/obj31", + "class": "Window", + "extensible": true, + "frozen": false, + "sealed": false, + "ownPropertyLength": 804, + "preview": { + "kind": "ObjectWithURL", + "url": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-console-api.html" + } + } + ], + "repeat": 1, + "repeatId": "{\"id\":null,\"allowRepeating\":true,\"source\":\"console-api\",\"type\":\"log\",\"level\":\"log\",\"messageText\":null,\"parameters\":[{\"type\":\"object\",\"actor\":\"server1.conn11.child1/obj31\",\"class\":\"Window\",\"extensible\":true,\"frozen\":false,\"sealed\":false,\"ownPropertyLength\":804,\"preview\":{\"kind\":\"ObjectWithURL\",\"url\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-console-api.html\"}}],\"repeatId\":null,\"stacktrace\":null,\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.dirxml(window)\",\"line\":1,\"column\":27},\"groupId\":null,\"exceptionDocURL\":null,\"userProvidedStyles\":[]}", + "stacktrace": null, + "frame": { + "source": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.dirxml(window)", + "line": 1, + "column": 27 + }, + "groupId": null, + "exceptionDocURL": null, + "userProvidedStyles": [] +})); + +stubPreparedMessages.set("console.trace()", new ConsoleMessage({ + "id": "1", + "allowRepeating": true, + "source": "console-api", + "type": "trace", + "level": "log", + "messageText": null, + "parameters": [], + "repeat": 1, + "repeatId": "{\"id\":null,\"allowRepeating\":true,\"source\":\"console-api\",\"type\":\"trace\",\"level\":\"log\",\"messageText\":null,\"parameters\":[],\"repeatId\":null,\"stacktrace\":[{\"columnNumber\":3,\"filename\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.trace()\",\"functionName\":\"testStacktraceFiltering\",\"language\":2,\"lineNumber\":3},{\"columnNumber\":3,\"filename\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.trace()\",\"functionName\":\"foo\",\"language\":2,\"lineNumber\":6},{\"columnNumber\":1,\"filename\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.trace()\",\"functionName\":\"triggerPacket\",\"language\":2,\"lineNumber\":9}],\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.trace()\",\"line\":3,\"column\":3},\"groupId\":null,\"exceptionDocURL\":null,\"userProvidedStyles\":[]}", + "stacktrace": [ + { + "columnNumber": 3, + "filename": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.trace()", + "functionName": "testStacktraceFiltering", + "language": 2, + "lineNumber": 3 + }, + { + "columnNumber": 3, + "filename": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.trace()", + "functionName": "foo", + "language": 2, + "lineNumber": 6 + }, + { + "columnNumber": 1, + "filename": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.trace()", + "functionName": "triggerPacket", + "language": 2, + "lineNumber": 9 + } + ], + "frame": { + "source": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.trace()", + "line": 3, + "column": 3 + }, + "groupId": null, + "exceptionDocURL": null, + "userProvidedStyles": [] +})); + +stubPreparedMessages.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?key=console.time(%27bar%27)\",\"line\":2,\"column\":1},\"groupId\":null,\"exceptionDocURL\":null,\"userProvidedStyles\":[]}", + "stacktrace": null, + "frame": { + "source": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.time(%27bar%27)", + "line": 2, + "column": 1 + }, + "groupId": null, + "exceptionDocURL": null, + "userProvidedStyles": [] +})); + +stubPreparedMessages.set("console.timeEnd('bar')", new ConsoleMessage({ + "id": "1", + "allowRepeating": true, + "source": "console-api", + "type": "timeEnd", + "level": "log", + "messageText": "bar: 1.36ms", + "parameters": null, + "repeat": 1, + "repeatId": "{\"id\":null,\"allowRepeating\":true,\"source\":\"console-api\",\"type\":\"timeEnd\",\"level\":\"log\",\"messageText\":\"bar: 1.36ms\",\"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?key=console.time(%27bar%27)\",\"line\":3,\"column\":1},\"groupId\":null,\"exceptionDocURL\":null,\"userProvidedStyles\":[]}", + "stacktrace": null, + "frame": { + "source": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.time(%27bar%27)", + "line": 3, + "column": 1 + }, + "groupId": null, + "exceptionDocURL": null, + "userProvidedStyles": [] +})); + +stubPreparedMessages.set("console.table('bar')", new ConsoleMessage({ + "id": "1", + "allowRepeating": true, + "source": "console-api", + "type": "log", + "level": "log", + "messageText": null, + "parameters": [ + "bar" + ], + "repeat": 1, + "repeatId": "{\"id\":null,\"allowRepeating\":true,\"source\":\"console-api\",\"type\":\"log\",\"level\":\"log\",\"messageText\":null,\"parameters\":[\"bar\"],\"repeatId\":null,\"stacktrace\":null,\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.table(%27bar%27)\",\"line\":2,\"column\":1},\"groupId\":null,\"exceptionDocURL\":null,\"userProvidedStyles\":[]}", + "stacktrace": null, + "frame": { + "source": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.table(%27bar%27)", + "line": 2, + "column": 1 + }, + "groupId": null, + "exceptionDocURL": null, + "userProvidedStyles": [] +})); + +stubPreparedMessages.set("console.table(['a', 'b', 'c'])", new ConsoleMessage({ + "id": "1", + "allowRepeating": true, + "source": "console-api", + "type": "table", + "level": "log", + "messageText": null, + "parameters": [ + { + "type": "object", + "actor": "server1.conn15.child1/obj31", + "class": "Array", + "extensible": true, + "frozen": false, + "sealed": false, + "ownPropertyLength": 4, + "preview": { + "kind": "ArrayLike", + "length": 3, + "items": [ + "a", + "b", + "c" + ] + } + } + ], + "repeat": 1, + "repeatId": "{\"id\":null,\"allowRepeating\":true,\"source\":\"console-api\",\"type\":\"table\",\"level\":\"log\",\"messageText\":null,\"parameters\":[{\"type\":\"object\",\"actor\":\"server1.conn15.child1/obj31\",\"class\":\"Array\",\"extensible\":true,\"frozen\":false,\"sealed\":false,\"ownPropertyLength\":4,\"preview\":{\"kind\":\"ArrayLike\",\"length\":3,\"items\":[\"a\",\"b\",\"c\"]}}],\"repeatId\":null,\"stacktrace\":null,\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.table(%5B%27a%27%2C%20%27b%27%2C%20%27c%27%5D)\",\"line\":2,\"column\":1},\"groupId\":null,\"exceptionDocURL\":null,\"userProvidedStyles\":[]}", + "stacktrace": null, + "frame": { + "source": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.table(%5B%27a%27%2C%20%27b%27%2C%20%27c%27%5D)", + "line": 2, + "column": 1 + }, + "groupId": null, + "exceptionDocURL": null, + "userProvidedStyles": [] +})); + +stubPreparedMessages.set("console.group('bar')", new ConsoleMessage({ + "id": "1", + "allowRepeating": true, + "source": "console-api", + "type": "startGroup", + "level": "log", + "messageText": "bar", + "parameters": null, + "repeat": 1, + "repeatId": "{\"id\":null,\"allowRepeating\":true,\"source\":\"console-api\",\"type\":\"startGroup\",\"level\":\"log\",\"messageText\":\"bar\",\"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?key=console.group(%27bar%27)\",\"line\":2,\"column\":1},\"groupId\":null,\"exceptionDocURL\":null,\"userProvidedStyles\":[]}", + "stacktrace": null, + "frame": { + "source": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.group(%27bar%27)", + "line": 2, + "column": 1 + }, + "groupId": null, + "exceptionDocURL": null, + "userProvidedStyles": [] +})); + +stubPreparedMessages.set("console.groupEnd('bar')", new ConsoleMessage({ + "id": "1", + "allowRepeating": true, + "source": "console-api", + "type": "endGroup", + "level": "log", + "messageText": null, + "parameters": null, + "repeat": 1, + "repeatId": "{\"id\":null,\"allowRepeating\":true,\"source\":\"console-api\",\"type\":\"endGroup\",\"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?key=console.group(%27bar%27)\",\"line\":3,\"column\":1},\"groupId\":null,\"exceptionDocURL\":null,\"userProvidedStyles\":[]}", + "stacktrace": null, + "frame": { + "source": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.group(%27bar%27)", + "line": 3, + "column": 1 + }, + "groupId": null, + "exceptionDocURL": null, + "userProvidedStyles": [] +})); + +stubPreparedMessages.set("console.groupCollapsed('foo')", new ConsoleMessage({ + "id": "1", + "allowRepeating": true, + "source": "console-api", + "type": "startGroupCollapsed", + "level": "log", + "messageText": "foo", + "parameters": null, + "repeat": 1, + "repeatId": "{\"id\":null,\"allowRepeating\":true,\"source\":\"console-api\",\"type\":\"startGroupCollapsed\",\"level\":\"log\",\"messageText\":\"foo\",\"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?key=console.groupCollapsed(%27foo%27)\",\"line\":2,\"column\":1},\"groupId\":null,\"exceptionDocURL\":null,\"userProvidedStyles\":[]}", + "stacktrace": null, + "frame": { + "source": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.groupCollapsed(%27foo%27)", + "line": 2, + "column": 1 + }, + "groupId": null, + "exceptionDocURL": null, + "userProvidedStyles": [] +})); + +stubPreparedMessages.set("console.groupEnd('foo')", new ConsoleMessage({ + "id": "1", + "allowRepeating": true, + "source": "console-api", + "type": "endGroup", + "level": "log", + "messageText": null, + "parameters": null, + "repeat": 1, + "repeatId": "{\"id\":null,\"allowRepeating\":true,\"source\":\"console-api\",\"type\":\"endGroup\",\"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?key=console.groupCollapsed(%27foo%27)\",\"line\":3,\"column\":1},\"groupId\":null,\"exceptionDocURL\":null,\"userProvidedStyles\":[]}", + "stacktrace": null, + "frame": { + "source": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.groupCollapsed(%27foo%27)", + "line": 3, + "column": 1 + }, + "groupId": null, + "exceptionDocURL": null, + "userProvidedStyles": [] +})); + +stubPreparedMessages.set("console.group()", new ConsoleMessage({ + "id": "1", + "allowRepeating": true, + "source": "console-api", + "type": "startGroup", + "level": "log", + "messageText": "<no group label>", + "parameters": null, + "repeat": 1, + "repeatId": "{\"id\":null,\"allowRepeating\":true,\"source\":\"console-api\",\"type\":\"startGroup\",\"level\":\"log\",\"messageText\":\"<no group label>\",\"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?key=console.group()\",\"line\":2,\"column\":1},\"groupId\":null,\"exceptionDocURL\":null,\"userProvidedStyles\":[]}", + "stacktrace": null, + "frame": { + "source": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.group()", + "line": 2, + "column": 1 + }, + "groupId": null, + "exceptionDocURL": null, + "userProvidedStyles": [] +})); + +stubPreparedMessages.set("console.groupEnd()", new ConsoleMessage({ + "id": "1", + "allowRepeating": true, + "source": "console-api", + "type": "endGroup", + "level": "log", + "messageText": null, + "parameters": null, + "repeat": 1, + "repeatId": "{\"id\":null,\"allowRepeating\":true,\"source\":\"console-api\",\"type\":\"endGroup\",\"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?key=console.group()\",\"line\":3,\"column\":1},\"groupId\":null,\"exceptionDocURL\":null,\"userProvidedStyles\":[]}", + "stacktrace": null, + "frame": { + "source": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.group()", + "line": 3, + "column": 1 + }, + "groupId": null, + "exceptionDocURL": null, + "userProvidedStyles": [] +})); + +stubPreparedMessages.set("console.log(%cfoobar)", new ConsoleMessage({ + "id": "1", + "allowRepeating": true, + "source": "console-api", + "type": "log", + "level": "log", + "messageText": null, + "parameters": [ + "foo", + "bar" + ], + "repeat": 1, + "repeatId": "{\"id\":null,\"allowRepeating\":true,\"source\":\"console-api\",\"type\":\"log\",\"level\":\"log\",\"messageText\":null,\"parameters\":[\"foo\",\"bar\"],\"repeatId\":null,\"stacktrace\":null,\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.log(%25cfoobar)\",\"line\":2,\"column\":1},\"groupId\":null,\"exceptionDocURL\":null,\"userProvidedStyles\":[\"color:blue;font-size:1.3em;background:url('http://example.com/test');position:absolute;top:10px\",\"color:red;background:url('http://example.com/test')\"]}", + "stacktrace": null, + "frame": { + "source": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.log(%25cfoobar)", + "line": 2, + "column": 1 + }, + "groupId": null, + "exceptionDocURL": null, + "userProvidedStyles": [ + "color:blue;font-size:1.3em;background:url('http://example.com/test');position:absolute;top:10px", + "color:red;background:url('http://example.com/test')" + ] +})); + + +stubPackets.set("console.log('foobar', 'test')", { + "from": "server1.conn0.child1/consoleActor2", + "type": "consoleAPICall", + "message": { + "arguments": [ + "foobar", + "test" + ], + "columnNumber": 27, + "counter": null, + "filename": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.log(%27foobar%27%2C%20%27test%27)", + "functionName": "triggerPacket", + "groupName": "", + "level": "log", + "lineNumber": 1, + "originAttributes": { + "addonId": "", + "appId": 0, + "firstPartyDomain": "", + "inIsolatedMozBrowser": false, + "privateBrowsingId": 0, + "userContextId": 0 + }, + "private": false, + "styles": [], + "timeStamp": 1477086261590, + "timer": null, + "workerType": "none", + "category": "webdev" + } +}); + +stubPackets.set("console.log(undefined)", { + "from": "server1.conn1.child1/consoleActor2", + "type": "consoleAPICall", + "message": { + "arguments": [ + { + "type": "undefined" + } + ], + "columnNumber": 27, + "counter": null, + "filename": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.log(undefined)", + "functionName": "triggerPacket", + "groupName": "", + "level": "log", + "lineNumber": 1, + "originAttributes": { + "addonId": "", + "appId": 0, + "firstPartyDomain": "", + "inIsolatedMozBrowser": false, + "privateBrowsingId": 0, + "userContextId": 0 + }, + "private": false, + "styles": [], + "timeStamp": 1477086264886, + "timer": null, + "workerType": "none", + "category": "webdev" + } +}); + +stubPackets.set("console.warn('danger, will robinson!')", { + "from": "server1.conn2.child1/consoleActor2", + "type": "consoleAPICall", + "message": { + "arguments": [ + "danger, will robinson!" + ], + "columnNumber": 27, + "counter": null, + "filename": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.warn(%27danger%2C%20will%20robinson!%27)", + "functionName": "triggerPacket", + "groupName": "", + "level": "warn", + "lineNumber": 1, + "originAttributes": { + "addonId": "", + "appId": 0, + "firstPartyDomain": "", + "inIsolatedMozBrowser": false, + "privateBrowsingId": 0, + "userContextId": 0 + }, + "private": false, + "styles": [], + "timeStamp": 1477086267284, + "timer": null, + "workerType": "none", + "category": "webdev" + } +}); + +stubPackets.set("console.log(NaN)", { + "from": "server1.conn3.child1/consoleActor2", + "type": "consoleAPICall", + "message": { + "arguments": [ + { + "type": "NaN" + } + ], + "columnNumber": 27, + "counter": null, + "filename": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.log(NaN)", + "functionName": "triggerPacket", + "groupName": "", + "level": "log", + "lineNumber": 1, + "originAttributes": { + "addonId": "", + "appId": 0, + "firstPartyDomain": "", + "inIsolatedMozBrowser": false, + "privateBrowsingId": 0, + "userContextId": 0 + }, + "private": false, + "styles": [], + "timeStamp": 1477086269484, + "timer": null, + "workerType": "none", + "category": "webdev" + } +}); + +stubPackets.set("console.log(null)", { + "from": "server1.conn4.child1/consoleActor2", + "type": "consoleAPICall", + "message": { + "arguments": [ + { + "type": "null" + } + ], + "columnNumber": 27, + "counter": null, + "filename": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.log(null)", + "functionName": "triggerPacket", + "groupName": "", + "level": "log", + "lineNumber": 1, + "originAttributes": { + "addonId": "", + "appId": 0, + "firstPartyDomain": "", + "inIsolatedMozBrowser": false, + "privateBrowsingId": 0, + "userContextId": 0 + }, + "private": false, + "styles": [], + "timeStamp": 1477086271418, + "timer": null, + "workerType": "none", + "category": "webdev" + } +}); + +stubPackets.set("console.log('鼬')", { + "from": "server1.conn5.child1/consoleActor2", + "type": "consoleAPICall", + "message": { + "arguments": [ + "鼬" + ], + "columnNumber": 27, + "counter": null, + "filename": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.log(%27%E9%BC%AC%27)", + "functionName": "triggerPacket", + "groupName": "", + "level": "log", + "lineNumber": 1, + "originAttributes": { + "addonId": "", + "appId": 0, + "firstPartyDomain": "", + "inIsolatedMozBrowser": false, + "privateBrowsingId": 0, + "userContextId": 0 + }, + "private": false, + "styles": [], + "timeStamp": 1477086273549, + "timer": null, + "workerType": "none", + "category": "webdev" + } +}); + +stubPackets.set("console.clear()", { + "from": "server1.conn6.child1/consoleActor2", + "type": "consoleAPICall", + "message": { + "arguments": [], + "columnNumber": 27, + "counter": null, + "filename": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.clear()", + "functionName": "triggerPacket", + "groupName": "", + "level": "clear", + "lineNumber": 1, + "originAttributes": { + "addonId": "", + "appId": 0, + "firstPartyDomain": "", + "inIsolatedMozBrowser": false, + "privateBrowsingId": 0, + "userContextId": 0 + }, + "private": false, + "timeStamp": 1477086275587, + "timer": null, + "workerType": "none", + "styles": [], + "category": "webdev" + } +}); + +stubPackets.set("console.count('bar')", { + "from": "server1.conn7.child1/consoleActor2", + "type": "consoleAPICall", + "message": { + "arguments": [ + "bar" + ], + "columnNumber": 27, + "counter": { + "count": 1, + "label": "bar" + }, + "filename": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.count(%27bar%27)", + "functionName": "triggerPacket", + "groupName": "", + "level": "count", + "lineNumber": 1, + "originAttributes": { + "addonId": "", + "appId": 0, + "firstPartyDomain": "", + "inIsolatedMozBrowser": false, + "privateBrowsingId": 0, + "userContextId": 0 + }, + "private": false, + "timeStamp": 1477086277812, + "timer": null, + "workerType": "none", + "styles": [], + "category": "webdev" + } +}); + +stubPackets.set("console.assert(false, {message: 'foobar'})", { + "from": "server1.conn8.child1/consoleActor2", + "type": "consoleAPICall", + "message": { + "arguments": [ + { + "type": "object", + "actor": "server1.conn8.child1/obj31", + "class": "Object", + "extensible": true, + "frozen": false, + "sealed": false, + "ownPropertyLength": 1, + "preview": { + "kind": "Object", + "ownProperties": { + "message": { + "configurable": true, + "enumerable": true, + "writable": true, + "value": "foobar" + } + }, + "ownPropertiesLength": 1, + "safeGetterValues": {} + } + } + ], + "columnNumber": 27, + "counter": null, + "filename": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.assert(false%2C%20%7Bmessage%3A%20%27foobar%27%7D)", + "functionName": "triggerPacket", + "groupName": "", + "level": "assert", + "lineNumber": 1, + "originAttributes": { + "addonId": "", + "appId": 0, + "firstPartyDomain": "", + "inIsolatedMozBrowser": false, + "privateBrowsingId": 0, + "userContextId": 0 + }, + "private": false, + "styles": [], + "timeStamp": 1477086280131, + "timer": null, + "stacktrace": [ + { + "columnNumber": 27, + "filename": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.assert(false%2C%20%7Bmessage%3A%20%27foobar%27%7D)", + "functionName": "triggerPacket", + "language": 2, + "lineNumber": 1 + } + ], + "workerType": "none", + "category": "webdev" + } +}); + +stubPackets.set("console.log('hello \nfrom \rthe \"string world!')", { + "from": "server1.conn9.child1/consoleActor2", + "type": "consoleAPICall", + "message": { + "arguments": [ + "hello \nfrom \rthe \"string world!" + ], + "columnNumber": 27, + "counter": null, + "filename": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.log(%27hello%20%5Cnfrom%20%5Crthe%20%5C%22string%20world!%27)", + "functionName": "triggerPacket", + "groupName": "", + "level": "log", + "lineNumber": 1, + "originAttributes": { + "addonId": "", + "appId": 0, + "firstPartyDomain": "", + "inIsolatedMozBrowser": false, + "privateBrowsingId": 0, + "userContextId": 0 + }, + "private": false, + "styles": [], + "timeStamp": 1477086281936, + "timer": null, + "workerType": "none", + "category": "webdev" + } +}); + +stubPackets.set("console.log('úṇĩçödê țĕșť')", { + "from": "server1.conn10.child1/consoleActor2", + "type": "consoleAPICall", + "message": { + "arguments": [ + "úṇĩçödê țĕșť" + ], + "columnNumber": 27, + "counter": null, + "filename": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.log(%27%C3%BA%E1%B9%87%C4%A9%C3%A7%C3%B6d%C3%AA%20%C8%9B%C4%95%C8%99%C5%A5%27)", + "functionName": "triggerPacket", + "groupName": "", + "level": "log", + "lineNumber": 1, + "originAttributes": { + "addonId": "", + "appId": 0, + "firstPartyDomain": "", + "inIsolatedMozBrowser": false, + "privateBrowsingId": 0, + "userContextId": 0 + }, + "private": false, + "styles": [], + "timeStamp": 1477086283713, + "timer": null, + "workerType": "none", + "category": "webdev" + } +}); + +stubPackets.set("console.dirxml(window)", { + "from": "server1.conn11.child1/consoleActor2", + "type": "consoleAPICall", + "message": { + "arguments": [ + { + "type": "object", + "actor": "server1.conn11.child1/obj31", + "class": "Window", + "extensible": true, + "frozen": false, + "sealed": false, + "ownPropertyLength": 804, + "preview": { + "kind": "ObjectWithURL", + "url": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-console-api.html" + } + } + ], + "columnNumber": 27, + "counter": null, + "filename": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.dirxml(window)", + "functionName": "triggerPacket", + "groupName": "", + "level": "dirxml", + "lineNumber": 1, + "originAttributes": { + "addonId": "", + "appId": 0, + "firstPartyDomain": "", + "inIsolatedMozBrowser": false, + "privateBrowsingId": 0, + "userContextId": 0 + }, + "private": false, + "timeStamp": 1477086285483, + "timer": null, + "workerType": "none", + "styles": [], + "category": "webdev" + } +}); + +stubPackets.set("console.trace()", { + "from": "server1.conn12.child1/consoleActor2", + "type": "consoleAPICall", + "message": { + "arguments": [], + "columnNumber": 3, + "counter": null, + "filename": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.trace()", + "functionName": "testStacktraceFiltering", + "groupName": "", + "level": "trace", + "lineNumber": 3, + "originAttributes": { + "addonId": "", + "appId": 0, + "firstPartyDomain": "", + "inIsolatedMozBrowser": false, + "privateBrowsingId": 0, + "userContextId": 0 + }, + "private": false, + "timeStamp": 1477086287286, + "timer": null, + "stacktrace": [ + { + "columnNumber": 3, + "filename": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.trace()", + "functionName": "testStacktraceFiltering", + "language": 2, + "lineNumber": 3 + }, + { + "columnNumber": 3, + "filename": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.trace()", + "functionName": "foo", + "language": 2, + "lineNumber": 6 + }, + { + "columnNumber": 1, + "filename": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.trace()", + "functionName": "triggerPacket", + "language": 2, + "lineNumber": 9 + } + ], + "workerType": "none", + "styles": [], + "category": "webdev" + } +}); + +stubPackets.set("console.time('bar')", { + "from": "server1.conn13.child1/consoleActor2", + "type": "consoleAPICall", + "message": { + "arguments": [ + "bar" + ], + "columnNumber": 1, + "counter": null, + "filename": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.time(%27bar%27)", + "functionName": "triggerPacket", + "groupName": "", + "level": "time", + "lineNumber": 2, + "originAttributes": { + "addonId": "", + "appId": 0, + "firstPartyDomain": "", + "inIsolatedMozBrowser": false, + "privateBrowsingId": 0, + "userContextId": 0 + }, + "private": false, + "timeStamp": 1477086289137, + "timer": { + "name": "bar", + "started": 1166.305 + }, + "workerType": "none", + "styles": [], + "category": "webdev" + } +}); + +stubPackets.set("console.timeEnd('bar')", { + "from": "server1.conn13.child1/consoleActor2", + "type": "consoleAPICall", + "message": { + "arguments": [ + "bar" + ], + "columnNumber": 1, + "counter": null, + "filename": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.time(%27bar%27)", + "functionName": "triggerPacket", + "groupName": "", + "level": "timeEnd", + "lineNumber": 3, + "originAttributes": { + "addonId": "", + "appId": 0, + "firstPartyDomain": "", + "inIsolatedMozBrowser": false, + "privateBrowsingId": 0, + "userContextId": 0 + }, + "private": false, + "timeStamp": 1477086289138, + "timer": { + "duration": 1.3550000000000182, + "name": "bar" + }, + "workerType": "none", + "styles": [], + "category": "webdev" + } +}); + +stubPackets.set("console.table('bar')", { + "from": "server1.conn14.child1/consoleActor2", + "type": "consoleAPICall", + "message": { + "arguments": [ + "bar" + ], + "columnNumber": 1, + "counter": null, + "filename": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.table(%27bar%27)", + "functionName": "triggerPacket", + "groupName": "", + "level": "table", + "lineNumber": 2, + "originAttributes": { + "addonId": "", + "appId": 0, + "firstPartyDomain": "", + "inIsolatedMozBrowser": false, + "privateBrowsingId": 0, + "userContextId": 0 + }, + "private": false, + "timeStamp": 1477086290984, + "timer": null, + "workerType": "none", + "styles": [], + "category": "webdev" + } +}); + +stubPackets.set("console.table(['a', 'b', 'c'])", { + "from": "server1.conn15.child1/consoleActor2", + "type": "consoleAPICall", + "message": { + "arguments": [ + { + "type": "object", + "actor": "server1.conn15.child1/obj31", + "class": "Array", + "extensible": true, + "frozen": false, + "sealed": false, + "ownPropertyLength": 4, + "preview": { + "kind": "ArrayLike", + "length": 3, + "items": [ + "a", + "b", + "c" + ] + } + } + ], + "columnNumber": 1, + "counter": null, + "filename": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.table(%5B%27a%27%2C%20%27b%27%2C%20%27c%27%5D)", + "functionName": "triggerPacket", + "groupName": "", + "level": "table", + "lineNumber": 2, + "originAttributes": { + "addonId": "", + "appId": 0, + "firstPartyDomain": "", + "inIsolatedMozBrowser": false, + "privateBrowsingId": 0, + "userContextId": 0 + }, + "private": false, + "timeStamp": 1477086292762, + "timer": null, + "workerType": "none", + "styles": [], + "category": "webdev" + } +}); + +stubPackets.set("console.group('bar')", { + "from": "server1.conn16.child1/consoleActor2", + "type": "consoleAPICall", + "message": { + "arguments": [ + "bar" + ], + "columnNumber": 1, + "counter": null, + "filename": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.group(%27bar%27)", + "functionName": "triggerPacket", + "groupName": "bar", + "level": "group", + "lineNumber": 2, + "originAttributes": { + "addonId": "", + "appId": 0, + "firstPartyDomain": "", + "inIsolatedMozBrowser": false, + "privateBrowsingId": 0, + "userContextId": 0 + }, + "private": false, + "timeStamp": 1477086294628, + "timer": null, + "workerType": "none", + "styles": [], + "category": "webdev" + } +}); + +stubPackets.set("console.groupEnd('bar')", { + "from": "server1.conn16.child1/consoleActor2", + "type": "consoleAPICall", + "message": { + "arguments": [ + "bar" + ], + "columnNumber": 1, + "counter": null, + "filename": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.group(%27bar%27)", + "functionName": "triggerPacket", + "groupName": "bar", + "level": "groupEnd", + "lineNumber": 3, + "originAttributes": { + "addonId": "", + "appId": 0, + "firstPartyDomain": "", + "inIsolatedMozBrowser": false, + "privateBrowsingId": 0, + "userContextId": 0 + }, + "private": false, + "timeStamp": 1477086294630, + "timer": null, + "workerType": "none", + "styles": [], + "category": "webdev" + } +}); + +stubPackets.set("console.groupCollapsed('foo')", { + "from": "server1.conn17.child1/consoleActor2", + "type": "consoleAPICall", + "message": { + "arguments": [ + "foo" + ], + "columnNumber": 1, + "counter": null, + "filename": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.groupCollapsed(%27foo%27)", + "functionName": "triggerPacket", + "groupName": "foo", + "level": "groupCollapsed", + "lineNumber": 2, + "originAttributes": { + "addonId": "", + "appId": 0, + "firstPartyDomain": "", + "inIsolatedMozBrowser": false, + "privateBrowsingId": 0, + "userContextId": 0 + }, + "private": false, + "timeStamp": 1477086296567, + "timer": null, + "workerType": "none", + "styles": [], + "category": "webdev" + } +}); + +stubPackets.set("console.groupEnd('foo')", { + "from": "server1.conn17.child1/consoleActor2", + "type": "consoleAPICall", + "message": { + "arguments": [ + "foo" + ], + "columnNumber": 1, + "counter": null, + "filename": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.groupCollapsed(%27foo%27)", + "functionName": "triggerPacket", + "groupName": "foo", + "level": "groupEnd", + "lineNumber": 3, + "originAttributes": { + "addonId": "", + "appId": 0, + "firstPartyDomain": "", + "inIsolatedMozBrowser": false, + "privateBrowsingId": 0, + "userContextId": 0 + }, + "private": false, + "timeStamp": 1477086296570, + "timer": null, + "workerType": "none", + "styles": [], + "category": "webdev" + } +}); + +stubPackets.set("console.group()", { + "from": "server1.conn18.child1/consoleActor2", + "type": "consoleAPICall", + "message": { + "arguments": [], + "columnNumber": 1, + "counter": null, + "filename": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.group()", + "functionName": "triggerPacket", + "groupName": "", + "level": "group", + "lineNumber": 2, + "originAttributes": { + "addonId": "", + "appId": 0, + "firstPartyDomain": "", + "inIsolatedMozBrowser": false, + "privateBrowsingId": 0, + "userContextId": 0 + }, + "private": false, + "timeStamp": 1477086298462, + "timer": null, + "workerType": "none", + "styles": [], + "category": "webdev" + } +}); + +stubPackets.set("console.groupEnd()", { + "from": "server1.conn18.child1/consoleActor2", + "type": "consoleAPICall", + "message": { + "arguments": [], + "columnNumber": 1, + "counter": null, + "filename": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.group()", + "functionName": "triggerPacket", + "groupName": "", + "level": "groupEnd", + "lineNumber": 3, + "originAttributes": { + "addonId": "", + "appId": 0, + "firstPartyDomain": "", + "inIsolatedMozBrowser": false, + "privateBrowsingId": 0, + "userContextId": 0 + }, + "private": false, + "timeStamp": 1477086298464, + "timer": null, + "workerType": "none", + "styles": [], + "category": "webdev" + } +}); + +stubPackets.set("console.log(%cfoobar)", { + "from": "server1.conn19.child1/consoleActor2", + "type": "consoleAPICall", + "message": { + "arguments": [ + "foo", + "bar" + ], + "columnNumber": 1, + "counter": null, + "filename": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=console.log(%25cfoobar)", + "functionName": "triggerPacket", + "groupName": "", + "level": "log", + "lineNumber": 2, + "originAttributes": { + "addonId": "", + "appId": 0, + "firstPartyDomain": "", + "inIsolatedMozBrowser": false, + "privateBrowsingId": 0, + "userContextId": 0 + }, + "private": false, + "styles": [ + "color:blue;font-size:1.3em;background:url('http://example.com/test');position:absolute;top:10px", + "color:red;background:url('http://example.com/test')" + ], + "timeStamp": 1477086300265, + "timer": null, + "workerType": "none", + "category": "webdev" + } +}); + + +module.exports = { + stubPreparedMessages, + stubPackets, +}
\ No newline at end of file diff --git a/devtools/client/webconsole/new-console-output/test/fixtures/stubs/evaluationResult.js b/devtools/client/webconsole/new-console-output/test/fixtures/stubs/evaluationResult.js new file mode 100644 index 000000000..098086044 --- /dev/null +++ b/devtools/client/webconsole/new-console-output/test/fixtures/stubs/evaluationResult.js @@ -0,0 +1,182 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +/* + * THIS FILE IS AUTOGENERATED. DO NOT MODIFY BY HAND. RUN TESTS IN FIXTURES/ TO UPDATE. + */ + +const { ConsoleMessage, NetworkEventMessage } = require("devtools/client/webconsole/new-console-output/types"); + +let stubPreparedMessages = new Map(); +let stubPackets = new Map(); + + +stubPreparedMessages.set("new Date(0)", new ConsoleMessage({ + "id": "1", + "allowRepeating": true, + "source": "javascript", + "type": "result", + "level": "log", + "parameters": { + "type": "object", + "actor": "server1.conn0.child1/obj30", + "class": "Date", + "extensible": true, + "frozen": false, + "sealed": false, + "ownPropertyLength": 0, + "preview": { + "timestamp": 0 + } + }, + "repeat": 1, + "repeatId": "{\"id\":null,\"allowRepeating\":true,\"source\":\"javascript\",\"type\":\"result\",\"level\":\"log\",\"parameters\":{\"type\":\"object\",\"actor\":\"server1.conn0.child1/obj30\",\"class\":\"Date\",\"extensible\":true,\"frozen\":false,\"sealed\":false,\"ownPropertyLength\":0,\"preview\":{\"timestamp\":0}},\"repeatId\":null,\"stacktrace\":null,\"frame\":null,\"groupId\":null,\"userProvidedStyles\":null}", + "stacktrace": null, + "frame": null, + "groupId": null, + "userProvidedStyles": null +})); + +stubPreparedMessages.set("asdf()", new ConsoleMessage({ + "id": "1", + "allowRepeating": true, + "source": "javascript", + "type": "result", + "level": "error", + "messageText": "ReferenceError: asdf is not defined", + "parameters": { + "type": "undefined" + }, + "repeat": 1, + "repeatId": "{\"id\":null,\"allowRepeating\":true,\"source\":\"javascript\",\"type\":\"result\",\"level\":\"error\",\"messageText\":\"ReferenceError: asdf is not defined\",\"parameters\":{\"type\":\"undefined\"},\"repeatId\":null,\"stacktrace\":null,\"frame\":{\"source\":\"debugger eval code\",\"line\":1,\"column\":1},\"groupId\":null,\"exceptionDocURL\":\"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Errors/Not_defined?utm_source=mozilla&utm_medium=firefox-console-errors&utm_campaign=default\",\"userProvidedStyles\":null}", + "stacktrace": null, + "frame": { + "source": "debugger eval code", + "line": 1, + "column": 1 + }, + "groupId": null, + "exceptionDocURL": "https://developer.mozilla.org/docs/Web/JavaScript/Reference/Errors/Not_defined?utm_source=mozilla&utm_medium=firefox-console-errors&utm_campaign=default", + "userProvidedStyles": null +})); + +stubPreparedMessages.set("1 + @", new ConsoleMessage({ + "id": "1", + "allowRepeating": true, + "source": "javascript", + "type": "result", + "level": "error", + "messageText": "SyntaxError: illegal character", + "parameters": { + "type": "undefined" + }, + "repeat": 1, + "repeatId": "{\"id\":null,\"allowRepeating\":true,\"source\":\"javascript\",\"type\":\"result\",\"level\":\"error\",\"messageText\":\"SyntaxError: illegal character\",\"parameters\":{\"type\":\"undefined\"},\"repeatId\":null,\"stacktrace\":null,\"frame\":{\"source\":\"debugger eval code\",\"line\":1,\"column\":4},\"groupId\":null,\"userProvidedStyles\":null}", + "stacktrace": null, + "frame": { + "source": "debugger eval code", + "line": 1, + "column": 4 + }, + "groupId": null, + "userProvidedStyles": null +})); + + +stubPackets.set("new Date(0)", { + "from": "server1.conn0.child1/consoleActor2", + "input": "new Date(0)", + "result": { + "type": "object", + "actor": "server1.conn0.child1/obj30", + "class": "Date", + "extensible": true, + "frozen": false, + "sealed": false, + "ownPropertyLength": 0, + "preview": { + "timestamp": 0 + } + }, + "timestamp": 1476573073424, + "exception": null, + "frame": null, + "helperResult": null +}); + +stubPackets.set("asdf()", { + "from": "server1.conn0.child1/consoleActor2", + "input": "asdf()", + "result": { + "type": "undefined" + }, + "timestamp": 1476573073442, + "exception": { + "type": "object", + "actor": "server1.conn0.child1/obj32", + "class": "Error", + "extensible": true, + "frozen": false, + "sealed": false, + "ownPropertyLength": 4, + "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 + } + }, + "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", + "frame": { + "source": "debugger eval code", + "line": 1, + "column": 1 + }, + "helperResult": null +}); + +stubPackets.set("1 + @", { + "from": "server1.conn0.child1/consoleActor2", + "input": "1 + @", + "result": { + "type": "undefined" + }, + "timestamp": 1478755616654, + "exception": { + "type": "object", + "actor": "server1.conn0.child1/obj33", + "class": "Error", + "extensible": true, + "frozen": false, + "sealed": false, + "ownPropertyLength": 4, + "preview": { + "kind": "Error", + "name": "SyntaxError", + "message": "illegal character", + "stack": "", + "fileName": "debugger eval code", + "lineNumber": 1, + "columnNumber": 4 + } + }, + "exceptionMessage": "SyntaxError: illegal character", + "frame": { + "source": "debugger eval code", + "line": 1, + "column": 4 + }, + "helperResult": null +}); + + +module.exports = { + stubPreparedMessages, + stubPackets, +}
\ No newline at end of file diff --git a/devtools/client/webconsole/new-console-output/test/fixtures/stubs/index.js b/devtools/client/webconsole/new-console-output/test/fixtures/stubs/index.js new file mode 100644 index 000000000..59b420180 --- /dev/null +++ b/devtools/client/webconsole/new-console-output/test/fixtures/stubs/index.js @@ -0,0 +1,29 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +let maps = []; + +[ + "consoleApi", + "evaluationResult", + "networkEvent", + "pageError", +].forEach((filename) => { + maps[filename] = require(`./${filename}`); +}); + +// Combine all the maps into a single map. +module.exports = { + stubPreparedMessages: new Map([ + ...maps.consoleApi.stubPreparedMessages, + ...maps.evaluationResult.stubPreparedMessages, + ...maps.networkEvent.stubPreparedMessages, + ...maps.pageError.stubPreparedMessages, ]), + stubPackets: new Map([ + ...maps.consoleApi.stubPackets, + ...maps.evaluationResult.stubPackets, + ...maps.networkEvent.stubPackets, + ...maps.pageError.stubPackets, ]), +}; diff --git a/devtools/client/webconsole/new-console-output/test/fixtures/stubs/moz.build b/devtools/client/webconsole/new-console-output/test/fixtures/stubs/moz.build new file mode 100644 index 000000000..88e9c46df --- /dev/null +++ b/devtools/client/webconsole/new-console-output/test/fixtures/stubs/moz.build @@ -0,0 +1,11 @@ +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +DevToolsModules( + 'consoleApi.js', + 'evaluationResult.js', + 'index.js', + 'networkEvent.js', + 'pageError.js', +) diff --git a/devtools/client/webconsole/new-console-output/test/fixtures/stubs/networkEvent.js b/devtools/client/webconsole/new-console-output/test/fixtures/stubs/networkEvent.js new file mode 100644 index 000000000..58a40d30b --- /dev/null +++ b/devtools/client/webconsole/new-console-output/test/fixtures/stubs/networkEvent.js @@ -0,0 +1,189 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +/* + * THIS FILE IS AUTOGENERATED. DO NOT MODIFY BY HAND. RUN TESTS IN FIXTURES/ TO UPDATE. + */ + +const { ConsoleMessage, NetworkEventMessage } = require("devtools/client/webconsole/new-console-output/types"); + +let stubPreparedMessages = new Map(); +let stubPackets = new Map(); + + +stubPreparedMessages.set("GET request", new NetworkEventMessage({ + "id": "1", + "actor": "server1.conn0.child1/netEvent29", + "level": "log", + "isXHR": false, + "request": { + "url": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/inexistent.html", + "method": "GET" + }, + "response": {}, + "source": "network", + "type": "log", + "groupId": null +})); + +stubPreparedMessages.set("XHR GET request", new NetworkEventMessage({ + "id": "1", + "actor": "server1.conn1.child1/netEvent29", + "level": "log", + "isXHR": true, + "request": { + "url": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/inexistent.html", + "method": "GET" + }, + "response": {}, + "source": "network", + "type": "log", + "groupId": null +})); + +stubPreparedMessages.set("XHR POST request", new NetworkEventMessage({ + "id": "1", + "actor": "server1.conn2.child1/netEvent29", + "level": "log", + "isXHR": true, + "request": { + "url": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/inexistent.html", + "method": "POST" + }, + "response": {}, + "source": "network", + "type": "log", + "groupId": null +})); + + +stubPackets.set("GET request", { + "from": "server1.conn0.child1/consoleActor2", + "type": "networkEvent", + "eventActor": { + "actor": "server1.conn0.child1/netEvent29", + "startedDateTime": "2016-10-15T23:12:04.196Z", + "timeStamp": 1476573124196, + "url": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/inexistent.html", + "method": "GET", + "isXHR": false, + "cause": { + "type": 3, + "loadingDocumentUri": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-network-event.html", + "stacktrace": [ + { + "filename": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js", + "lineNumber": 3, + "columnNumber": 1, + "functionName": "triggerPacket", + "asyncCause": null + }, + { + "filename": "chrome://mochikit/content/tests/BrowserTestUtils/content-task.js line 52 > eval", + "lineNumber": 4, + "columnNumber": 7, + "functionName": null, + "asyncCause": null + }, + { + "filename": "chrome://mochikit/content/tests/BrowserTestUtils/content-task.js", + "lineNumber": 53, + "columnNumber": 20, + "functionName": null, + "asyncCause": null + } + ] + }, + "private": false + } +}); + +stubPackets.set("XHR GET request", { + "from": "server1.conn1.child1/consoleActor2", + "type": "networkEvent", + "eventActor": { + "actor": "server1.conn1.child1/netEvent29", + "startedDateTime": "2016-10-15T23:12:05.690Z", + "timeStamp": 1476573125690, + "url": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/inexistent.html", + "method": "GET", + "isXHR": true, + "cause": { + "type": 11, + "loadingDocumentUri": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-network-event.html", + "stacktrace": [ + { + "filename": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js", + "lineNumber": 4, + "columnNumber": 1, + "functionName": "triggerPacket", + "asyncCause": null + }, + { + "filename": "chrome://mochikit/content/tests/BrowserTestUtils/content-task.js line 52 > eval", + "lineNumber": 4, + "columnNumber": 7, + "functionName": null, + "asyncCause": null + }, + { + "filename": "chrome://mochikit/content/tests/BrowserTestUtils/content-task.js", + "lineNumber": 53, + "columnNumber": 20, + "functionName": null, + "asyncCause": null + } + ] + }, + "private": false + } +}); + +stubPackets.set("XHR POST request", { + "from": "server1.conn2.child1/consoleActor2", + "type": "networkEvent", + "eventActor": { + "actor": "server1.conn2.child1/netEvent29", + "startedDateTime": "2016-10-15T23:12:07.158Z", + "timeStamp": 1476573127158, + "url": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/inexistent.html", + "method": "POST", + "isXHR": true, + "cause": { + "type": 11, + "loadingDocumentUri": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-network-event.html", + "stacktrace": [ + { + "filename": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js", + "lineNumber": 4, + "columnNumber": 1, + "functionName": "triggerPacket", + "asyncCause": null + }, + { + "filename": "chrome://mochikit/content/tests/BrowserTestUtils/content-task.js line 52 > eval", + "lineNumber": 4, + "columnNumber": 7, + "functionName": null, + "asyncCause": null + }, + { + "filename": "chrome://mochikit/content/tests/BrowserTestUtils/content-task.js", + "lineNumber": 53, + "columnNumber": 20, + "functionName": null, + "asyncCause": null + } + ] + }, + "private": false + } +}); + + +module.exports = { + stubPreparedMessages, + stubPackets, +}
\ No newline at end of file diff --git a/devtools/client/webconsole/new-console-output/test/fixtures/stubs/pageError.js b/devtools/client/webconsole/new-console-output/test/fixtures/stubs/pageError.js new file mode 100644 index 000000000..eda8e8b83 --- /dev/null +++ b/devtools/client/webconsole/new-console-output/test/fixtures/stubs/pageError.js @@ -0,0 +1,102 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +/* + * THIS FILE IS AUTOGENERATED. DO NOT MODIFY BY HAND. RUN TESTS IN FIXTURES/ TO UPDATE. + */ + +const { ConsoleMessage, NetworkEventMessage } = require("devtools/client/webconsole/new-console-output/types"); + +let stubPreparedMessages = new Map(); +let stubPackets = new Map(); + + +stubPreparedMessages.set("ReferenceError: asdf is not defined", new ConsoleMessage({ + "id": "1", + "allowRepeating": true, + "source": "javascript", + "type": "log", + "level": "error", + "messageText": "ReferenceError: asdf is not defined", + "parameters": null, + "repeat": 1, + "repeatId": "{\"id\":null,\"allowRepeating\":true,\"source\":\"javascript\",\"type\":\"log\",\"level\":\"error\",\"messageText\":\"ReferenceError: asdf is not defined\",\"parameters\":null,\"repeatId\":null,\"stacktrace\":[{\"filename\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=Reference%20Error\",\"lineNumber\":3,\"columnNumber\":5,\"functionName\":\"bar\"},{\"filename\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=Reference%20Error\",\"lineNumber\":6,\"columnNumber\":5,\"functionName\":\"foo\"},{\"filename\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=Reference%20Error\",\"lineNumber\":9,\"columnNumber\":3,\"functionName\":null}],\"frame\":{\"source\":\"http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=Reference%20Error\",\"line\":3,\"column\":5},\"groupId\":null,\"exceptionDocURL\":\"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Errors/Not_defined?utm_source=mozilla&utm_medium=firefox-console-errors&utm_campaign=default\"}", + "stacktrace": [ + { + "filename": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=Reference%20Error", + "lineNumber": 3, + "columnNumber": 5, + "functionName": "bar" + }, + { + "filename": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=Reference%20Error", + "lineNumber": 6, + "columnNumber": 5, + "functionName": "foo" + }, + { + "filename": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=Reference%20Error", + "lineNumber": 9, + "columnNumber": 3, + "functionName": null + } + ], + "frame": { + "source": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=Reference%20Error", + "line": 3, + "column": 5 + }, + "groupId": null, + "exceptionDocURL": "https://developer.mozilla.org/docs/Web/JavaScript/Reference/Errors/Not_defined?utm_source=mozilla&utm_medium=firefox-console-errors&utm_campaign=default" +})); + + +stubPackets.set("ReferenceError: asdf is not defined", { + "from": "server1.conn0.child1/consoleActor2", + "type": "pageError", + "pageError": { + "errorMessage": "ReferenceError: asdf is not defined", + "errorMessageName": "JSMSG_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", + "sourceName": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=Reference%20Error", + "lineText": "", + "lineNumber": 3, + "columnNumber": 5, + "category": "content javascript", + "timeStamp": 1476573167137, + "warning": false, + "error": false, + "exception": true, + "strict": false, + "info": false, + "private": false, + "stacktrace": [ + { + "filename": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=Reference%20Error", + "lineNumber": 3, + "columnNumber": 5, + "functionName": "bar" + }, + { + "filename": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=Reference%20Error", + "lineNumber": 6, + "columnNumber": 5, + "functionName": "foo" + }, + { + "filename": "http://example.com/browser/devtools/client/webconsole/new-console-output/test/fixtures/stub-generators/test-tempfile.js?key=Reference%20Error", + "lineNumber": 9, + "columnNumber": 3, + "functionName": null + } + ] + } +}); + + +module.exports = { + stubPreparedMessages, + stubPackets, +}
\ No newline at end of file diff --git a/devtools/client/webconsole/new-console-output/test/helpers.js b/devtools/client/webconsole/new-console-output/test/helpers.js new file mode 100644 index 000000000..39807eaed --- /dev/null +++ b/devtools/client/webconsole/new-console-output/test/helpers.js @@ -0,0 +1,67 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +let ReactDOM = require("devtools/client/shared/vendor/react-dom"); +let React = require("devtools/client/shared/vendor/react"); +var TestUtils = React.addons.TestUtils; + +const actions = require("devtools/client/webconsole/new-console-output/actions/index"); +const { configureStore } = require("devtools/client/webconsole/new-console-output/store"); +const { IdGenerator } = require("devtools/client/webconsole/new-console-output/utils/id-generator"); +const { stubPackets } = require("devtools/client/webconsole/new-console-output/test/fixtures/stubs/index"); + +/** + * 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({}, actions); + + const idGenerator = new IdGenerator(); + wrappedActions.messageAdd = (packet) => { + return actions.messageAdd(packet, idGenerator); + }; + + return wrappedActions; +} + +/** + * Prepare the store for use in testing. + */ +function setupStore(input) { + const store = configureStore(); + + // Add the messages from the input commands to the store. + input.forEach((cmd) => { + store.dispatch(actions.messageAdd(stubPackets.get(cmd))); + }); + + return store; +} + +function renderComponent(component, props) { + const el = React.createElement(component, props, {}); + // By default, renderIntoDocument() won't work for stateless components, but + // it will work if the stateless component is wrapped in a stateful one. + // See https://github.com/facebook/react/issues/4839 + const wrappedEl = React.DOM.span({}, [el]); + const renderedComponent = TestUtils.renderIntoDocument(wrappedEl); + return ReactDOM.findDOMNode(renderedComponent).children[0]; +} + +function shallowRenderComponent(component, props) { + const el = React.createElement(component, props); + const renderer = TestUtils.createRenderer(); + renderer.render(el, {}); + return renderer.getRenderOutput(); +} + +module.exports = { + setupActions, + setupStore, + renderComponent, + shallowRenderComponent +}; diff --git a/devtools/client/webconsole/new-console-output/test/mochitest/browser.ini b/devtools/client/webconsole/new-console-output/test/mochitest/browser.ini new file mode 100644 index 000000000..9881d0559 --- /dev/null +++ b/devtools/client/webconsole/new-console-output/test/mochitest/browser.ini @@ -0,0 +1,21 @@ +[DEFAULT] +tags = devtools +subsuite = devtools +support-files = + head.js + test-batching.html + test-console.html + test-console-filters.html + test-console-group.html + test-console-table.html + !/devtools/client/framework/test/shared-head.js + +[browser_webconsole_batching.js] +[browser_webconsole_console_group.js] +[browser_webconsole_console_table.js] +[browser_webconsole_filters.js] +[browser_webconsole_init.js] +[browser_webconsole_input_focus.js] +[browser_webconsole_keyboard_accessibility.js] +[browser_webconsole_observer_notifications.js] +[browser_webconsole_vview_close_on_esc_key.js] diff --git a/devtools/client/webconsole/new-console-output/test/mochitest/browser_webconsole_batching.js b/devtools/client/webconsole/new-console-output/test/mochitest/browser_webconsole_batching.js new file mode 100644 index 000000000..0bfdccc3c --- /dev/null +++ b/devtools/client/webconsole/new-console-output/test/mochitest/browser_webconsole_batching.js @@ -0,0 +1,51 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ +/* vim: set ft=javascript ts=2 et sw=2 tw=80: */ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +// Check adding console calls as batch keep the order of the message. + +const TEST_URI = "http://example.com/browser/devtools/client/webconsole/new-console-output/test/mochitest/test-batching.html"; +const { l10n } = require("devtools/client/webconsole/new-console-output/utils/messages"); + +add_task(function* () { + let hud = yield openNewTabAndConsole(TEST_URI); + const messageNumber = 100; + yield testSimpleBatchLogging(hud, messageNumber); + yield testBatchLoggingAndClear(hud, messageNumber); +}); + +function* testSimpleBatchLogging(hud, messageNumber) { + yield ContentTask.spawn(gBrowser.selectedBrowser, messageNumber, + function (numMessages) { + content.wrappedJSObject.batchLog(numMessages); + } + ); + + for (let i = 0; i < messageNumber; i++) { + let node = yield waitFor(() => findMessageAtIndex(hud, i, i)); + is(node.textContent, i.toString(), `message at index "${i}" is the expected one`); + } +} + +function* testBatchLoggingAndClear(hud, messageNumber) { + yield ContentTask.spawn(gBrowser.selectedBrowser, messageNumber, + function (numMessages) { + content.wrappedJSObject.batchLogAndClear(numMessages); + } + ); + yield waitFor(() => findMessage(hud, l10n.getStr("consoleCleared"))); + ok(true, "console cleared message is displayed"); + + // Passing the text argument as an empty string will returns all the message, + // whatever their content is. + const messages = findMessages(hud, ""); + is(messages.length, 1, "console was cleared as expected"); +} + +function findMessageAtIndex(hud, text, index) { + const selector = `.message:nth-of-type(${index + 1}) .message-body`; + return findMessage(hud, text, selector); +} diff --git a/devtools/client/webconsole/new-console-output/test/mochitest/browser_webconsole_console_group.js b/devtools/client/webconsole/new-console-output/test/mochitest/browser_webconsole_console_group.js new file mode 100644 index 000000000..94de78f13 --- /dev/null +++ b/devtools/client/webconsole/new-console-output/test/mochitest/browser_webconsole_console_group.js @@ -0,0 +1,91 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ +/* vim: set ft=javascript ts=2 et sw=2 tw=80: */ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +// Check console.group, console.groupCollapsed and console.groupEnd calls +// behave as expected. + +const TEST_URI = "http://example.com/browser/devtools/client/webconsole/new-console-output/test/mochitest/test-console-group.html"; +const { INDENT_WIDTH } = require("devtools/client/webconsole/new-console-output/components/message-indent"); + +add_task(function* () { + let toolbox = yield openNewTabAndToolbox(TEST_URI, "webconsole"); + let hud = toolbox.getCurrentPanel().hud; + + const store = hud.ui.newConsoleOutput.getStore(); + // Adding loggin each time the store is modified in order to check + // the store state in case of failure. + store.subscribe(() => { + const messages = store.getState().messages.messagesById.toJS() + .map(message => { + return { + id: message.id, + type: message.type, + parameters: message.parameters, + messageText: message.messageText + }; + } + ); + info("messages : " + JSON.stringify(messages)); + }); + + yield ContentTask.spawn(gBrowser.selectedBrowser, null, function () { + content.wrappedJSObject.doLog(); + }); + + info("Test a group at root level"); + let node = yield waitFor(() => findMessage(hud, "group-1")); + testClass(node, "startGroup"); + testIndent(node, 0); + + info("Test a message in a 1 level deep group"); + node = yield waitFor(() => findMessage(hud, "log-1")); + testClass(node, "log"); + testIndent(node, 1); + + info("Test a group in a 1 level deep group"); + node = yield waitFor(() => findMessage(hud, "group-2")); + testClass(node, "startGroup"); + testIndent(node, 1); + + info("Test a message in a 2 level deep group"); + node = yield waitFor(() => findMessage(hud, "log-2")); + testClass(node, "log"); + testIndent(node, 2); + + info("Test a message in a 1 level deep group, after closing a 2 level deep group"); + node = yield waitFor(() => findMessage(hud, "log-3")); + testClass(node, "log"); + testIndent(node, 1); + + info("Test a message at root level, after closing all the groups"); + node = yield waitFor(() => findMessage(hud, "log-4")); + testClass(node, "log"); + testIndent(node, 0); + + info("Test a collapsed group at root level"); + node = yield waitFor(() => findMessage(hud, "group-3")); + testClass(node, "startGroupCollapsed"); + testIndent(node, 0); + + info("Test a message at root level, after closing a collapsed group"); + node = yield waitFor(() => findMessage(hud, "log-6")); + testClass(node, "log"); + testIndent(node, 0); + + let nodes = hud.ui.experimentalOutputNode.querySelectorAll(".message"); + is(nodes.length, 8, "expected number of messages are displayed"); +}); + +function testClass(node, className) { + ok(node.classList.contains(className), `message has the expected "${className}" class`); +} + +function testIndent(node, indent) { + indent = `${indent * INDENT_WIDTH}px`; + is(node.querySelector(".indent").style.width, indent, + "message has the expected level of indentation"); +} diff --git a/devtools/client/webconsole/new-console-output/test/mochitest/browser_webconsole_console_table.js b/devtools/client/webconsole/new-console-output/test/mochitest/browser_webconsole_console_table.js new file mode 100644 index 000000000..a90ae1af1 --- /dev/null +++ b/devtools/client/webconsole/new-console-output/test/mochitest/browser_webconsole_console_table.js @@ -0,0 +1,173 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ +/* vim: set ft=javascript ts=2 et sw=2 tw=80: */ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +// Check console.table calls with all the test cases shown +// in the MDN doc (https://developer.mozilla.org/en-US/docs/Web/API/Console/table) + +const TEST_URI = "http://example.com/browser/devtools/client/webconsole/new-console-output/test/mochitest/test-console-table.html"; + +add_task(function* () { + let toolbox = yield openNewTabAndToolbox(TEST_URI, "webconsole"); + let hud = toolbox.getCurrentPanel().hud; + + function Person(firstName, lastName) { + this.firstName = firstName; + this.lastName = lastName; + } + + const testCases = [{ + info: "Testing when data argument is an array", + input: ["apples", "oranges", "bananas"], + expected: { + columns: ["(index)", "Values"], + rows: [ + ["0", "apples"], + ["1", "oranges"], + ["2", "bananas"], + ] + } + }, { + info: "Testing when data argument is an object", + input: new Person("John", "Smith"), + expected: { + columns: ["(index)", "Values"], + rows: [ + ["firstName", "John"], + ["lastName", "Smith"], + ] + } + }, { + info: "Testing when data argument is an array of arrays", + input: [["Jane", "Doe"], ["Emily", "Jones"]], + expected: { + columns: ["(index)", "0", "1"], + rows: [ + ["0", "Jane", "Doe"], + ["1", "Emily", "Jones"], + ] + } + }, { + info: "Testing when data argument is an array of objects", + input: [ + new Person("Jack", "Foo"), + new Person("Emma", "Bar"), + new Person("Michelle", "Rax"), + ], + expected: { + columns: ["(index)", "firstName", "lastName"], + rows: [ + ["0", "Jack", "Foo"], + ["1", "Emma", "Bar"], + ["2", "Michelle", "Rax"], + ] + } + }, { + info: "Testing when data argument is an object whose properties are objects", + input: { + father: new Person("Darth", "Vader"), + daughter: new Person("Leia", "Organa"), + son: new Person("Luke", "Skywalker"), + }, + expected: { + columns: ["(index)", "firstName", "lastName"], + rows: [ + ["father", "Darth", "Vader"], + ["daughter", "Leia", "Organa"], + ["son", "Luke", "Skywalker"], + ] + } + }, { + info: "Testing when data argument is a Set", + input: new Set(["a", "b", "c"]), + expected: { + columns: ["(iteration index)", "Values"], + rows: [ + ["0", "a"], + ["1", "b"], + ["2", "c"], + ] + } + }, { + info: "Testing when data argument is a Map", + input: new Map([["key-a", "value-a"], ["key-b", "value-b"]]), + expected: { + columns: ["(iteration index)", "Key", "Values"], + rows: [ + ["0", "key-a", "value-a"], + ["1", "key-b", "value-b"], + ] + } + }, { + info: "Testing restricting the columns displayed", + input: [ + new Person("Sam", "Wright"), + new Person("Elena", "Bartz"), + ], + headers: ["firstName"], + expected: { + columns: ["(index)", "firstName"], + rows: [ + ["0", "Sam"], + ["1", "Elena"], + ] + } + }]; + + yield ContentTask.spawn(gBrowser.selectedBrowser, testCases, function (tests) { + tests.forEach((test) => { + content.wrappedJSObject.doConsoleTable(test.input, test.headers); + }); + }); + + let nodes = []; + for (let testCase of testCases) { + let node = yield waitFor( + () => findConsoleTable(hud.ui.experimentalOutputNode, testCases.indexOf(testCase)) + ); + nodes.push(node); + } + + let consoleTableNodes = hud.ui.experimentalOutputNode.querySelectorAll( + ".message .new-consoletable"); + + is(consoleTableNodes.length, testCases.length, + "console has the expected number of consoleTable items"); + + testCases.forEach((testCase, index) => { + info(testCase.info); + + let node = nodes[index]; + let columns = Array.from(node.querySelectorAll("thead th")); + let rows = Array.from(node.querySelectorAll("tbody tr")); + + is( + JSON.stringify(testCase.expected.columns), + JSON.stringify(columns.map(column => column.textContent)), + "table has the expected columns" + ); + + is(testCase.expected.rows.length, rows.length, + "table has the expected number of rows"); + + testCase.expected.rows.forEach((expectedRow, rowIndex) => { + let row = rows[rowIndex]; + let cells = row.querySelectorAll("td"); + is(expectedRow.length, cells.length, "row has the expected number of cells"); + + expectedRow.forEach((expectedCell, cellIndex) => { + let cell = cells[cellIndex]; + is(expectedCell, cell.textContent, "cell has the expected content"); + }); + }); + }); +}); + +function findConsoleTable(node, index) { + let condition = node.querySelector( + `.message:nth-of-type(${index + 1}) .new-consoletable`); + return condition; +} diff --git a/devtools/client/webconsole/new-console-output/test/mochitest/browser_webconsole_filters.js b/devtools/client/webconsole/new-console-output/test/mochitest/browser_webconsole_filters.js new file mode 100644 index 000000000..8eb536926 --- /dev/null +++ b/devtools/client/webconsole/new-console-output/test/mochitest/browser_webconsole_filters.js @@ -0,0 +1,72 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ +/* vim: set ft=javascript ts=2 et sw=2 tw=80: */ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ */ + +// Tests filters. + +"use strict"; + +const { MESSAGE_LEVEL } = require("devtools/client/webconsole/new-console-output/constants"); + +const TEST_URI = "http://example.com/browser/devtools/client/webconsole/new-console-output/test/mochitest/test-console-filters.html"; + +add_task(function* () { + let hud = yield openNewTabAndConsole(TEST_URI); + const outputNode = hud.ui.experimentalOutputNode; + + const toolbar = yield waitFor(() => { + return outputNode.querySelector(".webconsole-filterbar-primary"); + }); + ok(toolbar, "Toolbar found"); + + // Show the filter bar + toolbar.querySelector(".devtools-filter-icon").click(); + const filterBar = yield waitFor(() => { + return outputNode.querySelector(".webconsole-filterbar-secondary"); + }); + ok(filterBar, "Filter bar is shown when filter icon is clicked."); + + // Check defaults. + Object.values(MESSAGE_LEVEL).forEach(level => { + ok(filterIsEnabled(filterBar.querySelector(`.${level}`)), + `Filter button for ${level} is on by default`); + }); + ["net", "netxhr"].forEach(category => { + ok(!filterIsEnabled(filterBar.querySelector(`.${category}`)), + `Filter button for ${category} is off by default`); + }); + + // Check that messages are shown as expected. This depends on cached messages being + // shown. + ok(findMessages(hud, "").length == 5, + "Messages of all levels shown when filters are on."); + + // Check that messages are not shown when their filter is turned off. + filterBar.querySelector(".error").click(); + yield waitFor(() => findMessages(hud, "").length == 4); + ok(true, "When a filter is turned off, its messages are not shown."); + + // Check that the ui settings were persisted. + yield closeTabAndToolbox(); + yield testFilterPersistence(); +}); + +function filterIsEnabled(button) { + return button.classList.contains("checked"); +} + +function* testFilterPersistence() { + let hud = yield openNewTabAndConsole(TEST_URI); + const outputNode = hud.ui.experimentalOutputNode; + const filterBar = yield waitFor(() => { + return outputNode.querySelector(".webconsole-filterbar-secondary"); + }); + ok(filterBar, "Filter bar ui setting is persisted."); + + // Check that the filter settings were persisted. + ok(!filterIsEnabled(filterBar.querySelector(".error")), + "Filter button setting is persisted"); + ok(findMessages(hud, "").length == 4, + "Messages of all levels shown when filters are on."); +} diff --git a/devtools/client/webconsole/new-console-output/test/mochitest/browser_webconsole_init.js b/devtools/client/webconsole/new-console-output/test/mochitest/browser_webconsole_init.js new file mode 100644 index 000000000..4280270dd --- /dev/null +++ b/devtools/client/webconsole/new-console-output/test/mochitest/browser_webconsole_init.js @@ -0,0 +1,35 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ +/* vim: set ft=javascript ts=2 et sw=2 tw=80: */ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +const TEST_URI = "http://example.com/browser/devtools/client/webconsole/new-console-output/test/mochitest/test-console.html"; + +add_task(function* () { + let toolbox = yield openNewTabAndToolbox(TEST_URI, "webconsole"); + let hud = toolbox.getCurrentPanel().hud; + let {ui} = hud; + + ok(ui.jsterm, "jsterm exists"); + ok(ui.newConsoleOutput, "newConsoleOutput exists"); + + // @TODO: fix proptype errors + let receievedMessages = waitForMessages({ + hud, + messages: [{ + text: '0', + }, { + text: '1', + }, { + text: '2', + }], + }); + + yield ContentTask.spawn(gBrowser.selectedBrowser, {}, function() { + content.wrappedJSObject.doLogs(3); + }); + + yield receievedMessages; +}); diff --git a/devtools/client/webconsole/new-console-output/test/mochitest/browser_webconsole_input_focus.js b/devtools/client/webconsole/new-console-output/test/mochitest/browser_webconsole_input_focus.js new file mode 100644 index 000000000..7660df238 --- /dev/null +++ b/devtools/client/webconsole/new-console-output/test/mochitest/browser_webconsole_input_focus.js @@ -0,0 +1,57 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ +/* vim: set ft=javascript ts=2 et sw=2 tw=80: */ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ */ + +// Tests that the input field is focused when the console is opened. + +"use strict"; + +const TEST_URI = + `data:text/html;charset=utf-8,Test input focused + <script> + console.log("console message 1"); + </script>`; + +add_task(function* () { + let hud = yield openNewTabAndConsole(TEST_URI); + hud.jsterm.clearOutput(); + + let inputNode = hud.jsterm.inputNode; + ok(inputNode.getAttribute("focused"), "input node is focused after output is cleared"); + + ContentTask.spawn(gBrowser.selectedBrowser, {}, function* () { + content.wrappedJSObject.console.log("console message 2"); + }); + let msg = yield waitFor(() => findMessage(hud, "console message 2")); + let outputItem = msg.querySelector(".message-body"); + + inputNode = hud.jsterm.inputNode; + ok(inputNode.getAttribute("focused"), "input node is focused, first"); + + yield waitForBlurredInput(inputNode); + + EventUtils.sendMouseEvent({type: "click"}, hud.outputNode); + ok(inputNode.getAttribute("focused"), "input node is focused, second time"); + + yield waitForBlurredInput(inputNode); + + info("Setting a text selection and making sure a click does not re-focus"); + let selection = hud.iframeWindow.getSelection(); + selection.selectAllChildren(outputItem); + + EventUtils.sendMouseEvent({type: "click"}, hud.outputNode); + ok(!inputNode.getAttribute("focused"), + "input node focused after text is selected"); +}); + +function waitForBlurredInput(inputNode) { + return new Promise(resolve => { + let lostFocus = () => { + ok(!inputNode.getAttribute("focused"), "input node is not focused"); + resolve(); + }; + inputNode.addEventListener("blur", lostFocus, { once: true }); + document.getElementById("urlbar").click(); + }); +} diff --git a/devtools/client/webconsole/new-console-output/test/mochitest/browser_webconsole_keyboard_accessibility.js b/devtools/client/webconsole/new-console-output/test/mochitest/browser_webconsole_keyboard_accessibility.js new file mode 100644 index 000000000..1038194b9 --- /dev/null +++ b/devtools/client/webconsole/new-console-output/test/mochitest/browser_webconsole_keyboard_accessibility.js @@ -0,0 +1,71 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ +/* vim: set ft=javascript ts=2 et sw=2 tw=80: */ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ */ + +// Check that basic keyboard shortcuts work in the web console. + +"use strict"; + +const TEST_URI = + `data:text/html;charset=utf-8,<p>Test keyboard accessibility</p> + <script> + for (let i = 1; i <= 100; i++) { + console.log("console message " + i); + } + </script> + `; + +add_task(function* () { + let hud = yield openNewTabAndConsole(TEST_URI); + info("Web Console opened"); + + const outputScroller = hud.ui.outputScroller; + + yield waitFor(() => findMessages(hud, "").length == 100); + + let currentPosition = outputScroller.scrollTop; + const bottom = currentPosition; + + EventUtils.sendMouseEvent({type: "click"}, hud.jsterm.inputNode); + + // Page up. + EventUtils.synthesizeKey("VK_PAGE_UP", {}); + isnot(outputScroller.scrollTop, currentPosition, + "scroll position changed after page up"); + + // Page down. + currentPosition = outputScroller.scrollTop; + EventUtils.synthesizeKey("VK_PAGE_DOWN", {}); + ok(outputScroller.scrollTop > currentPosition, + "scroll position now at bottom"); + + // Home + EventUtils.synthesizeKey("VK_HOME", {}); + is(outputScroller.scrollTop, 0, "scroll position now at top"); + + // End + EventUtils.synthesizeKey("VK_END", {}); + let scrollTop = outputScroller.scrollTop; + ok(scrollTop > 0 && Math.abs(scrollTop - bottom) <= 5, + "scroll position now at bottom"); + + // Clear output + info("try ctrl-l to clear output"); + let clearShortcut; + if (Services.appinfo.OS === "Darwin") { + clearShortcut = WCUL10n.getStr("webconsole.clear.keyOSX"); + } else { + clearShortcut = WCUL10n.getStr("webconsole.clear.key"); + } + synthesizeKeyShortcut(clearShortcut); + yield waitFor(() => findMessages(hud, "").length == 0); + is(hud.jsterm.inputNode.getAttribute("focused"), "true", "jsterm input is focused"); + + // Focus filter + info("try ctrl-f to focus filter"); + synthesizeKeyShortcut(WCUL10n.getStr("webconsole.find.key")); + ok(!hud.jsterm.inputNode.getAttribute("focused"), "jsterm input is not focused"); + is(hud.ui.filterBox, outputScroller.ownerDocument.activeElement, + "filter input is focused"); +}); diff --git a/devtools/client/webconsole/new-console-output/test/mochitest/browser_webconsole_observer_notifications.js b/devtools/client/webconsole/new-console-output/test/mochitest/browser_webconsole_observer_notifications.js new file mode 100644 index 000000000..5225a6ac1 --- /dev/null +++ b/devtools/client/webconsole/new-console-output/test/mochitest/browser_webconsole_observer_notifications.js @@ -0,0 +1,47 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ +/* vim: set ft=javascript ts=2 et sw=2 tw=80: */ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +const TEST_URI = "data:text/html;charset=utf-8,<p>Web Console test for " + + "obeserver notifications"; + +let created = false; +let destroyed = false; + +add_task(function* () { + setupObserver(); + yield openNewTabAndConsole(TEST_URI); + yield waitFor(() => created); + + yield closeTabAndToolbox(gBrowser.selectedTab); + yield waitFor(() => destroyed); +}); + +function setupObserver() { + const observer = { + QueryInterface: XPCOMUtils.generateQI([Ci.nsIObserver]), + + observe: function observe(subject, topic) { + subject = subject.QueryInterface(Ci.nsISupportsString); + + switch (topic) { + case "web-console-created": + ok(HUDService.getHudReferenceById(subject.data), "We have a hud reference"); + Services.obs.removeObserver(observer, "web-console-created"); + created = true; + break; + case "web-console-destroyed": + ok(!HUDService.getHudReferenceById(subject.data), "We do not have a hud reference"); + Services.obs.removeObserver(observer, "web-console-destroyed"); + destroyed = true; + break; + } + }, + }; + + Services.obs.addObserver(observer, "web-console-created", false); + Services.obs.addObserver(observer, "web-console-destroyed", false); +} diff --git a/devtools/client/webconsole/new-console-output/test/mochitest/browser_webconsole_vview_close_on_esc_key.js b/devtools/client/webconsole/new-console-output/test/mochitest/browser_webconsole_vview_close_on_esc_key.js new file mode 100644 index 000000000..712a990b4 --- /dev/null +++ b/devtools/client/webconsole/new-console-output/test/mochitest/browser_webconsole_vview_close_on_esc_key.js @@ -0,0 +1,46 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ +/* vim: set ft=javascript ts=2 et sw=2 tw=80: */ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ */ + +// Check that the variables view sidebar can be closed by pressing Escape in the +// web console. + +"use strict"; + +const TEST_URI = + "data:text/html;charset=utf8,<script>let fooObj = {testProp: 'testValue'}</script>"; + +add_task(function* () { + let hud = yield openNewTabAndConsole(TEST_URI); + let jsterm = hud.jsterm; + let vview; + + yield openSidebar("fooObj", 'testProp: "testValue"'); + vview.window.focus(); + + let sidebarClosed = jsterm.once("sidebar-closed"); + EventUtils.synthesizeKey("VK_ESCAPE", {}); + yield sidebarClosed; + + function* openSidebar(objName, expectedText) { + yield jsterm.execute(objName); + info("JSTerm executed"); + + let msg = yield waitFor(() => findMessage(hud, "Object")); + ok(msg, "Message found"); + + let anchor = msg.querySelector("a"); + let body = msg.querySelector(".message-body"); + ok(anchor, "object anchor"); + ok(body, "message body"); + ok(body.textContent.includes(expectedText), "message text check"); + + msg.scrollIntoView(); + yield EventUtils.synthesizeMouse(anchor, 2, 2, {}, hud.iframeWindow); + + let vviewVar = yield jsterm.once("variablesview-fetched"); + vview = vviewVar._variablesView; + ok(vview, "variables view object exists"); + } +}); diff --git a/devtools/client/webconsole/new-console-output/test/mochitest/head.js b/devtools/client/webconsole/new-console-output/test/mochitest/head.js new file mode 100644 index 000000000..b71eaec4f --- /dev/null +++ b/devtools/client/webconsole/new-console-output/test/mochitest/head.js @@ -0,0 +1,137 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ +/* vim: set ft=javascript ts=2 et sw=2 tw=80: */ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ */ +/* import-globals-from ../../../../framework/test/shared-head.js */ + +"use strict"; + +// shared-head.js handles imports, constants, and utility functions +// Load the shared-head file first. +Services.scriptloader.loadSubScript( + "chrome://mochitests/content/browser/devtools/client/framework/test/shared-head.js", + this); + +var {Utils: WebConsoleUtils} = require("devtools/client/webconsole/utils"); +const WEBCONSOLE_STRINGS_URI = "devtools/client/locales/webconsole.properties"; +var WCUL10n = new WebConsoleUtils.L10n(WEBCONSOLE_STRINGS_URI); + +Services.prefs.setBoolPref("devtools.webconsole.new-frontend-enabled", true); +registerCleanupFunction(function* () { + Services.prefs.clearUserPref("devtools.webconsole.new-frontend-enabled"); + + let browserConsole = HUDService.getBrowserConsole(); + if (browserConsole) { + if (browserConsole.jsterm) { + browserConsole.jsterm.clearOutput(true); + } + yield HUDService.toggleBrowserConsole(); + } +}); + +/** + * Add a new tab and open the toolbox in it, and select the webconsole. + * + * @param string url + * The URL for the tab to be opened. + * @return Promise + * Resolves when the tab has been added, loaded and the toolbox has been opened. + * Resolves to the toolbox. + */ +var openNewTabAndConsole = Task.async(function* (url) { + let toolbox = yield openNewTabAndToolbox(TEST_URI, "webconsole"); + let hud = toolbox.getCurrentPanel().hud; + hud.jsterm._lazyVariablesView = false; + return hud; +}); + +/** + * Wait for messages in the web console output, resolving once they are receieved. + * + * @param object options + * - hud: the webconsole + * - messages: Array[Object]. An array of messages to match. Current supported options: + * - text: Exact text match in .message-body + */ +function waitForMessages({ hud, messages }) { + return new Promise(resolve => { + let numMatched = 0; + let receivedLog = hud.ui.on("new-messages", function messagesReceieved(e, newMessages) { + for (let message of messages) { + if (message.matched) { + continue; + } + + for (let newMessage of newMessages) { + if (newMessage.node.querySelector(".message-body").textContent == message.text) { + numMatched++; + message.matched = true; + info("Matched a message with text: " + message.text + ", still waiting for " + (messages.length - numMatched) + " messages"); + break; + } + } + + if (numMatched === messages.length) { + hud.ui.off("new-messages", messagesReceieved); + resolve(receivedLog); + return; + } + } + }); + }); +} + +/** + * Wait for a predicate to return a result. + * + * @param function condition + * Invoked once in a while until it returns a truthy value. This should be an + * idempotent function, since we have to run it a second time after it returns + * true in order to return the value. + * @param string message [optional] + * A message to output if the condition failes. + * @param number interval [optional] + * How often the predicate is invoked, in milliseconds. + * @return object + * A promise that is resolved with the result of the condition. + */ +function* waitFor(condition, message = "waitFor", interval = 10, maxTries = 500) { + return new Promise(resolve => { + BrowserTestUtils.waitForCondition(condition, message, interval, maxTries) + .then(() => resolve(condition())); + }); +} + +/** + * Find a message in the output. + * + * @param object hud + * The web console. + * @param string text + * A substring that can be found in the message. + * @param selector [optional] + * The selector to use in finding the message. + */ +function findMessage(hud, text, selector = ".message") { + const elements = findMessages(hud, text, selector); + return elements.pop(); +} + +/** + * Find multiple messages in the output. + * + * @param object hud + * The web console. + * @param string text + * A substring that can be found in the message. + * @param selector [optional] + * The selector to use in finding the message. + */ +function findMessages(hud, text, selector = ".message") { + const messages = hud.ui.experimentalOutputNode.querySelectorAll(selector); + const elements = Array.prototype.filter.call( + messages, + (el) => el.textContent.includes(text) + ); + return elements; +} diff --git a/devtools/client/webconsole/new-console-output/test/mochitest/test-batching.html b/devtools/client/webconsole/new-console-output/test/mochitest/test-batching.html new file mode 100644 index 000000000..9d122387a --- /dev/null +++ b/devtools/client/webconsole/new-console-output/test/mochitest/test-batching.html @@ -0,0 +1,28 @@ +<!DOCTYPE html> +<html lang="en"> + <head> + <meta charset="utf-8"> + <title>Webconsole batch console calls test page</title> + </head> + <body> + <p>batch console calls test page</p> + <script> + "use strict"; + + function batchLog(numMessages = 0) { + for (let i = 0; i < numMessages; i++) { + console.log(i); + } + } + + function batchLogAndClear(numMessages = 0) { + for (let i = 0; i < numMessages; i++) { + console.log(i); + if (i === numMessages - 1) { + console.clear(); + } + } + } + </script> + </body> +</html> diff --git a/devtools/client/webconsole/new-console-output/test/mochitest/test-console-filters.html b/devtools/client/webconsole/new-console-output/test/mochitest/test-console-filters.html new file mode 100644 index 000000000..293421549 --- /dev/null +++ b/devtools/client/webconsole/new-console-output/test/mochitest/test-console-filters.html @@ -0,0 +1,17 @@ +<!DOCTYPE html> +<html lang="en"> + <head> + <meta charset="utf-8"> + <title>Webconsole filters test page</title> + </head> + <body> + <p>Webconsole filters test page</p> + <script> + console.log("console log"); + console.warn("console warn"); + console.error("console error"); + console.info("console info"); + console.count("console debug"); + </script> + </body> +</html> diff --git a/devtools/client/webconsole/new-console-output/test/mochitest/test-console-group.html b/devtools/client/webconsole/new-console-output/test/mochitest/test-console-group.html new file mode 100644 index 000000000..47373d3b9 --- /dev/null +++ b/devtools/client/webconsole/new-console-output/test/mochitest/test-console-group.html @@ -0,0 +1,28 @@ +<!DOCTYPE html> +<html lang="en"> + <head> + <meta charset="utf-8"> + <title>Webconsole console.group test page</title> + </head> + <body> + <p>console.group() & console.groupCollapsed() test page</p> + <script> + "use strict"; + + function doLog() { + console.group("group-1"); + console.log("log-1"); + console.group("group-2"); + console.log("log-2"); + console.groupEnd("group-2"); + console.log("log-3"); + console.groupEnd("group-1"); + console.log("log-4"); + console.groupCollapsed("group-3"); + console.log("log-5"); + console.groupEnd("group-3"); + console.log("log-6"); + } + </script> + </body> +</html> diff --git a/devtools/client/webconsole/new-console-output/test/mochitest/test-console-table.html b/devtools/client/webconsole/new-console-output/test/mochitest/test-console-table.html new file mode 100644 index 000000000..b7666e50b --- /dev/null +++ b/devtools/client/webconsole/new-console-output/test/mochitest/test-console-table.html @@ -0,0 +1,19 @@ +<!DOCTYPE html> +<html lang="en"> + <head> + <meta charset="utf-8"> + <title>Simple webconsole test page</title> + </head> + <body> + <p>console.table() test page</p> + <script> + function doConsoleTable(data, constrainedHeaders = null) { + if (constrainedHeaders) { + console.table(data, constrainedHeaders); + } else { + console.table(data); + } + } + </script> + </body> +</html> diff --git a/devtools/client/webconsole/new-console-output/test/mochitest/test-console.html b/devtools/client/webconsole/new-console-output/test/mochitest/test-console.html new file mode 100644 index 000000000..7ef09d9a1 --- /dev/null +++ b/devtools/client/webconsole/new-console-output/test/mochitest/test-console.html @@ -0,0 +1,18 @@ +<!DOCTYPE html> +<html lang="en"> + <head> + <meta charset="utf-8"> + <title>Simple webconsole test page</title> + </head> + <body> + <p>Simple webconsole test page</p> + <script> + function doLogs(num) { + num = num || 1; + for (var i = 0; i < num; i++) { + console.log(i); + } + } + </script> + </body> +</html> diff --git a/devtools/client/webconsole/new-console-output/test/moz.build b/devtools/client/webconsole/new-console-output/test/moz.build new file mode 100644 index 000000000..da06c3162 --- /dev/null +++ b/devtools/client/webconsole/new-console-output/test/moz.build @@ -0,0 +1,17 @@ +# vim: set filetype=python: +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +BROWSER_CHROME_MANIFESTS += [ + 'fixtures/stub-generators/browser.ini', + 'mochitest/browser.ini', +] + +DIRS += [ + 'fixtures' +] + +MOCHITEST_CHROME_MANIFESTS += [ + 'chrome/chrome.ini', +] diff --git a/devtools/client/webconsole/new-console-output/test/requireHelper.js b/devtools/client/webconsole/new-console-output/test/requireHelper.js new file mode 100644 index 000000000..ac6205808 --- /dev/null +++ b/devtools/client/webconsole/new-console-output/test/requireHelper.js @@ -0,0 +1,38 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ +"use strict"; + +const requireHacker = require("require-hacker"); + +requireHacker.global_hook("default", path => { + switch (path) { + // For Enzyme + case "react-dom/server": + return `const React = require('react-dev'); module.exports = React`; + case "react-addons-test-utils": + return `const React = require('react-dev'); module.exports = React.addons.TestUtils`; + // Use react-dev. This would be handled by browserLoader in Firefox. + case "react": + case "devtools/client/shared/vendor/react": + return `const React = require('react-dev'); module.exports = React`; + // For Rep's use of AMD + case "devtools/client/shared/vendor/react.default": + return `const React = require('react-dev'); module.exports = React`; + } + + // Some modules depend on Chrome APIs which don't work in mocha. When such a module + // is required, replace it with a mock version. + switch (path) { + case "devtools/client/webconsole/utils": + return `module.exports = require("devtools/client/webconsole/new-console-output/test/fixtures/WebConsoleUtils")`; + case "devtools/shared/l10n": + return `module.exports = require("devtools/client/webconsole/new-console-output/test/fixtures/LocalizationHelper")`; + case "devtools/shared/plural-form": + return `module.exports = require("devtools/client/webconsole/new-console-output/test/fixtures/PluralForm")`; + case "Services": + case "Services.default": + return `module.exports = require("devtools/client/webconsole/new-console-output/test/fixtures/Services")`; + case "devtools/shared/client/main": + return `module.exports = require("devtools/client/webconsole/new-console-output/test/fixtures/ObjectClient")`; + } +}); diff --git a/devtools/client/webconsole/new-console-output/test/store/filters.test.js b/devtools/client/webconsole/new-console-output/test/store/filters.test.js new file mode 100644 index 000000000..3c38a255a --- /dev/null +++ b/devtools/client/webconsole/new-console-output/test/store/filters.test.js @@ -0,0 +1,215 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +const expect = require("expect"); + +const actions = require("devtools/client/webconsole/new-console-output/actions/index"); +const { messageAdd } = require("devtools/client/webconsole/new-console-output/actions/index"); +const { ConsoleCommand } = require("devtools/client/webconsole/new-console-output/types"); +const { getAllMessages } = require("devtools/client/webconsole/new-console-output/selectors/messages"); +const { getAllFilters } = require("devtools/client/webconsole/new-console-output/selectors/filters"); +const { setupStore } = require("devtools/client/webconsole/new-console-output/test/helpers"); +const { MESSAGE_LEVEL } = require("devtools/client/webconsole/new-console-output/constants"); +const { stubPackets } = require("devtools/client/webconsole/new-console-output/test/fixtures/stubs/index"); +const { stubPreparedMessages } = require("devtools/client/webconsole/new-console-output/test/fixtures/stubs/index"); + +describe("Filtering", () => { + let store; + let numMessages; + // Number of messages in prepareBaseStore which are not filtered out, i.e. Evaluation + // Results, console commands and console.groups . + const numUnfilterableMessages = 3; + + beforeEach(() => { + store = prepareBaseStore(); + store.dispatch(actions.filtersClear()); + numMessages = getAllMessages(store.getState()).size; + }); + + describe("Level filter", () => { + it("filters log messages", () => { + store.dispatch(actions.filterToggle(MESSAGE_LEVEL.LOG)); + + let messages = getAllMessages(store.getState()); + expect(messages.size).toEqual(numMessages - 3); + }); + + it("filters debug messages", () => { + store.dispatch(actions.filterToggle(MESSAGE_LEVEL.DEBUG)); + + let messages = getAllMessages(store.getState()); + expect(messages.size).toEqual(numMessages - 1); + }); + + // @TODO add info stub + it("filters info messages"); + + it("filters warning messages", () => { + store.dispatch(actions.filterToggle(MESSAGE_LEVEL.WARN)); + + let messages = getAllMessages(store.getState()); + expect(messages.size).toEqual(numMessages - 1); + }); + + it("filters error messages", () => { + store.dispatch(actions.filterToggle(MESSAGE_LEVEL.ERROR)); + + let messages = getAllMessages(store.getState()); + expect(messages.size).toEqual(numMessages - 1); + }); + + it("filters xhr messages", () => { + let message = stubPreparedMessages.get("XHR GET request"); + store.dispatch(messageAdd(message)); + + let messages = getAllMessages(store.getState()); + expect(messages.size).toEqual(numMessages); + + store.dispatch(actions.filterToggle("netxhr")); + messages = getAllMessages(store.getState()); + expect(messages.size).toEqual(numMessages + 1); + }); + + it("filters network messages", () => { + let message = stubPreparedMessages.get("GET request"); + store.dispatch(messageAdd(message)); + + let messages = getAllMessages(store.getState()); + expect(messages.size).toEqual(numMessages); + + store.dispatch(actions.filterToggle("net")); + messages = getAllMessages(store.getState()); + expect(messages.size).toEqual(numMessages + 1); + }); + }); + + describe("Text filter", () => { + it("matches on value grips", () => { + store.dispatch(actions.filterTextSet("danger")); + + let messages = getAllMessages(store.getState()); + expect(messages.size - numUnfilterableMessages).toEqual(1); + }); + + it("matches unicode values", () => { + store.dispatch(actions.filterTextSet("鼬")); + + let messages = getAllMessages(store.getState()); + expect(messages.size - numUnfilterableMessages).toEqual(1); + }); + + it("matches locations", () => { + // Add a message with a different filename. + let locationMsg = + Object.assign({}, stubPackets.get("console.log('foobar', 'test')")); + locationMsg.message = + Object.assign({}, locationMsg.message, { filename: "search-location-test.js" }); + store.dispatch(messageAdd(locationMsg)); + + store.dispatch(actions.filterTextSet("search-location-test.js")); + + let messages = getAllMessages(store.getState()); + expect(messages.size - numUnfilterableMessages).toEqual(1); + }); + + it("matches stacktrace functionName", () => { + let traceMessage = stubPackets.get("console.trace()"); + store.dispatch(messageAdd(traceMessage)); + + store.dispatch(actions.filterTextSet("testStacktraceFiltering")); + + let messages = getAllMessages(store.getState()); + expect(messages.size - numUnfilterableMessages).toEqual(1); + }); + + it("matches stacktrace location", () => { + let traceMessage = stubPackets.get("console.trace()"); + traceMessage.message = + Object.assign({}, traceMessage.message, { + filename: "search-location-test.js", + lineNumber: 85, + columnNumber: 13 + }); + + store.dispatch(messageAdd(traceMessage)); + + store.dispatch(actions.filterTextSet("search-location-test.js:85:13")); + + let messages = getAllMessages(store.getState()); + expect(messages.size - numUnfilterableMessages).toEqual(1); + }); + + it("restores all messages once text is cleared", () => { + store.dispatch(actions.filterTextSet("danger")); + store.dispatch(actions.filterTextSet("")); + + let messages = getAllMessages(store.getState()); + expect(messages.size).toEqual(numMessages); + }); + }); + + describe("Combined filters", () => { + // @TODO add test + it("filters"); + }); +}); + +describe("Clear filters", () => { + it("clears all filters", () => { + const store = setupStore([]); + + // Setup test case + store.dispatch(actions.filterToggle(MESSAGE_LEVEL.ERROR)); + store.dispatch(actions.filterToggle("netxhr")); + store.dispatch(actions.filterTextSet("foobar")); + + let filters = getAllFilters(store.getState()); + expect(filters.toJS()).toEqual({ + "debug": true, + "error": false, + "info": true, + "log": true, + "net": false, + "netxhr": true, + "warn": true, + "text": "foobar" + }); + + store.dispatch(actions.filtersClear()); + + filters = getAllFilters(store.getState()); + expect(filters.toJS()).toEqual({ + "debug": true, + "error": true, + "info": true, + "log": true, + "net": false, + "netxhr": false, + "warn": true, + "text": "" + }); + }); +}); + +function prepareBaseStore() { + const store = setupStore([ + // Console API + "console.log('foobar', 'test')", + "console.warn('danger, will robinson!')", + "console.log(undefined)", + "console.count('bar')", + "console.log('鼬')", + // Evaluation Result - never filtered + "new Date(0)", + // PageError + "ReferenceError: asdf is not defined", + "console.group('bar')" + ]); + + // Console Command - never filtered + store.dispatch(messageAdd(new ConsoleCommand({ messageText: `console.warn("x")` }))); + + return store; +} 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 new file mode 100644 index 000000000..582ca36e3 --- /dev/null +++ b/devtools/client/webconsole/new-console-output/test/store/messages.test.js @@ -0,0 +1,353 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ +"use strict"; + +const { + getAllMessages, + getAllMessagesUiById, + getAllGroupsById, + getCurrentGroup, +} = require("devtools/client/webconsole/new-console-output/selectors/messages"); +const { + setupActions, + setupStore +} = require("devtools/client/webconsole/new-console-output/test/helpers"); +const { stubPackets, stubPreparedMessages } = require("devtools/client/webconsole/new-console-output/test/fixtures/stubs/index"); +const { + MESSAGE_TYPE, +} = require("devtools/client/webconsole/new-console-output/constants"); + +const expect = require("expect"); + +describe("Message reducer:", () => { + let actions; + + before(() => { + actions = setupActions(); + }); + + describe("messagesById", () => { + it("adds a message to an empty store", () => { + const { dispatch, getState } = setupStore([]); + + const packet = stubPackets.get("console.log('foobar', 'test')"); + const message = stubPreparedMessages.get("console.log('foobar', 'test')"); + dispatch(actions.messageAdd(packet)); + + const messages = getAllMessages(getState()); + + expect(messages.first()).toEqual(message); + }); + + it("increments repeat on a repeating message", () => { + const { dispatch, getState } = setupStore([ + "console.log('foobar', 'test')", + "console.log('foobar', 'test')" + ]); + + const packet = stubPackets.get("console.log('foobar', 'test')"); + dispatch(actions.messageAdd(packet)); + dispatch(actions.messageAdd(packet)); + + const messages = getAllMessages(getState()); + + expect(messages.size).toBe(1); + expect(messages.first().repeat).toBe(4); + }); + + it("does not clobber a unique message", () => { + const { dispatch, getState } = setupStore([ + "console.log('foobar', 'test')", + "console.log('foobar', 'test')" + ]); + + const packet = stubPackets.get("console.log('foobar', 'test')"); + dispatch(actions.messageAdd(packet)); + + const packet2 = stubPackets.get("console.log(undefined)"); + dispatch(actions.messageAdd(packet2)); + + const messages = getAllMessages(getState()); + + expect(messages.size).toBe(2); + expect(messages.first().repeat).toBe(3); + expect(messages.last().repeat).toBe(1); + }); + + it("adds a message in response to console.clear()", () => { + const { dispatch, getState } = setupStore([]); + + dispatch(actions.messageAdd(stubPackets.get("console.clear()"))); + + const messages = getAllMessages(getState()); + + expect(messages.size).toBe(1); + expect(messages.first().parameters[0]).toBe("Console was cleared."); + }); + + it("clears the messages list in response to MESSAGES_CLEAR action", () => { + const { dispatch, getState } = setupStore([ + "console.log('foobar', 'test')", + "console.log(undefined)" + ]); + + dispatch(actions.messagesClear()); + + const messages = getAllMessages(getState()); + expect(messages.size).toBe(0); + }); + + it("limits the number of messages displayed", () => { + const { dispatch, getState } = setupStore([]); + + const logLimit = 1000; + const packet = stubPackets.get("console.log(undefined)"); + for (let i = 1; i <= logLimit + 1; i++) { + packet.message.arguments = [`message num ${i}`]; + dispatch(actions.messageAdd(packet)); + } + + const messages = getAllMessages(getState()); + expect(messages.count()).toBe(logLimit); + 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 = stubPackets.get("console.time('bar')"); + dispatch(actions.messageAdd(message)); + + const messages = getAllMessages(getState()); + expect(messages.size).toBe(0); + }); + + it("adds console.table call with unsupported type as console.log", () => { + const { dispatch, getState } = setupStore([]); + + const packet = stubPackets.get("console.table('bar')"); + dispatch(actions.messageAdd(packet)); + + const messages = getAllMessages(getState()); + const tableMessage = messages.last(); + expect(tableMessage.level).toEqual(MESSAGE_TYPE.LOG); + }); + + it("adds console.group messages to the store", () => { + const { dispatch, getState } = setupStore([]); + + const message = stubPackets.get("console.group('bar')"); + dispatch(actions.messageAdd(message)); + + const messages = getAllMessages(getState()); + expect(messages.size).toBe(1); + }); + + it("sets groupId property as expected", () => { + const { dispatch, getState } = setupStore([]); + + dispatch(actions.messageAdd( + stubPackets.get("console.group('bar')"))); + + const packet = stubPackets.get("console.log('foobar', 'test')"); + dispatch(actions.messageAdd(packet)); + + const messages = getAllMessages(getState()); + expect(messages.size).toBe(2); + expect(messages.last().groupId).toBe(messages.first().id); + }); + + it("does not display console.groupEnd messages to the store", () => { + const { dispatch, getState } = setupStore([]); + + const message = stubPackets.get("console.groupEnd('bar')"); + dispatch(actions.messageAdd(message)); + + const messages = getAllMessages(getState()); + expect(messages.size).toBe(0); + }); + + it("filters out message added after a console.groupCollapsed message", () => { + const { dispatch, getState } = setupStore([]); + + const message = stubPackets.get("console.groupCollapsed('foo')"); + dispatch(actions.messageAdd(message)); + + dispatch(actions.messageAdd( + stubPackets.get("console.log('foobar', 'test')"))); + + const messages = getAllMessages(getState()); + expect(messages.size).toBe(1); + }); + + it("shows the group of the first displayed message when messages are pruned", () => { + const { dispatch, getState } = setupStore([]); + + const logLimit = 1000; + + const groupMessage = stubPreparedMessages.get("console.group('bar')"); + dispatch(actions.messageAdd( + stubPackets.get("console.group('bar')"))); + + const packet = stubPackets.get("console.log(undefined)"); + for (let i = 1; i <= logLimit + 1; i++) { + packet.message.arguments = [`message num ${i}`]; + dispatch(actions.messageAdd(packet)); + } + + const messages = getAllMessages(getState()); + expect(messages.count()).toBe(logLimit); + expect(messages.first().messageText).toBe(groupMessage.messageText); + expect(messages.get(1).parameters[0]).toBe(`message num 3`); + expect(messages.last().parameters[0]).toBe(`message num ${logLimit + 1}`); + }); + + it("adds console.dirxml call as console.log", () => { + const { dispatch, getState } = setupStore([]); + + const packet = stubPackets.get("console.dirxml(window)"); + dispatch(actions.messageAdd(packet)); + + const messages = getAllMessages(getState()); + const dirxmlMessage = messages.last(); + expect(dirxmlMessage.level).toEqual(MESSAGE_TYPE.LOG); + }); + }); + + describe("messagesUiById", () => { + it("opens console.trace messages when they are added", () => { + const { dispatch, getState } = setupStore([]); + + const message = stubPackets.get("console.trace()"); + dispatch(actions.messageAdd(message)); + + const messages = getAllMessages(getState()); + const messagesUi = getAllMessagesUiById(getState()); + expect(messagesUi.size).toBe(1); + expect(messagesUi.first()).toBe(messages.first().id); + }); + + it("clears the messages UI list in response to MESSAGES_CLEAR action", () => { + const { dispatch, getState } = setupStore([ + "console.log('foobar', 'test')", + "console.log(undefined)" + ]); + + const traceMessage = stubPackets.get("console.trace()"); + dispatch(actions.messageAdd(traceMessage)); + + dispatch(actions.messagesClear()); + + const messagesUi = getAllMessagesUiById(getState()); + expect(messagesUi.size).toBe(0); + }); + + it("opens console.group messages when they are added", () => { + const { dispatch, getState } = setupStore([]); + + const message = stubPackets.get("console.group('bar')"); + dispatch(actions.messageAdd(message)); + + const messages = getAllMessages(getState()); + const messagesUi = getAllMessagesUiById(getState()); + expect(messagesUi.size).toBe(1); + expect(messagesUi.first()).toBe(messages.first().id); + }); + + it("does not open console.groupCollapsed messages when they are added", () => { + const { dispatch, getState } = setupStore([]); + + const message = stubPackets.get("console.groupCollapsed('foo')"); + dispatch(actions.messageAdd(message)); + + const messagesUi = getAllMessagesUiById(getState()); + expect(messagesUi.size).toBe(0); + }); + }); + + describe("currentGroup", () => { + it("sets the currentGroup when console.group message is added", () => { + const { dispatch, getState } = setupStore([]); + + const packet = stubPackets.get("console.group('bar')"); + dispatch(actions.messageAdd(packet)); + + const messages = getAllMessages(getState()); + const currentGroup = getCurrentGroup(getState()); + expect(currentGroup).toBe(messages.first().id); + }); + + it("sets currentGroup to expected value when console.groupEnd is added", () => { + const { dispatch, getState } = setupStore([ + "console.group('bar')", + "console.groupCollapsed('foo')" + ]); + + let messages = getAllMessages(getState()); + let currentGroup = getCurrentGroup(getState()); + expect(currentGroup).toBe(messages.last().id); + + const endFooPacket = stubPackets.get("console.groupEnd('foo')"); + dispatch(actions.messageAdd(endFooPacket)); + messages = getAllMessages(getState()); + currentGroup = getCurrentGroup(getState()); + expect(currentGroup).toBe(messages.first().id); + + const endBarPacket = stubPackets.get("console.groupEnd('foo')"); + dispatch(actions.messageAdd(endBarPacket)); + messages = getAllMessages(getState()); + currentGroup = getCurrentGroup(getState()); + expect(currentGroup).toBe(null); + }); + + it("resets the currentGroup to null in response to MESSAGES_CLEAR action", () => { + const { dispatch, getState } = setupStore([ + "console.group('bar')" + ]); + + dispatch(actions.messagesClear()); + + const currentGroup = getCurrentGroup(getState()); + expect(currentGroup).toBe(null); + }); + }); + + describe("groupsById", () => { + it("adds the group with expected array when console.group message is added", () => { + const { dispatch, getState } = setupStore([]); + + const barPacket = stubPackets.get("console.group('bar')"); + dispatch(actions.messageAdd(barPacket)); + + let messages = getAllMessages(getState()); + let groupsById = getAllGroupsById(getState()); + expect(groupsById.size).toBe(1); + expect(groupsById.has(messages.first().id)).toBe(true); + expect(groupsById.get(messages.first().id)).toEqual([]); + + const fooPacket = stubPackets.get("console.groupCollapsed('foo')"); + dispatch(actions.messageAdd(fooPacket)); + messages = getAllMessages(getState()); + groupsById = getAllGroupsById(getState()); + expect(groupsById.size).toBe(2); + expect(groupsById.has(messages.last().id)).toBe(true); + expect(groupsById.get(messages.last().id)).toEqual([messages.first().id]); + }); + + it("resets groupsById in response to MESSAGES_CLEAR action", () => { + const { dispatch, getState } = setupStore([ + "console.group('bar')", + "console.groupCollapsed('foo')", + ]); + + let groupsById = getAllGroupsById(getState()); + expect(groupsById.size).toBe(2); + + dispatch(actions.messagesClear()); + + groupsById = getAllGroupsById(getState()); + expect(groupsById.size).toBe(0); + }); + }); +}); diff --git a/devtools/client/webconsole/new-console-output/test/utils/getRepeatId.test.js b/devtools/client/webconsole/new-console-output/test/utils/getRepeatId.test.js new file mode 100644 index 000000000..d27238e14 --- /dev/null +++ b/devtools/client/webconsole/new-console-output/test/utils/getRepeatId.test.js @@ -0,0 +1,41 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ +"use strict"; + +const { getRepeatId } = require("devtools/client/webconsole/new-console-output/utils/messages"); +const { stubPreparedMessages } = require("devtools/client/webconsole/new-console-output/test/fixtures/stubs/index"); + +const expect = require("expect"); + +describe("getRepeatId:", () => { + it("returns same repeatId for duplicate values", () => { + const message1 = stubPreparedMessages.get("console.log('foobar', 'test')"); + const message2 = message1.set("repeat", 3); + expect(getRepeatId(message1)).toEqual(getRepeatId(message2)); + }); + + it("returns different repeatIds for different values", () => { + const message1 = stubPreparedMessages.get("console.log('foobar', 'test')"); + const message2 = message1.set("parameters", ["funny", "monkey"]); + expect(getRepeatId(message1)).toNotEqual(getRepeatId(message2)); + }); + + it("returns different repeatIds for different severities", () => { + const message1 = stubPreparedMessages.get("console.log('foobar', 'test')"); + const message2 = message1.set("level", "error"); + expect(getRepeatId(message1)).toNotEqual(getRepeatId(message2)); + }); + + it("handles falsy values distinctly", () => { + const messageNaN = stubPreparedMessages.get("console.log(NaN)"); + const messageUnd = stubPreparedMessages.get("console.log(undefined)"); + const messageNul = stubPreparedMessages.get("console.log(null)"); + + const repeatIds = new Set([ + getRepeatId(messageNaN), + getRepeatId(messageUnd), + getRepeatId(messageNul)] + ); + expect(repeatIds.size).toEqual(3); + }); +}); |