Skip to content

Commit

Permalink
Add an additional test to check for the resource in the flamegraph to…
Browse files Browse the repository at this point in the history
…oltip
  • Loading branch information
julienw committed Oct 19, 2020
1 parent a66b4a5 commit acee7b6
Show file tree
Hide file tree
Showing 2 changed files with 223 additions and 13 deletions.
50 changes: 38 additions & 12 deletions src/test/components/FlameGraph.test.js
Expand Up @@ -4,7 +4,7 @@

// @flow
import * as React from 'react';
import { render, fireEvent } from '@testing-library/react';
import { render, fireEvent, within } from '@testing-library/react';
import { Provider } from 'react-redux';

// This module is mocked.
Expand All @@ -22,6 +22,7 @@ import {
getMouseEvent,
fireFullClick,
fireFullContextMenu,
findFillTextPositionFromDrawLog,
} from '../fixtures/utils';
import { getProfileFromTextSamples } from '../fixtures/profiles/processed-profile';
import {
Expand Down Expand Up @@ -71,18 +72,32 @@ describe('FlameGraph', function() {
});

it('shows a tooltip when hovering', () => {
const { getTooltip, moveMouse } = setupFlameGraph();
const { getTooltip, moveMouse, findFillTextPosition } = setupFlameGraph();
expect(getTooltip()).toBe(null);
moveMouse(GRAPH_WIDTH * 0.5, GRAPH_HEIGHT - 3);
moveMouse(findFillTextPosition('A'));
expect(getTooltip()).toBeTruthy();
});

it('has a tooltip that matches the snapshot', () => {
const { getTooltip, moveMouse } = setupFlameGraph();
moveMouse(GRAPH_WIDTH * 0.5, GRAPH_HEIGHT - 3);
const { getTooltip, moveMouse, findFillTextPosition } = setupFlameGraph();
moveMouse(findFillTextPosition('A'));
expect(getTooltip()).toMatchSnapshot();
});

it('shows a tooltip with the resource information', () => {
const { getTooltip, moveMouse, findFillTextPosition } = setupFlameGraph();
moveMouse(findFillTextPosition('J'));
const tooltip = ensureExists(getTooltip());

// First, a targeted test.
const { getByText } = within(tooltip);
const resourceLabel = getByText('Resource:');
const valueElement = ensureExists(resourceLabel.nextSibling);
expect(valueElement.textContent).toBe('libxul.so');
// But also do a good old snapshot.
expect(tooltip).toMatchSnapshot();
});

it('can be navigated with the keyboard', () => {
const { getState, dispatch, getContentDiv, funcNames } = setupFlameGraph();
const div = getContentDiv();
Expand Down Expand Up @@ -119,17 +134,22 @@ describe('FlameGraph', function() {
// Fake timers are indicated when dealing with the context menus.
jest.useFakeTimers();

const { rightClick, clickMenuItem, getContextMenu } = setupFlameGraph();
const {
rightClick,
clickMenuItem,
getContextMenu,
findFillTextPosition,
} = setupFlameGraph();

rightClick(GRAPH_WIDTH * 0.5, GRAPH_HEIGHT - 3);
rightClick(findFillTextPosition('A'));
expect(getContextMenu()).toHaveClass('react-contextmenu--visible');
clickMenuItem('Copy function name');
expect(copy).toHaveBeenLastCalledWith('A');

jest.runAllTimers();

// Try another node to make sure the menu can handle other nodes than the first.
rightClick(GRAPH_WIDTH * 0.5, GRAPH_HEIGHT - 25);
rightClick(findFillTextPosition('B'));
expect(getContextMenu()).toHaveClass('react-contextmenu--visible');
clickMenuItem('Copy function name');
expect(copy).toHaveBeenLastCalledWith('B');
Expand Down Expand Up @@ -189,6 +209,7 @@ function setupFlameGraph() {
C[cat:Graphics] C[cat:Graphics] H[cat:Network]
D[cat:Graphics] F[cat:Graphics] I[cat:Network]
E[cat:Graphics] G[cat:Graphics]
J[lib:libxul.so]
`);

// Add some file and line number to the profile so that tooltips generate
Expand Down Expand Up @@ -245,17 +266,17 @@ function setupFlameGraph() {
fireEvent(canvas, getMouseEvent(eventName, options));
}

// Note to a future developer: the x/y values can be derived from the
// array returned by flushDrawLog().
function rightClick(x: CssPixels, y: CssPixels) {
// You can use findFillTextPosition to derive the x, y positioning from the
// draw log.
function rightClick({ x, y }: { x: CssPixels, y: CssPixels }) {
const positioningOptions = getPositioningOptions(x, y);

fireMouseEvent('mousemove', positioningOptions);
fireFullContextMenu(canvas, positioningOptions);
flushRafCalls();
}

function moveMouse(x, y) {
function moveMouse({ x, y }) {
fireMouseEvent('mousemove', getPositioningOptions(x, y));
}

Expand Down Expand Up @@ -287,6 +308,10 @@ function setupFlameGraph() {
fireFullClick(getByText(strOrRegexp));
}

function findFillTextPosition(fillText: string) {
return findFillTextPositionFromDrawLog(ctx.__flushDrawLog(), fillText);
}

return {
...store,
...renderResult,
Expand All @@ -298,6 +323,7 @@ function setupFlameGraph() {
getContentDiv,
getContextMenu,
clickMenuItem,
findFillTextPosition,
flushDrawLog: () => ctx.__flushDrawLog(),
};
}
186 changes: 185 additions & 1 deletion src/test/components/__snapshots__/FlameGraph.test.js.snap
Expand Up @@ -55,7 +55,7 @@ exports[`FlameGraph has a tooltip that matches the snapshot 1`] = `
<div
class="tooltip"
data-testid="tooltip"
style="--tooltip-detail-max-width: 600px; left: 111px; top: 308px;"
style="--tooltip-detail-max-width: 600px; left: 14px; top: 306px;"
>
<div
class="tooltipCallNode"
Expand Down Expand Up @@ -686,5 +686,189 @@ Array [
69.66666666666666,
231,
],
Array [
"set fillStyle",
"#12bc0060",
],
Array [
"fillRect",
66.66666666666666,
204,
66.66666666666666,
15,
],
Array [
"set fillStyle",
"#ffffff",
],
Array [
"fillRect",
66.66666666666666,
204,
1,
15,
],
Array [
"measureText",
"J",
],
Array [
"set fillStyle",
"#000",
],
Array [
"fillText",
"J",
69.66666666666666,
215,
],
]
`;

exports[`FlameGraph shows a tooltip with the resource information 1`] = `
<div
class="tooltip"
data-testid="tooltip"
style="--tooltip-detail-max-width: 600px; left: 80.66666666666666px; top: 226px;"
>
<div
class="tooltipCallNode"
style="--graph-width: 150px; --graph-height: 10px;"
>
<div
class="tooltipOneLine tooltipHeader"
>
<div
class="tooltipTiming"
>
1.0ms (33%)
</div>
<div
class="tooltipTitle"
>
J
</div>
<div
class="tooltipIcon"
/>
</div>
<div
class="tooltipCallNodeDetails"
>
<div
class="tooltipCallNodeImplementation"
>
<div />
<div
class="tooltipCallNodeImplementationHeader"
/>
<div
class="tooltipCallNodeImplementationHeader"
>
<span
class="tooltipCallNodeImplementationHeaderSwatchRunning"
/>
Running
</div>
<div
class="tooltipCallNodeImplementationHeader"
>
<span
class="tooltipCallNodeImplementationHeaderSwatchSelf"
/>
Self
</div>
<div
class="tooltipLabel"
>
Overall
</div>
<div
class="tooltipCallNodeImplementationGraph"
>
<div
class="tooltipCallNodeImplementationGraphRunning"
style="width: 150px;"
/>
<div
class="tooltipCallNodeImplementationGraphSelf"
style="width: 150px;"
/>
</div>
<div
class="tooltipCallNodeImplementationTiming"
>
1 sample
</div>
<div
class="tooltipCallNodeImplementationTiming"
>
1 sample
</div>
<div
class="tooltipCallNodeImplementationName tooltipLabel"
>
Native code
</div>
<div
class="tooltipCallNodeImplementationGraph"
>
<div
class="tooltipCallNodeImplementationGraphRunning"
style="width: 150px;"
/>
<div
class="tooltipCallNodeImplementationGraphSelf"
style="width: 150px;"
/>
</div>
<div
class="tooltipCallNodeImplementationTiming"
>
1 sample
</div>
<div
class="tooltipCallNodeImplementationTiming"
>
1 sample
</div>
</div>
<div
class="tooltipDetails tooltipCallNodeDetailsLeft"
>
<div
class="tooltipLabel"
>
Stack Type:
</div>
<div>
Native
</div>
<div
class="tooltipLabel"
>
Category:
</div>
<div>
<span
class="colored-square category-color-green"
/>
Graphics
</div>
<div
class="tooltipLabel"
>
Script URL:
</div>
path/to/file:17:107
<div
class="tooltipLabel"
>
Resource:
</div>
libxul.so
</div>
</div>
</div>
</div>
`;

0 comments on commit acee7b6

Please sign in to comment.