Skip to content

Commit

Permalink
Added ability to inject large number of traces to test performance
Browse files Browse the repository at this point in the history
  • Loading branch information
kgpax committed Nov 19, 2023
1 parent f97024e commit ef0c084
Show file tree
Hide file tree
Showing 5 changed files with 68 additions and 10 deletions.
24 changes: 24 additions & 0 deletions packages/webui/src/components/Menu.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,30 @@ describe('Menu', () => {
expect(fn3).not.toHaveBeenCalled();
});

it('should include event object in callback when clicked', async () => {
const { getByRole, getAllByTestId } = render(<Menu label="Menu" items={itemsWithCallback} />);
const menu = getByRole('menu');

await act(async () => {
await userEvent.click(menu);
});

await act(async () => {
const user = userEvent.setup();

const listItems = getAllByTestId('menu-items-item');
const firstItem = listItems.at(0)!;

await user.keyboard('{Shift>}');
await user.keyboard('{Meta>}');
await user.click(firstItem);
await user.keyboard('{/Shift}');
await user.keyboard('{/Meta}');
});

expect(fn1).toHaveBeenCalledWith(expect.objectContaining({ shiftKey: true, metaKey: true }));
});

it('should hide items after clicked', async () => {
const { getByRole, getAllByTestId, queryByTestId } = render(<Menu label="Menu" items={items} />);
const menu = getByRole('menu');
Expand Down
8 changes: 4 additions & 4 deletions packages/webui/src/components/Menu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import Button from './Button';
export type MenuItem = {
label: string;
description?: string;
callback: () => void;
callback: (e: React.MouseEvent) => void;
};

type MenuProps = React.HTMLAttributes<HTMLDivElement> & {
Expand Down Expand Up @@ -45,8 +45,8 @@ function Menu({ Icon, label, items, className, focusKey, ...props }: MenuProps,

useClickAway(finalRef, () => setIsOpen(false));

function handleSelection(item: MenuItem) {
item.callback();
function handleSelection(e: React.MouseEvent, item: MenuItem) {
item.callback(e);
setIsOpen(false);
}

Expand All @@ -69,7 +69,7 @@ function Menu({ Icon, label, items, className, focusKey, ...props }: MenuProps,
key={x.label}
data-test-id="menu-items-item"
className="cursor-pointer py-2 px-4 hover:bg-apple-200"
onClick={() => handleSelection(x)}
onClick={e => handleSelection(e, x)}
>
<div className="flex flex-col">
<div data-test-id="label" className="block">
Expand Down
31 changes: 28 additions & 3 deletions packages/webui/src/components/ui/DebugToolbar.test.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { act, cleanup, render, within } from '@testing-library/react';
import userEvent from '@testing-library/user-event';

import mockTraces from '@/testing/mockTraces';
import mockTraces, { generateLotsOfMockTraces } from '@/testing/mockTraces';
import { setUseApplicationData } from '@/testing/mockUseApplication';

import DebugToolbar from './DebugToolbar';
Expand All @@ -12,7 +12,7 @@ jest.mock('@/components', () => ({
<div {...props}>
<div>{label}</div>
{items.map((x: any, idx: number) => (
<button key={idx} onClick={() => x.callback()}>
<button key={idx} onClick={x.callback}>
{x.label}
</button>
))}
Expand All @@ -31,7 +31,7 @@ describe('DebugToolbar', () => {
render(<DebugToolbar />);
});

it('should add all mock traces when the "Mock data" option is clicked', async () => {
it('should add all standard mock traces when the "Mock data" option is clicked', async () => {
const addEvent = jest.fn();

setUseApplicationData({
Expand All @@ -48,11 +48,36 @@ describe('DebugToolbar', () => {
await userEvent.click(buttons.at(0)!);
});

expect(addEvent).toHaveBeenCalledTimes(mockTraces.length);
for (const trace of mockTraces) {
expect(addEvent).toHaveBeenCalledWith(trace);
}
});

it('should add a large amount mock traces when the "Mock data" option is clicked with shift held', async () => {
const addEvent = jest.fn();

setUseApplicationData({
collector: {
addEvent,
} as any,
});

const { getByTestId } = render(<DebugToolbar />);

await act(async () => {
const user = userEvent.setup();
const menu = getByTestId('debug-menu');
const buttons = within(menu).getAllByRole('button');
await user.keyboard('{Shift>}');
await user.click(buttons.at(0)!);
await user.keyboard('{/Shift}');
});

const lotsOfTraces = generateLotsOfMockTraces();
expect(addEvent).toHaveBeenCalledTimes(lotsOfTraces.length);
});

it('should log all traces to the console when the "Print traces" option is clicked', async () => {
const spy = jest.spyOn(console, 'log');
spy.mockImplementation(() => void 0);
Expand Down
7 changes: 4 additions & 3 deletions packages/webui/src/components/ui/DebugToolbar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { Bug } from 'lucide-react';

import { Menu } from '@/components';
import useApplication from '@/hooks/useApplication';
import mockData from '@/testing/mockTraces';
import mockData, { generateLotsOfMockTraces } from '@/testing/mockTraces';

import { MenuItem } from '../Menu';

Expand All @@ -13,8 +13,9 @@ export default function DebugToolbar() {
{
label: 'Mock data',
description: 'Inject mock traces',
callback: () => {
for (const trace of mockData) {
callback: (e: React.MouseEvent) => {
const data = e.shiftKey ? generateLotsOfMockTraces() : mockData;
for (const trace of data) {
collector?.addEvent(trace);
}
},
Expand Down
8 changes: 8 additions & 0 deletions packages/webui/src/testing/mockTraces/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,14 @@ const mockTraces: Trace[] = withSequentialIds([...gql, ...largeGql, ...sanity, .

export default mockTraces;

// useful for testing performance with lots of traces in the list. Hold shift whilst choosing the "Inject Mock Traces"
// option in the debug dropdown menu. Going forward, we should increase the multiplier in order to really stress test
// the UI with large volumes of traces
export function generateLotsOfMockTraces(): Trace[] {
const multiplier = 100; // number of times to repeat mock traces
return withSequentialIds(new Array(multiplier).fill(mockTraces).flat());
}

export function mockTraceCollection(): Map<string, Trace> {
return mockTraces.reduce((acc, curr) => {
acc.set(curr.id, curr);
Expand Down

0 comments on commit ef0c084

Please sign in to comment.