summaryrefslogtreecommitdiffstats
path: root/devtools/client/debugger/src/components/SecondaryPanes/Frames
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/SecondaryPanes/Frames
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/SecondaryPanes/Frames')
-rw-r--r--devtools/client/debugger/src/components/SecondaryPanes/Frames/Frame.js232
-rw-r--r--devtools/client/debugger/src/components/SecondaryPanes/Frames/FrameIndent.js18
-rw-r--r--devtools/client/debugger/src/components/SecondaryPanes/Frames/Frames.css185
-rw-r--r--devtools/client/debugger/src/components/SecondaryPanes/Frames/Group.css38
-rw-r--r--devtools/client/debugger/src/components/SecondaryPanes/Frames/Group.js191
-rw-r--r--devtools/client/debugger/src/components/SecondaryPanes/Frames/index.js220
-rw-r--r--devtools/client/debugger/src/components/SecondaryPanes/Frames/moz.build13
-rw-r--r--devtools/client/debugger/src/components/SecondaryPanes/Frames/tests/Frame.spec.js110
-rw-r--r--devtools/client/debugger/src/components/SecondaryPanes/Frames/tests/Frames.spec.js270
-rw-r--r--devtools/client/debugger/src/components/SecondaryPanes/Frames/tests/Group.spec.js93
-rw-r--r--devtools/client/debugger/src/components/SecondaryPanes/Frames/tests/__snapshots__/Frame.spec.js.snap1172
-rw-r--r--devtools/client/debugger/src/components/SecondaryPanes/Frames/tests/__snapshots__/Frames.spec.js.snap1001
-rw-r--r--devtools/client/debugger/src/components/SecondaryPanes/Frames/tests/__snapshots__/Group.spec.js.snap2286
13 files changed, 5829 insertions, 0 deletions
diff --git a/devtools/client/debugger/src/components/SecondaryPanes/Frames/Frame.js b/devtools/client/debugger/src/components/SecondaryPanes/Frames/Frame.js
new file mode 100644
index 0000000000..0c81d8afb4
--- /dev/null
+++ b/devtools/client/debugger/src/components/SecondaryPanes/Frames/Frame.js
@@ -0,0 +1,232 @@
+/* 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, { Component, memo } from "devtools/client/shared/vendor/react";
+import PropTypes from "devtools/client/shared/vendor/react-prop-types";
+
+import AccessibleImage from "../../shared/AccessibleImage";
+import { formatDisplayName } from "../../../utils/pause/frames/index";
+import { getFilename, getFileURL } from "../../../utils/source";
+import FrameIndent from "./FrameIndent";
+const classnames = require("resource://devtools/client/shared/classnames.js");
+
+function FrameTitle({ frame, options = {}, l10n }) {
+ const displayName = formatDisplayName(frame, options, l10n);
+ return React.createElement(
+ "span",
+ {
+ className: "title",
+ },
+ displayName
+ );
+}
+
+FrameTitle.propTypes = {
+ frame: PropTypes.object.isRequired,
+ options: PropTypes.object.isRequired,
+ l10n: PropTypes.object.isRequired,
+ showFrameContextMenu: PropTypes.func.isRequired,
+};
+
+function getFrameLocation(frame, shouldDisplayOriginalLocation) {
+ if (shouldDisplayOriginalLocation) {
+ return frame.location;
+ }
+ return frame.generatedLocation || frame.location;
+}
+const FrameLocation = memo(
+ ({ frame, displayFullUrl = false, shouldDisplayOriginalLocation }) => {
+ if (frame.library) {
+ return React.createElement(
+ "span",
+ {
+ className: "location",
+ },
+ frame.library,
+ React.createElement(AccessibleImage, {
+ className: `annotation-logo ${frame.library.toLowerCase()}`,
+ })
+ );
+ }
+ const location = getFrameLocation(frame, shouldDisplayOriginalLocation);
+ const filename = displayFullUrl
+ ? getFileURL(location.source, false)
+ : getFilename(location.source);
+ return React.createElement(
+ "span",
+ {
+ className: "location",
+ title: location.source.url,
+ },
+ React.createElement(
+ "span",
+ {
+ className: "filename",
+ },
+ filename
+ ),
+ ":",
+ React.createElement(
+ "span",
+ {
+ className: "line",
+ },
+ location.line
+ )
+ );
+ }
+);
+FrameLocation.displayName = "FrameLocation";
+
+FrameLocation.propTypes = {
+ frame: PropTypes.object.isRequired,
+ displayFullUrl: PropTypes.bool.isRequired,
+};
+
+export default class FrameComponent extends Component {
+ static defaultProps = {
+ hideLocation: false,
+ shouldMapDisplayName: true,
+ disableContextMenu: false,
+ };
+
+ static get propTypes() {
+ return {
+ disableContextMenu: PropTypes.bool.isRequired,
+ displayFullUrl: PropTypes.bool.isRequired,
+ frame: PropTypes.object.isRequired,
+ getFrameTitle: PropTypes.func,
+ hideLocation: PropTypes.bool.isRequired,
+ isInGroup: PropTypes.bool,
+ panel: PropTypes.oneOf(["debugger", "webconsole"]).isRequired,
+ selectFrame: PropTypes.func.isRequired,
+ selectedFrame: PropTypes.object,
+ shouldMapDisplayName: PropTypes.bool.isRequired,
+ shouldDisplayOriginalLocation: PropTypes.bool.isRequired,
+ showFrameContextMenu: PropTypes.func.isRequired,
+ };
+ }
+
+ get isSelectable() {
+ return this.props.panel == "webconsole";
+ }
+
+ get isDebugger() {
+ return this.props.panel == "debugger";
+ }
+
+ onContextMenu(event) {
+ event.stopPropagation();
+ event.preventDefault();
+
+ const { frame } = this.props;
+ this.props.showFrameContextMenu(event, frame);
+ }
+
+ onMouseDown(e, frame, selectedFrame) {
+ if (e.button !== 0) {
+ return;
+ }
+
+ this.props.selectFrame(frame);
+ }
+
+ onKeyUp(event, frame, selectedFrame) {
+ if (event.key != "Enter") {
+ return;
+ }
+
+ this.props.selectFrame(frame);
+ }
+
+ render() {
+ const {
+ frame,
+ selectedFrame,
+ hideLocation,
+ shouldMapDisplayName,
+ displayFullUrl,
+ getFrameTitle,
+ disableContextMenu,
+ shouldDisplayOriginalLocation,
+ isInGroup,
+ } = this.props;
+ const { l10n } = this.context;
+
+ const className = classnames("frame", {
+ selected: selectedFrame && selectedFrame.id === frame.id,
+ });
+
+ const location = getFrameLocation(frame, shouldDisplayOriginalLocation);
+ const title = getFrameTitle
+ ? getFrameTitle(`${getFileURL(location.source, false)}:${location.line}`)
+ : undefined;
+ return React.createElement(
+ "div",
+ {
+ role: "listitem",
+ key: frame.id,
+ className: className,
+ onMouseDown: e => this.onMouseDown(e, frame, selectedFrame),
+ onKeyUp: e => this.onKeyUp(e, frame, selectedFrame),
+ onContextMenu: disableContextMenu ? null : e => this.onContextMenu(e),
+ tabIndex: 0,
+ title: title,
+ },
+ frame.asyncCause &&
+ React.createElement(
+ "span",
+ {
+ className: "location-async-cause",
+ },
+ this.isSelectable && React.createElement(FrameIndent, null),
+ this.isDebugger
+ ? React.createElement(
+ "span",
+ {
+ className: "async-label",
+ },
+ frame.asyncCause
+ )
+ : l10n.getFormatStr("stacktrace.asyncStack", frame.asyncCause),
+ this.isSelectable &&
+ React.createElement("br", {
+ className: "clipboard-only",
+ })
+ ),
+ this.isSelectable &&
+ React.createElement(FrameIndent, {
+ indentLevel: isInGroup ? 2 : 1,
+ }),
+ React.createElement(FrameTitle, {
+ frame,
+ options: {
+ shouldMapDisplayName,
+ },
+ l10n,
+ }),
+ !hideLocation &&
+ React.createElement(
+ "span",
+ {
+ className: "clipboard-only",
+ },
+ " "
+ ),
+ !hideLocation &&
+ React.createElement(FrameLocation, {
+ frame,
+ displayFullUrl,
+ shouldDisplayOriginalLocation,
+ }),
+ this.isSelectable &&
+ React.createElement("br", {
+ className: "clipboard-only",
+ })
+ );
+ }
+}
+
+FrameComponent.displayName = "Frame";
+FrameComponent.contextTypes = { l10n: PropTypes.object };
diff --git a/devtools/client/debugger/src/components/SecondaryPanes/Frames/FrameIndent.js b/devtools/client/debugger/src/components/SecondaryPanes/Frames/FrameIndent.js
new file mode 100644
index 0000000000..7eee92ffd1
--- /dev/null
+++ b/devtools/client/debugger/src/components/SecondaryPanes/Frames/FrameIndent.js
@@ -0,0 +1,18 @@
+/* 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";
+
+export default function FrameIndent({ indentLevel = 1 } = {}) {
+ // \xA0 represents the non breakable space &nbsp;
+ const indentWidth = 4 * indentLevel;
+ const nonBreakableSpaces = "\xA0".repeat(indentWidth);
+ return React.createElement(
+ "span",
+ {
+ className: "frame-indent clipboard-only",
+ },
+ nonBreakableSpaces
+ );
+}
diff --git a/devtools/client/debugger/src/components/SecondaryPanes/Frames/Frames.css b/devtools/client/debugger/src/components/SecondaryPanes/Frames/Frames.css
new file mode 100644
index 0000000000..5f57f97e51
--- /dev/null
+++ b/devtools/client/debugger/src/components/SecondaryPanes/Frames/Frames.css
@@ -0,0 +1,185 @@
+/* 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/>. */
+
+.frames [role="list"] {
+ list-style: none;
+ margin: 0;
+ padding: 4px 0;
+}
+
+.frames [role="list"] [role="listitem"] {
+ padding-bottom: 2px;
+ overflow: hidden;
+ display: flex;
+ justify-content: space-between;
+ column-gap: 0.5em;
+ flex-direction: row;
+ align-items: center;
+ margin: 0;
+ max-width: 100%;
+ flex-wrap: wrap;
+}
+
+.frames [role="list"] [role="listitem"] * {
+ user-select: none;
+}
+
+.frames .badge {
+ flex-shrink: 0;
+ margin-inline-end: 10px;
+}
+
+.frames .location {
+ font-weight: normal;
+ margin: 0;
+ flex-grow: 1;
+ max-width: 100%;
+ overflow: hidden;
+ white-space: nowrap;
+ /* Trick to get the ellipsis at the start of the string */
+ text-overflow: ellipsis;
+ direction: rtl;
+}
+
+.call-stack-pane:dir(ltr) .frames .location {
+ padding-right: 10px;
+ text-align: right;
+}
+
+.call-stack-pane:dir(rtl) .frames .location {
+ padding-left: 10px;
+ text-align: left;
+}
+
+.call-stack-pane .location-async-cause {
+ color: var(--theme-comment);
+}
+
+.theme-light .frames .location {
+ color: var(--theme-comment);
+}
+
+:root.theme-dark .frames .location {
+ color: var(--theme-body-color);
+ opacity: 0.6;
+}
+
+.frames .title {
+ text-overflow: ellipsis;
+ overflow: hidden;
+ padding-inline-start: 10px;
+}
+
+.frames-group .title {
+ padding-inline-start: 40px;
+}
+
+.frames [role="list"] [role="listitem"]:hover,
+.frames [role="list"] [role="listitem"]:focus {
+ background-color: var(--theme-toolbar-background-alt);
+}
+
+.frames [role="list"] [role="listitem"]:hover .location-async-cause,
+.frames [role="list"] [role="listitem"]:focus .location-async-cause,
+.frames [role="list"] [role="listitem"]:hover .async-label,
+.frames [role="list"] [role="listitem"]:focus .async-label {
+ background-color: var(--theme-body-background);
+}
+
+.theme-dark .frames [role="list"] [role="listitem"]:focus,
+.theme-dark .frames [role="list"] [role="listitem"]:focus .async-label,
+.theme-dark .frames [role="list"] [role="listitem"]:focus .async-label {
+ background-color: var(--theme-tab-toolbar-background);
+}
+
+.frames [role="list"] [role="listitem"].selected,
+.frames [role="list"] [role="listitem"].selected .async-label {
+ background-color: var(--theme-selection-background);
+ color: white;
+}
+
+.frames [role="list"] [role="listitem"].selected i.annotation-logo svg path {
+ fill: white;
+}
+
+:root.theme-light .frames [role="list"] [role="listitem"].selected .location,
+:root.theme-dark .frames [role="list"] [role="listitem"].selected .location {
+ color: white;
+}
+
+.frames .show-more-container {
+ display: flex;
+ min-height: 24px;
+ padding: 4px 0;
+}
+
+.frames .show-more {
+ text-align: center;
+ padding: 8px 0px;
+ margin: 7px 10px 7px 7px;
+ border: 1px solid var(--theme-splitter-color);
+ background-color: var(--theme-tab-toolbar-background);
+ width: 100%;
+ font-size: inherit;
+ color: inherit;
+}
+
+.frames .show-more:hover {
+ background-color: var(--theme-toolbar-background-hover);
+}
+
+.frames .img.annotation-logo {
+ margin-inline-end: 4px;
+ background-color: currentColor;
+}
+
+/*
+ * We also show the library icon in locations, which are forced to RTL.
+ */
+.frames .location .img.annotation-logo {
+ margin-inline-start: 4px;
+}
+
+/* Some elements are added to the DOM only to be printed into the clipboard
+ when the user copy some elements. We don't want those elements to mess with
+ the layout so we put them outside of the screen
+*/
+.frames .clipboard-only {
+ position: absolute;
+ left: -9999px;
+}
+
+.call-stack-pane [role="listitem"] .location-async-cause {
+ height: 20px;
+ line-height: 20px;
+ color: var(--theme-icon-dimmed-color);
+ display: block;
+ z-index: 4;
+ position: relative;
+ padding-inline-start: 17px;
+ width: 100%;
+ pointer-events: none;
+}
+
+.frames-group .location-async-cause {
+ padding-inline-start: 47px;
+}
+
+.call-stack-pane [role="listitem"] .location-async-cause::after {
+ content: " ";
+ position: absolute;
+ left: 0;
+ z-index: -1;
+ height: 30px;
+ top: 50%;
+ width: 100%;
+ border-top: 1px solid var(--theme-tab-toolbar-background);;
+}
+
+.call-stack-pane .async-label {
+ z-index: 1;
+ background-color: var(--theme-sidebar-background);
+ padding: 0 3px;
+ display: inline-block;
+}
diff --git a/devtools/client/debugger/src/components/SecondaryPanes/Frames/Group.css b/devtools/client/debugger/src/components/SecondaryPanes/Frames/Group.css
new file mode 100644
index 0000000000..14dbea9954
--- /dev/null
+++ b/devtools/client/debugger/src/components/SecondaryPanes/Frames/Group.css
@@ -0,0 +1,38 @@
+/* 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/>. */
+
+.frames-group .group,
+.frames-group .group .location {
+ font-weight: 500;
+ cursor: default;
+ /*
+ * direction:rtl is set in Frames.css to overflow the location text from the
+ * start. Here we need to reset it in order to display the framework icon
+ * after the framework name.
+ */
+ direction: ltr;
+}
+
+.frames-group.expanded .group,
+.frames-group.expanded .group .location {
+ color: var(--theme-highlight-blue);
+}
+
+.frames-group .frames-list {
+ border-top: 1px solid var(--theme-splitter-color);
+ border-bottom: 1px solid var(--theme-splitter-color);
+}
+
+.frames-group.expanded .badge {
+ color: var(--theme-highlight-blue);
+}
+
+.frames-group .img.arrow {
+ margin-inline-start: -1px;
+ margin-inline-end: 4px;
+}
+
+.frames-group .group-description {
+ padding-inline-start: 6px;
+}
diff --git a/devtools/client/debugger/src/components/SecondaryPanes/Frames/Group.js b/devtools/client/debugger/src/components/SecondaryPanes/Frames/Group.js
new file mode 100644
index 0000000000..ab9f7073a7
--- /dev/null
+++ b/devtools/client/debugger/src/components/SecondaryPanes/Frames/Group.js
@@ -0,0 +1,191 @@
+/* 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, { Component } from "devtools/client/shared/vendor/react";
+import PropTypes from "devtools/client/shared/vendor/react-prop-types";
+
+import { getLibraryFromUrl } from "../../../utils/pause/frames/index";
+
+import AccessibleImage from "../../shared/AccessibleImage";
+import FrameComponent from "./Frame";
+import Badge from "../../shared/Badge";
+import FrameIndent from "./FrameIndent";
+
+const classnames = require("resource://devtools/client/shared/classnames.js");
+
+function FrameLocation({ frame, expanded }) {
+ const library = frame.library || getLibraryFromUrl(frame);
+ if (!library) {
+ return null;
+ }
+ const arrowClassName = classnames("arrow", {
+ expanded,
+ });
+ return React.createElement(
+ "span",
+ {
+ className: "group-description",
+ },
+ React.createElement(AccessibleImage, {
+ className: arrowClassName,
+ }),
+ React.createElement(AccessibleImage, {
+ className: `annotation-logo ${library.toLowerCase()}`,
+ }),
+ React.createElement(
+ "span",
+ {
+ className: "group-description-name",
+ },
+ library
+ )
+ );
+}
+
+FrameLocation.propTypes = {
+ expanded: PropTypes.any.isRequired,
+ frame: PropTypes.object.isRequired,
+};
+
+FrameLocation.displayName = "FrameLocation";
+
+export default class Group extends Component {
+ constructor(...args) {
+ super(...args);
+ this.state = { expanded: false };
+ }
+
+ static get propTypes() {
+ return {
+ disableContextMenu: PropTypes.bool.isRequired,
+ displayFullUrl: PropTypes.bool.isRequired,
+ getFrameTitle: PropTypes.func,
+ group: PropTypes.array.isRequired,
+ panel: PropTypes.oneOf(["debugger", "webconsole"]).isRequired,
+ selectFrame: PropTypes.func.isRequired,
+ selectLocation: PropTypes.func,
+ selectedFrame: PropTypes.object,
+ showFrameContextMenu: PropTypes.func.isRequired,
+ };
+ }
+
+ get isSelectable() {
+ return this.props.panel == "webconsole";
+ }
+
+ onContextMenu(event) {
+ const { group } = this.props;
+ const frame = group[0];
+ this.props.showFrameContextMenu(event, frame, true);
+ }
+
+ toggleFrames = event => {
+ event.stopPropagation();
+ this.setState(prevState => ({ expanded: !prevState.expanded }));
+ };
+
+ renderFrames() {
+ const {
+ group,
+ selectFrame,
+ selectLocation,
+ selectedFrame,
+ displayFullUrl,
+ getFrameTitle,
+ disableContextMenu,
+ panel,
+ showFrameContextMenu,
+ } = this.props;
+
+ const { expanded } = this.state;
+ if (!expanded) {
+ return null;
+ }
+
+ return React.createElement(
+ "div",
+ {
+ className: "frames-list",
+ },
+ group.map(frame =>
+ React.createElement(FrameComponent, {
+ frame: frame,
+ showFrameContextMenu: showFrameContextMenu,
+ hideLocation: true,
+ key: frame.id,
+ selectedFrame: selectedFrame,
+ selectFrame: selectFrame,
+ selectLocation: selectLocation,
+ shouldMapDisplayName: false,
+ displayFullUrl: displayFullUrl,
+ getFrameTitle: getFrameTitle,
+ disableContextMenu: disableContextMenu,
+ panel: panel,
+ isInGroup: true,
+ })
+ )
+ );
+ }
+
+ renderDescription() {
+ const { l10n } = this.context;
+ const { group } = this.props;
+ const { expanded } = this.state;
+
+ const frame = group[0];
+ const l10NEntry = expanded
+ ? "callStack.group.collapseTooltip"
+ : "callStack.group.expandTooltip";
+ const title = l10n.getFormatStr(l10NEntry, frame.library);
+
+ return React.createElement(
+ "div",
+ {
+ role: "listitem",
+ key: frame.id,
+ className: "group",
+ onClick: this.toggleFrames,
+ tabIndex: 0,
+ title,
+ },
+ this.isSelectable && React.createElement(FrameIndent, null),
+ React.createElement(FrameLocation, {
+ frame,
+ expanded,
+ }),
+ this.isSelectable &&
+ React.createElement(
+ "span",
+ {
+ className: "clipboard-only",
+ },
+ " "
+ ),
+ React.createElement(Badge, { badgeText: this.props.group.length }),
+ this.isSelectable &&
+ React.createElement("br", {
+ className: "clipboard-only",
+ })
+ );
+ }
+
+ render() {
+ const { expanded } = this.state;
+ const { disableContextMenu } = this.props;
+ return React.createElement(
+ "div",
+ {
+ className: classnames("frames-group", {
+ expanded,
+ }),
+ onContextMenu: disableContextMenu ? null : e => this.onContextMenu(e),
+ },
+ this.renderDescription(),
+ this.renderFrames()
+ );
+ }
+}
+
+Group.displayName = "Group";
+Group.contextTypes = { l10n: PropTypes.object };
diff --git a/devtools/client/debugger/src/components/SecondaryPanes/Frames/index.js b/devtools/client/debugger/src/components/SecondaryPanes/Frames/index.js
new file mode 100644
index 0000000000..d83b413a01
--- /dev/null
+++ b/devtools/client/debugger/src/components/SecondaryPanes/Frames/index.js
@@ -0,0 +1,220 @@
+/* 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, { Component } from "devtools/client/shared/vendor/react";
+import { connect } from "devtools/client/shared/vendor/react-redux";
+import PropTypes from "devtools/client/shared/vendor/react-prop-types";
+
+import FrameComponent from "./Frame";
+import Group from "./Group";
+
+import actions from "../../../actions/index";
+import { collapseFrames } from "../../../utils/pause/frames/index";
+
+import {
+ getFrameworkGroupingState,
+ getSelectedFrame,
+ getCurrentThreadFrames,
+ getCurrentThread,
+ getShouldSelectOriginalLocation,
+} from "../../../selectors/index";
+
+const NUM_FRAMES_SHOWN = 7;
+
+class Frames extends Component {
+ constructor(props) {
+ super(props);
+
+ this.state = {
+ showAllFrames: !!props.disableFrameTruncate,
+ };
+ }
+
+ static get propTypes() {
+ return {
+ disableContextMenu: PropTypes.bool.isRequired,
+ disableFrameTruncate: PropTypes.bool.isRequired,
+ displayFullUrl: PropTypes.bool.isRequired,
+ frames: PropTypes.array.isRequired,
+ frameworkGroupingOn: PropTypes.bool.isRequired,
+ getFrameTitle: PropTypes.func,
+ panel: PropTypes.oneOf(["debugger", "webconsole"]).isRequired,
+ selectFrame: PropTypes.func.isRequired,
+ selectLocation: PropTypes.func,
+ selectedFrame: PropTypes.object,
+ showFrameContextMenu: PropTypes.func,
+ shouldDisplayOriginalLocation: PropTypes.bool,
+ };
+ }
+
+ shouldComponentUpdate(nextProps, nextState) {
+ const {
+ frames,
+ selectedFrame,
+ frameworkGroupingOn,
+ shouldDisplayOriginalLocation,
+ } = this.props;
+ const { showAllFrames } = this.state;
+ return (
+ frames !== nextProps.frames ||
+ selectedFrame !== nextProps.selectedFrame ||
+ showAllFrames !== nextState.showAllFrames ||
+ frameworkGroupingOn !== nextProps.frameworkGroupingOn ||
+ shouldDisplayOriginalLocation !== nextProps.shouldDisplayOriginalLocation
+ );
+ }
+
+ toggleFramesDisplay = () => {
+ this.setState(prevState => ({
+ showAllFrames: !prevState.showAllFrames,
+ }));
+ };
+
+ collapseFrames(frames) {
+ const { frameworkGroupingOn } = this.props;
+ if (!frameworkGroupingOn) {
+ return frames;
+ }
+
+ return collapseFrames(frames);
+ }
+
+ truncateFrames(frames) {
+ const numFramesToShow = this.state.showAllFrames
+ ? frames.length
+ : NUM_FRAMES_SHOWN;
+
+ return frames.slice(0, numFramesToShow);
+ }
+
+ renderFrames(frames) {
+ const {
+ selectFrame,
+ selectLocation,
+ selectedFrame,
+ displayFullUrl,
+ getFrameTitle,
+ disableContextMenu,
+ panel,
+ shouldDisplayOriginalLocation,
+ showFrameContextMenu,
+ } = this.props;
+
+ const framesOrGroups = this.truncateFrames(this.collapseFrames(frames));
+
+ // We're not using a <ul> because it adds new lines before and after when
+ // the user copies the trace. Needed for the console which has several
+ // places where we don't want to have those new lines.
+ return React.createElement(
+ "div",
+ {
+ role: "list",
+ },
+ framesOrGroups.map(frameOrGroup =>
+ frameOrGroup.id
+ ? React.createElement(FrameComponent, {
+ frame: frameOrGroup,
+ showFrameContextMenu: showFrameContextMenu,
+ selectFrame: selectFrame,
+ selectLocation: selectLocation,
+ selectedFrame: selectedFrame,
+ shouldDisplayOriginalLocation: shouldDisplayOriginalLocation,
+ key: String(frameOrGroup.id),
+ displayFullUrl: displayFullUrl,
+ getFrameTitle: getFrameTitle,
+ disableContextMenu: disableContextMenu,
+ panel: panel,
+ })
+ : React.createElement(Group, {
+ group: frameOrGroup,
+ showFrameContextMenu: showFrameContextMenu,
+ selectFrame: selectFrame,
+ selectLocation: selectLocation,
+ selectedFrame: selectedFrame,
+ key: frameOrGroup[0].id,
+ displayFullUrl: displayFullUrl,
+ getFrameTitle: getFrameTitle,
+ disableContextMenu: disableContextMenu,
+ panel: panel,
+ })
+ )
+ );
+ }
+
+ renderToggleButton(frames) {
+ const { l10n } = this.context;
+ const buttonMessage = this.state.showAllFrames
+ ? l10n.getStr("callStack.collapse")
+ : l10n.getStr("callStack.expand");
+
+ frames = this.collapseFrames(frames);
+ if (frames.length <= NUM_FRAMES_SHOWN) {
+ return null;
+ }
+ return React.createElement(
+ "div",
+ {
+ className: "show-more-container",
+ },
+ React.createElement(
+ "button",
+ {
+ className: "show-more",
+ onClick: this.toggleFramesDisplay,
+ },
+ buttonMessage
+ )
+ );
+ }
+
+ render() {
+ const { frames, disableFrameTruncate } = this.props;
+
+ if (!frames) {
+ return React.createElement(
+ "div",
+ {
+ className: "pane frames",
+ },
+ React.createElement(
+ "div",
+ {
+ className: "pane-info empty",
+ },
+ L10N.getStr("callStack.notPaused")
+ )
+ );
+ }
+ return React.createElement(
+ "div",
+ {
+ className: "pane frames",
+ },
+ this.renderFrames(frames),
+ disableFrameTruncate ? null : this.renderToggleButton(frames)
+ );
+ }
+}
+
+Frames.contextTypes = { l10n: PropTypes.object };
+
+const mapStateToProps = state => ({
+ frames: getCurrentThreadFrames(state),
+ frameworkGroupingOn: getFrameworkGroupingState(state),
+ selectedFrame: getSelectedFrame(state, getCurrentThread(state)),
+ shouldDisplayOriginalLocation: getShouldSelectOriginalLocation(state),
+ disableFrameTruncate: false,
+ disableContextMenu: false,
+ displayFullUrl: false,
+});
+
+export default connect(mapStateToProps, {
+ selectFrame: actions.selectFrame,
+ selectLocation: actions.selectLocation,
+ showFrameContextMenu: actions.showFrameContextMenu,
+})(Frames);
+
+// Export the non-connected component in order to use it outside of the debugger
+// panel (e.g. console, netmonitor, …).
+export { Frames };
diff --git a/devtools/client/debugger/src/components/SecondaryPanes/Frames/moz.build b/devtools/client/debugger/src/components/SecondaryPanes/Frames/moz.build
new file mode 100644
index 0000000000..54c188ed98
--- /dev/null
+++ b/devtools/client/debugger/src/components/SecondaryPanes/Frames/moz.build
@@ -0,0 +1,13 @@
+# vim: set filetype=python:
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+DIRS += []
+
+CompiledModules(
+ "Frame.js",
+ "FrameIndent.js",
+ "Group.js",
+ "index.js",
+)
diff --git a/devtools/client/debugger/src/components/SecondaryPanes/Frames/tests/Frame.spec.js b/devtools/client/debugger/src/components/SecondaryPanes/Frames/tests/Frame.spec.js
new file mode 100644
index 0000000000..e0dfc58a98
--- /dev/null
+++ b/devtools/client/debugger/src/components/SecondaryPanes/Frames/tests/Frame.spec.js
@@ -0,0 +1,110 @@
+/* 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, mount } from "enzyme";
+import Frame from "../Frame.js";
+import { makeMockFrame, makeMockSource } from "../../../../utils/test-mockup";
+
+function frameProperties(frame, selectedFrame, overrides = {}) {
+ return {
+ frame,
+ selectedFrame,
+ copyStackTrace: jest.fn(),
+ contextTypes: {},
+ selectFrame: jest.fn(),
+ selectLocation: jest.fn(),
+ toggleBlackBox: jest.fn(),
+ displayFullUrl: false,
+ frameworkGroupingOn: false,
+ panel: "webconsole",
+ toggleFrameworkGrouping: null,
+ restart: jest.fn(),
+ ...overrides,
+ };
+}
+
+function render(frameToSelect = {}, overrides = {}, propsOverrides = {}) {
+ const source = makeMockSource("foo-view.js");
+ const defaultFrame = makeMockFrame("1", source, undefined, 10, "renderFoo");
+
+ const frame = { ...defaultFrame, ...overrides };
+ const selectedFrame = { ...frame, ...frameToSelect };
+
+ const props = frameProperties(frame, selectedFrame, propsOverrides);
+ const component = shallow(React.createElement(Frame, props));
+ return { component, props };
+}
+
+describe("Frame", () => {
+ it("user frame", () => {
+ const { component } = render();
+ expect(component).toMatchSnapshot();
+ });
+
+ it("user frame (not selected)", () => {
+ const { component } = render({ id: "2" });
+ expect(component).toMatchSnapshot();
+ });
+
+ it("library frame", () => {
+ const source = makeMockSource("backbone.js");
+ const backboneFrame = {
+ ...makeMockFrame("3", source, undefined, 12, "updateEvents"),
+ library: "backbone",
+ };
+
+ const { component } = render({ id: "3" }, backboneFrame);
+ expect(component).toMatchSnapshot();
+ });
+
+ it("filename only", () => {
+ const source = makeMockSource(
+ "https://firefox.com/assets/src/js/foo-view.js"
+ );
+ const frame = makeMockFrame("1", source, undefined, 10, "renderFoo");
+
+ const props = frameProperties(frame, null);
+ const component = mount(React.createElement(Frame, props));
+ expect(component.text()).toBe("    renderFoo foo-view.js:10");
+ });
+
+ it("full URL", () => {
+ const url = `https://${"a".repeat(100)}.com/assets/src/js/foo-view.js`;
+ const source = makeMockSource(url);
+ const frame = makeMockFrame("1", source, undefined, 10, "renderFoo");
+
+ const props = frameProperties(frame, null, { displayFullUrl: true });
+ const component = mount(React.createElement(Frame, props));
+ expect(component.text()).toBe(`    renderFoo ${url}:10`);
+ });
+
+ it("renders asyncCause", () => {
+ const url = `https://example.com/async.js`;
+ const source = makeMockSource(url);
+ const frame = makeMockFrame("1", source, undefined, 10, "timeoutFn");
+ frame.asyncCause = "setTimeout handler";
+
+ const props = frameProperties(frame);
+ const component = mount(React.createElement(Frame, props), {
+ context: { l10n: L10N },
+ });
+ expect(component.find(".location-async-cause").text()).toBe(
+ `    (Async: setTimeout handler)`
+ );
+ });
+
+ it("getFrameTitle", () => {
+ const url = `https://${"a".repeat(100)}.com/assets/src/js/foo-view.js`;
+ const source = makeMockSource(url);
+ const frame = makeMockFrame("1", source, undefined, 10, "renderFoo");
+
+ const props = frameProperties(frame, null, {
+ getFrameTitle: x => `Jump to ${x}`,
+ });
+ const component = shallow(React.createElement(Frame, props));
+ expect(component.prop("title")).toBe(`Jump to ${url}:10`);
+ expect(component).toMatchSnapshot();
+ });
+});
diff --git a/devtools/client/debugger/src/components/SecondaryPanes/Frames/tests/Frames.spec.js b/devtools/client/debugger/src/components/SecondaryPanes/Frames/tests/Frames.spec.js
new file mode 100644
index 0000000000..240e455f75
--- /dev/null
+++ b/devtools/client/debugger/src/components/SecondaryPanes/Frames/tests/Frames.spec.js
@@ -0,0 +1,270 @@
+/* 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 { mount, shallow } from "enzyme";
+import Frames from "../index.js";
+
+function render(overrides = {}) {
+ const defaultProps = {
+ frames: null,
+ selectedFrame: null,
+ frameworkGroupingOn: false,
+ toggleFrameworkGrouping: jest.fn(),
+ contextTypes: {},
+ selectFrame: jest.fn(),
+ toggleBlackBox: jest.fn(),
+ };
+
+ const props = { ...defaultProps, ...overrides };
+ const component = shallow(
+ React.createElement(Frames.WrappedComponent, props),
+ {
+ context: {
+ l10n: L10N,
+ },
+ }
+ );
+
+ return component;
+}
+
+describe("Frames", () => {
+ describe("Supports different number of frames", () => {
+ it("empty frames", () => {
+ const component = render();
+ expect(component).toMatchSnapshot();
+ expect(component.find(".show-more").exists()).toBeFalsy();
+ });
+
+ it("one frame", () => {
+ const frames = [{ id: 1 }];
+ const selectedFrame = frames[0];
+ const component = render({ frames, selectedFrame });
+
+ expect(component.find(".show-more").exists()).toBeFalsy();
+ expect(component).toMatchSnapshot();
+ });
+
+ it("toggling the show more button", () => {
+ const frames = [
+ { id: 1 },
+ { id: 2 },
+ { id: 3 },
+ { id: 4 },
+ { id: 5 },
+ { id: 6 },
+ { id: 7 },
+ { id: 8 },
+ { id: 9 },
+ { id: 10 },
+ ];
+
+ const selectedFrame = frames[0];
+ const component = render({ selectedFrame, frames });
+
+ const getToggleBtn = () => component.find(".show-more");
+ const getFrames = () => component.find("Frame");
+
+ expect(getToggleBtn().text()).toEqual("Expand rows");
+ expect(getFrames()).toHaveLength(7);
+
+ getToggleBtn().simulate("click");
+ expect(getToggleBtn().text()).toEqual("Collapse rows");
+ expect(getFrames()).toHaveLength(10);
+ expect(component).toMatchSnapshot();
+ });
+
+ it("disable frame truncation", () => {
+ const framesNumber = 20;
+ const frames = Array.from({ length: framesNumber }, (_, i) => ({
+ id: i + 1,
+ }));
+
+ const component = render({
+ frames,
+ disableFrameTruncate: true,
+ });
+
+ const getToggleBtn = () => component.find(".show-more");
+ const getFrames = () => component.find("Frame");
+
+ expect(getToggleBtn().exists()).toBeFalsy();
+ expect(getFrames()).toHaveLength(framesNumber);
+
+ expect(component).toMatchSnapshot();
+ });
+
+ it("shows the full URL", () => {
+ const frames = [
+ {
+ id: 1,
+ displayName: "renderFoo",
+ location: {
+ source: {
+ url: "http://myfile.com/mahscripts.js",
+ },
+ line: 55,
+ },
+ },
+ ];
+
+ const component = mount(
+ <Frames.WrappedComponent
+ frames={frames}
+ disableFrameTruncate={true}
+ displayFullUrl={true}
+ />
+ );
+ expect(component.text()).toBe(
+ "renderFoo http://myfile.com/mahscripts.js:55"
+ );
+ });
+
+ it("passes the getFrameTitle prop to the Frame component", () => {
+ const frames = [
+ {
+ id: 1,
+ displayName: "renderFoo",
+ location: {
+ source: {
+ url: "http://myfile.com/mahscripts.js",
+ },
+ line: 55,
+ },
+ },
+ ];
+ const getFrameTitle = () => {};
+ const component = render({ frames, getFrameTitle });
+
+ expect(component.find("Frame").prop("getFrameTitle")).toBe(getFrameTitle);
+ expect(component).toMatchSnapshot();
+ });
+
+ it("passes the getFrameTitle prop to the Group component", () => {
+ const frames = [
+ {
+ id: 1,
+ displayName: "renderFoo",
+ location: {
+ source: {
+ url: "http://myfile.com/mahscripts.js",
+ },
+ line: 55,
+ },
+ },
+ {
+ id: 2,
+ library: "back",
+ displayName: "a",
+ location: {
+ source: {
+ url: "http://myfile.com/back.js",
+ },
+ line: 55,
+ },
+ },
+ {
+ id: 3,
+ library: "back",
+ displayName: "b",
+ location: {
+ source: {
+ url: "http://myfile.com/back.js",
+ },
+ line: 55,
+ },
+ },
+ ];
+ const getFrameTitle = () => {};
+ const component = render({
+ frames,
+ getFrameTitle,
+ frameworkGroupingOn: true,
+ });
+
+ expect(component.find("Group").prop("getFrameTitle")).toBe(getFrameTitle);
+ });
+ });
+
+ describe("Library Frames", () => {
+ it("toggling framework frames", () => {
+ const frames = [
+ { id: 1, location: { source: {} } },
+ { id: 2, library: "back", location: { source: {} } },
+ { id: 3, library: "back", location: { source: {} } },
+ { id: 8, location: { source: {} } },
+ ];
+
+ const selectedFrame = frames[0];
+ const frameworkGroupingOn = false;
+ const component = render({ frames, frameworkGroupingOn, selectedFrame });
+
+ expect(component.find("Frame")).toHaveLength(4);
+ expect(component).toMatchSnapshot();
+
+ component.setProps({ frameworkGroupingOn: true });
+
+ expect(component.find("Frame")).toHaveLength(2);
+ expect(component).toMatchSnapshot();
+ });
+
+ it("groups all the Webpack-related frames", () => {
+ const frames = [
+ { id: "1-appFrame", location: { source: {} } },
+ {
+ id: "2-webpackBootstrapFrame",
+ location: {
+ source: {
+ url: "webpack:///webpack/bootstrap 01d88449ca6e9335a66f",
+ },
+ },
+ },
+ {
+ id: "3-webpackBundleFrame",
+ location: { source: { url: "https://foo.com/bundle.js" } },
+ },
+ {
+ id: "4-webpackBootstrapFrame",
+ location: {
+ source: {
+ url: "webpack:///webpack/bootstrap 01d88449ca6e9335a66f",
+ },
+ },
+ },
+ {
+ id: "5-webpackBundleFrame",
+ location: { source: { url: "https://foo.com/bundle.js" } },
+ },
+ ];
+ const selectedFrame = frames[0];
+ const frameworkGroupingOn = true;
+ const component = render({ frames, frameworkGroupingOn, selectedFrame });
+
+ expect(component).toMatchSnapshot();
+ });
+
+ it("selectable framework frames", () => {
+ const frames = [
+ { id: 1, location: { source: {} } },
+ { id: 2, library: "back", location: { source: {} } },
+ { id: 3, library: "back", location: { source: {} } },
+ { id: 8, location: { source: {} } },
+ ];
+
+ const selectedFrame = frames[0];
+
+ const component = render({
+ frames,
+ frameworkGroupingOn: false,
+ selectedFrame,
+ selectable: true,
+ });
+ expect(component).toMatchSnapshot();
+
+ component.setProps({ frameworkGroupingOn: true });
+ expect(component).toMatchSnapshot();
+ });
+ });
+});
diff --git a/devtools/client/debugger/src/components/SecondaryPanes/Frames/tests/Group.spec.js b/devtools/client/debugger/src/components/SecondaryPanes/Frames/tests/Group.spec.js
new file mode 100644
index 0000000000..8d08fa0aed
--- /dev/null
+++ b/devtools/client/debugger/src/components/SecondaryPanes/Frames/tests/Group.spec.js
@@ -0,0 +1,93 @@
+/* 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 Group from "../Group.js";
+import { makeMockFrame, makeMockSource } from "../../../../utils/test-mockup";
+
+function render(overrides = {}) {
+ const frame = { ...makeMockFrame(), displayName: "foo", library: "Back" };
+ const defaultProps = {
+ group: [frame],
+ selectedFrame: frame,
+ frameworkGroupingOn: true,
+ toggleFrameworkGrouping: jest.fn(),
+ selectFrame: jest.fn(),
+ selectLocation: jest.fn(),
+ copyStackTrace: jest.fn(),
+ toggleBlackBox: jest.fn(),
+ disableContextMenu: false,
+ displayFullUrl: false,
+ panel: "webconsole",
+ restart: jest.fn(),
+ };
+
+ const props = { ...defaultProps, ...overrides };
+ const component = shallow(React.createElement(Group, props), {
+ context: { l10n: L10N },
+ });
+ return { component, props };
+}
+
+describe("Group", () => {
+ it("displays a group", () => {
+ const { component } = render();
+ expect(component).toMatchSnapshot();
+ });
+
+ it("passes the getFrameTitle prop to the Frame components", () => {
+ const mahscripts = makeMockSource("http://myfile.com/mahscripts.js");
+ const back = makeMockSource("http://myfile.com/back.js");
+ const group = [
+ {
+ ...makeMockFrame("1", mahscripts, undefined, 55, "renderFoo"),
+ library: "Back",
+ },
+ {
+ ...makeMockFrame("2", back, undefined, 55, "a"),
+ library: "Back",
+ },
+ {
+ ...makeMockFrame("3", back, undefined, 55, "b"),
+ library: "Back",
+ },
+ ];
+ const getFrameTitle = () => {};
+ const { component } = render({ group, getFrameTitle });
+
+ component.setState({ expanded: true });
+
+ const frameComponents = component.find("Frame");
+ expect(frameComponents).toHaveLength(3);
+ frameComponents.forEach(node => {
+ expect(node.prop("getFrameTitle")).toBe(getFrameTitle);
+ });
+ expect(component).toMatchSnapshot();
+ });
+
+ it("renders group with anonymous functions", () => {
+ const mahscripts = makeMockSource("http://myfile.com/mahscripts.js");
+ const back = makeMockSource("http://myfile.com/back.js");
+ const group = [
+ {
+ ...makeMockFrame("1", mahscripts, undefined, 55),
+ library: "Back",
+ },
+ {
+ ...makeMockFrame("2", back, undefined, 55),
+ library: "Back",
+ },
+ {
+ ...makeMockFrame("3", back, undefined, 55),
+ library: "Back",
+ },
+ ];
+
+ const { component } = render({ group });
+ expect(component).toMatchSnapshot();
+ component.setState({ expanded: true });
+ expect(component).toMatchSnapshot();
+ });
+});
diff --git a/devtools/client/debugger/src/components/SecondaryPanes/Frames/tests/__snapshots__/Frame.spec.js.snap b/devtools/client/debugger/src/components/SecondaryPanes/Frames/tests/__snapshots__/Frame.spec.js.snap
new file mode 100644
index 0000000000..90a5b1f906
--- /dev/null
+++ b/devtools/client/debugger/src/components/SecondaryPanes/Frames/tests/__snapshots__/Frame.spec.js.snap
@@ -0,0 +1,1172 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Frame getFrameTitle 1`] = `
+<div
+ className="frame"
+ key="1"
+ onContextMenu={[Function]}
+ onKeyUp={[Function]}
+ onMouseDown={[Function]}
+ role="listitem"
+ tabIndex={0}
+ title="Jump to https://aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.com/assets/src/js/foo-view.js:10"
+>
+ <FrameIndent
+ indentLevel={1}
+ />
+ <FrameTitle
+ frame={
+ Object {
+ "asyncCause": null,
+ "displayName": "renderFoo",
+ "generatedLocation": Object {
+ "column": undefined,
+ "line": 10,
+ "source": Object {
+ "displayURL": Object {
+ "fileExtension": "js",
+ "filename": "foo-view.js",
+ "group": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.com",
+ "path": "/assets/src/js/foo-view.js",
+ "search": "",
+ },
+ "extensionName": null,
+ "id": "source",
+ "isExtension": false,
+ "isOriginal": false,
+ "isPrettyPrinted": false,
+ "isWasm": false,
+ "thread": "FakeThread",
+ "url": "https://aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.com/assets/src/js/foo-view.js",
+ },
+ "sourceActor": Object {
+ "actor": "source-actor",
+ "id": "source-actor",
+ "source": "source",
+ "sourceObject": Object {
+ "displayURL": Object {
+ "fileExtension": "js",
+ "filename": "foo-view.js",
+ "group": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.com",
+ "path": "/assets/src/js/foo-view.js",
+ "search": "",
+ },
+ "extensionName": null,
+ "id": "source",
+ "isExtension": false,
+ "isOriginal": false,
+ "isPrettyPrinted": false,
+ "isWasm": false,
+ "thread": "FakeThread",
+ "url": "https://aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.com/assets/src/js/foo-view.js",
+ },
+ },
+ "sourceActorId": "source-actor",
+ },
+ "id": "1",
+ "index": 0,
+ "location": Object {
+ "column": undefined,
+ "line": 10,
+ "source": Object {
+ "displayURL": Object {
+ "fileExtension": "js",
+ "filename": "foo-view.js",
+ "group": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.com",
+ "path": "/assets/src/js/foo-view.js",
+ "search": "",
+ },
+ "extensionName": null,
+ "id": "source",
+ "isExtension": false,
+ "isOriginal": false,
+ "isPrettyPrinted": false,
+ "isWasm": false,
+ "thread": "FakeThread",
+ "url": "https://aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.com/assets/src/js/foo-view.js",
+ },
+ "sourceActor": Object {
+ "actor": "source-actor",
+ "id": "source-actor",
+ "source": "source",
+ "sourceObject": Object {
+ "displayURL": Object {
+ "fileExtension": "js",
+ "filename": "foo-view.js",
+ "group": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.com",
+ "path": "/assets/src/js/foo-view.js",
+ "search": "",
+ },
+ "extensionName": null,
+ "id": "source",
+ "isExtension": false,
+ "isOriginal": false,
+ "isPrettyPrinted": false,
+ "isWasm": false,
+ "thread": "FakeThread",
+ "url": "https://aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.com/assets/src/js/foo-view.js",
+ },
+ },
+ "sourceActorId": "source-actor",
+ },
+ "scope": Object {
+ "actor": "scope-actor",
+ "bindings": Object {
+ "arguments": Array [],
+ "variables": Object {},
+ },
+ "function": null,
+ "object": null,
+ "parent": null,
+ "scopeKind": "",
+ "type": "block",
+ },
+ "source": Object {
+ "displayURL": Object {
+ "fileExtension": "js",
+ "filename": "foo-view.js",
+ "group": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.com",
+ "path": "/assets/src/js/foo-view.js",
+ "search": "",
+ },
+ "extensionName": null,
+ "id": "source",
+ "isExtension": false,
+ "isOriginal": false,
+ "isPrettyPrinted": false,
+ "isWasm": false,
+ "thread": "FakeThread",
+ "url": "https://aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.com/assets/src/js/foo-view.js",
+ },
+ "state": "on-stack",
+ "this": Object {},
+ "thread": "FakeThread",
+ "type": "call",
+ }
+ }
+ options={
+ Object {
+ "shouldMapDisplayName": true,
+ }
+ }
+ />
+ <span
+ className="clipboard-only"
+ >
+
+ </span>
+ <FrameLocation
+ displayFullUrl={false}
+ frame={
+ Object {
+ "asyncCause": null,
+ "displayName": "renderFoo",
+ "generatedLocation": Object {
+ "column": undefined,
+ "line": 10,
+ "source": Object {
+ "displayURL": Object {
+ "fileExtension": "js",
+ "filename": "foo-view.js",
+ "group": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.com",
+ "path": "/assets/src/js/foo-view.js",
+ "search": "",
+ },
+ "extensionName": null,
+ "id": "source",
+ "isExtension": false,
+ "isOriginal": false,
+ "isPrettyPrinted": false,
+ "isWasm": false,
+ "thread": "FakeThread",
+ "url": "https://aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.com/assets/src/js/foo-view.js",
+ },
+ "sourceActor": Object {
+ "actor": "source-actor",
+ "id": "source-actor",
+ "source": "source",
+ "sourceObject": Object {
+ "displayURL": Object {
+ "fileExtension": "js",
+ "filename": "foo-view.js",
+ "group": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.com",
+ "path": "/assets/src/js/foo-view.js",
+ "search": "",
+ },
+ "extensionName": null,
+ "id": "source",
+ "isExtension": false,
+ "isOriginal": false,
+ "isPrettyPrinted": false,
+ "isWasm": false,
+ "thread": "FakeThread",
+ "url": "https://aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.com/assets/src/js/foo-view.js",
+ },
+ },
+ "sourceActorId": "source-actor",
+ },
+ "id": "1",
+ "index": 0,
+ "location": Object {
+ "column": undefined,
+ "line": 10,
+ "source": Object {
+ "displayURL": Object {
+ "fileExtension": "js",
+ "filename": "foo-view.js",
+ "group": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.com",
+ "path": "/assets/src/js/foo-view.js",
+ "search": "",
+ },
+ "extensionName": null,
+ "id": "source",
+ "isExtension": false,
+ "isOriginal": false,
+ "isPrettyPrinted": false,
+ "isWasm": false,
+ "thread": "FakeThread",
+ "url": "https://aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.com/assets/src/js/foo-view.js",
+ },
+ "sourceActor": Object {
+ "actor": "source-actor",
+ "id": "source-actor",
+ "source": "source",
+ "sourceObject": Object {
+ "displayURL": Object {
+ "fileExtension": "js",
+ "filename": "foo-view.js",
+ "group": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.com",
+ "path": "/assets/src/js/foo-view.js",
+ "search": "",
+ },
+ "extensionName": null,
+ "id": "source",
+ "isExtension": false,
+ "isOriginal": false,
+ "isPrettyPrinted": false,
+ "isWasm": false,
+ "thread": "FakeThread",
+ "url": "https://aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.com/assets/src/js/foo-view.js",
+ },
+ },
+ "sourceActorId": "source-actor",
+ },
+ "scope": Object {
+ "actor": "scope-actor",
+ "bindings": Object {
+ "arguments": Array [],
+ "variables": Object {},
+ },
+ "function": null,
+ "object": null,
+ "parent": null,
+ "scopeKind": "",
+ "type": "block",
+ },
+ "source": Object {
+ "displayURL": Object {
+ "fileExtension": "js",
+ "filename": "foo-view.js",
+ "group": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.com",
+ "path": "/assets/src/js/foo-view.js",
+ "search": "",
+ },
+ "extensionName": null,
+ "id": "source",
+ "isExtension": false,
+ "isOriginal": false,
+ "isPrettyPrinted": false,
+ "isWasm": false,
+ "thread": "FakeThread",
+ "url": "https://aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.com/assets/src/js/foo-view.js",
+ },
+ "state": "on-stack",
+ "this": Object {},
+ "thread": "FakeThread",
+ "type": "call",
+ }
+ }
+ />
+ <br
+ className="clipboard-only"
+ />
+</div>
+`;
+
+exports[`Frame library frame 1`] = `
+<div
+ className="frame selected"
+ key="3"
+ onContextMenu={[Function]}
+ onKeyUp={[Function]}
+ onMouseDown={[Function]}
+ role="listitem"
+ tabIndex={0}
+>
+ <FrameIndent
+ indentLevel={1}
+ />
+ <FrameTitle
+ frame={
+ Object {
+ "asyncCause": null,
+ "displayName": "updateEvents",
+ "generatedLocation": Object {
+ "column": undefined,
+ "line": 12,
+ "source": Object {
+ "displayURL": Object {
+ "fileExtension": "js",
+ "filename": "backbone.js",
+ "group": "",
+ "path": "backbone.js",
+ "search": "",
+ },
+ "extensionName": null,
+ "id": "source",
+ "isExtension": false,
+ "isOriginal": false,
+ "isPrettyPrinted": false,
+ "isWasm": false,
+ "thread": "FakeThread",
+ "url": "backbone.js",
+ },
+ "sourceActor": Object {
+ "actor": "source-actor",
+ "id": "source-actor",
+ "source": "source",
+ "sourceObject": Object {
+ "displayURL": Object {
+ "fileExtension": "js",
+ "filename": "backbone.js",
+ "group": "",
+ "path": "backbone.js",
+ "search": "",
+ },
+ "extensionName": null,
+ "id": "source",
+ "isExtension": false,
+ "isOriginal": false,
+ "isPrettyPrinted": false,
+ "isWasm": false,
+ "thread": "FakeThread",
+ "url": "backbone.js",
+ },
+ },
+ "sourceActorId": "source-actor",
+ },
+ "id": "3",
+ "index": 0,
+ "library": "backbone",
+ "location": Object {
+ "column": undefined,
+ "line": 12,
+ "source": Object {
+ "displayURL": Object {
+ "fileExtension": "js",
+ "filename": "backbone.js",
+ "group": "",
+ "path": "backbone.js",
+ "search": "",
+ },
+ "extensionName": null,
+ "id": "source",
+ "isExtension": false,
+ "isOriginal": false,
+ "isPrettyPrinted": false,
+ "isWasm": false,
+ "thread": "FakeThread",
+ "url": "backbone.js",
+ },
+ "sourceActor": Object {
+ "actor": "source-actor",
+ "id": "source-actor",
+ "source": "source",
+ "sourceObject": Object {
+ "displayURL": Object {
+ "fileExtension": "js",
+ "filename": "backbone.js",
+ "group": "",
+ "path": "backbone.js",
+ "search": "",
+ },
+ "extensionName": null,
+ "id": "source",
+ "isExtension": false,
+ "isOriginal": false,
+ "isPrettyPrinted": false,
+ "isWasm": false,
+ "thread": "FakeThread",
+ "url": "backbone.js",
+ },
+ },
+ "sourceActorId": "source-actor",
+ },
+ "scope": Object {
+ "actor": "scope-actor",
+ "bindings": Object {
+ "arguments": Array [],
+ "variables": Object {},
+ },
+ "function": null,
+ "object": null,
+ "parent": null,
+ "scopeKind": "",
+ "type": "block",
+ },
+ "source": Object {
+ "displayURL": Object {
+ "fileExtension": "js",
+ "filename": "backbone.js",
+ "group": "",
+ "path": "backbone.js",
+ "search": "",
+ },
+ "extensionName": null,
+ "id": "source",
+ "isExtension": false,
+ "isOriginal": false,
+ "isPrettyPrinted": false,
+ "isWasm": false,
+ "thread": "FakeThread",
+ "url": "backbone.js",
+ },
+ "state": "on-stack",
+ "this": Object {},
+ "thread": "FakeThread",
+ "type": "call",
+ }
+ }
+ options={
+ Object {
+ "shouldMapDisplayName": true,
+ }
+ }
+ />
+ <span
+ className="clipboard-only"
+ >
+
+ </span>
+ <FrameLocation
+ displayFullUrl={false}
+ frame={
+ Object {
+ "asyncCause": null,
+ "displayName": "updateEvents",
+ "generatedLocation": Object {
+ "column": undefined,
+ "line": 12,
+ "source": Object {
+ "displayURL": Object {
+ "fileExtension": "js",
+ "filename": "backbone.js",
+ "group": "",
+ "path": "backbone.js",
+ "search": "",
+ },
+ "extensionName": null,
+ "id": "source",
+ "isExtension": false,
+ "isOriginal": false,
+ "isPrettyPrinted": false,
+ "isWasm": false,
+ "thread": "FakeThread",
+ "url": "backbone.js",
+ },
+ "sourceActor": Object {
+ "actor": "source-actor",
+ "id": "source-actor",
+ "source": "source",
+ "sourceObject": Object {
+ "displayURL": Object {
+ "fileExtension": "js",
+ "filename": "backbone.js",
+ "group": "",
+ "path": "backbone.js",
+ "search": "",
+ },
+ "extensionName": null,
+ "id": "source",
+ "isExtension": false,
+ "isOriginal": false,
+ "isPrettyPrinted": false,
+ "isWasm": false,
+ "thread": "FakeThread",
+ "url": "backbone.js",
+ },
+ },
+ "sourceActorId": "source-actor",
+ },
+ "id": "3",
+ "index": 0,
+ "library": "backbone",
+ "location": Object {
+ "column": undefined,
+ "line": 12,
+ "source": Object {
+ "displayURL": Object {
+ "fileExtension": "js",
+ "filename": "backbone.js",
+ "group": "",
+ "path": "backbone.js",
+ "search": "",
+ },
+ "extensionName": null,
+ "id": "source",
+ "isExtension": false,
+ "isOriginal": false,
+ "isPrettyPrinted": false,
+ "isWasm": false,
+ "thread": "FakeThread",
+ "url": "backbone.js",
+ },
+ "sourceActor": Object {
+ "actor": "source-actor",
+ "id": "source-actor",
+ "source": "source",
+ "sourceObject": Object {
+ "displayURL": Object {
+ "fileExtension": "js",
+ "filename": "backbone.js",
+ "group": "",
+ "path": "backbone.js",
+ "search": "",
+ },
+ "extensionName": null,
+ "id": "source",
+ "isExtension": false,
+ "isOriginal": false,
+ "isPrettyPrinted": false,
+ "isWasm": false,
+ "thread": "FakeThread",
+ "url": "backbone.js",
+ },
+ },
+ "sourceActorId": "source-actor",
+ },
+ "scope": Object {
+ "actor": "scope-actor",
+ "bindings": Object {
+ "arguments": Array [],
+ "variables": Object {},
+ },
+ "function": null,
+ "object": null,
+ "parent": null,
+ "scopeKind": "",
+ "type": "block",
+ },
+ "source": Object {
+ "displayURL": Object {
+ "fileExtension": "js",
+ "filename": "backbone.js",
+ "group": "",
+ "path": "backbone.js",
+ "search": "",
+ },
+ "extensionName": null,
+ "id": "source",
+ "isExtension": false,
+ "isOriginal": false,
+ "isPrettyPrinted": false,
+ "isWasm": false,
+ "thread": "FakeThread",
+ "url": "backbone.js",
+ },
+ "state": "on-stack",
+ "this": Object {},
+ "thread": "FakeThread",
+ "type": "call",
+ }
+ }
+ />
+ <br
+ className="clipboard-only"
+ />
+</div>
+`;
+
+exports[`Frame user frame (not selected) 1`] = `
+<div
+ className="frame"
+ key="1"
+ onContextMenu={[Function]}
+ onKeyUp={[Function]}
+ onMouseDown={[Function]}
+ role="listitem"
+ tabIndex={0}
+>
+ <FrameIndent
+ indentLevel={1}
+ />
+ <FrameTitle
+ frame={
+ Object {
+ "asyncCause": null,
+ "displayName": "renderFoo",
+ "generatedLocation": Object {
+ "column": undefined,
+ "line": 10,
+ "source": Object {
+ "displayURL": Object {
+ "fileExtension": "js",
+ "filename": "foo-view.js",
+ "group": "",
+ "path": "foo-view.js",
+ "search": "",
+ },
+ "extensionName": null,
+ "id": "source",
+ "isExtension": false,
+ "isOriginal": false,
+ "isPrettyPrinted": false,
+ "isWasm": false,
+ "thread": "FakeThread",
+ "url": "foo-view.js",
+ },
+ "sourceActor": Object {
+ "actor": "source-actor",
+ "id": "source-actor",
+ "source": "source",
+ "sourceObject": Object {
+ "displayURL": Object {
+ "fileExtension": "js",
+ "filename": "foo-view.js",
+ "group": "",
+ "path": "foo-view.js",
+ "search": "",
+ },
+ "extensionName": null,
+ "id": "source",
+ "isExtension": false,
+ "isOriginal": false,
+ "isPrettyPrinted": false,
+ "isWasm": false,
+ "thread": "FakeThread",
+ "url": "foo-view.js",
+ },
+ },
+ "sourceActorId": "source-actor",
+ },
+ "id": "1",
+ "index": 0,
+ "location": Object {
+ "column": undefined,
+ "line": 10,
+ "source": Object {
+ "displayURL": Object {
+ "fileExtension": "js",
+ "filename": "foo-view.js",
+ "group": "",
+ "path": "foo-view.js",
+ "search": "",
+ },
+ "extensionName": null,
+ "id": "source",
+ "isExtension": false,
+ "isOriginal": false,
+ "isPrettyPrinted": false,
+ "isWasm": false,
+ "thread": "FakeThread",
+ "url": "foo-view.js",
+ },
+ "sourceActor": Object {
+ "actor": "source-actor",
+ "id": "source-actor",
+ "source": "source",
+ "sourceObject": Object {
+ "displayURL": Object {
+ "fileExtension": "js",
+ "filename": "foo-view.js",
+ "group": "",
+ "path": "foo-view.js",
+ "search": "",
+ },
+ "extensionName": null,
+ "id": "source",
+ "isExtension": false,
+ "isOriginal": false,
+ "isPrettyPrinted": false,
+ "isWasm": false,
+ "thread": "FakeThread",
+ "url": "foo-view.js",
+ },
+ },
+ "sourceActorId": "source-actor",
+ },
+ "scope": Object {
+ "actor": "scope-actor",
+ "bindings": Object {
+ "arguments": Array [],
+ "variables": Object {},
+ },
+ "function": null,
+ "object": null,
+ "parent": null,
+ "scopeKind": "",
+ "type": "block",
+ },
+ "source": Object {
+ "displayURL": Object {
+ "fileExtension": "js",
+ "filename": "foo-view.js",
+ "group": "",
+ "path": "foo-view.js",
+ "search": "",
+ },
+ "extensionName": null,
+ "id": "source",
+ "isExtension": false,
+ "isOriginal": false,
+ "isPrettyPrinted": false,
+ "isWasm": false,
+ "thread": "FakeThread",
+ "url": "foo-view.js",
+ },
+ "state": "on-stack",
+ "this": Object {},
+ "thread": "FakeThread",
+ "type": "call",
+ }
+ }
+ options={
+ Object {
+ "shouldMapDisplayName": true,
+ }
+ }
+ />
+ <span
+ className="clipboard-only"
+ >
+
+ </span>
+ <FrameLocation
+ displayFullUrl={false}
+ frame={
+ Object {
+ "asyncCause": null,
+ "displayName": "renderFoo",
+ "generatedLocation": Object {
+ "column": undefined,
+ "line": 10,
+ "source": Object {
+ "displayURL": Object {
+ "fileExtension": "js",
+ "filename": "foo-view.js",
+ "group": "",
+ "path": "foo-view.js",
+ "search": "",
+ },
+ "extensionName": null,
+ "id": "source",
+ "isExtension": false,
+ "isOriginal": false,
+ "isPrettyPrinted": false,
+ "isWasm": false,
+ "thread": "FakeThread",
+ "url": "foo-view.js",
+ },
+ "sourceActor": Object {
+ "actor": "source-actor",
+ "id": "source-actor",
+ "source": "source",
+ "sourceObject": Object {
+ "displayURL": Object {
+ "fileExtension": "js",
+ "filename": "foo-view.js",
+ "group": "",
+ "path": "foo-view.js",
+ "search": "",
+ },
+ "extensionName": null,
+ "id": "source",
+ "isExtension": false,
+ "isOriginal": false,
+ "isPrettyPrinted": false,
+ "isWasm": false,
+ "thread": "FakeThread",
+ "url": "foo-view.js",
+ },
+ },
+ "sourceActorId": "source-actor",
+ },
+ "id": "1",
+ "index": 0,
+ "location": Object {
+ "column": undefined,
+ "line": 10,
+ "source": Object {
+ "displayURL": Object {
+ "fileExtension": "js",
+ "filename": "foo-view.js",
+ "group": "",
+ "path": "foo-view.js",
+ "search": "",
+ },
+ "extensionName": null,
+ "id": "source",
+ "isExtension": false,
+ "isOriginal": false,
+ "isPrettyPrinted": false,
+ "isWasm": false,
+ "thread": "FakeThread",
+ "url": "foo-view.js",
+ },
+ "sourceActor": Object {
+ "actor": "source-actor",
+ "id": "source-actor",
+ "source": "source",
+ "sourceObject": Object {
+ "displayURL": Object {
+ "fileExtension": "js",
+ "filename": "foo-view.js",
+ "group": "",
+ "path": "foo-view.js",
+ "search": "",
+ },
+ "extensionName": null,
+ "id": "source",
+ "isExtension": false,
+ "isOriginal": false,
+ "isPrettyPrinted": false,
+ "isWasm": false,
+ "thread": "FakeThread",
+ "url": "foo-view.js",
+ },
+ },
+ "sourceActorId": "source-actor",
+ },
+ "scope": Object {
+ "actor": "scope-actor",
+ "bindings": Object {
+ "arguments": Array [],
+ "variables": Object {},
+ },
+ "function": null,
+ "object": null,
+ "parent": null,
+ "scopeKind": "",
+ "type": "block",
+ },
+ "source": Object {
+ "displayURL": Object {
+ "fileExtension": "js",
+ "filename": "foo-view.js",
+ "group": "",
+ "path": "foo-view.js",
+ "search": "",
+ },
+ "extensionName": null,
+ "id": "source",
+ "isExtension": false,
+ "isOriginal": false,
+ "isPrettyPrinted": false,
+ "isWasm": false,
+ "thread": "FakeThread",
+ "url": "foo-view.js",
+ },
+ "state": "on-stack",
+ "this": Object {},
+ "thread": "FakeThread",
+ "type": "call",
+ }
+ }
+ />
+ <br
+ className="clipboard-only"
+ />
+</div>
+`;
+
+exports[`Frame user frame 1`] = `
+<div
+ className="frame selected"
+ key="1"
+ onContextMenu={[Function]}
+ onKeyUp={[Function]}
+ onMouseDown={[Function]}
+ role="listitem"
+ tabIndex={0}
+>
+ <FrameIndent
+ indentLevel={1}
+ />
+ <FrameTitle
+ frame={
+ Object {
+ "asyncCause": null,
+ "displayName": "renderFoo",
+ "generatedLocation": Object {
+ "column": undefined,
+ "line": 10,
+ "source": Object {
+ "displayURL": Object {
+ "fileExtension": "js",
+ "filename": "foo-view.js",
+ "group": "",
+ "path": "foo-view.js",
+ "search": "",
+ },
+ "extensionName": null,
+ "id": "source",
+ "isExtension": false,
+ "isOriginal": false,
+ "isPrettyPrinted": false,
+ "isWasm": false,
+ "thread": "FakeThread",
+ "url": "foo-view.js",
+ },
+ "sourceActor": Object {
+ "actor": "source-actor",
+ "id": "source-actor",
+ "source": "source",
+ "sourceObject": Object {
+ "displayURL": Object {
+ "fileExtension": "js",
+ "filename": "foo-view.js",
+ "group": "",
+ "path": "foo-view.js",
+ "search": "",
+ },
+ "extensionName": null,
+ "id": "source",
+ "isExtension": false,
+ "isOriginal": false,
+ "isPrettyPrinted": false,
+ "isWasm": false,
+ "thread": "FakeThread",
+ "url": "foo-view.js",
+ },
+ },
+ "sourceActorId": "source-actor",
+ },
+ "id": "1",
+ "index": 0,
+ "location": Object {
+ "column": undefined,
+ "line": 10,
+ "source": Object {
+ "displayURL": Object {
+ "fileExtension": "js",
+ "filename": "foo-view.js",
+ "group": "",
+ "path": "foo-view.js",
+ "search": "",
+ },
+ "extensionName": null,
+ "id": "source",
+ "isExtension": false,
+ "isOriginal": false,
+ "isPrettyPrinted": false,
+ "isWasm": false,
+ "thread": "FakeThread",
+ "url": "foo-view.js",
+ },
+ "sourceActor": Object {
+ "actor": "source-actor",
+ "id": "source-actor",
+ "source": "source",
+ "sourceObject": Object {
+ "displayURL": Object {
+ "fileExtension": "js",
+ "filename": "foo-view.js",
+ "group": "",
+ "path": "foo-view.js",
+ "search": "",
+ },
+ "extensionName": null,
+ "id": "source",
+ "isExtension": false,
+ "isOriginal": false,
+ "isPrettyPrinted": false,
+ "isWasm": false,
+ "thread": "FakeThread",
+ "url": "foo-view.js",
+ },
+ },
+ "sourceActorId": "source-actor",
+ },
+ "scope": Object {
+ "actor": "scope-actor",
+ "bindings": Object {
+ "arguments": Array [],
+ "variables": Object {},
+ },
+ "function": null,
+ "object": null,
+ "parent": null,
+ "scopeKind": "",
+ "type": "block",
+ },
+ "source": Object {
+ "displayURL": Object {
+ "fileExtension": "js",
+ "filename": "foo-view.js",
+ "group": "",
+ "path": "foo-view.js",
+ "search": "",
+ },
+ "extensionName": null,
+ "id": "source",
+ "isExtension": false,
+ "isOriginal": false,
+ "isPrettyPrinted": false,
+ "isWasm": false,
+ "thread": "FakeThread",
+ "url": "foo-view.js",
+ },
+ "state": "on-stack",
+ "this": Object {},
+ "thread": "FakeThread",
+ "type": "call",
+ }
+ }
+ options={
+ Object {
+ "shouldMapDisplayName": true,
+ }
+ }
+ />
+ <span
+ className="clipboard-only"
+ >
+
+ </span>
+ <FrameLocation
+ displayFullUrl={false}
+ frame={
+ Object {
+ "asyncCause": null,
+ "displayName": "renderFoo",
+ "generatedLocation": Object {
+ "column": undefined,
+ "line": 10,
+ "source": Object {
+ "displayURL": Object {
+ "fileExtension": "js",
+ "filename": "foo-view.js",
+ "group": "",
+ "path": "foo-view.js",
+ "search": "",
+ },
+ "extensionName": null,
+ "id": "source",
+ "isExtension": false,
+ "isOriginal": false,
+ "isPrettyPrinted": false,
+ "isWasm": false,
+ "thread": "FakeThread",
+ "url": "foo-view.js",
+ },
+ "sourceActor": Object {
+ "actor": "source-actor",
+ "id": "source-actor",
+ "source": "source",
+ "sourceObject": Object {
+ "displayURL": Object {
+ "fileExtension": "js",
+ "filename": "foo-view.js",
+ "group": "",
+ "path": "foo-view.js",
+ "search": "",
+ },
+ "extensionName": null,
+ "id": "source",
+ "isExtension": false,
+ "isOriginal": false,
+ "isPrettyPrinted": false,
+ "isWasm": false,
+ "thread": "FakeThread",
+ "url": "foo-view.js",
+ },
+ },
+ "sourceActorId": "source-actor",
+ },
+ "id": "1",
+ "index": 0,
+ "location": Object {
+ "column": undefined,
+ "line": 10,
+ "source": Object {
+ "displayURL": Object {
+ "fileExtension": "js",
+ "filename": "foo-view.js",
+ "group": "",
+ "path": "foo-view.js",
+ "search": "",
+ },
+ "extensionName": null,
+ "id": "source",
+ "isExtension": false,
+ "isOriginal": false,
+ "isPrettyPrinted": false,
+ "isWasm": false,
+ "thread": "FakeThread",
+ "url": "foo-view.js",
+ },
+ "sourceActor": Object {
+ "actor": "source-actor",
+ "id": "source-actor",
+ "source": "source",
+ "sourceObject": Object {
+ "displayURL": Object {
+ "fileExtension": "js",
+ "filename": "foo-view.js",
+ "group": "",
+ "path": "foo-view.js",
+ "search": "",
+ },
+ "extensionName": null,
+ "id": "source",
+ "isExtension": false,
+ "isOriginal": false,
+ "isPrettyPrinted": false,
+ "isWasm": false,
+ "thread": "FakeThread",
+ "url": "foo-view.js",
+ },
+ },
+ "sourceActorId": "source-actor",
+ },
+ "scope": Object {
+ "actor": "scope-actor",
+ "bindings": Object {
+ "arguments": Array [],
+ "variables": Object {},
+ },
+ "function": null,
+ "object": null,
+ "parent": null,
+ "scopeKind": "",
+ "type": "block",
+ },
+ "source": Object {
+ "displayURL": Object {
+ "fileExtension": "js",
+ "filename": "foo-view.js",
+ "group": "",
+ "path": "foo-view.js",
+ "search": "",
+ },
+ "extensionName": null,
+ "id": "source",
+ "isExtension": false,
+ "isOriginal": false,
+ "isPrettyPrinted": false,
+ "isWasm": false,
+ "thread": "FakeThread",
+ "url": "foo-view.js",
+ },
+ "state": "on-stack",
+ "this": Object {},
+ "thread": "FakeThread",
+ "type": "call",
+ }
+ }
+ />
+ <br
+ className="clipboard-only"
+ />
+</div>
+`;
diff --git a/devtools/client/debugger/src/components/SecondaryPanes/Frames/tests/__snapshots__/Frames.spec.js.snap b/devtools/client/debugger/src/components/SecondaryPanes/Frames/tests/__snapshots__/Frames.spec.js.snap
new file mode 100644
index 0000000000..d1068b1aa0
--- /dev/null
+++ b/devtools/client/debugger/src/components/SecondaryPanes/Frames/tests/__snapshots__/Frames.spec.js.snap
@@ -0,0 +1,1001 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Frames Library Frames groups all the Webpack-related frames 1`] = `
+<div
+ className="pane frames"
+>
+ <div
+ role="list"
+ >
+ <Frame
+ disableContextMenu={false}
+ frame={
+ Object {
+ "id": "1-appFrame",
+ "location": Object {
+ "source": Object {},
+ },
+ }
+ }
+ hideLocation={false}
+ key="1-appFrame"
+ selectFrame={[MockFunction]}
+ selectedFrame={
+ Object {
+ "id": "1-appFrame",
+ "location": Object {
+ "source": Object {},
+ },
+ }
+ }
+ shouldMapDisplayName={true}
+ />
+ <Group
+ group={
+ Array [
+ Object {
+ "id": "2-webpackBootstrapFrame",
+ "location": Object {
+ "source": Object {
+ "url": "webpack:///webpack/bootstrap 01d88449ca6e9335a66f",
+ },
+ },
+ },
+ Object {
+ "id": "3-webpackBundleFrame",
+ "location": Object {
+ "source": Object {
+ "url": "https://foo.com/bundle.js",
+ },
+ },
+ },
+ Object {
+ "id": "4-webpackBootstrapFrame",
+ "location": Object {
+ "source": Object {
+ "url": "webpack:///webpack/bootstrap 01d88449ca6e9335a66f",
+ },
+ },
+ },
+ Object {
+ "id": "5-webpackBundleFrame",
+ "location": Object {
+ "source": Object {
+ "url": "https://foo.com/bundle.js",
+ },
+ },
+ },
+ ]
+ }
+ key="2-webpackBootstrapFrame"
+ selectFrame={[MockFunction]}
+ selectedFrame={
+ Object {
+ "id": "1-appFrame",
+ "location": Object {
+ "source": Object {},
+ },
+ }
+ }
+ />
+ </div>
+</div>
+`;
+
+exports[`Frames Library Frames selectable framework frames 1`] = `
+<div
+ className="pane frames"
+>
+ <div
+ role="list"
+ >
+ <Frame
+ disableContextMenu={false}
+ frame={
+ Object {
+ "id": 1,
+ "location": Object {
+ "source": Object {},
+ },
+ }
+ }
+ hideLocation={false}
+ key="1"
+ selectFrame={[MockFunction]}
+ selectedFrame={
+ Object {
+ "id": 1,
+ "location": Object {
+ "source": Object {},
+ },
+ }
+ }
+ shouldMapDisplayName={true}
+ />
+ <Frame
+ disableContextMenu={false}
+ frame={
+ Object {
+ "id": 2,
+ "library": "back",
+ "location": Object {
+ "source": Object {},
+ },
+ }
+ }
+ hideLocation={false}
+ key="2"
+ selectFrame={[MockFunction]}
+ selectedFrame={
+ Object {
+ "id": 1,
+ "location": Object {
+ "source": Object {},
+ },
+ }
+ }
+ shouldMapDisplayName={true}
+ />
+ <Frame
+ disableContextMenu={false}
+ frame={
+ Object {
+ "id": 3,
+ "library": "back",
+ "location": Object {
+ "source": Object {},
+ },
+ }
+ }
+ hideLocation={false}
+ key="3"
+ selectFrame={[MockFunction]}
+ selectedFrame={
+ Object {
+ "id": 1,
+ "location": Object {
+ "source": Object {},
+ },
+ }
+ }
+ shouldMapDisplayName={true}
+ />
+ <Frame
+ disableContextMenu={false}
+ frame={
+ Object {
+ "id": 8,
+ "location": Object {
+ "source": Object {},
+ },
+ }
+ }
+ hideLocation={false}
+ key="8"
+ selectFrame={[MockFunction]}
+ selectedFrame={
+ Object {
+ "id": 1,
+ "location": Object {
+ "source": Object {},
+ },
+ }
+ }
+ shouldMapDisplayName={true}
+ />
+ </div>
+</div>
+`;
+
+exports[`Frames Library Frames selectable framework frames 2`] = `
+<div
+ className="pane frames"
+>
+ <div
+ role="list"
+ >
+ <Frame
+ disableContextMenu={false}
+ frame={
+ Object {
+ "id": 1,
+ "location": Object {
+ "source": Object {},
+ },
+ }
+ }
+ hideLocation={false}
+ key="1"
+ selectFrame={[MockFunction]}
+ selectedFrame={
+ Object {
+ "id": 1,
+ "location": Object {
+ "source": Object {},
+ },
+ }
+ }
+ shouldMapDisplayName={true}
+ />
+ <Group
+ group={
+ Array [
+ Object {
+ "id": 2,
+ "library": "back",
+ "location": Object {
+ "source": Object {},
+ },
+ },
+ Object {
+ "id": 3,
+ "library": "back",
+ "location": Object {
+ "source": Object {},
+ },
+ },
+ ]
+ }
+ key="2"
+ selectFrame={[MockFunction]}
+ selectedFrame={
+ Object {
+ "id": 1,
+ "location": Object {
+ "source": Object {},
+ },
+ }
+ }
+ />
+ <Frame
+ disableContextMenu={false}
+ frame={
+ Object {
+ "id": 8,
+ "location": Object {
+ "source": Object {},
+ },
+ }
+ }
+ hideLocation={false}
+ key="8"
+ selectFrame={[MockFunction]}
+ selectedFrame={
+ Object {
+ "id": 1,
+ "location": Object {
+ "source": Object {},
+ },
+ }
+ }
+ shouldMapDisplayName={true}
+ />
+ </div>
+</div>
+`;
+
+exports[`Frames Library Frames toggling framework frames 1`] = `
+<div
+ className="pane frames"
+>
+ <div
+ role="list"
+ >
+ <Frame
+ disableContextMenu={false}
+ frame={
+ Object {
+ "id": 1,
+ "location": Object {
+ "source": Object {},
+ },
+ }
+ }
+ hideLocation={false}
+ key="1"
+ selectFrame={[MockFunction]}
+ selectedFrame={
+ Object {
+ "id": 1,
+ "location": Object {
+ "source": Object {},
+ },
+ }
+ }
+ shouldMapDisplayName={true}
+ />
+ <Frame
+ disableContextMenu={false}
+ frame={
+ Object {
+ "id": 2,
+ "library": "back",
+ "location": Object {
+ "source": Object {},
+ },
+ }
+ }
+ hideLocation={false}
+ key="2"
+ selectFrame={[MockFunction]}
+ selectedFrame={
+ Object {
+ "id": 1,
+ "location": Object {
+ "source": Object {},
+ },
+ }
+ }
+ shouldMapDisplayName={true}
+ />
+ <Frame
+ disableContextMenu={false}
+ frame={
+ Object {
+ "id": 3,
+ "library": "back",
+ "location": Object {
+ "source": Object {},
+ },
+ }
+ }
+ hideLocation={false}
+ key="3"
+ selectFrame={[MockFunction]}
+ selectedFrame={
+ Object {
+ "id": 1,
+ "location": Object {
+ "source": Object {},
+ },
+ }
+ }
+ shouldMapDisplayName={true}
+ />
+ <Frame
+ disableContextMenu={false}
+ frame={
+ Object {
+ "id": 8,
+ "location": Object {
+ "source": Object {},
+ },
+ }
+ }
+ hideLocation={false}
+ key="8"
+ selectFrame={[MockFunction]}
+ selectedFrame={
+ Object {
+ "id": 1,
+ "location": Object {
+ "source": Object {},
+ },
+ }
+ }
+ shouldMapDisplayName={true}
+ />
+ </div>
+</div>
+`;
+
+exports[`Frames Library Frames toggling framework frames 2`] = `
+<div
+ className="pane frames"
+>
+ <div
+ role="list"
+ >
+ <Frame
+ disableContextMenu={false}
+ frame={
+ Object {
+ "id": 1,
+ "location": Object {
+ "source": Object {},
+ },
+ }
+ }
+ hideLocation={false}
+ key="1"
+ selectFrame={[MockFunction]}
+ selectedFrame={
+ Object {
+ "id": 1,
+ "location": Object {
+ "source": Object {},
+ },
+ }
+ }
+ shouldMapDisplayName={true}
+ />
+ <Group
+ group={
+ Array [
+ Object {
+ "id": 2,
+ "library": "back",
+ "location": Object {
+ "source": Object {},
+ },
+ },
+ Object {
+ "id": 3,
+ "library": "back",
+ "location": Object {
+ "source": Object {},
+ },
+ },
+ ]
+ }
+ key="2"
+ selectFrame={[MockFunction]}
+ selectedFrame={
+ Object {
+ "id": 1,
+ "location": Object {
+ "source": Object {},
+ },
+ }
+ }
+ />
+ <Frame
+ disableContextMenu={false}
+ frame={
+ Object {
+ "id": 8,
+ "location": Object {
+ "source": Object {},
+ },
+ }
+ }
+ hideLocation={false}
+ key="8"
+ selectFrame={[MockFunction]}
+ selectedFrame={
+ Object {
+ "id": 1,
+ "location": Object {
+ "source": Object {},
+ },
+ }
+ }
+ shouldMapDisplayName={true}
+ />
+ </div>
+</div>
+`;
+
+exports[`Frames Supports different number of frames disable frame truncation 1`] = `
+<div
+ className="pane frames"
+>
+ <div
+ role="list"
+ >
+ <Frame
+ disableContextMenu={false}
+ frame={
+ Object {
+ "id": 1,
+ }
+ }
+ hideLocation={false}
+ key="1"
+ selectFrame={[MockFunction]}
+ selectedFrame={null}
+ shouldMapDisplayName={true}
+ />
+ <Frame
+ disableContextMenu={false}
+ frame={
+ Object {
+ "id": 2,
+ }
+ }
+ hideLocation={false}
+ key="2"
+ selectFrame={[MockFunction]}
+ selectedFrame={null}
+ shouldMapDisplayName={true}
+ />
+ <Frame
+ disableContextMenu={false}
+ frame={
+ Object {
+ "id": 3,
+ }
+ }
+ hideLocation={false}
+ key="3"
+ selectFrame={[MockFunction]}
+ selectedFrame={null}
+ shouldMapDisplayName={true}
+ />
+ <Frame
+ disableContextMenu={false}
+ frame={
+ Object {
+ "id": 4,
+ }
+ }
+ hideLocation={false}
+ key="4"
+ selectFrame={[MockFunction]}
+ selectedFrame={null}
+ shouldMapDisplayName={true}
+ />
+ <Frame
+ disableContextMenu={false}
+ frame={
+ Object {
+ "id": 5,
+ }
+ }
+ hideLocation={false}
+ key="5"
+ selectFrame={[MockFunction]}
+ selectedFrame={null}
+ shouldMapDisplayName={true}
+ />
+ <Frame
+ disableContextMenu={false}
+ frame={
+ Object {
+ "id": 6,
+ }
+ }
+ hideLocation={false}
+ key="6"
+ selectFrame={[MockFunction]}
+ selectedFrame={null}
+ shouldMapDisplayName={true}
+ />
+ <Frame
+ disableContextMenu={false}
+ frame={
+ Object {
+ "id": 7,
+ }
+ }
+ hideLocation={false}
+ key="7"
+ selectFrame={[MockFunction]}
+ selectedFrame={null}
+ shouldMapDisplayName={true}
+ />
+ <Frame
+ disableContextMenu={false}
+ frame={
+ Object {
+ "id": 8,
+ }
+ }
+ hideLocation={false}
+ key="8"
+ selectFrame={[MockFunction]}
+ selectedFrame={null}
+ shouldMapDisplayName={true}
+ />
+ <Frame
+ disableContextMenu={false}
+ frame={
+ Object {
+ "id": 9,
+ }
+ }
+ hideLocation={false}
+ key="9"
+ selectFrame={[MockFunction]}
+ selectedFrame={null}
+ shouldMapDisplayName={true}
+ />
+ <Frame
+ disableContextMenu={false}
+ frame={
+ Object {
+ "id": 10,
+ }
+ }
+ hideLocation={false}
+ key="10"
+ selectFrame={[MockFunction]}
+ selectedFrame={null}
+ shouldMapDisplayName={true}
+ />
+ <Frame
+ disableContextMenu={false}
+ frame={
+ Object {
+ "id": 11,
+ }
+ }
+ hideLocation={false}
+ key="11"
+ selectFrame={[MockFunction]}
+ selectedFrame={null}
+ shouldMapDisplayName={true}
+ />
+ <Frame
+ disableContextMenu={false}
+ frame={
+ Object {
+ "id": 12,
+ }
+ }
+ hideLocation={false}
+ key="12"
+ selectFrame={[MockFunction]}
+ selectedFrame={null}
+ shouldMapDisplayName={true}
+ />
+ <Frame
+ disableContextMenu={false}
+ frame={
+ Object {
+ "id": 13,
+ }
+ }
+ hideLocation={false}
+ key="13"
+ selectFrame={[MockFunction]}
+ selectedFrame={null}
+ shouldMapDisplayName={true}
+ />
+ <Frame
+ disableContextMenu={false}
+ frame={
+ Object {
+ "id": 14,
+ }
+ }
+ hideLocation={false}
+ key="14"
+ selectFrame={[MockFunction]}
+ selectedFrame={null}
+ shouldMapDisplayName={true}
+ />
+ <Frame
+ disableContextMenu={false}
+ frame={
+ Object {
+ "id": 15,
+ }
+ }
+ hideLocation={false}
+ key="15"
+ selectFrame={[MockFunction]}
+ selectedFrame={null}
+ shouldMapDisplayName={true}
+ />
+ <Frame
+ disableContextMenu={false}
+ frame={
+ Object {
+ "id": 16,
+ }
+ }
+ hideLocation={false}
+ key="16"
+ selectFrame={[MockFunction]}
+ selectedFrame={null}
+ shouldMapDisplayName={true}
+ />
+ <Frame
+ disableContextMenu={false}
+ frame={
+ Object {
+ "id": 17,
+ }
+ }
+ hideLocation={false}
+ key="17"
+ selectFrame={[MockFunction]}
+ selectedFrame={null}
+ shouldMapDisplayName={true}
+ />
+ <Frame
+ disableContextMenu={false}
+ frame={
+ Object {
+ "id": 18,
+ }
+ }
+ hideLocation={false}
+ key="18"
+ selectFrame={[MockFunction]}
+ selectedFrame={null}
+ shouldMapDisplayName={true}
+ />
+ <Frame
+ disableContextMenu={false}
+ frame={
+ Object {
+ "id": 19,
+ }
+ }
+ hideLocation={false}
+ key="19"
+ selectFrame={[MockFunction]}
+ selectedFrame={null}
+ shouldMapDisplayName={true}
+ />
+ <Frame
+ disableContextMenu={false}
+ frame={
+ Object {
+ "id": 20,
+ }
+ }
+ hideLocation={false}
+ key="20"
+ selectFrame={[MockFunction]}
+ selectedFrame={null}
+ shouldMapDisplayName={true}
+ />
+ </div>
+</div>
+`;
+
+exports[`Frames Supports different number of frames empty frames 1`] = `
+<div
+ className="pane frames"
+>
+ <div
+ className="pane-info empty"
+ >
+ Not paused
+ </div>
+</div>
+`;
+
+exports[`Frames Supports different number of frames one frame 1`] = `
+<div
+ className="pane frames"
+>
+ <div
+ role="list"
+ >
+ <Frame
+ disableContextMenu={false}
+ frame={
+ Object {
+ "id": 1,
+ }
+ }
+ hideLocation={false}
+ key="1"
+ selectFrame={[MockFunction]}
+ selectedFrame={
+ Object {
+ "id": 1,
+ }
+ }
+ shouldMapDisplayName={true}
+ />
+ </div>
+</div>
+`;
+
+exports[`Frames Supports different number of frames passes the getFrameTitle prop to the Frame component 1`] = `
+<div
+ className="pane frames"
+>
+ <div
+ role="list"
+ >
+ <Frame
+ disableContextMenu={false}
+ frame={
+ Object {
+ "displayName": "renderFoo",
+ "id": 1,
+ "location": Object {
+ "line": 55,
+ "source": Object {
+ "url": "http://myfile.com/mahscripts.js",
+ },
+ },
+ }
+ }
+ getFrameTitle={[Function]}
+ hideLocation={false}
+ key="1"
+ selectFrame={[MockFunction]}
+ selectedFrame={null}
+ shouldMapDisplayName={true}
+ />
+ </div>
+</div>
+`;
+
+exports[`Frames Supports different number of frames toggling the show more button 1`] = `
+<div
+ className="pane frames"
+>
+ <div
+ role="list"
+ >
+ <Frame
+ disableContextMenu={false}
+ frame={
+ Object {
+ "id": 1,
+ }
+ }
+ hideLocation={false}
+ key="1"
+ selectFrame={[MockFunction]}
+ selectedFrame={
+ Object {
+ "id": 1,
+ }
+ }
+ shouldMapDisplayName={true}
+ />
+ <Frame
+ disableContextMenu={false}
+ frame={
+ Object {
+ "id": 2,
+ }
+ }
+ hideLocation={false}
+ key="2"
+ selectFrame={[MockFunction]}
+ selectedFrame={
+ Object {
+ "id": 1,
+ }
+ }
+ shouldMapDisplayName={true}
+ />
+ <Frame
+ disableContextMenu={false}
+ frame={
+ Object {
+ "id": 3,
+ }
+ }
+ hideLocation={false}
+ key="3"
+ selectFrame={[MockFunction]}
+ selectedFrame={
+ Object {
+ "id": 1,
+ }
+ }
+ shouldMapDisplayName={true}
+ />
+ <Frame
+ disableContextMenu={false}
+ frame={
+ Object {
+ "id": 4,
+ }
+ }
+ hideLocation={false}
+ key="4"
+ selectFrame={[MockFunction]}
+ selectedFrame={
+ Object {
+ "id": 1,
+ }
+ }
+ shouldMapDisplayName={true}
+ />
+ <Frame
+ disableContextMenu={false}
+ frame={
+ Object {
+ "id": 5,
+ }
+ }
+ hideLocation={false}
+ key="5"
+ selectFrame={[MockFunction]}
+ selectedFrame={
+ Object {
+ "id": 1,
+ }
+ }
+ shouldMapDisplayName={true}
+ />
+ <Frame
+ disableContextMenu={false}
+ frame={
+ Object {
+ "id": 6,
+ }
+ }
+ hideLocation={false}
+ key="6"
+ selectFrame={[MockFunction]}
+ selectedFrame={
+ Object {
+ "id": 1,
+ }
+ }
+ shouldMapDisplayName={true}
+ />
+ <Frame
+ disableContextMenu={false}
+ frame={
+ Object {
+ "id": 7,
+ }
+ }
+ hideLocation={false}
+ key="7"
+ selectFrame={[MockFunction]}
+ selectedFrame={
+ Object {
+ "id": 1,
+ }
+ }
+ shouldMapDisplayName={true}
+ />
+ <Frame
+ disableContextMenu={false}
+ frame={
+ Object {
+ "id": 8,
+ }
+ }
+ hideLocation={false}
+ key="8"
+ selectFrame={[MockFunction]}
+ selectedFrame={
+ Object {
+ "id": 1,
+ }
+ }
+ shouldMapDisplayName={true}
+ />
+ <Frame
+ disableContextMenu={false}
+ frame={
+ Object {
+ "id": 9,
+ }
+ }
+ hideLocation={false}
+ key="9"
+ selectFrame={[MockFunction]}
+ selectedFrame={
+ Object {
+ "id": 1,
+ }
+ }
+ shouldMapDisplayName={true}
+ />
+ <Frame
+ disableContextMenu={false}
+ frame={
+ Object {
+ "id": 10,
+ }
+ }
+ hideLocation={false}
+ key="10"
+ selectFrame={[MockFunction]}
+ selectedFrame={
+ Object {
+ "id": 1,
+ }
+ }
+ shouldMapDisplayName={true}
+ />
+ </div>
+ <div
+ className="show-more-container"
+ >
+ <button
+ className="show-more"
+ onClick={[Function]}
+ >
+ Collapse rows
+ </button>
+ </div>
+</div>
+`;
diff --git a/devtools/client/debugger/src/components/SecondaryPanes/Frames/tests/__snapshots__/Group.spec.js.snap b/devtools/client/debugger/src/components/SecondaryPanes/Frames/tests/__snapshots__/Group.spec.js.snap
new file mode 100644
index 0000000000..97c4c2ad1a
--- /dev/null
+++ b/devtools/client/debugger/src/components/SecondaryPanes/Frames/tests/__snapshots__/Group.spec.js.snap
@@ -0,0 +1,2286 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Group displays a group 1`] = `
+<div
+ className="frames-group"
+ onContextMenu={[Function]}
+>
+ <div
+ className="group"
+ key="frame"
+ onClick={[Function]}
+ role="listitem"
+ tabIndex={0}
+ title="Show Back frames"
+ >
+ <FrameIndent />
+ <FrameLocation
+ expanded={false}
+ frame={
+ Object {
+ "asyncCause": null,
+ "displayName": "foo",
+ "generatedLocation": Object {
+ "column": undefined,
+ "line": 4,
+ "source": Object {
+ "displayURL": Object {
+ "fileExtension": "",
+ "filename": "url",
+ "group": "",
+ "path": "url",
+ "search": "",
+ },
+ "extensionName": null,
+ "id": "source",
+ "isExtension": false,
+ "isOriginal": false,
+ "isPrettyPrinted": false,
+ "isWasm": false,
+ "thread": "FakeThread",
+ "url": "url",
+ },
+ "sourceActor": Object {
+ "actor": "source-actor",
+ "id": "source-actor",
+ "source": "source",
+ "sourceObject": Object {
+ "displayURL": Object {
+ "fileExtension": "",
+ "filename": "url",
+ "group": "",
+ "path": "url",
+ "search": "",
+ },
+ "extensionName": null,
+ "id": "source",
+ "isExtension": false,
+ "isOriginal": false,
+ "isPrettyPrinted": false,
+ "isWasm": false,
+ "thread": "FakeThread",
+ "url": "url",
+ },
+ },
+ "sourceActorId": "source-actor",
+ },
+ "id": "frame",
+ "index": 0,
+ "library": "Back",
+ "location": Object {
+ "column": undefined,
+ "line": 4,
+ "source": Object {
+ "displayURL": Object {
+ "fileExtension": "",
+ "filename": "url",
+ "group": "",
+ "path": "url",
+ "search": "",
+ },
+ "extensionName": null,
+ "id": "source",
+ "isExtension": false,
+ "isOriginal": false,
+ "isPrettyPrinted": false,
+ "isWasm": false,
+ "thread": "FakeThread",
+ "url": "url",
+ },
+ "sourceActor": Object {
+ "actor": "source-actor",
+ "id": "source-actor",
+ "source": "source",
+ "sourceObject": Object {
+ "displayURL": Object {
+ "fileExtension": "",
+ "filename": "url",
+ "group": "",
+ "path": "url",
+ "search": "",
+ },
+ "extensionName": null,
+ "id": "source",
+ "isExtension": false,
+ "isOriginal": false,
+ "isPrettyPrinted": false,
+ "isWasm": false,
+ "thread": "FakeThread",
+ "url": "url",
+ },
+ },
+ "sourceActorId": "source-actor",
+ },
+ "scope": Object {
+ "actor": "scope-actor",
+ "bindings": Object {
+ "arguments": Array [],
+ "variables": Object {},
+ },
+ "function": null,
+ "object": null,
+ "parent": null,
+ "scopeKind": "",
+ "type": "block",
+ },
+ "source": Object {
+ "displayURL": Object {
+ "fileExtension": "",
+ "filename": "url",
+ "group": "",
+ "path": "url",
+ "search": "",
+ },
+ "extensionName": null,
+ "id": "source",
+ "isExtension": false,
+ "isOriginal": false,
+ "isPrettyPrinted": false,
+ "isWasm": false,
+ "thread": "FakeThread",
+ "url": "url",
+ },
+ "state": "on-stack",
+ "this": Object {},
+ "thread": "FakeThread",
+ "type": "call",
+ }
+ }
+ />
+ <span
+ className="clipboard-only"
+ >
+
+ </span>
+ <Badge
+ badgeText={1}
+ />
+ <br
+ className="clipboard-only"
+ />
+ </div>
+</div>
+`;
+
+exports[`Group passes the getFrameTitle prop to the Frame components 1`] = `
+<div
+ className="frames-group expanded"
+ onContextMenu={[Function]}
+>
+ <div
+ className="group"
+ key="1"
+ onClick={[Function]}
+ role="listitem"
+ tabIndex={0}
+ title="Collapse Back frames"
+ >
+ <FrameIndent />
+ <FrameLocation
+ expanded={true}
+ frame={
+ Object {
+ "asyncCause": null,
+ "displayName": "renderFoo",
+ "generatedLocation": Object {
+ "column": undefined,
+ "line": 55,
+ "source": Object {
+ "displayURL": Object {
+ "fileExtension": "js",
+ "filename": "mahscripts.js",
+ "group": "myfile.com",
+ "path": "/mahscripts.js",
+ "search": "",
+ },
+ "extensionName": null,
+ "id": "source",
+ "isExtension": false,
+ "isOriginal": false,
+ "isPrettyPrinted": false,
+ "isWasm": false,
+ "thread": "FakeThread",
+ "url": "http://myfile.com/mahscripts.js",
+ },
+ "sourceActor": Object {
+ "actor": "source-actor",
+ "id": "source-actor",
+ "source": "source",
+ "sourceObject": Object {
+ "displayURL": Object {
+ "fileExtension": "js",
+ "filename": "mahscripts.js",
+ "group": "myfile.com",
+ "path": "/mahscripts.js",
+ "search": "",
+ },
+ "extensionName": null,
+ "id": "source",
+ "isExtension": false,
+ "isOriginal": false,
+ "isPrettyPrinted": false,
+ "isWasm": false,
+ "thread": "FakeThread",
+ "url": "http://myfile.com/mahscripts.js",
+ },
+ },
+ "sourceActorId": "source-actor",
+ },
+ "id": "1",
+ "index": 0,
+ "library": "Back",
+ "location": Object {
+ "column": undefined,
+ "line": 55,
+ "source": Object {
+ "displayURL": Object {
+ "fileExtension": "js",
+ "filename": "mahscripts.js",
+ "group": "myfile.com",
+ "path": "/mahscripts.js",
+ "search": "",
+ },
+ "extensionName": null,
+ "id": "source",
+ "isExtension": false,
+ "isOriginal": false,
+ "isPrettyPrinted": false,
+ "isWasm": false,
+ "thread": "FakeThread",
+ "url": "http://myfile.com/mahscripts.js",
+ },
+ "sourceActor": Object {
+ "actor": "source-actor",
+ "id": "source-actor",
+ "source": "source",
+ "sourceObject": Object {
+ "displayURL": Object {
+ "fileExtension": "js",
+ "filename": "mahscripts.js",
+ "group": "myfile.com",
+ "path": "/mahscripts.js",
+ "search": "",
+ },
+ "extensionName": null,
+ "id": "source",
+ "isExtension": false,
+ "isOriginal": false,
+ "isPrettyPrinted": false,
+ "isWasm": false,
+ "thread": "FakeThread",
+ "url": "http://myfile.com/mahscripts.js",
+ },
+ },
+ "sourceActorId": "source-actor",
+ },
+ "scope": Object {
+ "actor": "scope-actor",
+ "bindings": Object {
+ "arguments": Array [],
+ "variables": Object {},
+ },
+ "function": null,
+ "object": null,
+ "parent": null,
+ "scopeKind": "",
+ "type": "block",
+ },
+ "source": Object {
+ "displayURL": Object {
+ "fileExtension": "js",
+ "filename": "mahscripts.js",
+ "group": "myfile.com",
+ "path": "/mahscripts.js",
+ "search": "",
+ },
+ "extensionName": null,
+ "id": "source",
+ "isExtension": false,
+ "isOriginal": false,
+ "isPrettyPrinted": false,
+ "isWasm": false,
+ "thread": "FakeThread",
+ "url": "http://myfile.com/mahscripts.js",
+ },
+ "state": "on-stack",
+ "this": Object {},
+ "thread": "FakeThread",
+ "type": "call",
+ }
+ }
+ />
+ <span
+ className="clipboard-only"
+ >
+
+ </span>
+ <Badge
+ badgeText={3}
+ />
+ <br
+ className="clipboard-only"
+ />
+ </div>
+ <div
+ className="frames-list"
+ >
+ <Frame
+ disableContextMenu={false}
+ displayFullUrl={false}
+ frame={
+ Object {
+ "asyncCause": null,
+ "displayName": "renderFoo",
+ "generatedLocation": Object {
+ "column": undefined,
+ "line": 55,
+ "source": Object {
+ "displayURL": Object {
+ "fileExtension": "js",
+ "filename": "mahscripts.js",
+ "group": "myfile.com",
+ "path": "/mahscripts.js",
+ "search": "",
+ },
+ "extensionName": null,
+ "id": "source",
+ "isExtension": false,
+ "isOriginal": false,
+ "isPrettyPrinted": false,
+ "isWasm": false,
+ "thread": "FakeThread",
+ "url": "http://myfile.com/mahscripts.js",
+ },
+ "sourceActor": Object {
+ "actor": "source-actor",
+ "id": "source-actor",
+ "source": "source",
+ "sourceObject": Object {
+ "displayURL": Object {
+ "fileExtension": "js",
+ "filename": "mahscripts.js",
+ "group": "myfile.com",
+ "path": "/mahscripts.js",
+ "search": "",
+ },
+ "extensionName": null,
+ "id": "source",
+ "isExtension": false,
+ "isOriginal": false,
+ "isPrettyPrinted": false,
+ "isWasm": false,
+ "thread": "FakeThread",
+ "url": "http://myfile.com/mahscripts.js",
+ },
+ },
+ "sourceActorId": "source-actor",
+ },
+ "id": "1",
+ "index": 0,
+ "library": "Back",
+ "location": Object {
+ "column": undefined,
+ "line": 55,
+ "source": Object {
+ "displayURL": Object {
+ "fileExtension": "js",
+ "filename": "mahscripts.js",
+ "group": "myfile.com",
+ "path": "/mahscripts.js",
+ "search": "",
+ },
+ "extensionName": null,
+ "id": "source",
+ "isExtension": false,
+ "isOriginal": false,
+ "isPrettyPrinted": false,
+ "isWasm": false,
+ "thread": "FakeThread",
+ "url": "http://myfile.com/mahscripts.js",
+ },
+ "sourceActor": Object {
+ "actor": "source-actor",
+ "id": "source-actor",
+ "source": "source",
+ "sourceObject": Object {
+ "displayURL": Object {
+ "fileExtension": "js",
+ "filename": "mahscripts.js",
+ "group": "myfile.com",
+ "path": "/mahscripts.js",
+ "search": "",
+ },
+ "extensionName": null,
+ "id": "source",
+ "isExtension": false,
+ "isOriginal": false,
+ "isPrettyPrinted": false,
+ "isWasm": false,
+ "thread": "FakeThread",
+ "url": "http://myfile.com/mahscripts.js",
+ },
+ },
+ "sourceActorId": "source-actor",
+ },
+ "scope": Object {
+ "actor": "scope-actor",
+ "bindings": Object {
+ "arguments": Array [],
+ "variables": Object {},
+ },
+ "function": null,
+ "object": null,
+ "parent": null,
+ "scopeKind": "",
+ "type": "block",
+ },
+ "source": Object {
+ "displayURL": Object {
+ "fileExtension": "js",
+ "filename": "mahscripts.js",
+ "group": "myfile.com",
+ "path": "/mahscripts.js",
+ "search": "",
+ },
+ "extensionName": null,
+ "id": "source",
+ "isExtension": false,
+ "isOriginal": false,
+ "isPrettyPrinted": false,
+ "isWasm": false,
+ "thread": "FakeThread",
+ "url": "http://myfile.com/mahscripts.js",
+ },
+ "state": "on-stack",
+ "this": Object {},
+ "thread": "FakeThread",
+ "type": "call",
+ }
+ }
+ getFrameTitle={[Function]}
+ hideLocation={true}
+ isInGroup={true}
+ key="1"
+ panel="webconsole"
+ selectFrame={[MockFunction]}
+ selectLocation={[MockFunction]}
+ selectedFrame={
+ Object {
+ "asyncCause": null,
+ "displayName": "foo",
+ "generatedLocation": Object {
+ "column": undefined,
+ "line": 4,
+ "source": Object {
+ "displayURL": Object {
+ "fileExtension": "",
+ "filename": "url",
+ "group": "",
+ "path": "url",
+ "search": "",
+ },
+ "extensionName": null,
+ "id": "source",
+ "isExtension": false,
+ "isOriginal": false,
+ "isPrettyPrinted": false,
+ "isWasm": false,
+ "thread": "FakeThread",
+ "url": "url",
+ },
+ "sourceActor": Object {
+ "actor": "source-actor",
+ "id": "source-actor",
+ "source": "source",
+ "sourceObject": Object {
+ "displayURL": Object {
+ "fileExtension": "",
+ "filename": "url",
+ "group": "",
+ "path": "url",
+ "search": "",
+ },
+ "extensionName": null,
+ "id": "source",
+ "isExtension": false,
+ "isOriginal": false,
+ "isPrettyPrinted": false,
+ "isWasm": false,
+ "thread": "FakeThread",
+ "url": "url",
+ },
+ },
+ "sourceActorId": "source-actor",
+ },
+ "id": "frame",
+ "index": 0,
+ "library": "Back",
+ "location": Object {
+ "column": undefined,
+ "line": 4,
+ "source": Object {
+ "displayURL": Object {
+ "fileExtension": "",
+ "filename": "url",
+ "group": "",
+ "path": "url",
+ "search": "",
+ },
+ "extensionName": null,
+ "id": "source",
+ "isExtension": false,
+ "isOriginal": false,
+ "isPrettyPrinted": false,
+ "isWasm": false,
+ "thread": "FakeThread",
+ "url": "url",
+ },
+ "sourceActor": Object {
+ "actor": "source-actor",
+ "id": "source-actor",
+ "source": "source",
+ "sourceObject": Object {
+ "displayURL": Object {
+ "fileExtension": "",
+ "filename": "url",
+ "group": "",
+ "path": "url",
+ "search": "",
+ },
+ "extensionName": null,
+ "id": "source",
+ "isExtension": false,
+ "isOriginal": false,
+ "isPrettyPrinted": false,
+ "isWasm": false,
+ "thread": "FakeThread",
+ "url": "url",
+ },
+ },
+ "sourceActorId": "source-actor",
+ },
+ "scope": Object {
+ "actor": "scope-actor",
+ "bindings": Object {
+ "arguments": Array [],
+ "variables": Object {},
+ },
+ "function": null,
+ "object": null,
+ "parent": null,
+ "scopeKind": "",
+ "type": "block",
+ },
+ "source": Object {
+ "displayURL": Object {
+ "fileExtension": "",
+ "filename": "url",
+ "group": "",
+ "path": "url",
+ "search": "",
+ },
+ "extensionName": null,
+ "id": "source",
+ "isExtension": false,
+ "isOriginal": false,
+ "isPrettyPrinted": false,
+ "isWasm": false,
+ "thread": "FakeThread",
+ "url": "url",
+ },
+ "state": "on-stack",
+ "this": Object {},
+ "thread": "FakeThread",
+ "type": "call",
+ }
+ }
+ shouldMapDisplayName={false}
+ />
+ <Frame
+ disableContextMenu={false}
+ displayFullUrl={false}
+ frame={
+ Object {
+ "asyncCause": null,
+ "displayName": "a",
+ "generatedLocation": Object {
+ "column": undefined,
+ "line": 55,
+ "source": Object {
+ "displayURL": Object {
+ "fileExtension": "js",
+ "filename": "back.js",
+ "group": "myfile.com",
+ "path": "/back.js",
+ "search": "",
+ },
+ "extensionName": null,
+ "id": "source",
+ "isExtension": false,
+ "isOriginal": false,
+ "isPrettyPrinted": false,
+ "isWasm": false,
+ "thread": "FakeThread",
+ "url": "http://myfile.com/back.js",
+ },
+ "sourceActor": Object {
+ "actor": "source-actor",
+ "id": "source-actor",
+ "source": "source",
+ "sourceObject": Object {
+ "displayURL": Object {
+ "fileExtension": "js",
+ "filename": "back.js",
+ "group": "myfile.com",
+ "path": "/back.js",
+ "search": "",
+ },
+ "extensionName": null,
+ "id": "source",
+ "isExtension": false,
+ "isOriginal": false,
+ "isPrettyPrinted": false,
+ "isWasm": false,
+ "thread": "FakeThread",
+ "url": "http://myfile.com/back.js",
+ },
+ },
+ "sourceActorId": "source-actor",
+ },
+ "id": "2",
+ "index": 0,
+ "library": "Back",
+ "location": Object {
+ "column": undefined,
+ "line": 55,
+ "source": Object {
+ "displayURL": Object {
+ "fileExtension": "js",
+ "filename": "back.js",
+ "group": "myfile.com",
+ "path": "/back.js",
+ "search": "",
+ },
+ "extensionName": null,
+ "id": "source",
+ "isExtension": false,
+ "isOriginal": false,
+ "isPrettyPrinted": false,
+ "isWasm": false,
+ "thread": "FakeThread",
+ "url": "http://myfile.com/back.js",
+ },
+ "sourceActor": Object {
+ "actor": "source-actor",
+ "id": "source-actor",
+ "source": "source",
+ "sourceObject": Object {
+ "displayURL": Object {
+ "fileExtension": "js",
+ "filename": "back.js",
+ "group": "myfile.com",
+ "path": "/back.js",
+ "search": "",
+ },
+ "extensionName": null,
+ "id": "source",
+ "isExtension": false,
+ "isOriginal": false,
+ "isPrettyPrinted": false,
+ "isWasm": false,
+ "thread": "FakeThread",
+ "url": "http://myfile.com/back.js",
+ },
+ },
+ "sourceActorId": "source-actor",
+ },
+ "scope": Object {
+ "actor": "scope-actor",
+ "bindings": Object {
+ "arguments": Array [],
+ "variables": Object {},
+ },
+ "function": null,
+ "object": null,
+ "parent": null,
+ "scopeKind": "",
+ "type": "block",
+ },
+ "source": Object {
+ "displayURL": Object {
+ "fileExtension": "js",
+ "filename": "back.js",
+ "group": "myfile.com",
+ "path": "/back.js",
+ "search": "",
+ },
+ "extensionName": null,
+ "id": "source",
+ "isExtension": false,
+ "isOriginal": false,
+ "isPrettyPrinted": false,
+ "isWasm": false,
+ "thread": "FakeThread",
+ "url": "http://myfile.com/back.js",
+ },
+ "state": "on-stack",
+ "this": Object {},
+ "thread": "FakeThread",
+ "type": "call",
+ }
+ }
+ getFrameTitle={[Function]}
+ hideLocation={true}
+ isInGroup={true}
+ key="2"
+ panel="webconsole"
+ selectFrame={[MockFunction]}
+ selectLocation={[MockFunction]}
+ selectedFrame={
+ Object {
+ "asyncCause": null,
+ "displayName": "foo",
+ "generatedLocation": Object {
+ "column": undefined,
+ "line": 4,
+ "source": Object {
+ "displayURL": Object {
+ "fileExtension": "",
+ "filename": "url",
+ "group": "",
+ "path": "url",
+ "search": "",
+ },
+ "extensionName": null,
+ "id": "source",
+ "isExtension": false,
+ "isOriginal": false,
+ "isPrettyPrinted": false,
+ "isWasm": false,
+ "thread": "FakeThread",
+ "url": "url",
+ },
+ "sourceActor": Object {
+ "actor": "source-actor",
+ "id": "source-actor",
+ "source": "source",
+ "sourceObject": Object {
+ "displayURL": Object {
+ "fileExtension": "",
+ "filename": "url",
+ "group": "",
+ "path": "url",
+ "search": "",
+ },
+ "extensionName": null,
+ "id": "source",
+ "isExtension": false,
+ "isOriginal": false,
+ "isPrettyPrinted": false,
+ "isWasm": false,
+ "thread": "FakeThread",
+ "url": "url",
+ },
+ },
+ "sourceActorId": "source-actor",
+ },
+ "id": "frame",
+ "index": 0,
+ "library": "Back",
+ "location": Object {
+ "column": undefined,
+ "line": 4,
+ "source": Object {
+ "displayURL": Object {
+ "fileExtension": "",
+ "filename": "url",
+ "group": "",
+ "path": "url",
+ "search": "",
+ },
+ "extensionName": null,
+ "id": "source",
+ "isExtension": false,
+ "isOriginal": false,
+ "isPrettyPrinted": false,
+ "isWasm": false,
+ "thread": "FakeThread",
+ "url": "url",
+ },
+ "sourceActor": Object {
+ "actor": "source-actor",
+ "id": "source-actor",
+ "source": "source",
+ "sourceObject": Object {
+ "displayURL": Object {
+ "fileExtension": "",
+ "filename": "url",
+ "group": "",
+ "path": "url",
+ "search": "",
+ },
+ "extensionName": null,
+ "id": "source",
+ "isExtension": false,
+ "isOriginal": false,
+ "isPrettyPrinted": false,
+ "isWasm": false,
+ "thread": "FakeThread",
+ "url": "url",
+ },
+ },
+ "sourceActorId": "source-actor",
+ },
+ "scope": Object {
+ "actor": "scope-actor",
+ "bindings": Object {
+ "arguments": Array [],
+ "variables": Object {},
+ },
+ "function": null,
+ "object": null,
+ "parent": null,
+ "scopeKind": "",
+ "type": "block",
+ },
+ "source": Object {
+ "displayURL": Object {
+ "fileExtension": "",
+ "filename": "url",
+ "group": "",
+ "path": "url",
+ "search": "",
+ },
+ "extensionName": null,
+ "id": "source",
+ "isExtension": false,
+ "isOriginal": false,
+ "isPrettyPrinted": false,
+ "isWasm": false,
+ "thread": "FakeThread",
+ "url": "url",
+ },
+ "state": "on-stack",
+ "this": Object {},
+ "thread": "FakeThread",
+ "type": "call",
+ }
+ }
+ shouldMapDisplayName={false}
+ />
+ <Frame
+ disableContextMenu={false}
+ displayFullUrl={false}
+ frame={
+ Object {
+ "asyncCause": null,
+ "displayName": "b",
+ "generatedLocation": Object {
+ "column": undefined,
+ "line": 55,
+ "source": Object {
+ "displayURL": Object {
+ "fileExtension": "js",
+ "filename": "back.js",
+ "group": "myfile.com",
+ "path": "/back.js",
+ "search": "",
+ },
+ "extensionName": null,
+ "id": "source",
+ "isExtension": false,
+ "isOriginal": false,
+ "isPrettyPrinted": false,
+ "isWasm": false,
+ "thread": "FakeThread",
+ "url": "http://myfile.com/back.js",
+ },
+ "sourceActor": Object {
+ "actor": "source-actor",
+ "id": "source-actor",
+ "source": "source",
+ "sourceObject": Object {
+ "displayURL": Object {
+ "fileExtension": "js",
+ "filename": "back.js",
+ "group": "myfile.com",
+ "path": "/back.js",
+ "search": "",
+ },
+ "extensionName": null,
+ "id": "source",
+ "isExtension": false,
+ "isOriginal": false,
+ "isPrettyPrinted": false,
+ "isWasm": false,
+ "thread": "FakeThread",
+ "url": "http://myfile.com/back.js",
+ },
+ },
+ "sourceActorId": "source-actor",
+ },
+ "id": "3",
+ "index": 0,
+ "library": "Back",
+ "location": Object {
+ "column": undefined,
+ "line": 55,
+ "source": Object {
+ "displayURL": Object {
+ "fileExtension": "js",
+ "filename": "back.js",
+ "group": "myfile.com",
+ "path": "/back.js",
+ "search": "",
+ },
+ "extensionName": null,
+ "id": "source",
+ "isExtension": false,
+ "isOriginal": false,
+ "isPrettyPrinted": false,
+ "isWasm": false,
+ "thread": "FakeThread",
+ "url": "http://myfile.com/back.js",
+ },
+ "sourceActor": Object {
+ "actor": "source-actor",
+ "id": "source-actor",
+ "source": "source",
+ "sourceObject": Object {
+ "displayURL": Object {
+ "fileExtension": "js",
+ "filename": "back.js",
+ "group": "myfile.com",
+ "path": "/back.js",
+ "search": "",
+ },
+ "extensionName": null,
+ "id": "source",
+ "isExtension": false,
+ "isOriginal": false,
+ "isPrettyPrinted": false,
+ "isWasm": false,
+ "thread": "FakeThread",
+ "url": "http://myfile.com/back.js",
+ },
+ },
+ "sourceActorId": "source-actor",
+ },
+ "scope": Object {
+ "actor": "scope-actor",
+ "bindings": Object {
+ "arguments": Array [],
+ "variables": Object {},
+ },
+ "function": null,
+ "object": null,
+ "parent": null,
+ "scopeKind": "",
+ "type": "block",
+ },
+ "source": Object {
+ "displayURL": Object {
+ "fileExtension": "js",
+ "filename": "back.js",
+ "group": "myfile.com",
+ "path": "/back.js",
+ "search": "",
+ },
+ "extensionName": null,
+ "id": "source",
+ "isExtension": false,
+ "isOriginal": false,
+ "isPrettyPrinted": false,
+ "isWasm": false,
+ "thread": "FakeThread",
+ "url": "http://myfile.com/back.js",
+ },
+ "state": "on-stack",
+ "this": Object {},
+ "thread": "FakeThread",
+ "type": "call",
+ }
+ }
+ getFrameTitle={[Function]}
+ hideLocation={true}
+ isInGroup={true}
+ key="3"
+ panel="webconsole"
+ selectFrame={[MockFunction]}
+ selectLocation={[MockFunction]}
+ selectedFrame={
+ Object {
+ "asyncCause": null,
+ "displayName": "foo",
+ "generatedLocation": Object {
+ "column": undefined,
+ "line": 4,
+ "source": Object {
+ "displayURL": Object {
+ "fileExtension": "",
+ "filename": "url",
+ "group": "",
+ "path": "url",
+ "search": "",
+ },
+ "extensionName": null,
+ "id": "source",
+ "isExtension": false,
+ "isOriginal": false,
+ "isPrettyPrinted": false,
+ "isWasm": false,
+ "thread": "FakeThread",
+ "url": "url",
+ },
+ "sourceActor": Object {
+ "actor": "source-actor",
+ "id": "source-actor",
+ "source": "source",
+ "sourceObject": Object {
+ "displayURL": Object {
+ "fileExtension": "",
+ "filename": "url",
+ "group": "",
+ "path": "url",
+ "search": "",
+ },
+ "extensionName": null,
+ "id": "source",
+ "isExtension": false,
+ "isOriginal": false,
+ "isPrettyPrinted": false,
+ "isWasm": false,
+ "thread": "FakeThread",
+ "url": "url",
+ },
+ },
+ "sourceActorId": "source-actor",
+ },
+ "id": "frame",
+ "index": 0,
+ "library": "Back",
+ "location": Object {
+ "column": undefined,
+ "line": 4,
+ "source": Object {
+ "displayURL": Object {
+ "fileExtension": "",
+ "filename": "url",
+ "group": "",
+ "path": "url",
+ "search": "",
+ },
+ "extensionName": null,
+ "id": "source",
+ "isExtension": false,
+ "isOriginal": false,
+ "isPrettyPrinted": false,
+ "isWasm": false,
+ "thread": "FakeThread",
+ "url": "url",
+ },
+ "sourceActor": Object {
+ "actor": "source-actor",
+ "id": "source-actor",
+ "source": "source",
+ "sourceObject": Object {
+ "displayURL": Object {
+ "fileExtension": "",
+ "filename": "url",
+ "group": "",
+ "path": "url",
+ "search": "",
+ },
+ "extensionName": null,
+ "id": "source",
+ "isExtension": false,
+ "isOriginal": false,
+ "isPrettyPrinted": false,
+ "isWasm": false,
+ "thread": "FakeThread",
+ "url": "url",
+ },
+ },
+ "sourceActorId": "source-actor",
+ },
+ "scope": Object {
+ "actor": "scope-actor",
+ "bindings": Object {
+ "arguments": Array [],
+ "variables": Object {},
+ },
+ "function": null,
+ "object": null,
+ "parent": null,
+ "scopeKind": "",
+ "type": "block",
+ },
+ "source": Object {
+ "displayURL": Object {
+ "fileExtension": "",
+ "filename": "url",
+ "group": "",
+ "path": "url",
+ "search": "",
+ },
+ "extensionName": null,
+ "id": "source",
+ "isExtension": false,
+ "isOriginal": false,
+ "isPrettyPrinted": false,
+ "isWasm": false,
+ "thread": "FakeThread",
+ "url": "url",
+ },
+ "state": "on-stack",
+ "this": Object {},
+ "thread": "FakeThread",
+ "type": "call",
+ }
+ }
+ shouldMapDisplayName={false}
+ />
+ </div>
+</div>
+`;
+
+exports[`Group renders group with anonymous functions 1`] = `
+<div
+ className="frames-group"
+ onContextMenu={[Function]}
+>
+ <div
+ className="group"
+ key="1"
+ onClick={[Function]}
+ role="listitem"
+ tabIndex={0}
+ title="Show Back frames"
+ >
+ <FrameIndent />
+ <FrameLocation
+ expanded={false}
+ frame={
+ Object {
+ "asyncCause": null,
+ "displayName": "display-1",
+ "generatedLocation": Object {
+ "column": undefined,
+ "line": 55,
+ "source": Object {
+ "displayURL": Object {
+ "fileExtension": "js",
+ "filename": "mahscripts.js",
+ "group": "myfile.com",
+ "path": "/mahscripts.js",
+ "search": "",
+ },
+ "extensionName": null,
+ "id": "source",
+ "isExtension": false,
+ "isOriginal": false,
+ "isPrettyPrinted": false,
+ "isWasm": false,
+ "thread": "FakeThread",
+ "url": "http://myfile.com/mahscripts.js",
+ },
+ "sourceActor": Object {
+ "actor": "source-actor",
+ "id": "source-actor",
+ "source": "source",
+ "sourceObject": Object {
+ "displayURL": Object {
+ "fileExtension": "js",
+ "filename": "mahscripts.js",
+ "group": "myfile.com",
+ "path": "/mahscripts.js",
+ "search": "",
+ },
+ "extensionName": null,
+ "id": "source",
+ "isExtension": false,
+ "isOriginal": false,
+ "isPrettyPrinted": false,
+ "isWasm": false,
+ "thread": "FakeThread",
+ "url": "http://myfile.com/mahscripts.js",
+ },
+ },
+ "sourceActorId": "source-actor",
+ },
+ "id": "1",
+ "index": 0,
+ "library": "Back",
+ "location": Object {
+ "column": undefined,
+ "line": 55,
+ "source": Object {
+ "displayURL": Object {
+ "fileExtension": "js",
+ "filename": "mahscripts.js",
+ "group": "myfile.com",
+ "path": "/mahscripts.js",
+ "search": "",
+ },
+ "extensionName": null,
+ "id": "source",
+ "isExtension": false,
+ "isOriginal": false,
+ "isPrettyPrinted": false,
+ "isWasm": false,
+ "thread": "FakeThread",
+ "url": "http://myfile.com/mahscripts.js",
+ },
+ "sourceActor": Object {
+ "actor": "source-actor",
+ "id": "source-actor",
+ "source": "source",
+ "sourceObject": Object {
+ "displayURL": Object {
+ "fileExtension": "js",
+ "filename": "mahscripts.js",
+ "group": "myfile.com",
+ "path": "/mahscripts.js",
+ "search": "",
+ },
+ "extensionName": null,
+ "id": "source",
+ "isExtension": false,
+ "isOriginal": false,
+ "isPrettyPrinted": false,
+ "isWasm": false,
+ "thread": "FakeThread",
+ "url": "http://myfile.com/mahscripts.js",
+ },
+ },
+ "sourceActorId": "source-actor",
+ },
+ "scope": Object {
+ "actor": "scope-actor",
+ "bindings": Object {
+ "arguments": Array [],
+ "variables": Object {},
+ },
+ "function": null,
+ "object": null,
+ "parent": null,
+ "scopeKind": "",
+ "type": "block",
+ },
+ "source": Object {
+ "displayURL": Object {
+ "fileExtension": "js",
+ "filename": "mahscripts.js",
+ "group": "myfile.com",
+ "path": "/mahscripts.js",
+ "search": "",
+ },
+ "extensionName": null,
+ "id": "source",
+ "isExtension": false,
+ "isOriginal": false,
+ "isPrettyPrinted": false,
+ "isWasm": false,
+ "thread": "FakeThread",
+ "url": "http://myfile.com/mahscripts.js",
+ },
+ "state": "on-stack",
+ "this": Object {},
+ "thread": "FakeThread",
+ "type": "call",
+ }
+ }
+ />
+ <span
+ className="clipboard-only"
+ >
+
+ </span>
+ <Badge
+ badgeText={3}
+ />
+ <br
+ className="clipboard-only"
+ />
+ </div>
+</div>
+`;
+
+exports[`Group renders group with anonymous functions 2`] = `
+<div
+ className="frames-group expanded"
+ onContextMenu={[Function]}
+>
+ <div
+ className="group"
+ key="1"
+ onClick={[Function]}
+ role="listitem"
+ tabIndex={0}
+ title="Collapse Back frames"
+ >
+ <FrameIndent />
+ <FrameLocation
+ expanded={true}
+ frame={
+ Object {
+ "asyncCause": null,
+ "displayName": "display-1",
+ "generatedLocation": Object {
+ "column": undefined,
+ "line": 55,
+ "source": Object {
+ "displayURL": Object {
+ "fileExtension": "js",
+ "filename": "mahscripts.js",
+ "group": "myfile.com",
+ "path": "/mahscripts.js",
+ "search": "",
+ },
+ "extensionName": null,
+ "id": "source",
+ "isExtension": false,
+ "isOriginal": false,
+ "isPrettyPrinted": false,
+ "isWasm": false,
+ "thread": "FakeThread",
+ "url": "http://myfile.com/mahscripts.js",
+ },
+ "sourceActor": Object {
+ "actor": "source-actor",
+ "id": "source-actor",
+ "source": "source",
+ "sourceObject": Object {
+ "displayURL": Object {
+ "fileExtension": "js",
+ "filename": "mahscripts.js",
+ "group": "myfile.com",
+ "path": "/mahscripts.js",
+ "search": "",
+ },
+ "extensionName": null,
+ "id": "source",
+ "isExtension": false,
+ "isOriginal": false,
+ "isPrettyPrinted": false,
+ "isWasm": false,
+ "thread": "FakeThread",
+ "url": "http://myfile.com/mahscripts.js",
+ },
+ },
+ "sourceActorId": "source-actor",
+ },
+ "id": "1",
+ "index": 0,
+ "library": "Back",
+ "location": Object {
+ "column": undefined,
+ "line": 55,
+ "source": Object {
+ "displayURL": Object {
+ "fileExtension": "js",
+ "filename": "mahscripts.js",
+ "group": "myfile.com",
+ "path": "/mahscripts.js",
+ "search": "",
+ },
+ "extensionName": null,
+ "id": "source",
+ "isExtension": false,
+ "isOriginal": false,
+ "isPrettyPrinted": false,
+ "isWasm": false,
+ "thread": "FakeThread",
+ "url": "http://myfile.com/mahscripts.js",
+ },
+ "sourceActor": Object {
+ "actor": "source-actor",
+ "id": "source-actor",
+ "source": "source",
+ "sourceObject": Object {
+ "displayURL": Object {
+ "fileExtension": "js",
+ "filename": "mahscripts.js",
+ "group": "myfile.com",
+ "path": "/mahscripts.js",
+ "search": "",
+ },
+ "extensionName": null,
+ "id": "source",
+ "isExtension": false,
+ "isOriginal": false,
+ "isPrettyPrinted": false,
+ "isWasm": false,
+ "thread": "FakeThread",
+ "url": "http://myfile.com/mahscripts.js",
+ },
+ },
+ "sourceActorId": "source-actor",
+ },
+ "scope": Object {
+ "actor": "scope-actor",
+ "bindings": Object {
+ "arguments": Array [],
+ "variables": Object {},
+ },
+ "function": null,
+ "object": null,
+ "parent": null,
+ "scopeKind": "",
+ "type": "block",
+ },
+ "source": Object {
+ "displayURL": Object {
+ "fileExtension": "js",
+ "filename": "mahscripts.js",
+ "group": "myfile.com",
+ "path": "/mahscripts.js",
+ "search": "",
+ },
+ "extensionName": null,
+ "id": "source",
+ "isExtension": false,
+ "isOriginal": false,
+ "isPrettyPrinted": false,
+ "isWasm": false,
+ "thread": "FakeThread",
+ "url": "http://myfile.com/mahscripts.js",
+ },
+ "state": "on-stack",
+ "this": Object {},
+ "thread": "FakeThread",
+ "type": "call",
+ }
+ }
+ />
+ <span
+ className="clipboard-only"
+ >
+
+ </span>
+ <Badge
+ badgeText={3}
+ />
+ <br
+ className="clipboard-only"
+ />
+ </div>
+ <div
+ className="frames-list"
+ >
+ <Frame
+ disableContextMenu={false}
+ displayFullUrl={false}
+ frame={
+ Object {
+ "asyncCause": null,
+ "displayName": "display-1",
+ "generatedLocation": Object {
+ "column": undefined,
+ "line": 55,
+ "source": Object {
+ "displayURL": Object {
+ "fileExtension": "js",
+ "filename": "mahscripts.js",
+ "group": "myfile.com",
+ "path": "/mahscripts.js",
+ "search": "",
+ },
+ "extensionName": null,
+ "id": "source",
+ "isExtension": false,
+ "isOriginal": false,
+ "isPrettyPrinted": false,
+ "isWasm": false,
+ "thread": "FakeThread",
+ "url": "http://myfile.com/mahscripts.js",
+ },
+ "sourceActor": Object {
+ "actor": "source-actor",
+ "id": "source-actor",
+ "source": "source",
+ "sourceObject": Object {
+ "displayURL": Object {
+ "fileExtension": "js",
+ "filename": "mahscripts.js",
+ "group": "myfile.com",
+ "path": "/mahscripts.js",
+ "search": "",
+ },
+ "extensionName": null,
+ "id": "source",
+ "isExtension": false,
+ "isOriginal": false,
+ "isPrettyPrinted": false,
+ "isWasm": false,
+ "thread": "FakeThread",
+ "url": "http://myfile.com/mahscripts.js",
+ },
+ },
+ "sourceActorId": "source-actor",
+ },
+ "id": "1",
+ "index": 0,
+ "library": "Back",
+ "location": Object {
+ "column": undefined,
+ "line": 55,
+ "source": Object {
+ "displayURL": Object {
+ "fileExtension": "js",
+ "filename": "mahscripts.js",
+ "group": "myfile.com",
+ "path": "/mahscripts.js",
+ "search": "",
+ },
+ "extensionName": null,
+ "id": "source",
+ "isExtension": false,
+ "isOriginal": false,
+ "isPrettyPrinted": false,
+ "isWasm": false,
+ "thread": "FakeThread",
+ "url": "http://myfile.com/mahscripts.js",
+ },
+ "sourceActor": Object {
+ "actor": "source-actor",
+ "id": "source-actor",
+ "source": "source",
+ "sourceObject": Object {
+ "displayURL": Object {
+ "fileExtension": "js",
+ "filename": "mahscripts.js",
+ "group": "myfile.com",
+ "path": "/mahscripts.js",
+ "search": "",
+ },
+ "extensionName": null,
+ "id": "source",
+ "isExtension": false,
+ "isOriginal": false,
+ "isPrettyPrinted": false,
+ "isWasm": false,
+ "thread": "FakeThread",
+ "url": "http://myfile.com/mahscripts.js",
+ },
+ },
+ "sourceActorId": "source-actor",
+ },
+ "scope": Object {
+ "actor": "scope-actor",
+ "bindings": Object {
+ "arguments": Array [],
+ "variables": Object {},
+ },
+ "function": null,
+ "object": null,
+ "parent": null,
+ "scopeKind": "",
+ "type": "block",
+ },
+ "source": Object {
+ "displayURL": Object {
+ "fileExtension": "js",
+ "filename": "mahscripts.js",
+ "group": "myfile.com",
+ "path": "/mahscripts.js",
+ "search": "",
+ },
+ "extensionName": null,
+ "id": "source",
+ "isExtension": false,
+ "isOriginal": false,
+ "isPrettyPrinted": false,
+ "isWasm": false,
+ "thread": "FakeThread",
+ "url": "http://myfile.com/mahscripts.js",
+ },
+ "state": "on-stack",
+ "this": Object {},
+ "thread": "FakeThread",
+ "type": "call",
+ }
+ }
+ hideLocation={true}
+ isInGroup={true}
+ key="1"
+ panel="webconsole"
+ selectFrame={[MockFunction]}
+ selectLocation={[MockFunction]}
+ selectedFrame={
+ Object {
+ "asyncCause": null,
+ "displayName": "foo",
+ "generatedLocation": Object {
+ "column": undefined,
+ "line": 4,
+ "source": Object {
+ "displayURL": Object {
+ "fileExtension": "",
+ "filename": "url",
+ "group": "",
+ "path": "url",
+ "search": "",
+ },
+ "extensionName": null,
+ "id": "source",
+ "isExtension": false,
+ "isOriginal": false,
+ "isPrettyPrinted": false,
+ "isWasm": false,
+ "thread": "FakeThread",
+ "url": "url",
+ },
+ "sourceActor": Object {
+ "actor": "source-actor",
+ "id": "source-actor",
+ "source": "source",
+ "sourceObject": Object {
+ "displayURL": Object {
+ "fileExtension": "",
+ "filename": "url",
+ "group": "",
+ "path": "url",
+ "search": "",
+ },
+ "extensionName": null,
+ "id": "source",
+ "isExtension": false,
+ "isOriginal": false,
+ "isPrettyPrinted": false,
+ "isWasm": false,
+ "thread": "FakeThread",
+ "url": "url",
+ },
+ },
+ "sourceActorId": "source-actor",
+ },
+ "id": "frame",
+ "index": 0,
+ "library": "Back",
+ "location": Object {
+ "column": undefined,
+ "line": 4,
+ "source": Object {
+ "displayURL": Object {
+ "fileExtension": "",
+ "filename": "url",
+ "group": "",
+ "path": "url",
+ "search": "",
+ },
+ "extensionName": null,
+ "id": "source",
+ "isExtension": false,
+ "isOriginal": false,
+ "isPrettyPrinted": false,
+ "isWasm": false,
+ "thread": "FakeThread",
+ "url": "url",
+ },
+ "sourceActor": Object {
+ "actor": "source-actor",
+ "id": "source-actor",
+ "source": "source",
+ "sourceObject": Object {
+ "displayURL": Object {
+ "fileExtension": "",
+ "filename": "url",
+ "group": "",
+ "path": "url",
+ "search": "",
+ },
+ "extensionName": null,
+ "id": "source",
+ "isExtension": false,
+ "isOriginal": false,
+ "isPrettyPrinted": false,
+ "isWasm": false,
+ "thread": "FakeThread",
+ "url": "url",
+ },
+ },
+ "sourceActorId": "source-actor",
+ },
+ "scope": Object {
+ "actor": "scope-actor",
+ "bindings": Object {
+ "arguments": Array [],
+ "variables": Object {},
+ },
+ "function": null,
+ "object": null,
+ "parent": null,
+ "scopeKind": "",
+ "type": "block",
+ },
+ "source": Object {
+ "displayURL": Object {
+ "fileExtension": "",
+ "filename": "url",
+ "group": "",
+ "path": "url",
+ "search": "",
+ },
+ "extensionName": null,
+ "id": "source",
+ "isExtension": false,
+ "isOriginal": false,
+ "isPrettyPrinted": false,
+ "isWasm": false,
+ "thread": "FakeThread",
+ "url": "url",
+ },
+ "state": "on-stack",
+ "this": Object {},
+ "thread": "FakeThread",
+ "type": "call",
+ }
+ }
+ shouldMapDisplayName={false}
+ />
+ <Frame
+ disableContextMenu={false}
+ displayFullUrl={false}
+ frame={
+ Object {
+ "asyncCause": null,
+ "displayName": "display-2",
+ "generatedLocation": Object {
+ "column": undefined,
+ "line": 55,
+ "source": Object {
+ "displayURL": Object {
+ "fileExtension": "js",
+ "filename": "back.js",
+ "group": "myfile.com",
+ "path": "/back.js",
+ "search": "",
+ },
+ "extensionName": null,
+ "id": "source",
+ "isExtension": false,
+ "isOriginal": false,
+ "isPrettyPrinted": false,
+ "isWasm": false,
+ "thread": "FakeThread",
+ "url": "http://myfile.com/back.js",
+ },
+ "sourceActor": Object {
+ "actor": "source-actor",
+ "id": "source-actor",
+ "source": "source",
+ "sourceObject": Object {
+ "displayURL": Object {
+ "fileExtension": "js",
+ "filename": "back.js",
+ "group": "myfile.com",
+ "path": "/back.js",
+ "search": "",
+ },
+ "extensionName": null,
+ "id": "source",
+ "isExtension": false,
+ "isOriginal": false,
+ "isPrettyPrinted": false,
+ "isWasm": false,
+ "thread": "FakeThread",
+ "url": "http://myfile.com/back.js",
+ },
+ },
+ "sourceActorId": "source-actor",
+ },
+ "id": "2",
+ "index": 0,
+ "library": "Back",
+ "location": Object {
+ "column": undefined,
+ "line": 55,
+ "source": Object {
+ "displayURL": Object {
+ "fileExtension": "js",
+ "filename": "back.js",
+ "group": "myfile.com",
+ "path": "/back.js",
+ "search": "",
+ },
+ "extensionName": null,
+ "id": "source",
+ "isExtension": false,
+ "isOriginal": false,
+ "isPrettyPrinted": false,
+ "isWasm": false,
+ "thread": "FakeThread",
+ "url": "http://myfile.com/back.js",
+ },
+ "sourceActor": Object {
+ "actor": "source-actor",
+ "id": "source-actor",
+ "source": "source",
+ "sourceObject": Object {
+ "displayURL": Object {
+ "fileExtension": "js",
+ "filename": "back.js",
+ "group": "myfile.com",
+ "path": "/back.js",
+ "search": "",
+ },
+ "extensionName": null,
+ "id": "source",
+ "isExtension": false,
+ "isOriginal": false,
+ "isPrettyPrinted": false,
+ "isWasm": false,
+ "thread": "FakeThread",
+ "url": "http://myfile.com/back.js",
+ },
+ },
+ "sourceActorId": "source-actor",
+ },
+ "scope": Object {
+ "actor": "scope-actor",
+ "bindings": Object {
+ "arguments": Array [],
+ "variables": Object {},
+ },
+ "function": null,
+ "object": null,
+ "parent": null,
+ "scopeKind": "",
+ "type": "block",
+ },
+ "source": Object {
+ "displayURL": Object {
+ "fileExtension": "js",
+ "filename": "back.js",
+ "group": "myfile.com",
+ "path": "/back.js",
+ "search": "",
+ },
+ "extensionName": null,
+ "id": "source",
+ "isExtension": false,
+ "isOriginal": false,
+ "isPrettyPrinted": false,
+ "isWasm": false,
+ "thread": "FakeThread",
+ "url": "http://myfile.com/back.js",
+ },
+ "state": "on-stack",
+ "this": Object {},
+ "thread": "FakeThread",
+ "type": "call",
+ }
+ }
+ hideLocation={true}
+ isInGroup={true}
+ key="2"
+ panel="webconsole"
+ selectFrame={[MockFunction]}
+ selectLocation={[MockFunction]}
+ selectedFrame={
+ Object {
+ "asyncCause": null,
+ "displayName": "foo",
+ "generatedLocation": Object {
+ "column": undefined,
+ "line": 4,
+ "source": Object {
+ "displayURL": Object {
+ "fileExtension": "",
+ "filename": "url",
+ "group": "",
+ "path": "url",
+ "search": "",
+ },
+ "extensionName": null,
+ "id": "source",
+ "isExtension": false,
+ "isOriginal": false,
+ "isPrettyPrinted": false,
+ "isWasm": false,
+ "thread": "FakeThread",
+ "url": "url",
+ },
+ "sourceActor": Object {
+ "actor": "source-actor",
+ "id": "source-actor",
+ "source": "source",
+ "sourceObject": Object {
+ "displayURL": Object {
+ "fileExtension": "",
+ "filename": "url",
+ "group": "",
+ "path": "url",
+ "search": "",
+ },
+ "extensionName": null,
+ "id": "source",
+ "isExtension": false,
+ "isOriginal": false,
+ "isPrettyPrinted": false,
+ "isWasm": false,
+ "thread": "FakeThread",
+ "url": "url",
+ },
+ },
+ "sourceActorId": "source-actor",
+ },
+ "id": "frame",
+ "index": 0,
+ "library": "Back",
+ "location": Object {
+ "column": undefined,
+ "line": 4,
+ "source": Object {
+ "displayURL": Object {
+ "fileExtension": "",
+ "filename": "url",
+ "group": "",
+ "path": "url",
+ "search": "",
+ },
+ "extensionName": null,
+ "id": "source",
+ "isExtension": false,
+ "isOriginal": false,
+ "isPrettyPrinted": false,
+ "isWasm": false,
+ "thread": "FakeThread",
+ "url": "url",
+ },
+ "sourceActor": Object {
+ "actor": "source-actor",
+ "id": "source-actor",
+ "source": "source",
+ "sourceObject": Object {
+ "displayURL": Object {
+ "fileExtension": "",
+ "filename": "url",
+ "group": "",
+ "path": "url",
+ "search": "",
+ },
+ "extensionName": null,
+ "id": "source",
+ "isExtension": false,
+ "isOriginal": false,
+ "isPrettyPrinted": false,
+ "isWasm": false,
+ "thread": "FakeThread",
+ "url": "url",
+ },
+ },
+ "sourceActorId": "source-actor",
+ },
+ "scope": Object {
+ "actor": "scope-actor",
+ "bindings": Object {
+ "arguments": Array [],
+ "variables": Object {},
+ },
+ "function": null,
+ "object": null,
+ "parent": null,
+ "scopeKind": "",
+ "type": "block",
+ },
+ "source": Object {
+ "displayURL": Object {
+ "fileExtension": "",
+ "filename": "url",
+ "group": "",
+ "path": "url",
+ "search": "",
+ },
+ "extensionName": null,
+ "id": "source",
+ "isExtension": false,
+ "isOriginal": false,
+ "isPrettyPrinted": false,
+ "isWasm": false,
+ "thread": "FakeThread",
+ "url": "url",
+ },
+ "state": "on-stack",
+ "this": Object {},
+ "thread": "FakeThread",
+ "type": "call",
+ }
+ }
+ shouldMapDisplayName={false}
+ />
+ <Frame
+ disableContextMenu={false}
+ displayFullUrl={false}
+ frame={
+ Object {
+ "asyncCause": null,
+ "displayName": "display-3",
+ "generatedLocation": Object {
+ "column": undefined,
+ "line": 55,
+ "source": Object {
+ "displayURL": Object {
+ "fileExtension": "js",
+ "filename": "back.js",
+ "group": "myfile.com",
+ "path": "/back.js",
+ "search": "",
+ },
+ "extensionName": null,
+ "id": "source",
+ "isExtension": false,
+ "isOriginal": false,
+ "isPrettyPrinted": false,
+ "isWasm": false,
+ "thread": "FakeThread",
+ "url": "http://myfile.com/back.js",
+ },
+ "sourceActor": Object {
+ "actor": "source-actor",
+ "id": "source-actor",
+ "source": "source",
+ "sourceObject": Object {
+ "displayURL": Object {
+ "fileExtension": "js",
+ "filename": "back.js",
+ "group": "myfile.com",
+ "path": "/back.js",
+ "search": "",
+ },
+ "extensionName": null,
+ "id": "source",
+ "isExtension": false,
+ "isOriginal": false,
+ "isPrettyPrinted": false,
+ "isWasm": false,
+ "thread": "FakeThread",
+ "url": "http://myfile.com/back.js",
+ },
+ },
+ "sourceActorId": "source-actor",
+ },
+ "id": "3",
+ "index": 0,
+ "library": "Back",
+ "location": Object {
+ "column": undefined,
+ "line": 55,
+ "source": Object {
+ "displayURL": Object {
+ "fileExtension": "js",
+ "filename": "back.js",
+ "group": "myfile.com",
+ "path": "/back.js",
+ "search": "",
+ },
+ "extensionName": null,
+ "id": "source",
+ "isExtension": false,
+ "isOriginal": false,
+ "isPrettyPrinted": false,
+ "isWasm": false,
+ "thread": "FakeThread",
+ "url": "http://myfile.com/back.js",
+ },
+ "sourceActor": Object {
+ "actor": "source-actor",
+ "id": "source-actor",
+ "source": "source",
+ "sourceObject": Object {
+ "displayURL": Object {
+ "fileExtension": "js",
+ "filename": "back.js",
+ "group": "myfile.com",
+ "path": "/back.js",
+ "search": "",
+ },
+ "extensionName": null,
+ "id": "source",
+ "isExtension": false,
+ "isOriginal": false,
+ "isPrettyPrinted": false,
+ "isWasm": false,
+ "thread": "FakeThread",
+ "url": "http://myfile.com/back.js",
+ },
+ },
+ "sourceActorId": "source-actor",
+ },
+ "scope": Object {
+ "actor": "scope-actor",
+ "bindings": Object {
+ "arguments": Array [],
+ "variables": Object {},
+ },
+ "function": null,
+ "object": null,
+ "parent": null,
+ "scopeKind": "",
+ "type": "block",
+ },
+ "source": Object {
+ "displayURL": Object {
+ "fileExtension": "js",
+ "filename": "back.js",
+ "group": "myfile.com",
+ "path": "/back.js",
+ "search": "",
+ },
+ "extensionName": null,
+ "id": "source",
+ "isExtension": false,
+ "isOriginal": false,
+ "isPrettyPrinted": false,
+ "isWasm": false,
+ "thread": "FakeThread",
+ "url": "http://myfile.com/back.js",
+ },
+ "state": "on-stack",
+ "this": Object {},
+ "thread": "FakeThread",
+ "type": "call",
+ }
+ }
+ hideLocation={true}
+ isInGroup={true}
+ key="3"
+ panel="webconsole"
+ selectFrame={[MockFunction]}
+ selectLocation={[MockFunction]}
+ selectedFrame={
+ Object {
+ "asyncCause": null,
+ "displayName": "foo",
+ "generatedLocation": Object {
+ "column": undefined,
+ "line": 4,
+ "source": Object {
+ "displayURL": Object {
+ "fileExtension": "",
+ "filename": "url",
+ "group": "",
+ "path": "url",
+ "search": "",
+ },
+ "extensionName": null,
+ "id": "source",
+ "isExtension": false,
+ "isOriginal": false,
+ "isPrettyPrinted": false,
+ "isWasm": false,
+ "thread": "FakeThread",
+ "url": "url",
+ },
+ "sourceActor": Object {
+ "actor": "source-actor",
+ "id": "source-actor",
+ "source": "source",
+ "sourceObject": Object {
+ "displayURL": Object {
+ "fileExtension": "",
+ "filename": "url",
+ "group": "",
+ "path": "url",
+ "search": "",
+ },
+ "extensionName": null,
+ "id": "source",
+ "isExtension": false,
+ "isOriginal": false,
+ "isPrettyPrinted": false,
+ "isWasm": false,
+ "thread": "FakeThread",
+ "url": "url",
+ },
+ },
+ "sourceActorId": "source-actor",
+ },
+ "id": "frame",
+ "index": 0,
+ "library": "Back",
+ "location": Object {
+ "column": undefined,
+ "line": 4,
+ "source": Object {
+ "displayURL": Object {
+ "fileExtension": "",
+ "filename": "url",
+ "group": "",
+ "path": "url",
+ "search": "",
+ },
+ "extensionName": null,
+ "id": "source",
+ "isExtension": false,
+ "isOriginal": false,
+ "isPrettyPrinted": false,
+ "isWasm": false,
+ "thread": "FakeThread",
+ "url": "url",
+ },
+ "sourceActor": Object {
+ "actor": "source-actor",
+ "id": "source-actor",
+ "source": "source",
+ "sourceObject": Object {
+ "displayURL": Object {
+ "fileExtension": "",
+ "filename": "url",
+ "group": "",
+ "path": "url",
+ "search": "",
+ },
+ "extensionName": null,
+ "id": "source",
+ "isExtension": false,
+ "isOriginal": false,
+ "isPrettyPrinted": false,
+ "isWasm": false,
+ "thread": "FakeThread",
+ "url": "url",
+ },
+ },
+ "sourceActorId": "source-actor",
+ },
+ "scope": Object {
+ "actor": "scope-actor",
+ "bindings": Object {
+ "arguments": Array [],
+ "variables": Object {},
+ },
+ "function": null,
+ "object": null,
+ "parent": null,
+ "scopeKind": "",
+ "type": "block",
+ },
+ "source": Object {
+ "displayURL": Object {
+ "fileExtension": "",
+ "filename": "url",
+ "group": "",
+ "path": "url",
+ "search": "",
+ },
+ "extensionName": null,
+ "id": "source",
+ "isExtension": false,
+ "isOriginal": false,
+ "isPrettyPrinted": false,
+ "isWasm": false,
+ "thread": "FakeThread",
+ "url": "url",
+ },
+ "state": "on-stack",
+ "this": Object {},
+ "thread": "FakeThread",
+ "type": "call",
+ }
+ }
+ shouldMapDisplayName={false}
+ />
+ </div>
+</div>
+`;