diff options
Diffstat (limited to 'devtools/client/debugger/src/components/SecondaryPanes/tests')
7 files changed, 1859 insertions, 0 deletions
diff --git a/devtools/client/debugger/src/components/SecondaryPanes/tests/CommandBar.spec.js b/devtools/client/debugger/src/components/SecondaryPanes/tests/CommandBar.spec.js new file mode 100644 index 0000000000..69dd75a187 --- /dev/null +++ b/devtools/client/debugger/src/components/SecondaryPanes/tests/CommandBar.spec.js @@ -0,0 +1,77 @@ +/* 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 "react"; +import { shallow } from "enzyme"; +import CommandBar from "../CommandBar"; +import { mockthreadcx } from "../../../utils/test-mockup"; + +describe("CommandBar", () => { + it("f8 key command calls props.breakOnNext when not in paused state", () => { + const props = { + cx: mockthreadcx, + breakOnNext: jest.fn(), + resume: jest.fn(), + isPaused: false, + }; + const mockEvent = { + preventDefault: jest.fn(), + stopPropagation: jest.fn(), + }; + + // The "on" spy will see all the keyboard listeners being registered by + // the shortcuts.on function + const context = { shortcuts: { on: jest.fn() } }; + + shallow(<CommandBar.WrappedComponent {...props} />, { context }); + + // get the keyboard event listeners recorded from the "on" spy. + // this will be an array where each item is itself a two item array + // containing the key code and the corresponding handler for that key code + const keyEventHandlers = context.shortcuts.on.mock.calls; + + // simulate pressing the F8 key by calling the F8 handlers + keyEventHandlers + .filter(i => i[0] === "F8") + .forEach(([_, handler]) => { + handler(mockEvent); + }); + + expect(props.breakOnNext).toHaveBeenCalled(); + expect(props.resume).not.toHaveBeenCalled(); + }); + + it("f8 key command calls props.resume when in paused state", () => { + const props = { + cx: { ...mockthreadcx, isPaused: true }, + breakOnNext: jest.fn(), + resume: jest.fn(), + isPaused: true, + }; + const mockEvent = { + preventDefault: jest.fn(), + stopPropagation: jest.fn(), + }; + + // The "on" spy will see all the keyboard listeners being registered by + // the shortcuts.on function + const context = { shortcuts: { on: jest.fn() } }; + + shallow(<CommandBar.WrappedComponent {...props} />, { context }); + + // get the keyboard event listeners recorded from the "on" spy. + // this will be an array where each item is itself a two item array + // containing the key code and the corresponding handler for that key code + const keyEventHandlers = context.shortcuts.on.mock.calls; + + // simulate pressing the F8 key by calling the F8 handlers + keyEventHandlers + .filter(i => i[0] === "F8") + .forEach(([_, handler]) => { + handler(mockEvent); + }); + expect(props.resume).toHaveBeenCalled(); + expect(props.breakOnNext).not.toHaveBeenCalled(); + }); +}); diff --git a/devtools/client/debugger/src/components/SecondaryPanes/tests/EventListeners.spec.js b/devtools/client/debugger/src/components/SecondaryPanes/tests/EventListeners.spec.js new file mode 100644 index 0000000000..f82b2093c9 --- /dev/null +++ b/devtools/client/debugger/src/components/SecondaryPanes/tests/EventListeners.spec.js @@ -0,0 +1,134 @@ +/* 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 "react"; +import { shallow } from "enzyme"; +import EventListeners from "../EventListeners"; + +function getCategories() { + return [ + { + name: "Category 1", + events: [ + { name: "Subcategory 1", id: "category1.subcategory1" }, + { name: "Subcategory 2", id: "category1.subcategory2" }, + ], + }, + { + name: "Category 2", + events: [ + { name: "Subcategory 3", id: "category2.subcategory1" }, + { name: "Subcategory 4", id: "category2.subcategory2" }, + ], + }, + ]; +} + +function generateDefaults(overrides = {}) { + const defaults = { + activeEventListeners: [], + expandedCategories: [], + categories: [], + }; + + return { ...defaults, ...overrides }; +} + +function render(overrides = {}) { + const props = generateDefaults(overrides); + const component = shallow(<EventListeners.WrappedComponent {...props} />); + return { component, props }; +} + +describe("EventListeners", () => { + it("should render", async () => { + const { component } = render(); + expect(component).toMatchSnapshot(); + }); + + it("should render categories appropriately", async () => { + const props = { + ...generateDefaults(), + categories: getCategories(), + }; + const { component } = render(props); + expect(component).toMatchSnapshot(); + }); + + it("should render expanded categories appropriately", async () => { + const props = { + ...generateDefaults(), + categories: getCategories(), + expandedCategories: ["Category 2"], + }; + const { component } = render(props); + expect(component).toMatchSnapshot(); + }); + + it("should render checked subcategories appropriately", async () => { + const props = { + ...generateDefaults(), + categories: getCategories(), + activeEventListeners: ["category1.subcategory2"], + expandedCategories: ["Category 1"], + }; + const { component } = render(props); + expect(component).toMatchSnapshot(); + }); + + it("should filter the event listeners based on the event name", async () => { + const props = { + ...generateDefaults(), + categories: getCategories(), + }; + const { component } = render(props); + component.find(".event-search-input").simulate("focus"); + + const searchInput = component.find(".event-search-input"); + // Simulate a search query of "Subcategory 3" to display just one event which + // will be the Subcategory 3 event + searchInput.simulate("change", { + currentTarget: { value: "Subcategory 3" }, + }); + + const displayedEvents = component.find(".event-listener-event"); + expect(displayedEvents).toHaveLength(1); + }); + + it("should filter the event listeners based on the category name", async () => { + const props = { + ...generateDefaults(), + categories: getCategories(), + }; + const { component } = render(props); + component.find(".event-search-input").simulate("focus"); + + const searchInput = component.find(".event-search-input"); + // Simulate a search query of "Category 1" to display two events which will be + // the Subcategory 1 event and the Subcategory 2 event + searchInput.simulate("change", { currentTarget: { value: "Category 1" } }); + + const displayedEvents = component.find(".event-listener-event"); + expect(displayedEvents).toHaveLength(2); + }); + + it("should be case insensitive when filtering events and categories", async () => { + const props = { + ...generateDefaults(), + categories: getCategories(), + }; + const { component } = render(props); + component.find(".event-search-input").simulate("focus"); + + const searchInput = component.find(".event-search-input"); + // Simulate a search query of "Subcategory 3" to display just one event which + // will be the Subcategory 3 event + searchInput.simulate("change", { + currentTarget: { value: "sUbCaTeGoRy 3" }, + }); + + const displayedEvents = component.find(".event-listener-event"); + expect(displayedEvents).toHaveLength(1); + }); +}); diff --git a/devtools/client/debugger/src/components/SecondaryPanes/tests/Expressions.spec.js b/devtools/client/debugger/src/components/SecondaryPanes/tests/Expressions.spec.js new file mode 100644 index 0000000000..ad14190276 --- /dev/null +++ b/devtools/client/debugger/src/components/SecondaryPanes/tests/Expressions.spec.js @@ -0,0 +1,75 @@ +/* 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 "react"; +import { shallow } from "enzyme"; +import Expressions from "../Expressions"; + +function generateDefaults(overrides) { + return { + evaluateExpressions: async () => {}, + expressions: [ + { + input: "expression1", + value: { + result: { + value: "foo", + class: "", + }, + }, + }, + { + input: "expression2", + value: { + result: { + value: "bar", + class: "", + }, + }, + }, + ], + ...overrides, + }; +} + +function render(overrides = {}) { + const props = generateDefaults(overrides); + const component = shallow(<Expressions.WrappedComponent {...props} />); + return { component, props }; +} + +describe("Expressions", () => { + it("should render", async () => { + const { component } = render(); + expect(component).toMatchSnapshot(); + }); + + it("should always have unique keys", async () => { + const overrides = { + expressions: [ + { + input: "expression1", + value: { + result: { + value: undefined, + class: "", + }, + }, + }, + { + input: "expression2", + value: { + result: { + value: undefined, + class: "", + }, + }, + }, + ], + }; + + const { component } = render(overrides); + expect(component).toMatchSnapshot(); + }); +}); diff --git a/devtools/client/debugger/src/components/SecondaryPanes/tests/XHRBreakpoints.spec.js b/devtools/client/debugger/src/components/SecondaryPanes/tests/XHRBreakpoints.spec.js new file mode 100644 index 0000000000..e269e89ac5 --- /dev/null +++ b/devtools/client/debugger/src/components/SecondaryPanes/tests/XHRBreakpoints.spec.js @@ -0,0 +1,345 @@ +/* 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 "react"; +import { mount } from "enzyme"; +import XHRBreakpoints from "../XHRBreakpoints"; + +const xhrMethods = [ + "ANY", + "GET", + "POST", + "PUT", + "HEAD", + "DELETE", + "PATCH", + "OPTIONS", +]; + +// default state includes xhrBreakpoints[0] which is the checkbox that +// enables breaking on any url during an XMLHTTPRequest +function generateDefaultState(propsOverride) { + return { + xhrBreakpoints: [ + { + path: "", + method: "ANY", + disabled: false, + loading: false, + text: 'URL contains ""', + }, + ], + enableXHRBreakpoint: () => {}, + disableXHRBreakpoint: () => {}, + updateXHRBreakpoint: () => {}, + removeXHRBreakpoint: () => {}, + setXHRBreakpoint: () => {}, + togglePauseOnAny: () => {}, + showInput: false, + shouldPauseOnAny: false, + onXHRAdded: () => {}, + ...propsOverride, + }; +} + +function renderXHRBreakpointsComponent(propsOverride) { + const props = generateDefaultState(propsOverride); + const xhrBreakpointsComponent = mount( + <XHRBreakpoints.WrappedComponent {...props} /> + ); + return xhrBreakpointsComponent; +} + +describe("XHR Breakpoints", function () { + it("should render with 0 expressions passed from props", function () { + const xhrBreakpointsComponent = renderXHRBreakpointsComponent(); + expect(xhrBreakpointsComponent).toMatchSnapshot(); + }); + + it("should render with 8 expressions passed from props", function () { + const allXHRBreakpointMethods = { + xhrBreakpoints: [ + { + path: "", + method: "ANY", + disabled: false, + loading: false, + text: 'URL contains ""', + }, + { + path: "this is any", + method: "ANY", + disabled: false, + loading: false, + text: 'URL contains "this is any"', + }, + { + path: "this is get", + method: "GET", + disabled: false, + loading: false, + text: 'URL contains "this is get"', + }, + { + path: "this is post", + method: "POST", + disabled: false, + loading: false, + text: 'URL contains "this is post"', + }, + { + path: "this is put", + method: "PUT", + disabled: false, + loading: false, + text: 'URL contains "this is put"', + }, + { + path: "this is head", + method: "HEAD", + disabled: false, + loading: false, + text: 'URL contains "this is head"', + }, + { + path: "this is delete", + method: "DELETE", + disabled: false, + loading: false, + text: 'URL contains "this is delete"', + }, + { + path: "this is patch", + method: "PATCH", + disabled: false, + loading: false, + text: 'URL contains "this is patch"', + }, + { + path: "this is options", + method: "OPTIONS", + disabled: false, + loading: false, + text: 'URL contains "this is options"', + }, + ], + }; + + const xhrBreakpointsComponent = renderXHRBreakpointsComponent( + allXHRBreakpointMethods + ); + expect(xhrBreakpointsComponent).toMatchSnapshot(); + }); + + it("should display xhr-input-method on click", function () { + const xhrBreakpointsComponent = renderXHRBreakpointsComponent(); + xhrBreakpointsComponent.find(".xhr-input-url").simulate("focus"); + + const xhrInputContainer = xhrBreakpointsComponent.find( + ".xhr-input-container" + ); + expect(xhrInputContainer.hasClass("focused")).toBeTruthy(); + }); + + it("should have focused and editing default to false", function () { + const xhrBreakpointsComponent = renderXHRBreakpointsComponent(); + expect(xhrBreakpointsComponent.state("focused")).toBe(false); + expect(xhrBreakpointsComponent.state("editing")).toBe(false); + }); + + it("should have state {..focused: true, editing: true} on focus", function () { + const xhrBreakpointsComponent = renderXHRBreakpointsComponent(); + xhrBreakpointsComponent.find(".xhr-input-url").simulate("focus"); + expect(xhrBreakpointsComponent.state("focused")).toBe(true); + expect(xhrBreakpointsComponent.state("editing")).toBe(true); + }); + + // shifting focus from .xhr-input to any other element apart from + // .xhr-input-method should unrender .xhr-input-method + it("shifting focus should unrender XHR methods", function () { + const propsOverride = { + onXHRAdded: jest.fn, + togglePauseOnAny: jest.fn, + }; + const xhrBreakpointsComponent = + renderXHRBreakpointsComponent(propsOverride); + xhrBreakpointsComponent.find(".xhr-input-url").simulate("focus"); + let xhrInputContainer = xhrBreakpointsComponent.find( + ".xhr-input-container" + ); + expect(xhrInputContainer.hasClass("focused")).toBeTruthy(); + + xhrBreakpointsComponent + .find(".breakpoints-exceptions-options") + .simulate("mousedown"); + expect(xhrBreakpointsComponent.state("focused")).toBe(true); + expect(xhrBreakpointsComponent.state("editing")).toBe(true); + expect(xhrBreakpointsComponent.state("clickedOnFormElement")).toBe(false); + + xhrBreakpointsComponent.find(".xhr-input-url").simulate("blur"); + expect(xhrBreakpointsComponent.state("focused")).toBe(false); + expect(xhrBreakpointsComponent.state("editing")).toBe(false); + expect(xhrBreakpointsComponent.state("clickedOnFormElement")).toBe(false); + + xhrBreakpointsComponent + .find(".breakpoints-exceptions-options") + .simulate("click"); + + xhrInputContainer = xhrBreakpointsComponent.find(".xhr-input-container"); + expect(xhrInputContainer.hasClass("focused")).not.toBeTruthy(); + }); + + // shifting focus from .xhr-input to .xhr-input-method + // should not unrender .xhr-input-method + it("shifting focus to XHR methods should not unrender", function () { + const xhrBreakpointsComponent = renderXHRBreakpointsComponent(); + xhrBreakpointsComponent.find(".xhr-input-url").simulate("focus"); + + xhrBreakpointsComponent.find(".xhr-input-method").simulate("mousedown"); + expect(xhrBreakpointsComponent.state("focused")).toBe(true); + expect(xhrBreakpointsComponent.state("editing")).toBe(false); + expect(xhrBreakpointsComponent.state("clickedOnFormElement")).toBe(true); + + xhrBreakpointsComponent.find(".xhr-input-url").simulate("blur"); + expect(xhrBreakpointsComponent.state("focused")).toBe(true); + expect(xhrBreakpointsComponent.state("editing")).toBe(false); + expect(xhrBreakpointsComponent.state("clickedOnFormElement")).toBe(false); + + xhrBreakpointsComponent.find(".xhr-input-method").simulate("click"); + const xhrInputContainer = xhrBreakpointsComponent.find( + ".xhr-input-container" + ); + expect(xhrInputContainer.hasClass("focused")).toBeTruthy(); + }); + + it("should have all 8 methods available as options", function () { + const xhrBreakpointsComponent = renderXHRBreakpointsComponent(); + xhrBreakpointsComponent.find(".xhr-input-url").simulate("focus"); + + const xhrInputMethod = xhrBreakpointsComponent.find(".xhr-input-method"); + expect(xhrInputMethod.children()).toHaveLength(8); + + const actualXHRMethods = []; + const expectedXHRMethods = xhrMethods; + + // fill the actualXHRMethods array with actual methods displayed in DOM + for (let i = 0; i < xhrInputMethod.children().length; i++) { + actualXHRMethods.push(xhrInputMethod.childAt(i).key()); + } + + // check each expected XHR Method to see if they match the actual methods + expectedXHRMethods.forEach((expectedMethod, i) => { + function compareMethods(actualMethod) { + return expectedMethod === actualMethod; + } + expect(actualXHRMethods.find(compareMethods)).toBeTruthy(); + }); + }); + + it("should return focus to input box after selecting a method", function () { + const xhrBreakpointsComponent = renderXHRBreakpointsComponent(); + + // focus starts off at .xhr-input + xhrBreakpointsComponent.find(".xhr-input-url").simulate("focus"); + + // click on method options and select GET + const methodEvent = { target: { value: "GET" } }; + xhrBreakpointsComponent.find(".xhr-input-method").simulate("mousedown"); + expect(xhrBreakpointsComponent.state("inputMethod")).toBe("ANY"); + expect(xhrBreakpointsComponent.state("editing")).toBe(false); + xhrBreakpointsComponent + .find(".xhr-input-method") + .simulate("change", methodEvent); + + // if state.editing changes from false to true, infer that + // this._input.focus() is called, which shifts focus back to input box + expect(xhrBreakpointsComponent.state("inputMethod")).toBe("GET"); + expect(xhrBreakpointsComponent.state("editing")).toBe(true); + }); + + it("should submit the URL and method when adding a breakpoint", function () { + const setXHRBreakpointCallback = jest.fn(); + const propsOverride = { + setXHRBreakpoint: setXHRBreakpointCallback, + onXHRAdded: jest.fn(), + }; + const mockEvent = { + preventDefault: jest.fn(), + stopPropagation: jest.fn(), + }; + const availableXHRMethods = xhrMethods; + expect(!!availableXHRMethods.length).toBeTruthy(); + + // check each of the available methods to see whether + // adding them as a method to a new breakpoint works as expected + availableXHRMethods.forEach(function (method) { + const xhrBreakpointsComponent = + renderXHRBreakpointsComponent(propsOverride); + xhrBreakpointsComponent.find(".xhr-input-url").simulate("focus"); + const urlValue = `${method.toLowerCase()}URLValue`; + + // simulate DOM event adding urlValue to .xhr-input + const xhrInput = xhrBreakpointsComponent.find(".xhr-input-url"); + xhrInput.simulate("change", { target: { value: urlValue } }); + + // simulate DOM event adding the input method to .xhr-input-method + const xhrInputMethod = xhrBreakpointsComponent.find(".xhr-input-method"); + xhrInputMethod.simulate("change", { target: { value: method } }); + + xhrBreakpointsComponent.find("form").simulate("submit", mockEvent); + expect(setXHRBreakpointCallback).toHaveBeenCalledWith(urlValue, method); + }); + }); + + it("should submit the URL and method when editing a breakpoint", function () { + const setXHRBreakpointCallback = jest.fn(); + const mockEvent = { + preventDefault: jest.fn(), + stopPropagation: jest.fn(), + }; + const propsOverride = { + updateXHRBreakpoint: setXHRBreakpointCallback, + onXHRAdded: jest.fn(), + xhrBreakpoints: [ + { + path: "", + method: "ANY", + disabled: false, + loading: false, + text: 'URL contains ""', + }, + { + path: "this is GET", + method: "GET", + disabled: false, + loading: false, + text: 'URL contains "this is get"', + }, + ], + }; + const xhrBreakpointsComponent = + renderXHRBreakpointsComponent(propsOverride); + + // load xhrBreakpoints pane with one existing xhrBreakpoint + const existingXHRbreakpoint = + xhrBreakpointsComponent.find(".xhr-container"); + expect(existingXHRbreakpoint).toHaveLength(1); + + // double click on existing breakpoint + existingXHRbreakpoint.simulate("doubleclick"); + const xhrInput = xhrBreakpointsComponent.find(".xhr-input-url"); + xhrInput.simulate("focus"); + + // change inputs and submit form + const xhrInputMethod = xhrBreakpointsComponent.find(".xhr-input-method"); + xhrInput.simulate("change", { target: { value: "POSTURLValue" } }); + xhrInputMethod.simulate("change", { target: { value: "POST" } }); + xhrBreakpointsComponent.find("form").simulate("submit", mockEvent); + expect(setXHRBreakpointCallback).toHaveBeenCalledWith( + 1, + "POSTURLValue", + "POST" + ); + }); +}); diff --git a/devtools/client/debugger/src/components/SecondaryPanes/tests/__snapshots__/EventListeners.spec.js.snap b/devtools/client/debugger/src/components/SecondaryPanes/tests/__snapshots__/EventListeners.spec.js.snap new file mode 100644 index 0000000000..cc2ddf09f6 --- /dev/null +++ b/devtools/client/debugger/src/components/SecondaryPanes/tests/__snapshots__/EventListeners.spec.js.snap @@ -0,0 +1,408 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`EventListeners should render 1`] = ` +<div + className="event-listeners" +> + <div + className="event-search-container" + > + <form + className="event-search-form" + onSubmit={[Function]} + > + <input + className="event-search-input" + onBlur={[Function]} + onChange={[Function]} + onFocus={[Function]} + onKeyDown={[Function]} + placeholder="Filter by event type" + value="" + /> + </form> + </div> + <div + className="event-listeners-content" + > + <ul + className="event-listeners-list" + /> + </div> +</div> +`; + +exports[`EventListeners should render categories appropriately 1`] = ` +<div + className="event-listeners" +> + <div + className="event-search-container" + > + <form + className="event-search-form" + onSubmit={[Function]} + > + <input + className="event-search-input" + onBlur={[Function]} + onChange={[Function]} + onFocus={[Function]} + onKeyDown={[Function]} + placeholder="Filter by event type" + value="" + /> + </form> + </div> + <div + className="event-listeners-content" + > + <ul + className="event-listeners-list" + > + <li + className="event-listener-group" + key="0" + > + <div + className="event-listener-header" + > + <button + className="event-listener-expand" + onClick={[Function]} + > + <AccessibleImage + className="arrow" + /> + </button> + <label + className="event-listener-label" + > + <input + checked={false} + onChange={[Function]} + type="checkbox" + value="Category 1" + /> + <span + className="event-listener-category" + > + Category 1 + </span> + </label> + </div> + </li> + <li + className="event-listener-group" + key="1" + > + <div + className="event-listener-header" + > + <button + className="event-listener-expand" + onClick={[Function]} + > + <AccessibleImage + className="arrow" + /> + </button> + <label + className="event-listener-label" + > + <input + checked={false} + onChange={[Function]} + type="checkbox" + value="Category 2" + /> + <span + className="event-listener-category" + > + Category 2 + </span> + </label> + </div> + </li> + </ul> + </div> +</div> +`; + +exports[`EventListeners should render checked subcategories appropriately 1`] = ` +<div + className="event-listeners" +> + <div + className="event-search-container" + > + <form + className="event-search-form" + onSubmit={[Function]} + > + <input + className="event-search-input" + onBlur={[Function]} + onChange={[Function]} + onFocus={[Function]} + onKeyDown={[Function]} + placeholder="Filter by event type" + value="" + /> + </form> + </div> + <div + className="event-listeners-content" + > + <ul + className="event-listeners-list" + > + <li + className="event-listener-group" + key="0" + > + <div + className="event-listener-header" + > + <button + className="event-listener-expand" + onClick={[Function]} + > + <AccessibleImage + className="arrow expanded" + /> + </button> + <label + className="event-listener-label" + > + <input + checked={false} + onChange={[Function]} + type="checkbox" + value="Category 1" + /> + <span + className="event-listener-category" + > + Category 1 + </span> + </label> + </div> + <ul> + <li + className="event-listener-event" + key="category1.subcategory1" + > + <label + className="event-listener-label" + > + <input + checked={false} + onChange={[Function]} + type="checkbox" + value="category1.subcategory1" + /> + <span + className="event-listener-name" + > + Subcategory 1 + </span> + </label> + </li> + <li + className="event-listener-event" + key="category1.subcategory2" + > + <label + className="event-listener-label" + > + <input + checked={true} + onChange={[Function]} + type="checkbox" + value="category1.subcategory2" + /> + <span + className="event-listener-name" + > + Subcategory 2 + </span> + </label> + </li> + </ul> + </li> + <li + className="event-listener-group" + key="1" + > + <div + className="event-listener-header" + > + <button + className="event-listener-expand" + onClick={[Function]} + > + <AccessibleImage + className="arrow" + /> + </button> + <label + className="event-listener-label" + > + <input + checked={false} + onChange={[Function]} + type="checkbox" + value="Category 2" + /> + <span + className="event-listener-category" + > + Category 2 + </span> + </label> + </div> + </li> + </ul> + </div> +</div> +`; + +exports[`EventListeners should render expanded categories appropriately 1`] = ` +<div + className="event-listeners" +> + <div + className="event-search-container" + > + <form + className="event-search-form" + onSubmit={[Function]} + > + <input + className="event-search-input" + onBlur={[Function]} + onChange={[Function]} + onFocus={[Function]} + onKeyDown={[Function]} + placeholder="Filter by event type" + value="" + /> + </form> + </div> + <div + className="event-listeners-content" + > + <ul + className="event-listeners-list" + > + <li + className="event-listener-group" + key="0" + > + <div + className="event-listener-header" + > + <button + className="event-listener-expand" + onClick={[Function]} + > + <AccessibleImage + className="arrow" + /> + </button> + <label + className="event-listener-label" + > + <input + checked={false} + onChange={[Function]} + type="checkbox" + value="Category 1" + /> + <span + className="event-listener-category" + > + Category 1 + </span> + </label> + </div> + </li> + <li + className="event-listener-group" + key="1" + > + <div + className="event-listener-header" + > + <button + className="event-listener-expand" + onClick={[Function]} + > + <AccessibleImage + className="arrow expanded" + /> + </button> + <label + className="event-listener-label" + > + <input + checked={false} + onChange={[Function]} + type="checkbox" + value="Category 2" + /> + <span + className="event-listener-category" + > + Category 2 + </span> + </label> + </div> + <ul> + <li + className="event-listener-event" + key="category2.subcategory1" + > + <label + className="event-listener-label" + > + <input + checked={false} + onChange={[Function]} + type="checkbox" + value="category2.subcategory1" + /> + <span + className="event-listener-name" + > + Subcategory 3 + </span> + </label> + </li> + <li + className="event-listener-event" + key="category2.subcategory2" + > + <label + className="event-listener-label" + > + <input + checked={false} + onChange={[Function]} + type="checkbox" + value="category2.subcategory2" + /> + <span + className="event-listener-name" + > + Subcategory 4 + </span> + </label> + </li> + </ul> + </li> + </ul> + </div> +</div> +`; diff --git a/devtools/client/debugger/src/components/SecondaryPanes/tests/__snapshots__/Expressions.spec.js.snap b/devtools/client/debugger/src/components/SecondaryPanes/tests/__snapshots__/Expressions.spec.js.snap new file mode 100644 index 0000000000..4869b15a73 --- /dev/null +++ b/devtools/client/debugger/src/components/SecondaryPanes/tests/__snapshots__/Expressions.spec.js.snap @@ -0,0 +1,199 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Expressions should always have unique keys 1`] = ` +<Fragment> + <ul + className="pane expressions-list" + > + <li + className="expression-container" + key="expression1" + title="expression1" + > + <div + className="expression-content" + > + <Component + autoExpandDepth={0} + createElement={[Function]} + disableWrap={true} + mayUseCustomFormatter={true} + onDOMNodeClick={[Function]} + onDOMNodeMouseOut={[Function]} + onDOMNodeMouseOver={[Function]} + onDoubleClick={[Function]} + onInspectIconClick={[Function]} + roots={ + Array [ + Object { + "contents": Object { + "front": null, + "value": Object { + "class": "", + "value": undefined, + }, + }, + "name": "expression1", + "path": "expression1", + }, + ] + } + shouldRenderTooltip={true} + /> + <div + className="expression-container__close-btn" + > + <CloseButton + handleClick={[Function]} + tooltip="Remove watch expression" + /> + </div> + </div> + </li> + <li + className="expression-container" + key="expression2" + title="expression2" + > + <div + className="expression-content" + > + <Component + autoExpandDepth={0} + createElement={[Function]} + disableWrap={true} + mayUseCustomFormatter={true} + onDOMNodeClick={[Function]} + onDOMNodeMouseOut={[Function]} + onDOMNodeMouseOver={[Function]} + onDoubleClick={[Function]} + onInspectIconClick={[Function]} + roots={ + Array [ + Object { + "contents": Object { + "front": null, + "value": Object { + "class": "", + "value": undefined, + }, + }, + "name": "expression2", + "path": "expression2", + }, + ] + } + shouldRenderTooltip={true} + /> + <div + className="expression-container__close-btn" + > + <CloseButton + handleClick={[Function]} + tooltip="Remove watch expression" + /> + </div> + </div> + </li> + </ul> +</Fragment> +`; + +exports[`Expressions should render 1`] = ` +<Fragment> + <ul + className="pane expressions-list" + > + <li + className="expression-container" + key="expression1" + title="expression1" + > + <div + className="expression-content" + > + <Component + autoExpandDepth={0} + createElement={[Function]} + disableWrap={true} + mayUseCustomFormatter={true} + onDOMNodeClick={[Function]} + onDOMNodeMouseOut={[Function]} + onDOMNodeMouseOver={[Function]} + onDoubleClick={[Function]} + onInspectIconClick={[Function]} + roots={ + Array [ + Object { + "contents": Object { + "front": null, + "value": Object { + "class": "", + "value": "foo", + }, + }, + "name": "expression1", + "path": "expression1", + }, + ] + } + shouldRenderTooltip={true} + /> + <div + className="expression-container__close-btn" + > + <CloseButton + handleClick={[Function]} + tooltip="Remove watch expression" + /> + </div> + </div> + </li> + <li + className="expression-container" + key="expression2" + title="expression2" + > + <div + className="expression-content" + > + <Component + autoExpandDepth={0} + createElement={[Function]} + disableWrap={true} + mayUseCustomFormatter={true} + onDOMNodeClick={[Function]} + onDOMNodeMouseOut={[Function]} + onDOMNodeMouseOver={[Function]} + onDoubleClick={[Function]} + onInspectIconClick={[Function]} + roots={ + Array [ + Object { + "contents": Object { + "front": null, + "value": Object { + "class": "", + "value": "bar", + }, + }, + "name": "expression2", + "path": "expression2", + }, + ] + } + shouldRenderTooltip={true} + /> + <div + className="expression-container__close-btn" + > + <CloseButton + handleClick={[Function]} + tooltip="Remove watch expression" + /> + </div> + </div> + </li> + </ul> +</Fragment> +`; diff --git a/devtools/client/debugger/src/components/SecondaryPanes/tests/__snapshots__/XHRBreakpoints.spec.js.snap b/devtools/client/debugger/src/components/SecondaryPanes/tests/__snapshots__/XHRBreakpoints.spec.js.snap new file mode 100644 index 0000000000..5611f6ceef --- /dev/null +++ b/devtools/client/debugger/src/components/SecondaryPanes/tests/__snapshots__/XHRBreakpoints.spec.js.snap @@ -0,0 +1,621 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`XHR Breakpoints should render with 0 expressions passed from props 1`] = ` +<XHRBreakpoints + disableXHRBreakpoint={[Function]} + enableXHRBreakpoint={[Function]} + onXHRAdded={[Function]} + removeXHRBreakpoint={[Function]} + setXHRBreakpoint={[Function]} + shouldPauseOnAny={false} + showInput={false} + togglePauseOnAny={[Function]} + updateXHRBreakpoint={[Function]} + xhrBreakpoints={ + Array [ + Object { + "disabled": false, + "loading": false, + "method": "ANY", + "path": "", + "text": "URL contains \\"\\"", + }, + ] + } +> + <div + className="breakpoints-exceptions-options empty" + > + <ExceptionOption + className="breakpoints-exceptions" + isChecked={false} + label="Pause on any URL" + onChange={[Function]} + > + <div + className="breakpoints-exceptions" + onClick={[Function]} + > + <input + checked="" + onChange={[Function]} + type="checkbox" + /> + <div + className="breakpoint-exceptions-label" + > + Pause on any URL + </div> + </div> + </ExceptionOption> + </div> + <form + className="xhr-input-container xhr-input-form" + key="xhr-input-container" + onSubmit={[Function]} + > + <input + className="xhr-input-url" + onBlur={[Function]} + onChange={[Function]} + onFocus={[Function]} + onKeyDown={[Function]} + placeholder="Break when URL contains" + type="text" + value="" + /> + <select + className="xhr-input-method" + onChange={[Function]} + onKeyDown={[Function]} + onMouseDown={[Function]} + value="ANY" + > + <option + key="ANY" + onMouseDown={[Function]} + value="ANY" + > + ANY + </option> + <option + key="GET" + onMouseDown={[Function]} + value="GET" + > + GET + </option> + <option + key="POST" + onMouseDown={[Function]} + value="POST" + > + POST + </option> + <option + key="PUT" + onMouseDown={[Function]} + value="PUT" + > + PUT + </option> + <option + key="HEAD" + onMouseDown={[Function]} + value="HEAD" + > + HEAD + </option> + <option + key="DELETE" + onMouseDown={[Function]} + value="DELETE" + > + DELETE + </option> + <option + key="PATCH" + onMouseDown={[Function]} + value="PATCH" + > + PATCH + </option> + <option + key="OPTIONS" + onMouseDown={[Function]} + value="OPTIONS" + > + OPTIONS + </option> + </select> + <input + style={ + Object { + "display": "none", + } + } + type="submit" + /> + </form> +</XHRBreakpoints> +`; + +exports[`XHR Breakpoints should render with 8 expressions passed from props 1`] = ` +<XHRBreakpoints + disableXHRBreakpoint={[Function]} + enableXHRBreakpoint={[Function]} + onXHRAdded={[Function]} + removeXHRBreakpoint={[Function]} + setXHRBreakpoint={[Function]} + shouldPauseOnAny={false} + showInput={false} + togglePauseOnAny={[Function]} + updateXHRBreakpoint={[Function]} + xhrBreakpoints={ + Array [ + Object { + "disabled": false, + "loading": false, + "method": "ANY", + "path": "", + "text": "URL contains \\"\\"", + }, + Object { + "disabled": false, + "loading": false, + "method": "ANY", + "path": "this is any", + "text": "URL contains \\"this is any\\"", + }, + Object { + "disabled": false, + "loading": false, + "method": "GET", + "path": "this is get", + "text": "URL contains \\"this is get\\"", + }, + Object { + "disabled": false, + "loading": false, + "method": "POST", + "path": "this is post", + "text": "URL contains \\"this is post\\"", + }, + Object { + "disabled": false, + "loading": false, + "method": "PUT", + "path": "this is put", + "text": "URL contains \\"this is put\\"", + }, + Object { + "disabled": false, + "loading": false, + "method": "HEAD", + "path": "this is head", + "text": "URL contains \\"this is head\\"", + }, + Object { + "disabled": false, + "loading": false, + "method": "DELETE", + "path": "this is delete", + "text": "URL contains \\"this is delete\\"", + }, + Object { + "disabled": false, + "loading": false, + "method": "PATCH", + "path": "this is patch", + "text": "URL contains \\"this is patch\\"", + }, + Object { + "disabled": false, + "loading": false, + "method": "OPTIONS", + "path": "this is options", + "text": "URL contains \\"this is options\\"", + }, + ] + } +> + <div + className="breakpoints-exceptions-options" + > + <ExceptionOption + className="breakpoints-exceptions" + isChecked={false} + label="Pause on any URL" + onChange={[Function]} + > + <div + className="breakpoints-exceptions" + onClick={[Function]} + > + <input + checked="" + onChange={[Function]} + type="checkbox" + /> + <div + className="breakpoint-exceptions-label" + > + Pause on any URL + </div> + </div> + </ExceptionOption> + </div> + <ul + className="pane expressions-list" + > + <li + className="xhr-container" + key="this is any-ANY" + onDoubleClick={[Function]} + title="this is any" + > + <label> + <input + checked={true} + className="xhr-checkbox" + onChange={[Function]} + onClick={[Function]} + type="checkbox" + /> + <div + className="xhr-label-method" + > + ANY + </div> + <div + className="xhr-label-url" + > + this is any + </div> + <div + className="xhr-container__close-btn" + > + <CloseButton + handleClick={[Function]} + > + <button + className="close-btn" + onClick={[Function]} + > + <AccessibleImage + className="close" + > + <span + className="img close" + /> + </AccessibleImage> + </button> + </CloseButton> + </div> + </label> + </li> + <li + className="xhr-container" + key="this is get-GET" + onDoubleClick={[Function]} + title="this is get" + > + <label> + <input + checked={true} + className="xhr-checkbox" + onChange={[Function]} + onClick={[Function]} + type="checkbox" + /> + <div + className="xhr-label-method" + > + GET + </div> + <div + className="xhr-label-url" + > + this is get + </div> + <div + className="xhr-container__close-btn" + > + <CloseButton + handleClick={[Function]} + > + <button + className="close-btn" + onClick={[Function]} + > + <AccessibleImage + className="close" + > + <span + className="img close" + /> + </AccessibleImage> + </button> + </CloseButton> + </div> + </label> + </li> + <li + className="xhr-container" + key="this is post-POST" + onDoubleClick={[Function]} + title="this is post" + > + <label> + <input + checked={true} + className="xhr-checkbox" + onChange={[Function]} + onClick={[Function]} + type="checkbox" + /> + <div + className="xhr-label-method" + > + POST + </div> + <div + className="xhr-label-url" + > + this is post + </div> + <div + className="xhr-container__close-btn" + > + <CloseButton + handleClick={[Function]} + > + <button + className="close-btn" + onClick={[Function]} + > + <AccessibleImage + className="close" + > + <span + className="img close" + /> + </AccessibleImage> + </button> + </CloseButton> + </div> + </label> + </li> + <li + className="xhr-container" + key="this is put-PUT" + onDoubleClick={[Function]} + title="this is put" + > + <label> + <input + checked={true} + className="xhr-checkbox" + onChange={[Function]} + onClick={[Function]} + type="checkbox" + /> + <div + className="xhr-label-method" + > + PUT + </div> + <div + className="xhr-label-url" + > + this is put + </div> + <div + className="xhr-container__close-btn" + > + <CloseButton + handleClick={[Function]} + > + <button + className="close-btn" + onClick={[Function]} + > + <AccessibleImage + className="close" + > + <span + className="img close" + /> + </AccessibleImage> + </button> + </CloseButton> + </div> + </label> + </li> + <li + className="xhr-container" + key="this is head-HEAD" + onDoubleClick={[Function]} + title="this is head" + > + <label> + <input + checked={true} + className="xhr-checkbox" + onChange={[Function]} + onClick={[Function]} + type="checkbox" + /> + <div + className="xhr-label-method" + > + HEAD + </div> + <div + className="xhr-label-url" + > + this is head + </div> + <div + className="xhr-container__close-btn" + > + <CloseButton + handleClick={[Function]} + > + <button + className="close-btn" + onClick={[Function]} + > + <AccessibleImage + className="close" + > + <span + className="img close" + /> + </AccessibleImage> + </button> + </CloseButton> + </div> + </label> + </li> + <li + className="xhr-container" + key="this is delete-DELETE" + onDoubleClick={[Function]} + title="this is delete" + > + <label> + <input + checked={true} + className="xhr-checkbox" + onChange={[Function]} + onClick={[Function]} + type="checkbox" + /> + <div + className="xhr-label-method" + > + DELETE + </div> + <div + className="xhr-label-url" + > + this is delete + </div> + <div + className="xhr-container__close-btn" + > + <CloseButton + handleClick={[Function]} + > + <button + className="close-btn" + onClick={[Function]} + > + <AccessibleImage + className="close" + > + <span + className="img close" + /> + </AccessibleImage> + </button> + </CloseButton> + </div> + </label> + </li> + <li + className="xhr-container" + key="this is patch-PATCH" + onDoubleClick={[Function]} + title="this is patch" + > + <label> + <input + checked={true} + className="xhr-checkbox" + onChange={[Function]} + onClick={[Function]} + type="checkbox" + /> + <div + className="xhr-label-method" + > + PATCH + </div> + <div + className="xhr-label-url" + > + this is patch + </div> + <div + className="xhr-container__close-btn" + > + <CloseButton + handleClick={[Function]} + > + <button + className="close-btn" + onClick={[Function]} + > + <AccessibleImage + className="close" + > + <span + className="img close" + /> + </AccessibleImage> + </button> + </CloseButton> + </div> + </label> + </li> + <li + className="xhr-container" + key="this is options-OPTIONS" + onDoubleClick={[Function]} + title="this is options" + > + <label> + <input + checked={true} + className="xhr-checkbox" + onChange={[Function]} + onClick={[Function]} + type="checkbox" + /> + <div + className="xhr-label-method" + > + OPTIONS + </div> + <div + className="xhr-label-url" + > + this is options + </div> + <div + className="xhr-container__close-btn" + > + <CloseButton + handleClick={[Function]} + > + <button + className="close-btn" + onClick={[Function]} + > + <AccessibleImage + className="close" + > + <span + className="img close" + /> + </AccessibleImage> + </button> + </CloseButton> + </div> + </label> + </li> + </ul> +</XHRBreakpoints> +`; |