summaryrefslogtreecommitdiffstats
path: root/devtools/client/debugger/src/components/test
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-19 00:47:55 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-19 00:47:55 +0000
commit26a029d407be480d791972afb5975cf62c9360a6 (patch)
treef435a8308119effd964b339f76abb83a57c29483 /devtools/client/debugger/src/components/test
parentInitial commit. (diff)
downloadfirefox-26a029d407be480d791972afb5975cf62c9360a6.tar.xz
firefox-26a029d407be480d791972afb5975cf62c9360a6.zip
Adding upstream version 124.0.1.upstream/124.0.1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'devtools/client/debugger/src/components/test')
-rw-r--r--devtools/client/debugger/src/components/test/QuickOpenModal.spec.js803
-rw-r--r--devtools/client/debugger/src/components/test/WelcomeBox.spec.js58
-rw-r--r--devtools/client/debugger/src/components/test/WhyPaused.spec.js61
-rw-r--r--devtools/client/debugger/src/components/test/__snapshots__/QuickOpenModal.spec.js.snap1777
-rw-r--r--devtools/client/debugger/src/components/test/__snapshots__/WelcomeBox.spec.js.snap67
-rw-r--r--devtools/client/debugger/src/components/test/__snapshots__/WhyPaused.spec.js.snap103
6 files changed, 2869 insertions, 0 deletions
diff --git a/devtools/client/debugger/src/components/test/QuickOpenModal.spec.js b/devtools/client/debugger/src/components/test/QuickOpenModal.spec.js
new file mode 100644
index 0000000000..74bc7c75bc
--- /dev/null
+++ b/devtools/client/debugger/src/components/test/QuickOpenModal.spec.js
@@ -0,0 +1,803 @@
+/* eslint max-nested-callbacks: ["error", 4] */
+/* 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/>. */
+
+import React from "devtools/client/shared/vendor/react";
+import { Provider } from "devtools/client/shared/vendor/react-redux";
+import configureStore from "redux-mock-store";
+import { shallow, mount } from "enzyme";
+import { getDisplayURL } from "../../utils/sources-tree/getURL";
+import { searchKeys } from "../../constants";
+
+// it's important to mock the module before importing the QuickOpenModal
+jest.mock("devtools/client/shared/vendor/fuzzaldrin-plus.js", () => {
+ return {
+ filter: jest.fn(() => []),
+ prepareQuery: jest.fn(() => {}),
+ wrap: jest.fn(() => {}),
+ };
+});
+import { QuickOpenModal } from "../QuickOpenModal";
+const { filter } = require("devtools/client/shared/vendor/fuzzaldrin-plus.js");
+
+function generateModal(propOverrides, renderType = "shallow") {
+ const mockStore = configureStore([]);
+ const store = mockStore({
+ ui: {
+ mutableSearchOptions: {
+ [searchKeys.QUICKOPEN_SEARCH]: {
+ regexMatch: false,
+ wholeWord: false,
+ caseSensitive: false,
+ excludePatterns: "",
+ },
+ },
+ },
+ });
+ const props = {
+ enabled: false,
+ query: "",
+ searchType: "sources",
+ displayedSources: [],
+ blackBoxRanges: {},
+ openedTabUrls: [],
+ selectedLocation: { source: { id: "foo" } },
+ selectSpecificLocation: jest.fn(),
+ setQuickOpenQuery: jest.fn(),
+ highlightLineRange: jest.fn(),
+ clearHighlightLineRange: jest.fn(),
+ closeQuickOpen: jest.fn(),
+ getFunctionSymbols: jest.fn(() => []),
+ shortcutsModalEnabled: false,
+ toggleShortcutsModal: jest.fn(),
+ isOriginal: false,
+ thread: "FakeThread",
+ ...propOverrides,
+ };
+ return {
+ wrapper:
+ renderType === "shallow"
+ ? shallow(
+ <Provider store={store}>
+ <QuickOpenModal {...props} />
+ </Provider>
+ ).dive()
+ : mount(
+ <Provider store={store}>
+ <QuickOpenModal {...props} />
+ </Provider>
+ ),
+ props,
+ };
+}
+
+async function waitForUpdateResultsThrottle() {
+ await new Promise(res =>
+ setTimeout(res, QuickOpenModal.UPDATE_RESULTS_THROTTLE)
+ );
+}
+
+describe("QuickOpenModal", () => {
+ beforeEach(() => {
+ filter.mockClear();
+ });
+ test("Doesn't render when disabled", () => {
+ const { wrapper } = generateModal();
+ expect(wrapper).toMatchSnapshot();
+ });
+
+ test("Renders when enabled", () => {
+ const { wrapper } = generateModal({ enabled: true });
+ expect(wrapper).toMatchSnapshot();
+ });
+
+ test("Basic render with mount", () => {
+ const { wrapper } = generateModal({ enabled: true }, "mount");
+ expect(wrapper).toMatchSnapshot();
+ });
+
+ test("Basic render with mount & searchType = functions", () => {
+ const { wrapper } = generateModal(
+ {
+ enabled: true,
+ query: "@",
+ searchType: "functions",
+ },
+ "mount"
+ );
+ expect(wrapper).toMatchSnapshot();
+ });
+
+ test("toggles shortcut modal if enabled", () => {
+ const { props } = generateModal(
+ {
+ enabled: true,
+ query: "test",
+ shortcutsModalEnabled: true,
+ toggleShortcutsModal: jest.fn(),
+ },
+ "shallow"
+ );
+ expect(props.toggleShortcutsModal).toHaveBeenCalled();
+ });
+
+ test("shows top sources", () => {
+ const { wrapper } = generateModal(
+ {
+ enabled: true,
+ query: "",
+ displayedSources: [
+ {
+ url: "mozilla.com",
+ displayURL: getDisplayURL("mozilla.com"),
+ },
+ ],
+ openedTabUrls: ["mozilla.com"],
+ },
+ "shallow"
+ );
+ expect(wrapper.state("results")).toEqual([
+ {
+ id: undefined,
+ icon: "tab result-item-icon",
+ subtitle: "mozilla.com",
+ title: "mozilla.com",
+ url: "mozilla.com",
+ value: "mozilla.com",
+ source: {
+ url: "mozilla.com",
+ displayURL: getDisplayURL("mozilla.com"),
+ },
+ },
+ ]);
+ });
+
+ describe("shows loading", () => {
+ it("loads with function type search", () => {
+ const { wrapper } = generateModal(
+ {
+ enabled: true,
+ query: "",
+ searchType: "functions",
+ },
+ "shallow"
+ );
+ expect(wrapper).toMatchSnapshot();
+ });
+ });
+
+ test("Basic render with mount & searchType = variables", () => {
+ const { wrapper } = generateModal(
+ {
+ enabled: true,
+ query: "#",
+ searchType: "variables",
+ },
+ "mount"
+ );
+ expect(wrapper).toMatchSnapshot();
+ });
+
+ test("Basic render with mount & searchType = shortcuts", () => {
+ const { wrapper } = generateModal(
+ {
+ enabled: true,
+ query: "?",
+ searchType: "shortcuts",
+ },
+ "mount"
+ );
+ expect(wrapper.find("ResultList")).toHaveLength(1);
+ expect(wrapper.find("li")).toHaveLength(3);
+ });
+
+ test("updateResults on enable", () => {
+ const { wrapper } = generateModal({}, "mount");
+ expect(wrapper).toMatchSnapshot();
+ wrapper.setProps({ enabled: true });
+ expect(wrapper).toMatchSnapshot();
+ });
+
+ test("basic source search", async () => {
+ const { wrapper } = generateModal(
+ {
+ enabled: true,
+ },
+ "mount"
+ );
+ wrapper.find("input").simulate("change", { target: { value: "somefil" } });
+ await waitForUpdateResultsThrottle();
+ expect(filter).toHaveBeenCalledWith([], "somefil", {
+ key: "value",
+ maxResults: 100,
+ });
+ });
+
+ test("basic gotoSource search", async () => {
+ const { wrapper } = generateModal(
+ {
+ enabled: true,
+ searchType: "gotoSource",
+ },
+ "mount"
+ );
+ wrapper
+ .find("input")
+ .simulate("change", { target: { value: "somefil:33" } });
+
+ await waitForUpdateResultsThrottle();
+
+ expect(filter).toHaveBeenCalledWith([], "somefil", {
+ key: "value",
+ maxResults: 100,
+ });
+ });
+
+ describe("empty symbol search", () => {
+ it("basic symbol search", async () => {
+ const { wrapper } = generateModal(
+ {
+ enabled: true,
+ searchType: "functions",
+ // symbol searching relies on a source being selected.
+ // So we dummy out the source and the API.
+ selectedLocation: { source: { id: "foo", text: "yo" } },
+ selectedContentLoaded: true,
+ },
+ "mount"
+ );
+
+ wrapper
+ .find("input")
+ .simulate("change", { target: { value: "@someFunc" } });
+ await waitForUpdateResultsThrottle();
+ expect(filter).toHaveBeenCalledWith([], "someFunc", {
+ key: "name",
+ maxResults: 100,
+ preparedQuery: undefined,
+ });
+ });
+
+ it("does not do symbol search if no selected source", () => {
+ const { wrapper } = generateModal(
+ {
+ enabled: true,
+ searchType: "functions",
+
+ // symbol searching relies on a source being selected.
+ // So we dummy out the source and the API.
+ selectedLocation: null,
+ selectedContentLoaded: false,
+ },
+ "mount"
+ );
+ wrapper
+ .find("input")
+ .simulate("change", { target: { value: "@someFunc" } });
+ expect(filter).not.toHaveBeenCalled();
+ });
+ });
+
+ test("Simple goto search query = :abc & searchType = goto", () => {
+ const { wrapper } = generateModal(
+ {
+ enabled: true,
+ query: ":abc",
+ searchType: "goto",
+ },
+ "mount"
+ );
+ expect(wrapper.childAt(0)).toMatchSnapshot();
+ expect(wrapper.childAt(0).state().results).toEqual(null);
+ });
+
+ describe("onEnter", () => {
+ it("on Enter go to location", () => {
+ const { wrapper, props } = generateModal(
+ {
+ enabled: true,
+ query: ":34:12",
+ searchType: "goto",
+ selectedLocation: { source: { id: "foo" } },
+ },
+ "shallow"
+ );
+ const event = {
+ key: "Enter",
+ };
+ wrapper.find("Connect(SearchInput)").simulate("keydown", event);
+ expect(props.selectSpecificLocation).toHaveBeenCalledWith({
+ column: 11,
+ line: 34,
+ source: {
+ id: "foo",
+ },
+ sourceActorId: undefined,
+ sourceActor: null,
+ });
+ });
+
+ it("on Enter go to location with sourceId", () => {
+ const sourceId = "source_id";
+ const { wrapper, props } = generateModal(
+ {
+ enabled: true,
+ query: ":34:12",
+ searchType: "goto",
+ selectedLocation: { source: { id: sourceId } },
+ selectedContentLoaded: true,
+ },
+ "shallow"
+ );
+ const event = {
+ key: "Enter",
+ };
+ wrapper.find("Connect(SearchInput)").simulate("keydown", event);
+ expect(props.selectSpecificLocation).toHaveBeenCalledWith({
+ column: 11,
+ line: 34,
+ source: {
+ id: sourceId,
+ },
+ sourceActorId: undefined,
+ sourceActor: null,
+ });
+ });
+
+ it("on Enter with no location, does no action", () => {
+ const { wrapper, props } = generateModal(
+ {
+ enabled: true,
+ query: ":",
+ searchType: "goto",
+ },
+ "shallow"
+ );
+ const event = {
+ key: "Enter",
+ };
+ wrapper.find("Connect(SearchInput)").simulate("keydown", event);
+ expect(props.setQuickOpenQuery).not.toHaveBeenCalled();
+ expect(props.selectSpecificLocation).not.toHaveBeenCalled();
+ expect(props.highlightLineRange).not.toHaveBeenCalled();
+ });
+
+ it("on Enter with empty results, handle no item", () => {
+ const { wrapper, props } = generateModal(
+ {
+ enabled: true,
+ query: "",
+ searchType: "shortcuts",
+ },
+ "shallow"
+ );
+ wrapper.setState(() => ({
+ results: [],
+ selectedIndex: 0,
+ }));
+ const event = {
+ key: "Enter",
+ };
+ wrapper.find("Connect(SearchInput)").simulate("keydown", event);
+ expect(props.setQuickOpenQuery).not.toHaveBeenCalled();
+ expect(props.selectSpecificLocation).not.toHaveBeenCalled();
+ expect(props.highlightLineRange).not.toHaveBeenCalled();
+ });
+
+ it("on Enter with results, handle symbol shortcut", () => {
+ const symbols = [":", "#", "@"];
+ for (const symbol of symbols) {
+ const { wrapper, props } = generateModal(
+ {
+ enabled: true,
+ query: "",
+ searchType: "shortcuts",
+ },
+ "shallow"
+ );
+ wrapper.setState(() => ({
+ results: [{ id: symbol }],
+ selectedIndex: 0,
+ }));
+ const event = {
+ key: "Enter",
+ };
+ wrapper.find("Connect(SearchInput)").simulate("keydown", event);
+ expect(props.setQuickOpenQuery).toHaveBeenCalledWith(symbol);
+ }
+ });
+
+ it("on Enter, returns the result with the selected index", () => {
+ const { wrapper, props } = generateModal(
+ {
+ enabled: true,
+ query: "@test",
+ searchType: "shortcuts",
+ },
+ "shallow"
+ );
+ wrapper.setState(() => ({
+ results: [{ id: "@" }, { id: ":" }, { id: "#" }],
+ selectedIndex: 1,
+ }));
+ const event = {
+ key: "Enter",
+ };
+ wrapper.find("Connect(SearchInput)").simulate("keydown", event);
+ expect(props.setQuickOpenQuery).toHaveBeenCalledWith(":");
+ });
+
+ it("on Enter with results, handle result item", () => {
+ const id = "test_id";
+ const { wrapper, props } = generateModal(
+ {
+ enabled: true,
+ query: "@test",
+ searchType: "other",
+ selectedLocation: { source: { id } },
+ },
+ "shallow"
+ );
+ wrapper.setState(() => ({
+ results: [{}, { id }],
+ selectedIndex: 1,
+ }));
+ const event = {
+ key: "Enter",
+ };
+ wrapper.find("Connect(SearchInput)").simulate("keydown", event);
+ expect(props.selectSpecificLocation).toHaveBeenCalledWith({
+ column: undefined,
+ line: 0,
+ source: { id },
+ sourceActorId: undefined,
+ sourceActor: null,
+ });
+ expect(props.setQuickOpenQuery).not.toHaveBeenCalled();
+ });
+
+ it("on Enter with results, handle functions result item", () => {
+ const id = "test_id";
+ const { wrapper, props } = generateModal(
+ {
+ enabled: true,
+ query: "@test",
+ searchType: "functions",
+ selectedLocation: { source: { id } },
+ },
+ "shallow"
+ );
+ wrapper.setState(() => ({
+ results: [{}, { id }],
+ selectedIndex: 1,
+ }));
+ const event = {
+ key: "Enter",
+ };
+ wrapper.find("Connect(SearchInput)").simulate("keydown", event);
+ expect(props.selectSpecificLocation).toHaveBeenCalledWith({
+ column: undefined,
+ line: 0,
+ source: { id },
+ sourceActorId: undefined,
+ sourceActor: null,
+ });
+ expect(props.setQuickOpenQuery).not.toHaveBeenCalled();
+ });
+
+ it("on Enter with results, handle gotoSource search", () => {
+ const id = "test_id";
+ const { wrapper, props } = generateModal(
+ {
+ enabled: true,
+ query: ":3:4",
+ searchType: "gotoSource",
+ selectedLocation: { source: { id } },
+ },
+ "shallow"
+ );
+ wrapper.setState(() => ({
+ results: [{}, { id }],
+ selectedIndex: 1,
+ }));
+ const event = {
+ key: "Enter",
+ };
+ wrapper.find("Connect(SearchInput)").simulate("keydown", event);
+ expect(props.selectSpecificLocation).toHaveBeenCalledWith({
+ column: 3,
+ line: 3,
+ source: { id },
+ sourceActorId: undefined,
+ sourceActor: null,
+ });
+ expect(props.setQuickOpenQuery).not.toHaveBeenCalled();
+ });
+
+ it("on Enter with results, handle shortcuts search", () => {
+ const { wrapper, props } = generateModal(
+ {
+ enabled: true,
+ query: "@",
+ searchType: "shortcuts",
+ },
+ "shallow"
+ );
+ const id = "#";
+ wrapper.setState(() => ({
+ results: [{}, { id }],
+ selectedIndex: 1,
+ }));
+ const event = {
+ key: "Enter",
+ };
+ wrapper.find("Connect(SearchInput)").simulate("keydown", event);
+ expect(props.selectSpecificLocation).not.toHaveBeenCalled();
+ expect(props.setQuickOpenQuery).toHaveBeenCalledWith(id);
+ });
+ });
+
+ describe("onKeyDown", () => {
+ it("does nothing if search type is not goto", () => {
+ const { wrapper, props } = generateModal(
+ {
+ enabled: true,
+ query: "test",
+ searchType: "other",
+ },
+ "shallow"
+ );
+ wrapper.find("Connect(SearchInput)").simulate("keydown", {});
+ expect(props.selectSpecificLocation).not.toHaveBeenCalled();
+ expect(props.setQuickOpenQuery).not.toHaveBeenCalled();
+ });
+
+ it("on Tab, close modal", () => {
+ const { wrapper, props } = generateModal(
+ {
+ enabled: true,
+ query: ":34:12",
+ searchType: "goto",
+ },
+ "shallow"
+ );
+ const event = {
+ key: "Tab",
+ };
+ wrapper.find("Connect(SearchInput)").simulate("keydown", event);
+ expect(props.closeQuickOpen).toHaveBeenCalled();
+ expect(props.selectSpecificLocation).not.toHaveBeenCalled();
+ });
+ });
+
+ describe("with arrow keys", () => {
+ it("on ArrowUp, traverse results up with functions", () => {
+ const sourceId = "sourceId";
+ const { wrapper, props } = generateModal(
+ {
+ enabled: true,
+ query: "test",
+ searchType: "functions",
+ selectedLocation: { source: { id: sourceId } },
+ selectedContentLoaded: true,
+ },
+ "shallow"
+ );
+ const event = {
+ preventDefault: jest.fn(),
+ key: "ArrowUp",
+ };
+ const location = {
+ sourceId: "sourceId",
+ start: {
+ line: 1,
+ },
+ end: {
+ line: 3,
+ },
+ };
+
+ wrapper.setState(() => ({
+ results: [{ id: "0", location }, { id: "1" }, { id: "2" }],
+ selectedIndex: 1,
+ }));
+ wrapper.find("Connect(SearchInput)").simulate("keydown", event);
+ expect(event.preventDefault).toHaveBeenCalled();
+ expect(wrapper.state().selectedIndex).toEqual(0);
+ expect(props.highlightLineRange).toHaveBeenCalledWith({
+ sourceId: "sourceId",
+ end: 3,
+ start: 1,
+ });
+ });
+
+ it("on ArrowDown, traverse down with no results", () => {
+ const { wrapper, props } = generateModal(
+ {
+ enabled: true,
+ query: "test",
+ searchType: "goto",
+ },
+ "shallow"
+ );
+ const event = {
+ preventDefault: jest.fn(),
+ key: "ArrowDown",
+ };
+ wrapper.setState(() => ({
+ results: null,
+ selectedIndex: 1,
+ }));
+ wrapper.find("Connect(SearchInput)").simulate("keydown", event);
+ expect(event.preventDefault).toHaveBeenCalled();
+ expect(wrapper.state().selectedIndex).toEqual(0);
+ expect(props.selectSpecificLocation).not.toHaveBeenCalledWith();
+ expect(props.highlightLineRange).not.toHaveBeenCalled();
+ });
+
+ it("on ArrowUp, traverse results up to function with no location", () => {
+ const sourceId = "sourceId";
+ const { wrapper, props } = generateModal(
+ {
+ enabled: true,
+ query: "test",
+ searchType: "functions",
+ selectedLocation: { source: { id: sourceId } },
+ selectedContentLoaded: true,
+ },
+ "shallow"
+ );
+ const event = {
+ preventDefault: jest.fn(),
+ key: "ArrowUp",
+ };
+ wrapper.setState(() => ({
+ results: [{ id: "0", location: null }, { id: "1" }, { id: "2" }],
+ selectedIndex: 1,
+ }));
+ wrapper.find("Connect(SearchInput)").simulate("keydown", event);
+ expect(event.preventDefault).toHaveBeenCalled();
+ expect(wrapper.state().selectedIndex).toEqual(0);
+ expect(props.highlightLineRange).not.toHaveBeenCalled();
+ expect(props.clearHighlightLineRange).toHaveBeenCalled();
+ });
+
+ it(
+ "on ArrowDown, traverse down results, without " +
+ "taking action if no selectedSource",
+ () => {
+ const { wrapper, props } = generateModal(
+ {
+ enabled: true,
+ query: "test",
+ searchType: "variables",
+ selectedLocation: null,
+ selectedContentLoaded: true,
+ },
+ "shallow"
+ );
+ const event = {
+ preventDefault: jest.fn(),
+ key: "ArrowDown",
+ };
+ const location = {
+ sourceId: "sourceId",
+ start: {
+ line: 7,
+ },
+ };
+ wrapper.setState(() => ({
+ results: [{ id: "0", location }, { id: "1" }, { id: "2" }],
+ selectedIndex: 1,
+ }));
+ wrapper.find("Connect(SearchInput)").simulate("keydown", event);
+ expect(event.preventDefault).toHaveBeenCalled();
+ expect(wrapper.state().selectedIndex).toEqual(2);
+ expect(props.selectSpecificLocation).not.toHaveBeenCalled();
+ expect(props.highlightLineRange).not.toHaveBeenCalled();
+ }
+ );
+
+ it(
+ "on ArrowUp, traverse up results, without taking action if " +
+ "the query is not for variables or functions",
+ () => {
+ const sourceId = "sourceId";
+ const { wrapper, props } = generateModal(
+ {
+ enabled: true,
+ query: "test",
+ searchType: "other",
+ selectedLocation: { source: { id: sourceId } },
+ selectedContentLoaded: true,
+ },
+ "shallow"
+ );
+ const event = {
+ preventDefault: jest.fn(),
+ key: "ArrowUp",
+ };
+ const location = {
+ sourceId: "sourceId",
+ start: {
+ line: 7,
+ },
+ };
+ wrapper.setState(() => ({
+ results: [{ id: "0", location }, { id: "1" }, { id: "2" }],
+ selectedIndex: 1,
+ }));
+ wrapper.find("Connect(SearchInput)").simulate("keydown", event);
+ expect(event.preventDefault).toHaveBeenCalled();
+ expect(wrapper.state().selectedIndex).toEqual(0);
+ expect(props.selectSpecificLocation).not.toHaveBeenCalled();
+ expect(props.highlightLineRange).not.toHaveBeenCalled();
+ }
+ );
+ });
+
+ describe("showErrorEmoji", () => {
+ it("true when no count + query", () => {
+ const { wrapper } = generateModal(
+ {
+ enabled: true,
+ query: "test",
+ searchType: "other",
+ },
+ "mount"
+ );
+ expect(wrapper).toMatchSnapshot();
+ });
+
+ it("false when count + query", () => {
+ const { wrapper } = generateModal(
+ {
+ enabled: true,
+ query: "dasdasdas",
+ },
+ "mount"
+ );
+ wrapper.setState(() => ({
+ results: [1, 2],
+ }));
+ expect(wrapper).toMatchSnapshot();
+ });
+
+ it("false when no query", () => {
+ const { wrapper } = generateModal(
+ {
+ enabled: true,
+ query: "",
+ searchType: "other",
+ },
+ "mount"
+ );
+ expect(wrapper).toMatchSnapshot();
+ });
+
+ it("false when goto numeric ':2222'", () => {
+ const { wrapper } = generateModal(
+ {
+ enabled: true,
+ query: ":2222",
+ searchType: "goto",
+ },
+ "mount"
+ );
+ expect(wrapper).toMatchSnapshot();
+ });
+
+ it("true when goto not numeric ':22k22'", () => {
+ const { wrapper } = generateModal(
+ {
+ enabled: true,
+ query: ":22k22",
+ searchType: "goto",
+ },
+ "mount"
+ );
+ expect(wrapper).toMatchSnapshot();
+ });
+ });
+});
diff --git a/devtools/client/debugger/src/components/test/WelcomeBox.spec.js b/devtools/client/debugger/src/components/test/WelcomeBox.spec.js
new file mode 100644
index 0000000000..5599c416fe
--- /dev/null
+++ b/devtools/client/debugger/src/components/test/WelcomeBox.spec.js
@@ -0,0 +1,58 @@
+/* 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/>. */
+
+import React from "devtools/client/shared/vendor/react";
+import { shallow } from "enzyme";
+
+import { WelcomeBox } from "../WelcomeBox";
+
+function render(overrides = {}) {
+ const props = {
+ horizontal: false,
+ togglePaneCollapse: jest.fn(),
+ endPanelCollapsed: false,
+ setActiveSearch: jest.fn(),
+ openQuickOpen: jest.fn(),
+ toggleShortcutsModal: jest.fn(),
+ setPrimaryPaneTab: jest.fn(),
+ ...overrides,
+ };
+ const component = shallow(React.createElement(WelcomeBox, props));
+ return { component, props };
+}
+
+describe("WelomeBox", () => {
+ it("renders with default values", () => {
+ const { component } = render();
+ expect(component).toMatchSnapshot();
+ });
+
+ it("doesn't render toggle button in horizontal mode", () => {
+ const { component } = render({
+ horizontal: true,
+ });
+ expect(component.find("PaneToggleButton")).toHaveLength(0);
+ });
+
+ it("calls correct function on searchSources click", () => {
+ const { component, props } = render();
+
+ component.find(".welcomebox__searchSources").simulate("click");
+ expect(props.openQuickOpen).toHaveBeenCalled();
+ });
+
+ it("calls correct function on searchProject click", () => {
+ const { component, props } = render();
+
+ component.find(".welcomebox__searchProject").simulate("click");
+ expect(props.setActiveSearch).toHaveBeenCalled();
+ });
+
+ it("calls correct function on allShotcuts click", () => {
+ const { component, props } = render();
+
+ component.find(".welcomebox__allShortcuts").simulate("click");
+ expect(props.toggleShortcutsModal).toHaveBeenCalled();
+ });
+});
diff --git a/devtools/client/debugger/src/components/test/WhyPaused.spec.js b/devtools/client/debugger/src/components/test/WhyPaused.spec.js
new file mode 100644
index 0000000000..5466976dfb
--- /dev/null
+++ b/devtools/client/debugger/src/components/test/WhyPaused.spec.js
@@ -0,0 +1,61 @@
+/* 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/>. */
+
+import React from "devtools/client/shared/vendor/react";
+import { shallow } from "enzyme";
+import WhyPaused from "../SecondaryPanes/WhyPaused.js";
+
+function render(why, delay) {
+ const props = { why, delay };
+ const component = shallow(
+ React.createElement(WhyPaused.WrappedComponent, props)
+ );
+
+ return { component, props };
+}
+
+describe("WhyPaused", () => {
+ it("should pause reason with message", () => {
+ const why = {
+ type: "breakpoint",
+ message: "bla is hit",
+ };
+ const { component } = render(why);
+ expect(component).toMatchSnapshot();
+ });
+
+ it("should show pause reason with exception details", () => {
+ const why = {
+ type: "exception",
+ exception: {
+ class: "ReferenceError",
+ isError: true,
+ preview: {
+ name: "ReferenceError",
+ message: "o is not defined",
+ },
+ },
+ };
+
+ const { component } = render(why);
+ expect(component).toMatchSnapshot();
+ });
+
+ it("should show pause reason with exception string", () => {
+ const why = {
+ type: "exception",
+ exception: "Not Available",
+ };
+
+ const { component } = render(why);
+ expect(component).toMatchSnapshot();
+ });
+
+ it("should show an empty div when there is no pause reason", () => {
+ const why = undefined;
+
+ const { component } = render(why);
+ expect(component).toMatchSnapshot();
+ });
+});
diff --git a/devtools/client/debugger/src/components/test/__snapshots__/QuickOpenModal.spec.js.snap b/devtools/client/debugger/src/components/test/__snapshots__/QuickOpenModal.spec.js.snap
new file mode 100644
index 0000000000..d58d2d58a0
--- /dev/null
+++ b/devtools/client/debugger/src/components/test/__snapshots__/QuickOpenModal.spec.js.snap
@@ -0,0 +1,1777 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`QuickOpenModal Basic render with mount & searchType = functions 1`] = `
+<Provider
+ store={
+ Object {
+ "clearActions": [Function],
+ "dispatch": [Function],
+ "getActions": [Function],
+ "getState": [Function],
+ "replaceReducer": [Function],
+ "subscribe": [Function],
+ }
+ }
+>
+ <QuickOpenModal
+ blackBoxRanges={Object {}}
+ clearHighlightLineRange={[MockFunction]}
+ closeQuickOpen={[MockFunction]}
+ displayedSources={Array []}
+ enabled={true}
+ getFunctionSymbols={
+ [MockFunction] {
+ "calls": Array [
+ Array [
+ Object {
+ "source": Object {
+ "id": "foo",
+ },
+ },
+ 100,
+ ],
+ ],
+ "results": Array [
+ Object {
+ "type": "return",
+ "value": Array [],
+ },
+ ],
+ }
+ }
+ highlightLineRange={[MockFunction]}
+ isOriginal={false}
+ openedTabUrls={Array []}
+ query="@"
+ searchType="functions"
+ selectSpecificLocation={[MockFunction]}
+ selectedLocation={
+ Object {
+ "source": Object {
+ "id": "foo",
+ },
+ }
+ }
+ setQuickOpenQuery={[MockFunction]}
+ shortcutsModalEnabled={false}
+ thread="FakeThread"
+ toggleShortcutsModal={[MockFunction]}
+ >
+ <Modal
+ handleClose={[Function]}
+ >
+ <div
+ className="modal-wrapper"
+ onClick={[Function]}
+ >
+ <div
+ className="modal"
+ onClick={[Function]}
+ >
+ <Connect(SearchInput)
+ count={0}
+ expanded={false}
+ handleClose={[Function]}
+ hasPrefix={true}
+ isLoading={false}
+ onChange={[Function]}
+ onKeyDown={[Function]}
+ placeholder="Go to file…"
+ query="@"
+ searchKey="quickopen-search"
+ selectedItemId=""
+ showClose={false}
+ showErrorEmoji={true}
+ showExcludePatterns={false}
+ showSearchModifiers={false}
+ summaryMsg="Loading…"
+ >
+ <SearchInput
+ count={0}
+ expanded={false}
+ handleClose={[Function]}
+ hasPrefix={true}
+ isLoading={false}
+ onChange={[Function]}
+ onKeyDown={[Function]}
+ placeholder="Go to file…"
+ query="@"
+ searchKey="quickopen-search"
+ searchOptions={
+ Object {
+ "caseSensitive": false,
+ "excludePatterns": "",
+ "regexMatch": false,
+ "wholeWord": false,
+ }
+ }
+ selectedItemId=""
+ setSearchOptions={[Function]}
+ showClose={false}
+ showErrorEmoji={true}
+ showExcludePatterns={false}
+ showSearchModifiers={false}
+ size=""
+ summaryMsg="Loading…"
+ >
+ <div
+ className="search-outline"
+ >
+ <div
+ aria-expanded={false}
+ aria-haspopup="listbox"
+ aria-owns="result-list"
+ className="search-field"
+ role="combobox"
+ >
+ <AccessibleImage
+ className="search"
+ >
+ <span
+ className="img search"
+ />
+ </AccessibleImage>
+ <input
+ aria-activedescendant=""
+ aria-autocomplete="list"
+ aria-controls="result-list"
+ className="empty"
+ onBlur={[Function]}
+ onChange={[Function]}
+ onFocus={[Function]}
+ onKeyDown={[Function]}
+ placeholder="Go to file…"
+ spellCheck={false}
+ value="@"
+ />
+ <div
+ className="search-field-summary"
+ >
+ Loading…
+ </div>
+ <div
+ className="search-buttons-bar"
+ />
+ </div>
+ </div>
+ </SearchInput>
+ </Connect(SearchInput)>
+ </div>
+ </div>
+ </Modal>
+ </QuickOpenModal>
+</Provider>
+`;
+
+exports[`QuickOpenModal Basic render with mount & searchType = variables 1`] = `
+<Provider
+ store={
+ Object {
+ "clearActions": [Function],
+ "dispatch": [Function],
+ "getActions": [Function],
+ "getState": [Function],
+ "replaceReducer": [Function],
+ "subscribe": [Function],
+ }
+ }
+>
+ <QuickOpenModal
+ blackBoxRanges={Object {}}
+ clearHighlightLineRange={[MockFunction]}
+ closeQuickOpen={[MockFunction]}
+ displayedSources={Array []}
+ enabled={true}
+ getFunctionSymbols={[MockFunction]}
+ highlightLineRange={[MockFunction]}
+ isOriginal={false}
+ openedTabUrls={Array []}
+ query="#"
+ searchType="variables"
+ selectSpecificLocation={[MockFunction]}
+ selectedLocation={
+ Object {
+ "source": Object {
+ "id": "foo",
+ },
+ }
+ }
+ setQuickOpenQuery={[MockFunction]}
+ shortcutsModalEnabled={false}
+ thread="FakeThread"
+ toggleShortcutsModal={[MockFunction]}
+ >
+ <Modal
+ handleClose={[Function]}
+ >
+ <div
+ className="modal-wrapper"
+ onClick={[Function]}
+ >
+ <div
+ className="modal"
+ onClick={[Function]}
+ >
+ <Connect(SearchInput)
+ count={0}
+ expanded={false}
+ handleClose={[Function]}
+ hasPrefix={true}
+ isLoading={false}
+ onChange={[Function]}
+ onKeyDown={[Function]}
+ placeholder="Go to file…"
+ query="#"
+ searchKey="quickopen-search"
+ selectedItemId=""
+ showClose={false}
+ showErrorEmoji={true}
+ showExcludePatterns={false}
+ showSearchModifiers={false}
+ summaryMsg=""
+ >
+ <SearchInput
+ count={0}
+ expanded={false}
+ handleClose={[Function]}
+ hasPrefix={true}
+ isLoading={false}
+ onChange={[Function]}
+ onKeyDown={[Function]}
+ placeholder="Go to file…"
+ query="#"
+ searchKey="quickopen-search"
+ searchOptions={
+ Object {
+ "caseSensitive": false,
+ "excludePatterns": "",
+ "regexMatch": false,
+ "wholeWord": false,
+ }
+ }
+ selectedItemId=""
+ setSearchOptions={[Function]}
+ showClose={false}
+ showErrorEmoji={true}
+ showExcludePatterns={false}
+ showSearchModifiers={false}
+ size=""
+ summaryMsg=""
+ >
+ <div
+ className="search-outline"
+ >
+ <div
+ aria-expanded={false}
+ aria-haspopup="listbox"
+ aria-owns="result-list"
+ className="search-field"
+ role="combobox"
+ >
+ <AccessibleImage
+ className="search"
+ >
+ <span
+ className="img search"
+ />
+ </AccessibleImage>
+ <input
+ aria-activedescendant=""
+ aria-autocomplete="list"
+ aria-controls="result-list"
+ className="empty"
+ onBlur={[Function]}
+ onChange={[Function]}
+ onFocus={[Function]}
+ onKeyDown={[Function]}
+ placeholder="Go to file…"
+ spellCheck={false}
+ value="#"
+ />
+ <div
+ className="search-buttons-bar"
+ />
+ </div>
+ </div>
+ </SearchInput>
+ </Connect(SearchInput)>
+ <ResultList
+ expanded={false}
+ items={Array []}
+ key="results"
+ role="listbox"
+ selectItem={[Function]}
+ selected={0}
+ size="small"
+ >
+ <ul
+ aria-live="polite"
+ className="result-list small"
+ id="result-list"
+ role="listbox"
+ />
+ </ResultList>
+ </div>
+ </div>
+ </Modal>
+ </QuickOpenModal>
+</Provider>
+`;
+
+exports[`QuickOpenModal Basic render with mount 1`] = `
+<Provider
+ store={
+ Object {
+ "clearActions": [Function],
+ "dispatch": [Function],
+ "getActions": [Function],
+ "getState": [Function],
+ "replaceReducer": [Function],
+ "subscribe": [Function],
+ }
+ }
+>
+ <QuickOpenModal
+ blackBoxRanges={Object {}}
+ clearHighlightLineRange={[MockFunction]}
+ closeQuickOpen={[MockFunction]}
+ displayedSources={Array []}
+ enabled={true}
+ getFunctionSymbols={[MockFunction]}
+ highlightLineRange={[MockFunction]}
+ isOriginal={false}
+ openedTabUrls={Array []}
+ query=""
+ searchType="sources"
+ selectSpecificLocation={[MockFunction]}
+ selectedLocation={
+ Object {
+ "source": Object {
+ "id": "foo",
+ },
+ }
+ }
+ setQuickOpenQuery={[MockFunction]}
+ shortcutsModalEnabled={false}
+ thread="FakeThread"
+ toggleShortcutsModal={[MockFunction]}
+ >
+ <Modal
+ handleClose={[Function]}
+ >
+ <div
+ className="modal-wrapper"
+ onClick={[Function]}
+ >
+ <div
+ className="modal"
+ onClick={[Function]}
+ >
+ <Connect(SearchInput)
+ count={0}
+ expanded={false}
+ handleClose={[Function]}
+ hasPrefix={true}
+ isLoading={false}
+ onChange={[Function]}
+ onKeyDown={[Function]}
+ placeholder="Go to file…"
+ query=""
+ searchKey="quickopen-search"
+ selectedItemId=""
+ showClose={false}
+ showErrorEmoji={false}
+ showExcludePatterns={false}
+ showSearchModifiers={false}
+ size="big"
+ summaryMsg=""
+ >
+ <SearchInput
+ count={0}
+ expanded={false}
+ handleClose={[Function]}
+ hasPrefix={true}
+ isLoading={false}
+ onChange={[Function]}
+ onKeyDown={[Function]}
+ placeholder="Go to file…"
+ query=""
+ searchKey="quickopen-search"
+ searchOptions={
+ Object {
+ "caseSensitive": false,
+ "excludePatterns": "",
+ "regexMatch": false,
+ "wholeWord": false,
+ }
+ }
+ selectedItemId=""
+ setSearchOptions={[Function]}
+ showClose={false}
+ showErrorEmoji={false}
+ showExcludePatterns={false}
+ showSearchModifiers={false}
+ size="big"
+ summaryMsg=""
+ >
+ <div
+ className="search-outline"
+ >
+ <div
+ aria-expanded={false}
+ aria-haspopup="listbox"
+ aria-owns="result-list"
+ className="search-field big"
+ role="combobox"
+ >
+ <AccessibleImage
+ className="search"
+ >
+ <span
+ className="img search"
+ />
+ </AccessibleImage>
+ <input
+ aria-activedescendant=""
+ aria-autocomplete="list"
+ aria-controls="result-list"
+ className=""
+ onBlur={[Function]}
+ onChange={[Function]}
+ onFocus={[Function]}
+ onKeyDown={[Function]}
+ placeholder="Go to file…"
+ spellCheck={false}
+ value=""
+ />
+ <div
+ className="search-buttons-bar"
+ />
+ </div>
+ </div>
+ </SearchInput>
+ </Connect(SearchInput)>
+ <ResultList
+ expanded={false}
+ items={Array []}
+ key="results"
+ role="listbox"
+ selectItem={[Function]}
+ selected={0}
+ size="big"
+ >
+ <ul
+ aria-live="polite"
+ className="result-list big"
+ id="result-list"
+ role="listbox"
+ />
+ </ResultList>
+ </div>
+ </div>
+ </Modal>
+ </QuickOpenModal>
+</Provider>
+`;
+
+exports[`QuickOpenModal Doesn't render when disabled 1`] = `
+<Modal
+ handleClose={[Function]}
+>
+ <Connect(SearchInput)
+ count={0}
+ expanded={false}
+ handleClose={[Function]}
+ hasPrefix={true}
+ isLoading={false}
+ onChange={[Function]}
+ onKeyDown={[Function]}
+ placeholder="Go to file…"
+ query=""
+ searchKey="quickopen-search"
+ selectedItemId=""
+ showClose={false}
+ showErrorEmoji={false}
+ showExcludePatterns={false}
+ showSearchModifiers={false}
+ size="big"
+ summaryMsg=""
+ />
+ <ResultList
+ expanded={false}
+ items={Array []}
+ key="results"
+ role="listbox"
+ selectItem={[Function]}
+ selected={0}
+ size="big"
+ />
+</Modal>
+`;
+
+exports[`QuickOpenModal Renders when enabled 1`] = `
+<Modal
+ handleClose={[Function]}
+>
+ <Connect(SearchInput)
+ count={0}
+ expanded={false}
+ handleClose={[Function]}
+ hasPrefix={true}
+ isLoading={false}
+ onChange={[Function]}
+ onKeyDown={[Function]}
+ placeholder="Go to file…"
+ query=""
+ searchKey="quickopen-search"
+ selectedItemId=""
+ showClose={false}
+ showErrorEmoji={false}
+ showExcludePatterns={false}
+ showSearchModifiers={false}
+ size="big"
+ summaryMsg=""
+ />
+ <ResultList
+ expanded={false}
+ items={Array []}
+ key="results"
+ role="listbox"
+ selectItem={[Function]}
+ selected={0}
+ size="big"
+ />
+</Modal>
+`;
+
+exports[`QuickOpenModal Simple goto search query = :abc & searchType = goto 1`] = `
+<QuickOpenModal
+ blackBoxRanges={Object {}}
+ clearHighlightLineRange={[MockFunction]}
+ closeQuickOpen={[MockFunction]}
+ displayedSources={Array []}
+ enabled={true}
+ getFunctionSymbols={[MockFunction]}
+ highlightLineRange={[MockFunction]}
+ isOriginal={false}
+ openedTabUrls={Array []}
+ query=":abc"
+ searchType="goto"
+ selectSpecificLocation={[MockFunction]}
+ selectedLocation={
+ Object {
+ "source": Object {
+ "id": "foo",
+ },
+ }
+ }
+ setQuickOpenQuery={[MockFunction]}
+ shortcutsModalEnabled={false}
+ thread="FakeThread"
+ toggleShortcutsModal={[MockFunction]}
+>
+ <Modal
+ handleClose={[Function]}
+ >
+ <div
+ className="modal-wrapper"
+ onClick={[Function]}
+ >
+ <div
+ className="modal"
+ onClick={[Function]}
+ >
+ <Connect(SearchInput)
+ count={0}
+ expanded={false}
+ handleClose={[Function]}
+ hasPrefix={true}
+ isLoading={false}
+ onChange={[Function]}
+ onKeyDown={[Function]}
+ placeholder="Go to file…"
+ query=":abc"
+ searchKey="quickopen-search"
+ selectedItemId=""
+ showClose={false}
+ showErrorEmoji={true}
+ showExcludePatterns={false}
+ showSearchModifiers={false}
+ summaryMsg="Go to line"
+ >
+ <SearchInput
+ count={0}
+ expanded={false}
+ handleClose={[Function]}
+ hasPrefix={true}
+ isLoading={false}
+ onChange={[Function]}
+ onKeyDown={[Function]}
+ placeholder="Go to file…"
+ query=":abc"
+ searchKey="quickopen-search"
+ searchOptions={
+ Object {
+ "caseSensitive": false,
+ "excludePatterns": "",
+ "regexMatch": false,
+ "wholeWord": false,
+ }
+ }
+ selectedItemId=""
+ setSearchOptions={[Function]}
+ showClose={false}
+ showErrorEmoji={true}
+ showExcludePatterns={false}
+ showSearchModifiers={false}
+ size=""
+ summaryMsg="Go to line"
+ >
+ <div
+ className="search-outline"
+ >
+ <div
+ aria-expanded={false}
+ aria-haspopup="listbox"
+ aria-owns="result-list"
+ className="search-field"
+ role="combobox"
+ >
+ <AccessibleImage
+ className="search"
+ >
+ <span
+ className="img search"
+ />
+ </AccessibleImage>
+ <input
+ aria-activedescendant=""
+ aria-autocomplete="list"
+ aria-controls="result-list"
+ className="empty"
+ onBlur={[Function]}
+ onChange={[Function]}
+ onFocus={[Function]}
+ onKeyDown={[Function]}
+ placeholder="Go to file…"
+ spellCheck={false}
+ value=":abc"
+ />
+ <div
+ className="search-field-summary"
+ >
+ Go to line
+ </div>
+ <div
+ className="search-buttons-bar"
+ />
+ </div>
+ </div>
+ </SearchInput>
+ </Connect(SearchInput)>
+ </div>
+ </div>
+ </Modal>
+</QuickOpenModal>
+`;
+
+exports[`QuickOpenModal showErrorEmoji false when count + query 1`] = `
+<Provider
+ store={
+ Object {
+ "clearActions": [Function],
+ "dispatch": [Function],
+ "getActions": [Function],
+ "getState": [Function],
+ "replaceReducer": [Function],
+ "subscribe": [Function],
+ }
+ }
+>
+ <QuickOpenModal
+ blackBoxRanges={Object {}}
+ clearHighlightLineRange={[MockFunction]}
+ closeQuickOpen={[MockFunction]}
+ displayedSources={Array []}
+ enabled={true}
+ getFunctionSymbols={[MockFunction]}
+ highlightLineRange={[MockFunction]}
+ isOriginal={false}
+ openedTabUrls={Array []}
+ query="dasdasdas"
+ searchType="sources"
+ selectSpecificLocation={[MockFunction]}
+ selectedLocation={
+ Object {
+ "source": Object {
+ "id": "foo",
+ },
+ }
+ }
+ setQuickOpenQuery={[MockFunction]}
+ shortcutsModalEnabled={false}
+ thread="FakeThread"
+ toggleShortcutsModal={[MockFunction]}
+ >
+ <Modal
+ handleClose={[Function]}
+ >
+ <div
+ className="modal-wrapper"
+ onClick={[Function]}
+ >
+ <div
+ className="modal"
+ onClick={[Function]}
+ >
+ <Connect(SearchInput)
+ count={0}
+ expanded={false}
+ handleClose={[Function]}
+ hasPrefix={true}
+ isLoading={false}
+ onChange={[Function]}
+ onKeyDown={[Function]}
+ placeholder="Go to file…"
+ query="dasdasdas"
+ searchKey="quickopen-search"
+ selectedItemId=""
+ showClose={false}
+ showErrorEmoji={true}
+ showExcludePatterns={false}
+ showSearchModifiers={false}
+ size="big"
+ summaryMsg=""
+ >
+ <SearchInput
+ count={0}
+ expanded={false}
+ handleClose={[Function]}
+ hasPrefix={true}
+ isLoading={false}
+ onChange={[Function]}
+ onKeyDown={[Function]}
+ placeholder="Go to file…"
+ query="dasdasdas"
+ searchKey="quickopen-search"
+ searchOptions={
+ Object {
+ "caseSensitive": false,
+ "excludePatterns": "",
+ "regexMatch": false,
+ "wholeWord": false,
+ }
+ }
+ selectedItemId=""
+ setSearchOptions={[Function]}
+ showClose={false}
+ showErrorEmoji={true}
+ showExcludePatterns={false}
+ showSearchModifiers={false}
+ size="big"
+ summaryMsg=""
+ >
+ <div
+ className="search-outline"
+ >
+ <div
+ aria-expanded={false}
+ aria-haspopup="listbox"
+ aria-owns="result-list"
+ className="search-field big"
+ role="combobox"
+ >
+ <AccessibleImage
+ className="search"
+ >
+ <span
+ className="img search"
+ />
+ </AccessibleImage>
+ <input
+ aria-activedescendant=""
+ aria-autocomplete="list"
+ aria-controls="result-list"
+ className="empty"
+ onBlur={[Function]}
+ onChange={[Function]}
+ onFocus={[Function]}
+ onKeyDown={[Function]}
+ placeholder="Go to file…"
+ spellCheck={false}
+ value="dasdasdas"
+ />
+ <div
+ className="search-buttons-bar"
+ />
+ </div>
+ </div>
+ </SearchInput>
+ </Connect(SearchInput)>
+ <ResultList
+ expanded={false}
+ items={Array []}
+ key="results"
+ role="listbox"
+ selectItem={[Function]}
+ selected={0}
+ size="big"
+ >
+ <ul
+ aria-live="polite"
+ className="result-list big"
+ id="result-list"
+ role="listbox"
+ />
+ </ResultList>
+ </div>
+ </div>
+ </Modal>
+ </QuickOpenModal>
+</Provider>
+`;
+
+exports[`QuickOpenModal showErrorEmoji false when goto numeric ':2222' 1`] = `
+<Provider
+ store={
+ Object {
+ "clearActions": [Function],
+ "dispatch": [Function],
+ "getActions": [Function],
+ "getState": [Function],
+ "replaceReducer": [Function],
+ "subscribe": [Function],
+ }
+ }
+>
+ <QuickOpenModal
+ blackBoxRanges={Object {}}
+ clearHighlightLineRange={[MockFunction]}
+ closeQuickOpen={[MockFunction]}
+ displayedSources={Array []}
+ enabled={true}
+ getFunctionSymbols={[MockFunction]}
+ highlightLineRange={[MockFunction]}
+ isOriginal={false}
+ openedTabUrls={Array []}
+ query=":2222"
+ searchType="goto"
+ selectSpecificLocation={[MockFunction]}
+ selectedLocation={
+ Object {
+ "source": Object {
+ "id": "foo",
+ },
+ }
+ }
+ setQuickOpenQuery={[MockFunction]}
+ shortcutsModalEnabled={false}
+ thread="FakeThread"
+ toggleShortcutsModal={[MockFunction]}
+ >
+ <Modal
+ handleClose={[Function]}
+ >
+ <div
+ className="modal-wrapper"
+ onClick={[Function]}
+ >
+ <div
+ className="modal"
+ onClick={[Function]}
+ >
+ <Connect(SearchInput)
+ count={0}
+ expanded={false}
+ handleClose={[Function]}
+ hasPrefix={true}
+ isLoading={false}
+ onChange={[Function]}
+ onKeyDown={[Function]}
+ placeholder="Go to file…"
+ query=":2222"
+ searchKey="quickopen-search"
+ selectedItemId=""
+ showClose={false}
+ showErrorEmoji={false}
+ showExcludePatterns={false}
+ showSearchModifiers={false}
+ summaryMsg="Go to line"
+ >
+ <SearchInput
+ count={0}
+ expanded={false}
+ handleClose={[Function]}
+ hasPrefix={true}
+ isLoading={false}
+ onChange={[Function]}
+ onKeyDown={[Function]}
+ placeholder="Go to file…"
+ query=":2222"
+ searchKey="quickopen-search"
+ searchOptions={
+ Object {
+ "caseSensitive": false,
+ "excludePatterns": "",
+ "regexMatch": false,
+ "wholeWord": false,
+ }
+ }
+ selectedItemId=""
+ setSearchOptions={[Function]}
+ showClose={false}
+ showErrorEmoji={false}
+ showExcludePatterns={false}
+ showSearchModifiers={false}
+ size=""
+ summaryMsg="Go to line"
+ >
+ <div
+ className="search-outline"
+ >
+ <div
+ aria-expanded={false}
+ aria-haspopup="listbox"
+ aria-owns="result-list"
+ className="search-field"
+ role="combobox"
+ >
+ <AccessibleImage
+ className="search"
+ >
+ <span
+ className="img search"
+ />
+ </AccessibleImage>
+ <input
+ aria-activedescendant=""
+ aria-autocomplete="list"
+ aria-controls="result-list"
+ className=""
+ onBlur={[Function]}
+ onChange={[Function]}
+ onFocus={[Function]}
+ onKeyDown={[Function]}
+ placeholder="Go to file…"
+ spellCheck={false}
+ value=":2222"
+ />
+ <div
+ className="search-field-summary"
+ >
+ Go to line
+ </div>
+ <div
+ className="search-buttons-bar"
+ />
+ </div>
+ </div>
+ </SearchInput>
+ </Connect(SearchInput)>
+ </div>
+ </div>
+ </Modal>
+ </QuickOpenModal>
+</Provider>
+`;
+
+exports[`QuickOpenModal showErrorEmoji false when no query 1`] = `
+<Provider
+ store={
+ Object {
+ "clearActions": [Function],
+ "dispatch": [Function],
+ "getActions": [Function],
+ "getState": [Function],
+ "replaceReducer": [Function],
+ "subscribe": [Function],
+ }
+ }
+>
+ <QuickOpenModal
+ blackBoxRanges={Object {}}
+ clearHighlightLineRange={[MockFunction]}
+ closeQuickOpen={[MockFunction]}
+ displayedSources={Array []}
+ enabled={true}
+ getFunctionSymbols={[MockFunction]}
+ highlightLineRange={[MockFunction]}
+ isOriginal={false}
+ openedTabUrls={Array []}
+ query=""
+ searchType="other"
+ selectSpecificLocation={[MockFunction]}
+ selectedLocation={
+ Object {
+ "source": Object {
+ "id": "foo",
+ },
+ }
+ }
+ setQuickOpenQuery={[MockFunction]}
+ shortcutsModalEnabled={false}
+ thread="FakeThread"
+ toggleShortcutsModal={[MockFunction]}
+ >
+ <Modal
+ handleClose={[Function]}
+ >
+ <div
+ className="modal-wrapper"
+ onClick={[Function]}
+ >
+ <div
+ className="modal"
+ onClick={[Function]}
+ >
+ <Connect(SearchInput)
+ count={0}
+ expanded={false}
+ handleClose={[Function]}
+ hasPrefix={true}
+ isLoading={false}
+ onChange={[Function]}
+ onKeyDown={[Function]}
+ placeholder="Go to file…"
+ query=""
+ searchKey="quickopen-search"
+ selectedItemId=""
+ showClose={false}
+ showErrorEmoji={false}
+ showExcludePatterns={false}
+ showSearchModifiers={false}
+ summaryMsg=""
+ >
+ <SearchInput
+ count={0}
+ expanded={false}
+ handleClose={[Function]}
+ hasPrefix={true}
+ isLoading={false}
+ onChange={[Function]}
+ onKeyDown={[Function]}
+ placeholder="Go to file…"
+ query=""
+ searchKey="quickopen-search"
+ searchOptions={
+ Object {
+ "caseSensitive": false,
+ "excludePatterns": "",
+ "regexMatch": false,
+ "wholeWord": false,
+ }
+ }
+ selectedItemId=""
+ setSearchOptions={[Function]}
+ showClose={false}
+ showErrorEmoji={false}
+ showExcludePatterns={false}
+ showSearchModifiers={false}
+ size=""
+ summaryMsg=""
+ >
+ <div
+ className="search-outline"
+ >
+ <div
+ aria-expanded={false}
+ aria-haspopup="listbox"
+ aria-owns="result-list"
+ className="search-field"
+ role="combobox"
+ >
+ <AccessibleImage
+ className="search"
+ >
+ <span
+ className="img search"
+ />
+ </AccessibleImage>
+ <input
+ aria-activedescendant=""
+ aria-autocomplete="list"
+ aria-controls="result-list"
+ className=""
+ onBlur={[Function]}
+ onChange={[Function]}
+ onFocus={[Function]}
+ onKeyDown={[Function]}
+ placeholder="Go to file…"
+ spellCheck={false}
+ value=""
+ />
+ <div
+ className="search-buttons-bar"
+ />
+ </div>
+ </div>
+ </SearchInput>
+ </Connect(SearchInput)>
+ <ResultList
+ expanded={false}
+ items={Array []}
+ key="results"
+ role="listbox"
+ selectItem={[Function]}
+ selected={0}
+ size="small"
+ >
+ <ul
+ aria-live="polite"
+ className="result-list small"
+ id="result-list"
+ role="listbox"
+ />
+ </ResultList>
+ </div>
+ </div>
+ </Modal>
+ </QuickOpenModal>
+</Provider>
+`;
+
+exports[`QuickOpenModal showErrorEmoji true when goto not numeric ':22k22' 1`] = `
+<Provider
+ store={
+ Object {
+ "clearActions": [Function],
+ "dispatch": [Function],
+ "getActions": [Function],
+ "getState": [Function],
+ "replaceReducer": [Function],
+ "subscribe": [Function],
+ }
+ }
+>
+ <QuickOpenModal
+ blackBoxRanges={Object {}}
+ clearHighlightLineRange={[MockFunction]}
+ closeQuickOpen={[MockFunction]}
+ displayedSources={Array []}
+ enabled={true}
+ getFunctionSymbols={[MockFunction]}
+ highlightLineRange={[MockFunction]}
+ isOriginal={false}
+ openedTabUrls={Array []}
+ query=":22k22"
+ searchType="goto"
+ selectSpecificLocation={[MockFunction]}
+ selectedLocation={
+ Object {
+ "source": Object {
+ "id": "foo",
+ },
+ }
+ }
+ setQuickOpenQuery={[MockFunction]}
+ shortcutsModalEnabled={false}
+ thread="FakeThread"
+ toggleShortcutsModal={[MockFunction]}
+ >
+ <Modal
+ handleClose={[Function]}
+ >
+ <div
+ className="modal-wrapper"
+ onClick={[Function]}
+ >
+ <div
+ className="modal"
+ onClick={[Function]}
+ >
+ <Connect(SearchInput)
+ count={0}
+ expanded={false}
+ handleClose={[Function]}
+ hasPrefix={true}
+ isLoading={false}
+ onChange={[Function]}
+ onKeyDown={[Function]}
+ placeholder="Go to file…"
+ query=":22k22"
+ searchKey="quickopen-search"
+ selectedItemId=""
+ showClose={false}
+ showErrorEmoji={true}
+ showExcludePatterns={false}
+ showSearchModifiers={false}
+ summaryMsg="Go to line"
+ >
+ <SearchInput
+ count={0}
+ expanded={false}
+ handleClose={[Function]}
+ hasPrefix={true}
+ isLoading={false}
+ onChange={[Function]}
+ onKeyDown={[Function]}
+ placeholder="Go to file…"
+ query=":22k22"
+ searchKey="quickopen-search"
+ searchOptions={
+ Object {
+ "caseSensitive": false,
+ "excludePatterns": "",
+ "regexMatch": false,
+ "wholeWord": false,
+ }
+ }
+ selectedItemId=""
+ setSearchOptions={[Function]}
+ showClose={false}
+ showErrorEmoji={true}
+ showExcludePatterns={false}
+ showSearchModifiers={false}
+ size=""
+ summaryMsg="Go to line"
+ >
+ <div
+ className="search-outline"
+ >
+ <div
+ aria-expanded={false}
+ aria-haspopup="listbox"
+ aria-owns="result-list"
+ className="search-field"
+ role="combobox"
+ >
+ <AccessibleImage
+ className="search"
+ >
+ <span
+ className="img search"
+ />
+ </AccessibleImage>
+ <input
+ aria-activedescendant=""
+ aria-autocomplete="list"
+ aria-controls="result-list"
+ className="empty"
+ onBlur={[Function]}
+ onChange={[Function]}
+ onFocus={[Function]}
+ onKeyDown={[Function]}
+ placeholder="Go to file…"
+ spellCheck={false}
+ value=":22k22"
+ />
+ <div
+ className="search-field-summary"
+ >
+ Go to line
+ </div>
+ <div
+ className="search-buttons-bar"
+ />
+ </div>
+ </div>
+ </SearchInput>
+ </Connect(SearchInput)>
+ </div>
+ </div>
+ </Modal>
+ </QuickOpenModal>
+</Provider>
+`;
+
+exports[`QuickOpenModal showErrorEmoji true when no count + query 1`] = `
+<Provider
+ store={
+ Object {
+ "clearActions": [Function],
+ "dispatch": [Function],
+ "getActions": [Function],
+ "getState": [Function],
+ "replaceReducer": [Function],
+ "subscribe": [Function],
+ }
+ }
+>
+ <QuickOpenModal
+ blackBoxRanges={Object {}}
+ clearHighlightLineRange={[MockFunction]}
+ closeQuickOpen={[MockFunction]}
+ displayedSources={Array []}
+ enabled={true}
+ getFunctionSymbols={[MockFunction]}
+ highlightLineRange={[MockFunction]}
+ isOriginal={false}
+ openedTabUrls={Array []}
+ query="test"
+ searchType="other"
+ selectSpecificLocation={[MockFunction]}
+ selectedLocation={
+ Object {
+ "source": Object {
+ "id": "foo",
+ },
+ }
+ }
+ setQuickOpenQuery={[MockFunction]}
+ shortcutsModalEnabled={false}
+ thread="FakeThread"
+ toggleShortcutsModal={[MockFunction]}
+ >
+ <Modal
+ handleClose={[Function]}
+ >
+ <div
+ className="modal-wrapper"
+ onClick={[Function]}
+ >
+ <div
+ className="modal"
+ onClick={[Function]}
+ >
+ <Connect(SearchInput)
+ count={0}
+ expanded={false}
+ handleClose={[Function]}
+ hasPrefix={true}
+ isLoading={false}
+ onChange={[Function]}
+ onKeyDown={[Function]}
+ placeholder="Go to file…"
+ query="test"
+ searchKey="quickopen-search"
+ selectedItemId=""
+ showClose={false}
+ showErrorEmoji={true}
+ showExcludePatterns={false}
+ showSearchModifiers={false}
+ summaryMsg=""
+ >
+ <SearchInput
+ count={0}
+ expanded={false}
+ handleClose={[Function]}
+ hasPrefix={true}
+ isLoading={false}
+ onChange={[Function]}
+ onKeyDown={[Function]}
+ placeholder="Go to file…"
+ query="test"
+ searchKey="quickopen-search"
+ searchOptions={
+ Object {
+ "caseSensitive": false,
+ "excludePatterns": "",
+ "regexMatch": false,
+ "wholeWord": false,
+ }
+ }
+ selectedItemId=""
+ setSearchOptions={[Function]}
+ showClose={false}
+ showErrorEmoji={true}
+ showExcludePatterns={false}
+ showSearchModifiers={false}
+ size=""
+ summaryMsg=""
+ >
+ <div
+ className="search-outline"
+ >
+ <div
+ aria-expanded={false}
+ aria-haspopup="listbox"
+ aria-owns="result-list"
+ className="search-field"
+ role="combobox"
+ >
+ <AccessibleImage
+ className="search"
+ >
+ <span
+ className="img search"
+ />
+ </AccessibleImage>
+ <input
+ aria-activedescendant=""
+ aria-autocomplete="list"
+ aria-controls="result-list"
+ className="empty"
+ onBlur={[Function]}
+ onChange={[Function]}
+ onFocus={[Function]}
+ onKeyDown={[Function]}
+ placeholder="Go to file…"
+ spellCheck={false}
+ value="test"
+ />
+ <div
+ className="search-buttons-bar"
+ />
+ </div>
+ </div>
+ </SearchInput>
+ </Connect(SearchInput)>
+ <ResultList
+ expanded={false}
+ items={Array []}
+ key="results"
+ role="listbox"
+ selectItem={[Function]}
+ selected={0}
+ size="small"
+ >
+ <ul
+ aria-live="polite"
+ className="result-list small"
+ id="result-list"
+ role="listbox"
+ />
+ </ResultList>
+ </div>
+ </div>
+ </Modal>
+ </QuickOpenModal>
+</Provider>
+`;
+
+exports[`QuickOpenModal shows loading loads with function type search 1`] = `
+<Modal
+ handleClose={[Function]}
+>
+ <Connect(SearchInput)
+ count={0}
+ expanded={false}
+ handleClose={[Function]}
+ hasPrefix={true}
+ isLoading={false}
+ onChange={[Function]}
+ onKeyDown={[Function]}
+ placeholder="Go to file…"
+ query=""
+ searchKey="quickopen-search"
+ selectedItemId=""
+ showClose={false}
+ showErrorEmoji={false}
+ showExcludePatterns={false}
+ showSearchModifiers={false}
+ summaryMsg=""
+ />
+ <ResultList
+ expanded={false}
+ items={Array []}
+ key="results"
+ role="listbox"
+ selectItem={[Function]}
+ selected={0}
+ size="small"
+ />
+</Modal>
+`;
+
+exports[`QuickOpenModal updateResults on enable 1`] = `
+<Provider
+ store={
+ Object {
+ "clearActions": [Function],
+ "dispatch": [Function],
+ "getActions": [Function],
+ "getState": [Function],
+ "replaceReducer": [Function],
+ "subscribe": [Function],
+ }
+ }
+>
+ <QuickOpenModal
+ blackBoxRanges={Object {}}
+ clearHighlightLineRange={[MockFunction]}
+ closeQuickOpen={[MockFunction]}
+ displayedSources={Array []}
+ enabled={false}
+ getFunctionSymbols={[MockFunction]}
+ highlightLineRange={[MockFunction]}
+ isOriginal={false}
+ openedTabUrls={Array []}
+ query=""
+ searchType="sources"
+ selectSpecificLocation={[MockFunction]}
+ selectedLocation={
+ Object {
+ "source": Object {
+ "id": "foo",
+ },
+ }
+ }
+ setQuickOpenQuery={[MockFunction]}
+ shortcutsModalEnabled={false}
+ thread="FakeThread"
+ toggleShortcutsModal={[MockFunction]}
+ >
+ <Modal
+ handleClose={[Function]}
+ >
+ <div
+ className="modal-wrapper"
+ onClick={[Function]}
+ >
+ <div
+ className="modal"
+ onClick={[Function]}
+ >
+ <Connect(SearchInput)
+ count={0}
+ expanded={false}
+ handleClose={[Function]}
+ hasPrefix={true}
+ isLoading={false}
+ onChange={[Function]}
+ onKeyDown={[Function]}
+ placeholder="Go to file…"
+ query=""
+ searchKey="quickopen-search"
+ selectedItemId=""
+ showClose={false}
+ showErrorEmoji={false}
+ showExcludePatterns={false}
+ showSearchModifiers={false}
+ size="big"
+ summaryMsg=""
+ >
+ <SearchInput
+ count={0}
+ expanded={false}
+ handleClose={[Function]}
+ hasPrefix={true}
+ isLoading={false}
+ onChange={[Function]}
+ onKeyDown={[Function]}
+ placeholder="Go to file…"
+ query=""
+ searchKey="quickopen-search"
+ searchOptions={
+ Object {
+ "caseSensitive": false,
+ "excludePatterns": "",
+ "regexMatch": false,
+ "wholeWord": false,
+ }
+ }
+ selectedItemId=""
+ setSearchOptions={[Function]}
+ showClose={false}
+ showErrorEmoji={false}
+ showExcludePatterns={false}
+ showSearchModifiers={false}
+ size="big"
+ summaryMsg=""
+ >
+ <div
+ className="search-outline"
+ >
+ <div
+ aria-expanded={false}
+ aria-haspopup="listbox"
+ aria-owns="result-list"
+ className="search-field big"
+ role="combobox"
+ >
+ <AccessibleImage
+ className="search"
+ >
+ <span
+ className="img search"
+ />
+ </AccessibleImage>
+ <input
+ aria-activedescendant=""
+ aria-autocomplete="list"
+ aria-controls="result-list"
+ className=""
+ onBlur={[Function]}
+ onChange={[Function]}
+ onFocus={[Function]}
+ onKeyDown={[Function]}
+ placeholder="Go to file…"
+ spellCheck={false}
+ value=""
+ />
+ <div
+ className="search-buttons-bar"
+ />
+ </div>
+ </div>
+ </SearchInput>
+ </Connect(SearchInput)>
+ <ResultList
+ expanded={false}
+ items={Array []}
+ key="results"
+ role="listbox"
+ selectItem={[Function]}
+ selected={0}
+ size="big"
+ >
+ <ul
+ aria-live="polite"
+ className="result-list big"
+ id="result-list"
+ role="listbox"
+ />
+ </ResultList>
+ </div>
+ </div>
+ </Modal>
+ </QuickOpenModal>
+</Provider>
+`;
+
+exports[`QuickOpenModal updateResults on enable 2`] = `
+<Provider
+ enabled={true}
+ store={
+ Object {
+ "clearActions": [Function],
+ "dispatch": [Function],
+ "getActions": [Function],
+ "getState": [Function],
+ "replaceReducer": [Function],
+ "subscribe": [Function],
+ }
+ }
+>
+ <QuickOpenModal
+ blackBoxRanges={Object {}}
+ clearHighlightLineRange={[MockFunction]}
+ closeQuickOpen={[MockFunction]}
+ displayedSources={Array []}
+ enabled={false}
+ getFunctionSymbols={[MockFunction]}
+ highlightLineRange={[MockFunction]}
+ isOriginal={false}
+ openedTabUrls={Array []}
+ query=""
+ searchType="sources"
+ selectSpecificLocation={[MockFunction]}
+ selectedLocation={
+ Object {
+ "source": Object {
+ "id": "foo",
+ },
+ }
+ }
+ setQuickOpenQuery={[MockFunction]}
+ shortcutsModalEnabled={false}
+ thread="FakeThread"
+ toggleShortcutsModal={[MockFunction]}
+ >
+ <Modal
+ handleClose={[Function]}
+ >
+ <div
+ className="modal-wrapper"
+ onClick={[Function]}
+ >
+ <div
+ className="modal"
+ onClick={[Function]}
+ >
+ <Connect(SearchInput)
+ count={0}
+ expanded={false}
+ handleClose={[Function]}
+ hasPrefix={true}
+ isLoading={false}
+ onChange={[Function]}
+ onKeyDown={[Function]}
+ placeholder="Go to file…"
+ query=""
+ searchKey="quickopen-search"
+ selectedItemId=""
+ showClose={false}
+ showErrorEmoji={false}
+ showExcludePatterns={false}
+ showSearchModifiers={false}
+ size="big"
+ summaryMsg=""
+ >
+ <SearchInput
+ count={0}
+ expanded={false}
+ handleClose={[Function]}
+ hasPrefix={true}
+ isLoading={false}
+ onChange={[Function]}
+ onKeyDown={[Function]}
+ placeholder="Go to file…"
+ query=""
+ searchKey="quickopen-search"
+ searchOptions={
+ Object {
+ "caseSensitive": false,
+ "excludePatterns": "",
+ "regexMatch": false,
+ "wholeWord": false,
+ }
+ }
+ selectedItemId=""
+ setSearchOptions={[Function]}
+ showClose={false}
+ showErrorEmoji={false}
+ showExcludePatterns={false}
+ showSearchModifiers={false}
+ size="big"
+ summaryMsg=""
+ >
+ <div
+ className="search-outline"
+ >
+ <div
+ aria-expanded={false}
+ aria-haspopup="listbox"
+ aria-owns="result-list"
+ className="search-field big"
+ role="combobox"
+ >
+ <AccessibleImage
+ className="search"
+ >
+ <span
+ className="img search"
+ />
+ </AccessibleImage>
+ <input
+ aria-activedescendant=""
+ aria-autocomplete="list"
+ aria-controls="result-list"
+ className=""
+ onBlur={[Function]}
+ onChange={[Function]}
+ onFocus={[Function]}
+ onKeyDown={[Function]}
+ placeholder="Go to file…"
+ spellCheck={false}
+ value=""
+ />
+ <div
+ className="search-buttons-bar"
+ />
+ </div>
+ </div>
+ </SearchInput>
+ </Connect(SearchInput)>
+ <ResultList
+ expanded={false}
+ items={Array []}
+ key="results"
+ role="listbox"
+ selectItem={[Function]}
+ selected={0}
+ size="big"
+ >
+ <ul
+ aria-live="polite"
+ className="result-list big"
+ id="result-list"
+ role="listbox"
+ />
+ </ResultList>
+ </div>
+ </div>
+ </Modal>
+ </QuickOpenModal>
+</Provider>
+`;
diff --git a/devtools/client/debugger/src/components/test/__snapshots__/WelcomeBox.spec.js.snap b/devtools/client/debugger/src/components/test/__snapshots__/WelcomeBox.spec.js.snap
new file mode 100644
index 0000000000..9828e88ef4
--- /dev/null
+++ b/devtools/client/debugger/src/components/test/__snapshots__/WelcomeBox.spec.js.snap
@@ -0,0 +1,67 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`WelomeBox renders with default values 1`] = `
+<div
+ className="welcomebox"
+>
+ <div
+ className="alignlabel"
+ >
+ <div
+ className="shortcutFunction"
+ >
+ <p
+ className="welcomebox__searchSources"
+ onClick={[Function]}
+ role="button"
+ tabIndex="0"
+ >
+ <span
+ className="shortcutKey"
+ >
+ Ctrl+P
+ </span>
+ <span
+ className="shortcutLabel"
+ >
+ Go to file
+ </span>
+ </p>
+ <p
+ className="welcomebox__searchProject"
+ onClick={[Function]}
+ role="button"
+ tabIndex="0"
+ >
+ <span
+ className="shortcutKey"
+ >
+ Ctrl+Shift+F
+ </span>
+ <span
+ className="shortcutLabel"
+ >
+ Find in files
+ </span>
+ </p>
+ <p
+ className="welcomebox__allShortcuts"
+ onClick={[Function]}
+ role="button"
+ tabIndex="0"
+ >
+ <span
+ className="shortcutKey"
+ >
+ Ctrl+/
+ </span>
+ <span
+ className="shortcutLabel"
+ >
+ Show all shortcuts
+ </span>
+ </p>
+ </div>
+ </div>
+</div>
+`;
diff --git a/devtools/client/debugger/src/components/test/__snapshots__/WhyPaused.spec.js.snap b/devtools/client/debugger/src/components/test/__snapshots__/WhyPaused.spec.js.snap
new file mode 100644
index 0000000000..0762a0b69d
--- /dev/null
+++ b/devtools/client/debugger/src/components/test/__snapshots__/WhyPaused.spec.js.snap
@@ -0,0 +1,103 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`WhyPaused should pause reason with message 1`] = `
+<LocalizationProvider
+ bundles={Array []}
+>
+ <div
+ className="pane why-paused"
+ >
+ <div>
+ <div
+ className="info icon"
+ >
+ <AccessibleImage
+ className="info"
+ />
+ </div>
+ <div
+ className="pause reason"
+ >
+ <Localized
+ id="whypaused-breakpoint"
+ />
+ <div
+ className="message"
+ >
+ bla is hit
+ </div>
+ </div>
+ </div>
+ </div>
+</LocalizationProvider>
+`;
+
+exports[`WhyPaused should show an empty div when there is no pause reason 1`] = `
+<div
+ className=""
+/>
+`;
+
+exports[`WhyPaused should show pause reason with exception details 1`] = `
+<LocalizationProvider
+ bundles={Array []}
+>
+ <div
+ className="pane why-paused"
+ >
+ <div>
+ <div
+ className="info icon"
+ >
+ <AccessibleImage
+ className="info"
+ />
+ </div>
+ <div
+ className="pause reason"
+ >
+ <Localized
+ id="whypaused-exception"
+ />
+ <div
+ className="message warning"
+ >
+ ReferenceError: o is not defined
+ </div>
+ </div>
+ </div>
+ </div>
+</LocalizationProvider>
+`;
+
+exports[`WhyPaused should show pause reason with exception string 1`] = `
+<LocalizationProvider
+ bundles={Array []}
+>
+ <div
+ className="pane why-paused"
+ >
+ <div>
+ <div
+ className="info icon"
+ >
+ <AccessibleImage
+ className="info"
+ />
+ </div>
+ <div
+ className="pause reason"
+ >
+ <Localized
+ id="whypaused-exception"
+ />
+ <div
+ className="message warning"
+ >
+ Not Available
+ </div>
+ </div>
+ </div>
+ </div>
+</LocalizationProvider>
+`;