summaryrefslogtreecommitdiffstats
path: root/devtools/client/webconsole/new-console-output/test/components
diff options
context:
space:
mode:
authorMatt A. Tobin <mattatobin@localhost.localdomain>2018-02-02 04:16:08 -0500
committerMatt A. Tobin <mattatobin@localhost.localdomain>2018-02-02 04:16:08 -0500
commit5f8de423f190bbb79a62f804151bc24824fa32d8 (patch)
tree10027f336435511475e392454359edea8e25895d /devtools/client/webconsole/new-console-output/test/components
parent49ee0794b5d912db1f95dce6eb52d781dc210db5 (diff)
downloadUXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar
UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.gz
UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.lz
UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.xz
UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.zip
Add m-esr52 at 52.6.0
Diffstat (limited to 'devtools/client/webconsole/new-console-output/test/components')
-rw-r--r--devtools/client/webconsole/new-console-output/test/components/console-api-call.test.js230
-rw-r--r--devtools/client/webconsole/new-console-output/test/components/evaluation-result.test.js84
-rw-r--r--devtools/client/webconsole/new-console-output/test/components/filter-bar.test.js96
-rw-r--r--devtools/client/webconsole/new-console-output/test/components/filter-button.test.js34
-rw-r--r--devtools/client/webconsole/new-console-output/test/components/message-container.test.js54
-rw-r--r--devtools/client/webconsole/new-console-output/test/components/message-icon.test.js23
-rw-r--r--devtools/client/webconsole/new-console-output/test/components/message-repeat.test.js25
-rw-r--r--devtools/client/webconsole/new-console-output/test/components/network-event-message.test.js74
-rw-r--r--devtools/client/webconsole/new-console-output/test/components/page-error.test.js126
9 files changed, 746 insertions, 0 deletions
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`);
+ });
+});