Chore: adjust more unit tests to work with react 18 (#64759)

adjust unit tests to work with react 18
This commit is contained in:
Ashley Harrison
2023-03-15 10:12:13 +00:00
committed by GitHub
parent b6f77bdfdb
commit e0e6165f70
19 changed files with 256 additions and 265 deletions
-5
View File
@@ -4560,11 +4560,6 @@ exports[`better eslint`] = {
[0, 0, 0, "Unexpected any. Specify a different type.", "0"], [0, 0, 0, "Unexpected any. Specify a different type.", "0"],
[0, 0, 0, "Unexpected any. Specify a different type.", "1"] [0, 0, 0, "Unexpected any. Specify a different type.", "1"]
], ],
"public/app/plugins/datasource/cloudwatch/components/QueryEditor.test.tsx:5381": [
[0, 0, 0, "Unexpected any. Specify a different type.", "0"],
[0, 0, 0, "Unexpected any. Specify a different type.", "1"],
[0, 0, 0, "Unexpected any. Specify a different type.", "2"]
],
"public/app/plugins/datasource/cloudwatch/datasource.ts:5381": [ "public/app/plugins/datasource/cloudwatch/datasource.ts:5381": [
[0, 0, 0, "Unexpected any. Specify a different type.", "0"] [0, 0, 0, "Unexpected any. Specify a different type.", "0"]
], ],
@@ -548,7 +548,7 @@ describe('Table', () => {
}); });
describe('when mounted with data and sub-data', () => { describe('when mounted with data and sub-data', () => {
it('then correct rows should be rendered and new table is rendered when expander is clicked', () => { it('then correct rows should be rendered and new table is rendered when expander is clicked', async () => {
getTestContext({ getTestContext({
subData: new Array(getDefaultDataFrame().length).fill(0).map((i) => subData: new Array(getDefaultDataFrame().length).fill(0).map((i) =>
toDataFrame({ toDataFrame({
@@ -588,7 +588,7 @@ describe('Table', () => {
{ time: '2021-01-01 02:00:00', temperature: '12', link: '12' }, { time: '2021-01-01 02:00:00', temperature: '12', link: '12' },
]); ]);
within(rows[1]).getByLabelText('Expand row').click(); await userEvent.click(within(rows[1]).getByLabelText('Expand row'));
const rowsAfterClick = within(getTable()).getAllByRole('row'); const rowsAfterClick = within(getTable()).getAllByRole('row');
expect(within(rowsAfterClick[1]).getByRole('table')).toBeInTheDocument(); expect(within(rowsAfterClick[1]).getByRole('table')).toBeInTheDocument();
expect(within(rowsAfterClick[1]).getByText(/number0/)).toBeInTheDocument(); expect(within(rowsAfterClick[1]).getByText(/number0/)).toBeInTheDocument();
@@ -133,9 +133,11 @@ describe('SharedPreferences', () => {
expect(lightThemeRadio.checked).toBeTruthy(); expect(lightThemeRadio.checked).toBeTruthy();
}); });
it('renders the home dashboard preference', () => { it('renders the home dashboard preference', async () => {
const dashboardSelect = getSelectParent(screen.getByLabelText('Home Dashboard')); const dashboardSelect = getSelectParent(screen.getByLabelText('Home Dashboard'));
expect(dashboardSelect).toHaveTextContent('My Dashboard'); await waitFor(() => {
expect(dashboardSelect).toHaveTextContent('My Dashboard');
});
}); });
it('renders the timezone preference', () => { it('renders the timezone preference', () => {
@@ -379,7 +379,7 @@ describe('NotificationPolicies', () => {
}); });
}); });
it('hides create and edit button if user does not have permission', () => { it('hides create and edit button if user does not have permission', async () => {
mocks.contextSrv.hasAccess.mockImplementation((action) => mocks.contextSrv.hasAccess.mockImplementation((action) =>
[AccessControlAction.AlertingNotificationsRead, AccessControlAction.AlertingNotificationsRead].includes( [AccessControlAction.AlertingNotificationsRead, AccessControlAction.AlertingNotificationsRead].includes(
action as AccessControlAction action as AccessControlAction
@@ -387,6 +387,7 @@ describe('NotificationPolicies', () => {
); );
renderNotificationPolicies(); renderNotificationPolicies();
await waitFor(() => expect(mocks.api.fetchAlertManagerConfig).toHaveBeenCalledTimes(1));
expect(ui.newPolicyButton.query()).not.toBeInTheDocument(); expect(ui.newPolicyButton.query()).not.toBeInTheDocument();
expect(ui.editButton.query()).not.toBeInTheDocument(); expect(ui.editButton.query()).not.toBeInTheDocument();
}); });
@@ -1,4 +1,4 @@
import { render, waitFor, screen, within } from '@testing-library/react'; import { render, waitFor, screen, within, act } from '@testing-library/react';
import userEvent from '@testing-library/user-event'; import userEvent from '@testing-library/user-event';
import React from 'react'; import React from 'react';
import { Route } from 'react-router-dom'; import { Route } from 'react-router-dom';
@@ -185,7 +185,9 @@ describe('RuleEditor grafana managed rules', () => {
//check that '+ Add new' option is in folders drop down even if we don't have values //check that '+ Add new' option is in folders drop down even if we don't have values
const emptyFolderInput = await ui.inputs.folderContainer.find(); const emptyFolderInput = await ui.inputs.folderContainer.find();
mocks.searchFolders.mockResolvedValue([] as DashboardSearchHit[]); mocks.searchFolders.mockResolvedValue([] as DashboardSearchHit[]);
await renderRuleEditor(uid); await act(async () => {
renderRuleEditor(uid);
});
await userEvent.click(within(emptyFolderInput).getByRole('combobox')); await userEvent.click(within(emptyFolderInput).getByRole('combobox'));
expect(screen.getByText(ADD_NEW_FOLER_OPTION)).toBeInTheDocument(); expect(screen.getByText(ADD_NEW_FOLER_OPTION)).toBeInTheDocument();
@@ -1,13 +1,5 @@
import { import { render, waitFor, screen, fireEvent, within, Matcher, getByRole } from '@testing-library/react';
render, import userEvent from '@testing-library/user-event';
waitFor,
screen,
fireEvent,
waitForElementToBeRemoved,
within,
Matcher,
getByRole,
} from '@testing-library/react';
import { merge, uniqueId } from 'lodash'; import { merge, uniqueId } from 'lodash';
import React from 'react'; import React from 'react';
import { DeepPartial } from 'react-hook-form'; import { DeepPartial } from 'react-hook-form';
@@ -280,6 +272,9 @@ describe('CorrelationsPage', () => {
}); });
it('shows CTA', async () => { it('shows CTA', async () => {
const CTAButton = await screen.findByRole('button', { name: /add correlation/i });
expect(CTAButton).toBeInTheDocument();
// insert form should not be present // insert form should not be present
expect(screen.queryByRole('button', { name: /add$/i })).not.toBeInTheDocument(); expect(screen.queryByRole('button', { name: /add$/i })).not.toBeInTheDocument();
@@ -289,51 +284,43 @@ describe('CorrelationsPage', () => {
// there's no table in the page // there's no table in the page
expect(screen.queryByRole('table')).not.toBeInTheDocument(); expect(screen.queryByRole('table')).not.toBeInTheDocument();
const CTAButton = screen.getByRole('button', { name: /add correlation/i }); await userEvent.click(CTAButton);
expect(CTAButton).toBeInTheDocument();
fireEvent.click(CTAButton);
// wait for the form to be rendered and query editor to be mounted
await waitForElementToBeRemoved(() => screen.queryByText(/loading query editor/i));
// form's submit button // form's submit button
expect(screen.getByRole('button', { name: /add$/i })).toBeInTheDocument(); expect(await screen.findByRole('button', { name: /add$/i })).toBeInTheDocument();
}); });
it('correctly adds first correlation', async () => { it('correctly adds first correlation', async () => {
const CTAButton = screen.getByRole('button', { name: /add correlation/i }); const CTAButton = await screen.findByRole('button', { name: /add correlation/i });
expect(CTAButton).toBeInTheDocument(); expect(CTAButton).toBeInTheDocument();
// there's no table in the page, as we are adding the first correlation // there's no table in the page, as we are adding the first correlation
expect(screen.queryByRole('table')).not.toBeInTheDocument(); expect(screen.queryByRole('table')).not.toBeInTheDocument();
fireEvent.click(CTAButton); await userEvent.click(CTAButton);
fireEvent.change(screen.getByRole('textbox', { name: /label/i }), { target: { value: 'A Label' } }); await userEvent.clear(screen.getByRole('textbox', { name: /label/i }));
fireEvent.change(screen.getByRole('textbox', { name: /description/i }), { target: { value: 'A Description' } }); await userEvent.type(screen.getByRole('textbox', { name: /label/i }), 'A Label');
await userEvent.clear(screen.getByRole('textbox', { name: /description/i }));
await userEvent.type(screen.getByRole('textbox', { name: /description/i }), 'A Description');
// set source datasource picker value // set source datasource picker value
fireEvent.keyDown(screen.getByLabelText(/^source$/i), { keyCode: 40 }); fireEvent.keyDown(screen.getByLabelText(/^source$/i), { keyCode: 40 });
fireEvent.click(screen.getByText('loki')); await userEvent.click(screen.getByText('loki'));
// set target datasource picker value // set target datasource picker value
fireEvent.keyDown(screen.getByLabelText(/^target$/i), { keyCode: 40 }); fireEvent.keyDown(screen.getByLabelText(/^target$/i), { keyCode: 40 });
fireEvent.click(screen.getByText('prometheus')); await userEvent.click(screen.getByText('prometheus'));
fireEvent.change(screen.getByRole('textbox', { name: /target field/i }), { target: { value: 'Line' } }); await userEvent.clear(screen.getByRole('textbox', { name: /target field/i }));
await userEvent.type(screen.getByRole('textbox', { name: /target field/i }), 'Line');
await waitForElementToBeRemoved(() => screen.queryByText(/loading query editor/i)); await userEvent.click(await screen.findByRole('button', { name: /add$/i }));
fireEvent.click(screen.getByRole('button', { name: /add$/i }));
// Waits for the form to be removed, meaning the correlation got successfully saved
await waitForElementToBeRemoved(() => screen.queryByRole('button', { name: /add$/i }));
expect(mocks.reportInteraction).toHaveBeenLastCalledWith('grafana_correlations_added'); expect(mocks.reportInteraction).toHaveBeenLastCalledWith('grafana_correlations_added');
// the table showing correlations should have appeared // the table showing correlations should have appeared
expect(screen.getByRole('table')).toBeInTheDocument(); expect(await screen.findByRole('table')).toBeInTheDocument();
}); });
}); });
@@ -413,12 +400,15 @@ describe('CorrelationsPage', () => {
}); });
it('shows a table with correlations', async () => { it('shows a table with correlations', async () => {
expect(screen.getByRole('table')).toBeInTheDocument(); expect(await screen.findByRole('table')).toBeInTheDocument();
}); });
it('correctly sorts by source', async () => { it('correctly sorts by source', async () => {
// wait for table to appear
await screen.findByRole('table');
const sourceHeader = getByRole(getHeaderByName('Source'), 'button'); const sourceHeader = getByRole(getHeaderByName('Source'), 'button');
fireEvent.click(sourceHeader); await userEvent.click(sourceHeader);
let cells = queryCellsByColumnName('Source'); let cells = queryCellsByColumnName('Source');
cells.forEach((cell, i, allCells) => { cells.forEach((cell, i, allCells) => {
const prevCell = allCells[i - 1]; const prevCell = allCells[i - 1];
@@ -427,7 +417,7 @@ describe('CorrelationsPage', () => {
} }
}); });
fireEvent.click(sourceHeader); await userEvent.click(sourceHeader);
cells = queryCellsByColumnName('Source'); cells = queryCellsByColumnName('Source');
cells.forEach((cell, i, allCells) => { cells.forEach((cell, i, allCells) => {
const prevCell = allCells[i - 1]; const prevCell = allCells[i - 1];
@@ -438,46 +428,47 @@ describe('CorrelationsPage', () => {
}); });
it('correctly adds new correlation', async () => { it('correctly adds new correlation', async () => {
const addNewButton = screen.getByRole('button', { name: /add new/i }); const addNewButton = await screen.findByRole('button', { name: /add new/i });
expect(addNewButton).toBeInTheDocument(); expect(addNewButton).toBeInTheDocument();
fireEvent.click(addNewButton); await userEvent.click(addNewButton);
fireEvent.change(screen.getByRole('textbox', { name: /label/i }), { target: { value: 'A Label' } }); await userEvent.clear(screen.getByRole('textbox', { name: /label/i }));
fireEvent.change(screen.getByRole('textbox', { name: /description/i }), { target: { value: 'A Description' } }); await userEvent.type(screen.getByRole('textbox', { name: /label/i }), 'A Label');
await userEvent.clear(screen.getByRole('textbox', { name: /description/i }));
await userEvent.type(screen.getByRole('textbox', { name: /description/i }), 'A Description');
// set source datasource picker value // set source datasource picker value
fireEvent.keyDown(screen.getByLabelText(/^source$/i), { keyCode: 40 }); fireEvent.keyDown(screen.getByLabelText(/^source$/i), { keyCode: 40 });
fireEvent.click(within(screen.getByLabelText('Select options menu')).getByText('prometheus')); await userEvent.click(within(screen.getByLabelText('Select options menu')).getByText('prometheus'));
// set target datasource picker value // set target datasource picker value
fireEvent.keyDown(screen.getByLabelText(/^target$/i), { keyCode: 40 }); fireEvent.keyDown(screen.getByLabelText(/^target$/i), { keyCode: 40 });
fireEvent.click(screen.getByText('elastic')); await userEvent.click(screen.getByText('elastic'));
fireEvent.change(screen.getByRole('textbox', { name: /target field/i }), { target: { value: 'Line' } }); await userEvent.clear(screen.getByRole('textbox', { name: /target field/i }));
await userEvent.type(screen.getByRole('textbox', { name: /target field/i }), 'Line');
await waitForElementToBeRemoved(() => screen.queryByText(/loading query editor/i)); await userEvent.click(screen.getByRole('button', { name: /add$/i }));
fireEvent.click(screen.getByRole('button', { name: /add$/i }));
// the form should get removed after successful submissions
await waitForElementToBeRemoved(() => screen.queryByRole('button', { name: /add$/i }));
expect(mocks.reportInteraction).toHaveBeenLastCalledWith('grafana_correlations_added'); expect(mocks.reportInteraction).toHaveBeenLastCalledWith('grafana_correlations_added');
// the table showing correlations should have appeared
expect(await screen.findByRole('table')).toBeInTheDocument();
}); });
it('correctly closes the form when clicking on the close icon', async () => { it('correctly closes the form when clicking on the close icon', async () => {
const addNewButton = screen.getByRole('button', { name: /add new/i }); const addNewButton = await screen.findByRole('button', { name: /add new/i });
expect(addNewButton).toBeInTheDocument(); expect(addNewButton).toBeInTheDocument();
fireEvent.click(addNewButton); await userEvent.click(addNewButton);
fireEvent.click(screen.getByRole('button', { name: /close$/i })); await userEvent.click(screen.getByRole('button', { name: /close$/i }));
expect(screen.queryByRole('button', { name: /add$/i })).not.toBeInTheDocument(); expect(screen.queryByRole('button', { name: /add$/i })).not.toBeInTheDocument();
}); });
it('correctly deletes correlations', async () => { it('correctly deletes correlations', async () => {
// A row with the correlation should exist // A row with the correlation should exist
expect(screen.getByRole('cell', { name: /some label/i })).toBeInTheDocument(); expect(await screen.findByRole('cell', { name: /some label/i })).toBeInTheDocument();
const tableRows = queryRowsByCellValue('Source', 'loki'); const tableRows = queryRowsByCellValue('Source', 'loki');
@@ -485,36 +476,37 @@ describe('CorrelationsPage', () => {
expect(deleteButton).toBeInTheDocument(); expect(deleteButton).toBeInTheDocument();
fireEvent.click(deleteButton); await userEvent.click(deleteButton);
const confirmButton = within(tableRows[0]).getByRole('button', { name: /delete$/i }); const confirmButton = within(tableRows[0]).getByRole('button', { name: /delete$/i });
expect(confirmButton).toBeInTheDocument(); expect(confirmButton).toBeInTheDocument();
fireEvent.click(confirmButton); await userEvent.click(confirmButton);
await waitForElementToBeRemoved(() => screen.queryByRole('cell', { name: /some label$/i })); expect(screen.queryByRole('cell', { name: /some label$/i })).not.toBeInTheDocument();
expect(mocks.reportInteraction).toHaveBeenLastCalledWith('grafana_correlations_deleted'); expect(mocks.reportInteraction).toHaveBeenLastCalledWith('grafana_correlations_deleted');
}); });
it('correctly edits correlations', async () => { it('correctly edits correlations', async () => {
// wait for table to appear
await screen.findByRole('table');
const tableRows = queryRowsByCellValue('Source', 'loki'); const tableRows = queryRowsByCellValue('Source', 'loki');
const rowExpanderButton = within(tableRows[0]).getByRole('button', { name: /toggle row expanded/i }); const rowExpanderButton = within(tableRows[0]).getByRole('button', { name: /toggle row expanded/i });
fireEvent.click(rowExpanderButton); await userEvent.click(rowExpanderButton);
expect(mocks.reportInteraction).toHaveBeenLastCalledWith('grafana_correlations_details_expanded'); expect(mocks.reportInteraction).toHaveBeenLastCalledWith('grafana_correlations_details_expanded');
await waitForElementToBeRemoved(() => screen.queryByText(/loading query editor/i)); await userEvent.clear(screen.getByRole('textbox', { name: /label/i }));
await userEvent.type(screen.getByRole('textbox', { name: /label/i }), 'edited label');
fireEvent.change(screen.getByRole('textbox', { name: /label/i }), { target: { value: 'edited label' } }); await userEvent.clear(screen.getByRole('textbox', { name: /description/i }));
fireEvent.change(screen.getByRole('textbox', { name: /description/i }), { await userEvent.type(screen.getByRole('textbox', { name: /description/i }), 'edited description');
target: { value: 'edited description' },
});
expect(screen.queryByRole('cell', { name: /edited label$/i })).not.toBeInTheDocument(); expect(screen.queryByRole('cell', { name: /edited label$/i })).not.toBeInTheDocument();
fireEvent.click(screen.getByRole('button', { name: /save$/i })); await userEvent.click(screen.getByRole('button', { name: /save$/i }));
await waitFor(() => { await waitFor(() => {
expect(screen.queryByRole('cell', { name: /edited label$/i })).toBeInTheDocument(); expect(screen.queryByRole('cell', { name: /edited label$/i })).toBeInTheDocument();
@@ -554,24 +546,21 @@ describe('CorrelationsPage', () => {
it("doesn't render delete button", async () => { it("doesn't render delete button", async () => {
// A row with the correlation should exist // A row with the correlation should exist
expect(screen.getByRole('cell', { name: /some label/i })).toBeInTheDocument(); expect(await screen.findByRole('cell', { name: /some label/i })).toBeInTheDocument();
expect(screen.queryByRole('button', { name: /delete correlation/i })).not.toBeInTheDocument(); expect(screen.queryByRole('button', { name: /delete correlation/i })).not.toBeInTheDocument();
}); });
it('edit form is read only', async () => { it('edit form is read only', async () => {
// A row with the correlation should exist // A row with the correlation should exist
const rowExpanderButton = screen.getByRole('button', { name: /toggle row expanded/i }); const rowExpanderButton = await screen.findByRole('button', { name: /toggle row expanded/i });
fireEvent.click(rowExpanderButton); await userEvent.click(rowExpanderButton);
expect(mocks.reportInteraction).toHaveBeenLastCalledWith('grafana_correlations_details_expanded'); expect(mocks.reportInteraction).toHaveBeenLastCalledWith('grafana_correlations_details_expanded');
// wait for the form to be rendered and query editor to be mounted
await waitForElementToBeRemoved(() => screen.queryByText(/loading query editor/i));
// form elements should be readonly // form elements should be readonly
const labelInput = screen.getByRole('textbox', { name: /label/i }); const labelInput = await screen.findByRole('textbox', { name: /label/i });
expect(labelInput).toBeInTheDocument(); expect(labelInput).toBeInTheDocument();
expect(labelInput).toHaveAttribute('readonly'); expect(labelInput).toHaveAttribute('readonly');
@@ -1,4 +1,4 @@
import { fireEvent, screen, waitFor } from '@testing-library/react'; import { act, fireEvent, screen, waitFor } from '@testing-library/react';
import userEvent from '@testing-library/user-event'; import userEvent from '@testing-library/user-event';
import React, { ComponentProps } from 'react'; import React, { ComponentProps } from 'react';
import AutoSizer from 'react-virtualized-auto-sizer'; import AutoSizer from 'react-virtualized-auto-sizer';
@@ -43,7 +43,7 @@ describe('ExplorePage', () => {
setupExplore(); setupExplore();
// Wait for rendering the editor // Wait for rendering the editor
const splitButton = await screen.findByText(/split/i); const splitButton = await screen.findByText(/split/i);
fireEvent.click(splitButton); await userEvent.click(splitButton);
await waitFor(() => { await waitFor(() => {
const editors = screen.getAllByText('loki Editor input:'); const editors = screen.getAllByText('loki Editor input:');
expect(editors.length).toBe(2); expect(editors.length).toBe(2);
@@ -123,9 +123,11 @@ describe('ExplorePage', () => {
jest.mocked(datasources.loki.query).mockReturnValue(makeLogsQueryResponse()); jest.mocked(datasources.loki.query).mockReturnValue(makeLogsQueryResponse());
jest.mocked(datasources.elastic.query).mockReturnValue(makeLogsQueryResponse()); jest.mocked(datasources.elastic.query).mockReturnValue(makeLogsQueryResponse());
locationService.partial({ act(() => {
left: JSON.stringify(['now-1h', 'now', 'loki', { expr: '{ label="value"}' }]), locationService.partial({
right: JSON.stringify(['now-1h', 'now', 'elastic', { expr: 'error' }]), left: JSON.stringify(['now-1h', 'now', 'loki', { expr: '{ label="value"}' }]),
right: JSON.stringify(['now-1h', 'now', 'elastic', { expr: 'error' }]),
});
}); });
// Editor renders the new query // Editor renders the new query
@@ -145,7 +147,9 @@ describe('ExplorePage', () => {
// to work // to work
await screen.findByText(`loki Editor input: { label="value"}`); await screen.findByText(`loki Editor input: { label="value"}`);
store.dispatch(mainState.splitOpen({ datasourceUid: 'elastic', query: { expr: 'error', refId: 'A' } })); act(() => {
store.dispatch(mainState.splitOpen({ datasourceUid: 'elastic', query: { expr: 'error', refId: 'A' } }));
});
// Editor renders the new query // Editor renders the new query
await screen.findByText(`elastic Editor input: error`); await screen.findByText(`elastic Editor input: error`);
@@ -155,7 +159,7 @@ describe('ExplorePage', () => {
it('handles split size events and sets relevant variables', async () => { it('handles split size events and sets relevant variables', async () => {
setupExplore(); setupExplore();
const splitButton = await screen.findByText(/split/i); const splitButton = await screen.findByText(/split/i);
fireEvent.click(splitButton); await userEvent.click(splitButton);
await waitForExplore(undefined, true); await waitForExplore(undefined, true);
let widenButton = await screen.findAllByLabelText('Widen pane'); let widenButton = await screen.findAllByLabelText('Widen pane');
let narrowButton = await screen.queryAllByLabelText('Narrow pane'); let narrowButton = await screen.queryAllByLabelText('Narrow pane');
@@ -202,7 +206,9 @@ describe('ExplorePage', () => {
// to work // to work
await screen.findByText(`loki Editor input: { label="value"}`); await screen.findByText(`loki Editor input: { label="value"}`);
store.dispatch(mainState.splitOpen({ datasourceUid: 'elastic', query: { expr: 'error', refId: 'A' } })); act(() => {
store.dispatch(mainState.splitOpen({ datasourceUid: 'elastic', query: { expr: 'error', refId: 'A' } }));
});
await waitFor(() => expect(document.title).toEqual('Explore - loki | elastic - Grafana')); await waitFor(() => expect(document.title).toEqual('Explore - loki | elastic - Grafana'));
}); });
}); });
@@ -404,6 +410,7 @@ describe('ExplorePage', () => {
it('removes `from` and `to` parameters from url when first mounted', async () => { it('removes `from` and `to` parameters from url when first mounted', async () => {
setupExplore({ searchParams: 'from=1&to=2&orgId=1' }); setupExplore({ searchParams: 'from=1&to=2&orgId=1' });
await waitForExplore();
expect(locationService.getSearchObject()).toEqual(expect.not.objectContaining({ from: '1', to: '2' })); expect(locationService.getSearchObject()).toEqual(expect.not.objectContaining({ from: '1', to: '2' }));
expect(locationService.getSearchObject()).toEqual(expect.objectContaining({ orgId: '1' })); expect(locationService.getSearchObject()).toEqual(expect.objectContaining({ orgId: '1' }));
@@ -1,4 +1,4 @@
import { screen } from '@testing-library/react'; import { act, screen } from '@testing-library/react';
import { serializeStateToUrlParam } from '@grafana/data'; import { serializeStateToUrlParam } from '@grafana/data';
import { locationService } from '@grafana/runtime'; import { locationService } from '@grafana/runtime';
@@ -70,8 +70,10 @@ describe('Explore: handle running/not running query', () => {
jest.mocked(datasources.loki.query).mockReturnValueOnce(makeLogsQueryResponse('different log')); jest.mocked(datasources.loki.query).mockReturnValueOnce(makeLogsQueryResponse('different log'));
locationService.partial({ act(() => {
left: JSON.stringify(['now-1h', 'now', 'loki', { expr: '{ label="different"}' }]), locationService.partial({
left: JSON.stringify(['now-1h', 'now', 'loki', { expr: '{ label="different"}' }]),
});
}); });
// Editor renders the new query // Editor renders the new query
@@ -89,8 +91,10 @@ describe('Explore: handle running/not running query', () => {
jest.mocked(datasources.elastic.query).mockReturnValueOnce(makeMetricsQueryResponse()); jest.mocked(datasources.elastic.query).mockReturnValueOnce(makeMetricsQueryResponse());
locationService.partial({ act(() => {
left: JSON.stringify(['now-1h', 'now', 'elastic', { expr: 'other query' }]), locationService.partial({
left: JSON.stringify(['now-1h', 'now', 'elastic', { expr: 'other query' }]),
});
}); });
// Editor renders the new query // Editor renders the new query
@@ -465,17 +465,17 @@ describe('Plugin details page', () => {
// Does not show an Install button // Does not show an Install button
rendered = renderPluginDetails({ id }, { pluginsStateOverride }); rendered = renderPluginDetails({ id }, { pluginsStateOverride });
expect(await rendered.queryByRole('button', { name: /(un)?install/i })).not.toBeInTheDocument(); expect(rendered.queryByRole('button', { name: /(un)?install/i })).not.toBeInTheDocument();
rendered.unmount(); rendered.unmount();
// Does not show a Uninstall button // Does not show a Uninstall button
rendered = renderPluginDetails({ id, isInstalled: true }, { pluginsStateOverride }); rendered = renderPluginDetails({ id, isInstalled: true }, { pluginsStateOverride });
expect(await rendered.queryByRole('button', { name: /(un)?install/i })).not.toBeInTheDocument(); expect(rendered.queryByRole('button', { name: /(un)?install/i })).not.toBeInTheDocument();
rendered.unmount(); rendered.unmount();
// Does not show an Update button // Does not show an Update button
rendered = renderPluginDetails({ id, isInstalled: true, hasUpdate: true }, { pluginsStateOverride }); rendered = renderPluginDetails({ id, isInstalled: true, hasUpdate: true }, { pluginsStateOverride });
expect(await rendered.queryByRole('button', { name: /update/i })).not.toBeInTheDocument(); expect(rendered.queryByRole('button', { name: /update/i })).not.toBeInTheDocument();
// Shows a message to the user // Shows a message to the user
// TODO<Import these texts from a single source of truth instead of having them defined in multiple places> // TODO<Import these texts from a single source of truth instead of having them defined in multiple places>
@@ -491,15 +491,17 @@ describe('Plugin details page', () => {
// Should not show an "Install" button // Should not show an "Install" button
rendered = renderPluginDetails({ id, isInstalled: false }); rendered = renderPluginDetails({ id, isInstalled: false });
expect(await rendered.queryByRole('button', { name: /^install/i })).not.toBeInTheDocument(); expect(rendered.queryByRole('button', { name: /^install/i })).not.toBeInTheDocument();
rendered.unmount();
// Should not show an "Uninstall" button // Should not show an "Uninstall" button
rendered = renderPluginDetails({ id, isInstalled: true }); rendered = renderPluginDetails({ id, isInstalled: true });
expect(await rendered.queryByRole('button', { name: /^uninstall/i })).not.toBeInTheDocument(); expect(rendered.queryByRole('button', { name: /^uninstall/i })).not.toBeInTheDocument();
rendered.unmount();
// Should not show an "Update" button // Should not show an "Update" button
rendered = renderPluginDetails({ id, isInstalled: true, hasUpdate: true }); rendered = renderPluginDetails({ id, isInstalled: true, hasUpdate: true });
expect(await rendered.queryByRole('button', { name: /^update/i })).not.toBeInTheDocument(); expect(rendered.queryByRole('button', { name: /^update/i })).not.toBeInTheDocument();
}); });
it('should display a "Create" button as a post installation step for installed data source plugins', async () => { it('should display a "Create" button as a post installation step for installed data source plugins', async () => {
@@ -1,4 +1,5 @@
import { act, render, screen } from '@testing-library/react'; import { render, screen, waitFor } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import React from 'react'; import React from 'react';
import config from 'app/core/config'; import config from 'app/core/config';
@@ -37,10 +38,13 @@ jest.mock('@grafana/runtime/src/services/dataSourceSrv', () => {
}); });
describe('QueryGroup', () => { describe('QueryGroup', () => {
// QueryGroup relies on this being present
Object.defineProperty(HTMLElement.prototype, 'scrollTo', { value: jest.fn() });
beforeEach(() => { beforeEach(() => {
jest.useFakeTimers();
config.expressionsEnabled = true; config.expressionsEnabled = true;
}); });
it('Should add expression on click', async () => { it('Should add expression on click', async () => {
renderScenario({}); renderScenario({});
@@ -48,8 +52,10 @@ describe('QueryGroup', () => {
const queryRowsContainer = await screen.findByTestId('query-editor-rows'); const queryRowsContainer = await screen.findByTestId('query-editor-rows');
expect(queryRowsContainer.children.length).toBe(2); expect(queryRowsContainer.children.length).toBe(2);
await addExpressionButton.click(); await userEvent.click(addExpressionButton);
expect(queryRowsContainer.children.length).toBe(3); await waitFor(() => {
expect(queryRowsContainer.children.length).toBe(3);
});
}); });
it('Should add query on click', async () => { it('Should add query on click', async () => {
@@ -59,9 +65,11 @@ describe('QueryGroup', () => {
const queryRowsContainer = await screen.findByTestId('query-editor-rows'); const queryRowsContainer = await screen.findByTestId('query-editor-rows');
expect(queryRowsContainer.children.length).toBe(2); expect(queryRowsContainer.children.length).toBe(2);
await addQueryButton.click(); await userEvent.click(addQueryButton);
expect(queryRowsContainer.children.length).toBe(3); await waitFor(() => {
expect(queryRowsContainer.children.length).toBe(3);
});
}); });
it('New expression should be expanded', async () => { it('New expression should be expanded', async () => {
@@ -69,14 +77,16 @@ describe('QueryGroup', () => {
const addExpressionButton = await screen.findByTestId('query-tab-add-expression'); const addExpressionButton = await screen.findByTestId('query-tab-add-expression');
const queryRowsContainer = await screen.findByTestId('query-editor-rows'); const queryRowsContainer = await screen.findByTestId('query-editor-rows');
await addExpressionButton.click(); await userEvent.click(addExpressionButton);
const lastQueryEditorRow = (await screen.findAllByTestId('query-editor-row')).at(-1); const lastQueryEditorRow = (await screen.findAllByTestId('query-editor-row')).at(-1);
const lastEditorToggleRow = (await screen.findAllByLabelText('toggle collapse and expand query row')).at(-1); const lastEditorToggleRow = (await screen.findAllByLabelText('toggle collapse and expand query row')).at(-1);
expect(lastEditorToggleRow?.getAttribute('aria-expanded')).toBe('true'); expect(lastEditorToggleRow?.getAttribute('aria-expanded')).toBe('true');
expect(lastQueryEditorRow?.firstElementChild?.children.length).toBe(2); expect(lastQueryEditorRow?.firstElementChild?.children.length).toBe(2);
expect(queryRowsContainer.children.length).toBe(3); await waitFor(() => {
expect(queryRowsContainer.children.length).toBe(3);
});
}); });
it('New query should be expanded', async () => { it('New query should be expanded', async () => {
@@ -84,23 +94,23 @@ describe('QueryGroup', () => {
const addQueryButton = await screen.findByTestId('query-tab-add-query'); const addQueryButton = await screen.findByTestId('query-tab-add-query');
const queryRowsContainer = await screen.findByTestId('query-editor-rows'); const queryRowsContainer = await screen.findByTestId('query-editor-rows');
await addQueryButton.click(); await userEvent.click(addQueryButton);
const lastQueryEditorRow = (await screen.findAllByTestId('query-editor-row')).at(-1); const lastQueryEditorRow = (await screen.findAllByTestId('query-editor-row')).at(-1);
const lastEditorToggleRow = (await screen.findAllByLabelText('toggle collapse and expand query row')).at(-1); const lastEditorToggleRow = (await screen.findAllByLabelText('toggle collapse and expand query row')).at(-1);
expect(lastEditorToggleRow?.getAttribute('aria-expanded')).toBe('true'); expect(lastEditorToggleRow?.getAttribute('aria-expanded')).toBe('true');
expect(lastQueryEditorRow?.firstElementChild?.children.length).toBe(2); expect(lastQueryEditorRow?.firstElementChild?.children.length).toBe(2);
expect(queryRowsContainer.children.length).toBe(3); await waitFor(() => {
expect(queryRowsContainer.children.length).toBe(3);
});
}); });
it('Should open data source help modal', async () => { it('Should open data source help modal', async () => {
renderScenario({}); renderScenario({});
const openHelpButton = await screen.findByTestId('query-tab-help-button'); const openHelpButton = await screen.findByTestId('query-tab-help-button');
await act(async () => { await userEvent.click(openHelpButton);
await openHelpButton.click();
});
const helpModal = await screen.findByRole('dialog'); const helpModal = await screen.findByRole('dialog');
expect(helpModal).toBeInTheDocument(); expect(helpModal).toBeInTheDocument();
@@ -109,6 +119,7 @@ describe('QueryGroup', () => {
it('Should not show add expression button when expressions are disabled', async () => { it('Should not show add expression button when expressions are disabled', async () => {
config.expressionsEnabled = false; config.expressionsEnabled = false;
renderScenario({}); renderScenario({});
await screen.findByTestId('query-tab-add-query');
const addExpressionButton = screen.queryByTestId('query-tab-add-expression'); const addExpressionButton = screen.queryByTestId('query-tab-add-expression');
expect(addExpressionButton).not.toBeInTheDocument(); expect(addExpressionButton).not.toBeInTheDocument();
}); });
@@ -22,7 +22,7 @@ const variableOptionGroup = {
options: [], options: [],
}; };
describe('LogsQueryEdiutor', () => { describe('LogsQueryEditor', () => {
const originalScrollIntoView = window.HTMLElement.prototype.scrollIntoView; const originalScrollIntoView = window.HTMLElement.prototype.scrollIntoView;
beforeEach(() => { beforeEach(() => {
@@ -50,13 +50,13 @@ describe('LogsQueryEdiutor', () => {
); );
const resourcePickerButton = await screen.findByRole('button', { name: 'Select a resource' }); const resourcePickerButton = await screen.findByRole('button', { name: 'Select a resource' });
resourcePickerButton.click(); await userEvent.click(resourcePickerButton);
const subscriptionButton = await screen.findByRole('button', { name: 'Expand Primary Subscription' }); const subscriptionButton = await screen.findByRole('button', { name: 'Expand Primary Subscription' });
subscriptionButton.click(); await userEvent.click(subscriptionButton);
const resourceGroupButton = await screen.findByRole('button', { name: 'Expand A Great Resource Group' }); const resourceGroupButton = await screen.findByRole('button', { name: 'Expand A Great Resource Group' });
resourceGroupButton.click(); await userEvent.click(resourceGroupButton);
const checkbox = await screen.findByLabelText('web-server'); const checkbox = await screen.findByLabelText('web-server');
await userEvent.click(checkbox); await userEvent.click(checkbox);
@@ -98,13 +98,13 @@ describe('LogsQueryEdiutor', () => {
); );
const resourcePickerButton = await screen.findByRole('button', { name: 'Select a resource' }); const resourcePickerButton = await screen.findByRole('button', { name: 'Select a resource' });
resourcePickerButton.click(); await userEvent.click(resourcePickerButton);
const subscriptionButton = await screen.findByRole('button', { name: 'Expand Primary Subscription' }); const subscriptionButton = await screen.findByRole('button', { name: 'Expand Primary Subscription' });
subscriptionButton.click(); await userEvent.click(subscriptionButton);
const resourceGroupButton = await screen.findByRole('button', { name: 'Expand A Great Resource Group' }); const resourceGroupButton = await screen.findByRole('button', { name: 'Expand A Great Resource Group' });
resourceGroupButton.click(); await userEvent.click(resourceGroupButton);
const checkbox = await screen.findByLabelText('web-server'); const checkbox = await screen.findByLabelText('web-server');
await userEvent.click(checkbox); await userEvent.click(checkbox);
@@ -131,13 +131,13 @@ describe('LogsQueryEdiutor', () => {
); );
const resourcePickerButton = await screen.findByRole('button', { name: 'Select a resource' }); const resourcePickerButton = await screen.findByRole('button', { name: 'Select a resource' });
resourcePickerButton.click(); await userEvent.click(resourcePickerButton);
const subscriptionButton = await screen.findByRole('button', { name: 'Expand Primary Subscription' }); const subscriptionButton = await screen.findByRole('button', { name: 'Expand Primary Subscription' });
subscriptionButton.click(); await userEvent.click(subscriptionButton);
const resourceGroupButton = await screen.findByRole('button', { name: 'Expand A Great Resource Group' }); const resourceGroupButton = await screen.findByRole('button', { name: 'Expand A Great Resource Group' });
resourceGroupButton.click(); await userEvent.click(resourceGroupButton);
const checkbox = await screen.findByLabelText('web-server'); const checkbox = await screen.findByLabelText('web-server');
await userEvent.click(checkbox); await userEvent.click(checkbox);
@@ -164,17 +164,17 @@ describe('LogsQueryEdiutor', () => {
); );
const resourcePickerButton = await screen.findByRole('button', { name: 'Select a resource' }); const resourcePickerButton = await screen.findByRole('button', { name: 'Select a resource' });
resourcePickerButton.click(); await userEvent.click(resourcePickerButton);
const advancedSection = screen.getByText('Advanced'); const advancedSection = screen.getByText('Advanced');
advancedSection.click(); await userEvent.click(advancedSection);
const advancedInput = await screen.findByTestId('input-advanced-resource-picker-1'); const advancedInput = await screen.findByTestId('input-advanced-resource-picker-1');
// const advancedInput = await screen.findByLabelText('Resource URI(s)'); // const advancedInput = await screen.findByLabelText('Resource URI(s)');
await userEvent.type(advancedInput, '/subscriptions/def-123'); await userEvent.type(advancedInput, '/subscriptions/def-123');
const applyButton = screen.getByRole('button', { name: 'Apply' }); const applyButton = screen.getByRole('button', { name: 'Apply' });
applyButton.click(); await userEvent.click(applyButton);
expect(onChange).toBeCalledWith( expect(onChange).toBeCalledWith(
expect.objectContaining({ expect.objectContaining({
@@ -89,6 +89,10 @@ describe('AzureMonitor ResourcePicker', () => {
it('should show a subscription as selected if there is one saved', async () => { it('should show a subscription as selected if there is one saved', async () => {
render(<ResourcePicker {...defaultProps} resources={[singleSubscriptionSelectionURI]} />); render(<ResourcePicker {...defaultProps} resources={[singleSubscriptionSelectionURI]} />);
await waitFor(async () => {
const subscriptionCheckboxes = await screen.findAllByLabelText('Dev Subscription');
expect(subscriptionCheckboxes.length).toBe(2);
});
const subscriptionCheckboxes = await screen.findAllByLabelText('Dev Subscription'); const subscriptionCheckboxes = await screen.findAllByLabelText('Dev Subscription');
expect(subscriptionCheckboxes.length).toBe(2); expect(subscriptionCheckboxes.length).toBe(2);
expect(subscriptionCheckboxes[0]).toBeChecked(); expect(subscriptionCheckboxes[0]).toBeChecked();
@@ -133,7 +137,7 @@ describe('AzureMonitor ResourcePicker', () => {
const expandSubscriptionButton = await screen.findByLabelText('Expand Primary Subscription'); const expandSubscriptionButton = await screen.findByLabelText('Expand Primary Subscription');
expect(expandSubscriptionButton).toBeInTheDocument(); expect(expandSubscriptionButton).toBeInTheDocument();
expect(screen.queryByLabelText('A Great Resource Group')).not.toBeInTheDocument(); expect(screen.queryByLabelText('A Great Resource Group')).not.toBeInTheDocument();
expandSubscriptionButton.click(); await userEvent.click(expandSubscriptionButton);
expect(await screen.findByLabelText('A Great Resource Group')).toBeInTheDocument(); expect(await screen.findByLabelText('A Great Resource Group')).toBeInTheDocument();
}); });
@@ -143,10 +147,10 @@ describe('AzureMonitor ResourcePicker', () => {
const subscriptionCheckbox = await screen.findByLabelText('Primary Subscription'); const subscriptionCheckbox = await screen.findByLabelText('Primary Subscription');
expect(subscriptionCheckbox).toBeInTheDocument(); expect(subscriptionCheckbox).toBeInTheDocument();
expect(subscriptionCheckbox).not.toBeChecked(); expect(subscriptionCheckbox).not.toBeChecked();
subscriptionCheckbox.click(); await userEvent.click(subscriptionCheckbox);
const applyButton = screen.getByRole('button', { name: 'Apply' }); const applyButton = screen.getByRole('button', { name: 'Apply' });
expect(applyButton).toBeEnabled(); expect(applyButton).toBeEnabled();
applyButton.click(); await userEvent.click(applyButton);
expect(onApply).toBeCalledTimes(1); expect(onApply).toBeCalledTimes(1);
expect(onApply).toBeCalledWith(['/subscriptions/def-123']); expect(onApply).toBeCalledWith(['/subscriptions/def-123']);
}); });
@@ -157,9 +161,9 @@ describe('AzureMonitor ResourcePicker', () => {
const subscriptionCheckbox = await screen.findAllByLabelText('Primary Subscription'); const subscriptionCheckbox = await screen.findAllByLabelText('Primary Subscription');
expect(subscriptionCheckbox).toHaveLength(2); expect(subscriptionCheckbox).toHaveLength(2);
expect(subscriptionCheckbox.at(0)).toBeChecked(); expect(subscriptionCheckbox.at(0)).toBeChecked();
subscriptionCheckbox.at(0)?.click(); await userEvent.click(subscriptionCheckbox.at(0)!);
const applyButton = screen.getByRole('button', { name: 'Apply' }); const applyButton = screen.getByRole('button', { name: 'Apply' });
applyButton.click(); await userEvent.click(applyButton);
expect(onApply).toBeCalledTimes(1); expect(onApply).toBeCalledTimes(1);
expect(onApply).toBeCalledWith([]); expect(onApply).toBeCalledWith([]);
}); });
@@ -172,9 +176,9 @@ describe('AzureMonitor ResourcePicker', () => {
const subscriptionCheckbox = await screen.findAllByLabelText('A Great Resource Group'); const subscriptionCheckbox = await screen.findAllByLabelText('A Great Resource Group');
expect(subscriptionCheckbox).toHaveLength(2); expect(subscriptionCheckbox).toHaveLength(2);
expect(subscriptionCheckbox.at(0)).toBeChecked(); expect(subscriptionCheckbox.at(0)).toBeChecked();
subscriptionCheckbox.at(0)?.click(); await userEvent.click(subscriptionCheckbox.at(0)!);
const applyButton = screen.getByRole('button', { name: 'Apply' }); const applyButton = screen.getByRole('button', { name: 'Apply' });
applyButton.click(); await userEvent.click(applyButton);
expect(onApply).toBeCalledTimes(1); expect(onApply).toBeCalledTimes(1);
expect(onApply).toBeCalledWith([]); expect(onApply).toBeCalledWith([]);
}); });
@@ -186,15 +190,15 @@ describe('AzureMonitor ResourcePicker', () => {
const subscriptionButton = await screen.findByRole('button', { name: 'Expand Primary Subscription' }); const subscriptionButton = await screen.findByRole('button', { name: 'Expand Primary Subscription' });
expect(subscriptionButton).toBeInTheDocument(); expect(subscriptionButton).toBeInTheDocument();
expect(screen.queryByRole('button', { name: 'Expand A Great Resource Group' })).not.toBeInTheDocument(); expect(screen.queryByRole('button', { name: 'Expand A Great Resource Group' })).not.toBeInTheDocument();
subscriptionButton.click(); await userEvent.click(subscriptionButton);
const resourceGroupButton = await screen.findByRole('button', { name: 'Expand A Great Resource Group' }); const resourceGroupButton = await screen.findByRole('button', { name: 'Expand A Great Resource Group' });
resourceGroupButton.click(); await userEvent.click(resourceGroupButton);
const checkbox = await screen.findByLabelText('web-server'); const checkbox = await screen.findByLabelText('web-server');
await userEvent.click(checkbox); await userEvent.click(checkbox);
expect(checkbox).toBeChecked(); expect(checkbox).toBeChecked();
const applyButton = screen.getByRole('button', { name: 'Apply' }); const applyButton = screen.getByRole('button', { name: 'Apply' });
applyButton.click(); await userEvent.click(applyButton);
expect(onApply).toBeCalledTimes(1); expect(onApply).toBeCalledTimes(1);
expect(onApply).toBeCalledWith([ expect(onApply).toBeCalledWith([
@@ -231,9 +235,9 @@ describe('AzureMonitor ResourcePicker', () => {
const checkbox = await screen.findAllByLabelText('web-server'); const checkbox = await screen.findAllByLabelText('web-server');
expect(checkbox).toHaveLength(2); expect(checkbox).toHaveLength(2);
expect(checkbox.at(0)).toBeChecked(); expect(checkbox.at(0)).toBeChecked();
checkbox.at(0)?.click(); await userEvent.click(checkbox.at(0)!);
const applyButton = screen.getByRole('button', { name: 'Apply' }); const applyButton = screen.getByRole('button', { name: 'Apply' });
applyButton.click(); await userEvent.click(applyButton);
expect(onApply).toBeCalledTimes(1); expect(onApply).toBeCalledTimes(1);
expect(onApply).toBeCalledWith([]); expect(onApply).toBeCalledWith([]);
}); });
@@ -269,13 +273,11 @@ describe('AzureMonitor ResourcePicker', () => {
it('renders a loading state while waiting for search results', async () => { it('renders a loading state while waiting for search results', async () => {
const rpd = createMockResourcePickerData(); const rpd = createMockResourcePickerData();
rpd.search = jest.fn().mockImplementation(() => { let promiseResolver: (value: unknown) => void = () => {};
return new Promise((resolve) => { const promiseToResolve = new Promise((resolve) => {
setTimeout(() => { promiseResolver = resolve;
return resolve(mockSearchResults());
}, 1); // purposely slow down call by a tick so as to force a loading state
});
}); });
rpd.search = jest.fn().mockImplementation(() => promiseToResolve);
render(<ResourcePicker {...defaultProps} resourcePickerData={rpd} />); render(<ResourcePicker {...defaultProps} resourcePickerData={rpd} />);
@@ -287,6 +289,9 @@ describe('AzureMonitor ResourcePicker', () => {
const loading = await screen.findByText('Loading...'); const loading = await screen.findByText('Loading...');
expect(loading).toBeInTheDocument(); expect(loading).toBeInTheDocument();
// resolve the promise
promiseResolver(mockSearchResults());
const searchResult = await screen.findByLabelText('search-result'); const searchResult = await screen.findByLabelText('search-result');
expect(searchResult).toBeInTheDocument(); expect(searchResult).toBeInTheDocument();
@@ -330,7 +335,7 @@ describe('AzureMonitor ResourcePicker', () => {
/> />
); );
const subscriptionExpand = await screen.findByLabelText('Expand Primary Subscription'); const subscriptionExpand = await screen.findByLabelText('Expand Primary Subscription');
await subscriptionExpand.click(); await userEvent.click(subscriptionExpand);
const error = await screen.findByRole('alert'); const error = await screen.findByRole('alert');
expect(error).toHaveTextContent('An error occurred while requesting resources from Azure Monitor'); expect(error).toHaveTextContent('An error occurred while requesting resources from Azure Monitor');
expect(error).toHaveTextContent( expect(error).toHaveTextContent(
@@ -47,7 +47,7 @@ describe('VariableEditor:', () => {
render(<VariableEditor {...defaultProps} onChange={onChange} query={legacyQuery} />); render(<VariableEditor {...defaultProps} onChange={onChange} query={legacyQuery} />);
await waitFor(() => screen.getByLabelText('select query type')); await waitFor(() => screen.getByLabelText('select query type'));
expect(screen.getByLabelText('select query type')).toBeInTheDocument(); expect(screen.getByLabelText('select query type')).toBeInTheDocument();
screen.getByLabelText('select query type').click(); await userEvent.click(screen.getByLabelText('select query type'));
await select(screen.getByLabelText('select query type'), 'Grafana Query Function', { await select(screen.getByLabelText('select query type'), 'Grafana Query Function', {
container: document.body, container: document.body,
}); });
@@ -185,7 +185,7 @@ describe('VariableEditor:', () => {
rerender: (ui: React.ReactElement) => void rerender: (ui: React.ReactElement) => void
) => { ) => {
openMenu(screen.getByLabelText(label)); openMenu(screen.getByLabelText(label));
screen.getByText(text).click(); await userEvent.click(screen.getByText(text));
// Simulate onChange behavior // Simulate onChange behavior
const newQuery = onChange.mock.calls.at(-1)[0]; const newQuery = onChange.mock.calls.at(-1)[0];
rerender(<VariableEditor {...defaultProps} query={newQuery} onChange={onChange} />); rerender(<VariableEditor {...defaultProps} query={newQuery} onChange={onChange} />);
@@ -226,7 +226,7 @@ describe('VariableEditor:', () => {
// Select a subscription // Select a subscription
openMenu(screen.getByLabelText('select subscription')); openMenu(screen.getByLabelText('select subscription'));
await waitFor(() => expect(screen.getByText('Primary Subscription')).toBeInTheDocument()); await waitFor(() => expect(screen.getByText('Primary Subscription')).toBeInTheDocument());
screen.getByText('Template Variables').click(); await userEvent.click(screen.getByText('Template Variables'));
// Simulate onChange behavior // Simulate onChange behavior
const lastQuery = onChange.mock.calls.at(-1)[0]; const lastQuery = onChange.mock.calls.at(-1)[0];
rerender(<VariableEditor {...defaultProps} query={lastQuery} onChange={onChange} />); rerender(<VariableEditor {...defaultProps} query={lastQuery} onChange={onChange} />);
@@ -45,13 +45,13 @@ describe('VisualMetricQueryEditor', () => {
render(<VisualMetricQueryEditor {...defaultProps} onChange={onChange} datasource={datasource} query={query} />); render(<VisualMetricQueryEditor {...defaultProps} onChange={onChange} datasource={datasource} query={query} />);
const service = await screen.findByLabelText('Service'); const service = await screen.findByLabelText('Service');
await openMenu(service); openMenu(service);
await act(async () => { await act(async () => {
await select(service, 'Srv', { container: document.body }); await select(service, 'Srv', { container: document.body });
expect(onChange).toBeCalledWith(
expect.objectContaining({ filters: ['metric.type', '=', mockMetricDescriptor.type] })
);
}); });
expect(onChange).toBeCalledWith(
expect.objectContaining({ filters: ['metric.type', '=', mockMetricDescriptor.type] })
);
}); });
it('can select a metric name', async () => { it('can select a metric name', async () => {
@@ -66,19 +66,19 @@ describe('VisualMetricQueryEditor', () => {
render(<VisualMetricQueryEditor {...defaultProps} onChange={onChange} datasource={datasource} query={query} />); render(<VisualMetricQueryEditor {...defaultProps} onChange={onChange} datasource={datasource} query={query} />);
const service = await screen.findByLabelText('Service'); const service = await screen.findByLabelText('Service');
await openMenu(service); openMenu(service);
await act(async () => { await act(async () => {
await select(service, 'Srv', { container: document.body }); await select(service, 'Srv', { container: document.body });
}); });
const metricName = await screen.findByLabelText('Metric name'); const metricName = await screen.findByLabelText('Metric name');
await openMenu(metricName); openMenu(metricName);
await waitFor(() => expect(document.body).toHaveTextContent('metricName_test')); await waitFor(() => expect(document.body).toHaveTextContent('metricName_test'));
await act(async () => { await act(async () => {
await select(metricName, 'metricName_test', { container: document.body }); await select(metricName, 'metricName_test', { container: document.body });
expect(onChange).toBeCalledWith(
expect.objectContaining({ filters: ['metric.type', '=', mockMetricDescriptor.type] })
);
}); });
expect(onChange).toBeCalledWith(
expect.objectContaining({ filters: ['metric.type', '=', mockMetricDescriptor.type] })
);
}); });
it('should render available metric options according to the selected service', async () => { it('should render available metric options according to the selected service', async () => {
@@ -114,12 +114,12 @@ describe('VisualMetricQueryEditor', () => {
render(<VisualMetricQueryEditor {...defaultProps} onChange={onChange} datasource={datasource} query={query} />); render(<VisualMetricQueryEditor {...defaultProps} onChange={onChange} datasource={datasource} query={query} />);
const service = await screen.findByLabelText('Service'); const service = await screen.findByLabelText('Service');
await openMenu(service); openMenu(service);
await act(async () => { await act(async () => {
await select(service, 'Srv A', { container: document.body }); await select(service, 'Srv A', { container: document.body });
}); });
const metricName = await screen.findByLabelText('Metric name'); const metricName = await screen.findByLabelText('Metric name');
await openMenu(metricName); openMenu(metricName);
const metricNameOptions = screen.getByLabelText('Select options menu'); const metricNameOptions = screen.getByLabelText('Select options menu');
expect(within(metricNameOptions).getByText('description_metric1')).toBeInTheDocument(); expect(within(metricNameOptions).getByText('description_metric1')).toBeInTheDocument();
@@ -129,7 +129,7 @@ describe('VisualMetricQueryEditor', () => {
expect(within(metricNameOptions).queryByText('displayName_metric3')).not.toBeInTheDocument(); expect(within(metricNameOptions).queryByText('displayName_metric3')).not.toBeInTheDocument();
expect(within(metricNameOptions).queryByText('description_metric3')).not.toBeInTheDocument(); expect(within(metricNameOptions).queryByText('description_metric3')).not.toBeInTheDocument();
await openMenu(service); openMenu(service);
await act(async () => { await act(async () => {
await select(service, 'Srv B', { container: document.body }); await select(service, 'Srv B', { container: document.body });
}); });
@@ -172,7 +172,7 @@ describe('VisualMetricQueryEditor', () => {
render(<VisualMetricQueryEditor {...defaultProps} onChange={onChange} datasource={datasource} query={query} />); render(<VisualMetricQueryEditor {...defaultProps} onChange={onChange} datasource={datasource} query={query} />);
const service = await screen.findByLabelText('Service'); const service = await screen.findByLabelText('Service');
await openMenu(service); openMenu(service);
expect(screen.getAllByLabelText('Select option').length).toEqual(2); expect(screen.getAllByLabelText('Select option').length).toEqual(2);
}); });
@@ -233,8 +233,8 @@ describe('VisualMetricQueryEditor', () => {
); );
expect(query).toEqual(defaultQuery); expect(query).toEqual(defaultQuery);
expect(document.body).toHaveTextContent('metric.test_label'); expect(document.body).toHaveTextContent('metric.test_label');
expect(await screen.queryByText('Delta')).not.toBeInTheDocument(); expect(screen.queryByText('Delta')).not.toBeInTheDocument();
expect(await screen.queryByText('metric.test_groupby')).not.toBeInTheDocument(); expect(screen.queryByText('metric.test_groupby')).not.toBeInTheDocument();
}); });
it('updates labels on time range change', async () => { it('updates labels on time range change', async () => {
@@ -257,30 +257,28 @@ describe('VisualMetricQueryEditor', () => {
); );
const service = await screen.findByLabelText('Service'); const service = await screen.findByLabelText('Service');
await openMenu(service); openMenu(service);
await act(async () => { await act(async () => {
await select(service, 'Srv', { container: document.body }); await select(service, 'Srv', { container: document.body });
}); });
const metricName = await screen.findByLabelText('Metric name'); const metricName = await screen.findByLabelText('Metric name');
await openMenu(metricName); openMenu(metricName);
await waitFor(() => expect(document.body).toHaveTextContent('metricName')); await waitFor(() => expect(document.body).toHaveTextContent('metricName'));
await act(async () => { await act(async () => {
await select(metricName, 'metricName', { container: document.body }); await select(metricName, 'metricName', { container: document.body });
}); });
const groupBy = await screen.findByLabelText('Group by'); const groupBy = await screen.findByLabelText('Group by');
await openMenu(groupBy); openMenu(groupBy);
await waitFor(() => expect(document.body).toHaveTextContent('metric.test_groupby')); await waitFor(() => expect(document.body).toHaveTextContent('metric.test_groupby'));
await act(async () => { timeSrv.setTime({ from: 'now-12h', to: 'now' });
timeSrv.setTime({ from: 'now-12h', to: 'now' }); const datasourceUpdated = createMockDatasource({
const datasourceUpdated = createMockDatasource({ timeSrv,
timeSrv, getLabels: jest.fn().mockResolvedValue({ 'metric.test_groupby_1': '' }),
getLabels: jest.fn().mockResolvedValue({ 'metric.test_groupby_1': '' }),
});
rerender(
<VisualMetricQueryEditor {...defaultProps} onChange={onChange} datasource={datasourceUpdated} query={query} />
);
await openMenu(groupBy);
await waitFor(() => expect(document.body).toHaveTextContent('metric.test_groupby_1'));
}); });
rerender(
<VisualMetricQueryEditor {...defaultProps} onChange={onChange} datasource={datasourceUpdated} query={query} />
);
openMenu(groupBy);
await waitFor(() => expect(document.body).toHaveTextContent('metric.test_groupby_1'));
}); });
}); });
@@ -1,4 +1,5 @@
import { act, fireEvent, render, screen } from '@testing-library/react'; import { render, screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import React from 'react'; import React from 'react';
import { QueryEditorProps } from '@grafana/data'; import { QueryEditorProps } from '@grafana/data';
@@ -64,10 +65,8 @@ describe('QueryEditor should render right editor', () => {
region: 'default', region: 'default',
returnData: false, returnData: false,
}; };
await act(async () => { render(<QueryEditor {...props} query={query} />);
render(<QueryEditor {...props} query={query} />); expect(await screen.findByText('Metric name')).toBeInTheDocument();
});
expect(screen.getByText('Metric name')).toBeInTheDocument();
}); });
}); });
@@ -91,11 +90,9 @@ describe('QueryEditor should render right editor', () => {
refId: 'A', refId: 'A',
region: 'ap-northeast-2', region: 'ap-northeast-2',
statistics: 'Average', statistics: 'Average',
} as any; } as CloudWatchQuery;
await act(async () => { render(<QueryEditor {...props} query={query} />);
render(<QueryEditor {...props} query={query} />); expect(await screen.findByText('Metric name')).toBeInTheDocument();
});
expect(screen.getByText('Metric name')).toBeInTheDocument();
}); });
}); });
@@ -119,11 +116,9 @@ describe('QueryEditor should render right editor', () => {
refId: 'A', refId: 'A',
region: 'ap-northeast-2', region: 'ap-northeast-2',
statistic: 'Average', statistic: 'Average',
} as any; } as CloudWatchQuery;
await act(async () => { render(<QueryEditor {...props} query={query} />);
render(<QueryEditor {...props} query={query} />); expect(await screen.findByText('Select Log Groups')).toBeInTheDocument();
});
expect(screen.getByText('Select Log Groups')).toBeInTheDocument();
}); });
}); });
@@ -146,11 +141,9 @@ describe('QueryEditor should render right editor', () => {
refId: 'B', refId: 'B',
region: '$region', region: '$region',
statistic: 'Average', statistic: 'Average',
} as any; } as CloudWatchQuery;
await act(async () => { render(<QueryEditor {...props} query={query} />);
render(<QueryEditor {...props} query={query} />); expect(await screen.findByText('Metric name')).toBeInTheDocument();
});
expect(screen.getByText('Metric name')).toBeInTheDocument();
}); });
}); });
@@ -191,10 +184,8 @@ describe('QueryEditor should render right editor', () => {
test.each(cases)('$name', async ({ query, toggle }) => { test.each(cases)('$name', async ({ query, toggle }) => {
config.featureToggles.cloudWatchCrossAccountQuerying = toggle; config.featureToggles.cloudWatchCrossAccountQuerying = toggle;
await act(async () => { render(<QueryEditor {...props} datasource={datasourceMock.datasource} query={query} />);
render(<QueryEditor {...props} datasource={datasourceMock.datasource} query={query} />); expect(await screen.findByText('Monitoring account')).toBeInTheDocument();
});
expect(await screen.getByText('Monitoring account')).toBeInTheDocument();
}); });
}); });
@@ -224,34 +215,29 @@ describe('QueryEditor should render right editor', () => {
]; ];
test.each(cases)('$name', async ({ query, toggle }) => { test.each(cases)('$name', async ({ query, toggle }) => {
config.featureToggles.cloudWatchCrossAccountQuerying = toggle; config.featureToggles.cloudWatchCrossAccountQuerying = toggle;
await act(async () => { render(<QueryEditor {...props} datasource={datasourceMock.datasource} query={query} />);
render(<QueryEditor {...props} datasource={datasourceMock.datasource} query={query} />); expect(await screen.findByText('Run queries')).toBeInTheDocument();
}); expect(screen.queryByText('Monitoring account')).toBeNull();
expect(await screen.queryByText('Monitoring account')).toBeNull();
}); });
}); });
}); });
describe('QueryHeader', () => { describe('QueryHeader', () => {
it('should display metric actions in header when metric query is used', async () => { it('should display metric actions in header when metric query is used', async () => {
await act(async () => { render(<QueryEditor {...props} query={validMetricQueryCodeQuery} />);
render(<QueryEditor {...props} query={validMetricQueryCodeQuery} />);
});
expect(await screen.findByText('CloudWatch Metrics')).toBeInTheDocument();
expect(screen.getByLabelText(/Region.*/)).toBeInTheDocument(); expect(screen.getByLabelText(/Region.*/)).toBeInTheDocument();
expect(screen.getByText('CloudWatch Metrics')).toBeInTheDocument();
expect(screen.getByLabelText('Builder')).toBeInTheDocument(); expect(screen.getByLabelText('Builder')).toBeInTheDocument();
expect(screen.getByLabelText('Code')).toBeInTheDocument(); expect(screen.getByLabelText('Code')).toBeInTheDocument();
expect(screen.getByText('Metric Query')).toBeInTheDocument(); expect(screen.getByText('Metric Query')).toBeInTheDocument();
}); });
it('should display metric actions in header when metric query is used', async () => { it('should display metric actions in header when metric query is used', async () => {
await act(async () => { render(<QueryEditor {...props} query={validLogsQuery} />);
render(<QueryEditor {...props} query={validLogsQuery} />);
});
expect(await screen.findByText('CloudWatch Logs')).toBeInTheDocument();
expect(screen.getByLabelText(/Region.*/)).toBeInTheDocument(); expect(screen.getByLabelText(/Region.*/)).toBeInTheDocument();
expect(screen.getByText('CloudWatch Logs')).toBeInTheDocument();
expect(screen.queryByLabelText('Builder')).not.toBeInTheDocument(); expect(screen.queryByLabelText('Builder')).not.toBeInTheDocument();
expect(screen.queryByLabelText('Code')).not.toBeInTheDocument(); expect(screen.queryByLabelText('Code')).not.toBeInTheDocument();
expect(screen.queryByText('Metric Query')).not.toBeInTheDocument(); expect(screen.queryByText('Metric Query')).not.toBeInTheDocument();
@@ -260,42 +246,33 @@ describe('QueryEditor should render right editor', () => {
describe('metrics editor should handle editor modes correctly', () => { describe('metrics editor should handle editor modes correctly', () => {
it('when metric query type is metric search and editor mode is builder', async () => { it('when metric query type is metric search and editor mode is builder', async () => {
await act(async () => { render(<QueryEditor {...props} query={validMetricSearchBuilderQuery} />);
render(<QueryEditor {...props} query={validMetricSearchBuilderQuery} />);
});
expect(screen.getByText('Metric Search')).toBeInTheDocument(); expect(await screen.findByText('Metric Search')).toBeInTheDocument();
const radio = screen.getByLabelText('Builder'); const radio = screen.getByLabelText('Builder');
expect(radio instanceof HTMLInputElement && radio.checked).toBeTruthy(); expect(radio instanceof HTMLInputElement && radio.checked).toBeTruthy();
}); });
it('when metric query type is metric search and editor mode is raw', async () => { it('when metric query type is metric search and editor mode is raw', async () => {
await act(async () => { render(<QueryEditor {...props} query={validMetricSearchCodeQuery} />);
render(<QueryEditor {...props} query={validMetricSearchCodeQuery} />);
}); expect(await screen.findByText('Metric Search')).toBeInTheDocument();
expect(screen.getByText('Metric Search')).toBeInTheDocument();
const radio = screen.getByLabelText('Code'); const radio = screen.getByLabelText('Code');
expect(radio instanceof HTMLInputElement && radio.checked).toBeTruthy(); expect(radio instanceof HTMLInputElement && radio.checked).toBeTruthy();
}); });
it('when metric query type is metric query and editor mode is builder', async () => { it('when metric query type is metric query and editor mode is builder', async () => {
await act(async () => { render(<QueryEditor {...props} query={validMetricQueryBuilderQuery} />);
await act(async () => {
render(<QueryEditor {...props} query={validMetricQueryBuilderQuery} />);
});
expect(screen.getByText('Metric Query')).toBeInTheDocument(); expect(await screen.findByText('Metric Query')).toBeInTheDocument();
const radio = screen.getByLabelText('Builder'); const radio = screen.getByLabelText('Builder');
expect(radio instanceof HTMLInputElement && radio.checked).toBeTruthy(); expect(radio instanceof HTMLInputElement && radio.checked).toBeTruthy();
});
}); });
it('when metric query type is metric query and editor mode is raw', async () => { it('when metric query type is metric query and editor mode is raw', async () => {
await act(async () => { render(<QueryEditor {...props} query={validMetricQueryCodeQuery} />);
render(<QueryEditor {...props} query={validMetricQueryCodeQuery} />);
});
expect(screen.getByText('Metric Query')).toBeInTheDocument(); expect(await screen.findByText('Metric Query')).toBeInTheDocument();
const radio = screen.getByLabelText('Code'); const radio = screen.getByLabelText('Code');
expect(radio instanceof HTMLInputElement && radio.checked).toBeTruthy(); expect(radio instanceof HTMLInputElement && radio.checked).toBeTruthy();
}); });
@@ -315,12 +292,11 @@ describe('QueryEditor should render right editor', () => {
// the modal should not be shown unless the code editor is "dirty", so need to trigger a change // the modal should not be shown unless the code editor is "dirty", so need to trigger a change
const codeEditorElement = screen.getByLabelText(FAKE_EDITOR_LABEL); const codeEditorElement = screen.getByLabelText(FAKE_EDITOR_LABEL);
fireEvent.change(codeEditorElement, { target: { value: 'select * from ' } }); await userEvent.clear(codeEditorElement);
await userEvent.type(codeEditorElement, 'select * from ');
const builderElement = screen.getByLabelText('Builder'); const builderElement = screen.getByLabelText('Builder');
expect(builderElement).toBeInTheDocument(); expect(builderElement).toBeInTheDocument();
await act(async () => { await userEvent.click(builderElement);
await builderElement.click();
});
const modalTitleElem = screen.getByText('Are you sure?'); const modalTitleElem = screen.getByText('Are you sure?');
expect(modalTitleElem).toBeInTheDocument(); expect(modalTitleElem).toBeInTheDocument();
@@ -332,9 +308,7 @@ describe('QueryEditor should render right editor', () => {
); );
const builderElement = screen.getByLabelText('Builder'); const builderElement = screen.getByLabelText('Builder');
expect(builderElement).toBeInTheDocument(); expect(builderElement).toBeInTheDocument();
await act(async () => { await userEvent.click(builderElement);
await builderElement.click();
});
expect(screen.queryByText('Are you sure?')).toBeNull(); expect(screen.queryByText('Are you sure?')).toBeNull();
}); });
@@ -343,9 +317,7 @@ describe('QueryEditor should render right editor', () => {
const builderElement = screen.getByLabelText('Builder'); const builderElement = screen.getByLabelText('Builder');
expect(builderElement).toBeInTheDocument(); expect(builderElement).toBeInTheDocument();
await act(async () => { await userEvent.click(builderElement);
await builderElement.click();
});
expect(screen.queryByText('Are you sure?')).toBeNull(); expect(screen.queryByText('Are you sure?')).toBeNull();
}); });
}); });
@@ -88,19 +88,21 @@ describe('LokiQueryEditorSelector', () => {
await expectBuilder(); await expectBuilder();
}); });
it('shows Run Queries button in Dashboards', () => { it('shows Run Queries button in Dashboards', async () => {
renderWithProps({}, { app: CoreApp.Dashboard }); renderWithProps({}, { app: CoreApp.Dashboard });
expectRunQueriesButton(); await expectRunQueriesButton();
}); });
it('hides Run Queries button in Explore', async () => { it('hides Run Queries button in Explore', async () => {
renderWithProps({}, { app: CoreApp.Explore }); renderWithProps({}, { app: CoreApp.Explore });
await expectCodeEditor();
expectNoRunQueriesButton(); expectNoRunQueriesButton();
}); });
it('hides Run Queries button in Correlations Page', async () => { it('hides Run Queries button in Correlations Page', async () => {
renderWithProps({}, { app: CoreApp.Correlations }); renderWithProps({}, { app: CoreApp.Correlations });
await expectNoRunQueriesButton(); await expectCodeEditor();
expectNoRunQueriesButton();
}); });
it('changes to builder mode', async () => { it('changes to builder mode', async () => {
@@ -128,7 +130,7 @@ describe('LokiQueryEditorSelector', () => {
it('Can enable explain', async () => { it('Can enable explain', async () => {
renderWithMode(QueryEditorMode.Builder); renderWithMode(QueryEditorMode.Builder);
expect(screen.queryByText(EXPLAIN_LABEL_FILTER_CONTENT)).not.toBeInTheDocument(); expect(screen.queryByText(EXPLAIN_LABEL_FILTER_CONTENT)).not.toBeInTheDocument();
screen.getByLabelText('Explain query').click(); await userEvent.click(screen.getByLabelText('Explain query'));
expect(await screen.findByText(EXPLAIN_LABEL_FILTER_CONTENT)).toBeInTheDocument(); expect(await screen.findByText(EXPLAIN_LABEL_FILTER_CONTENT)).toBeInTheDocument();
}); });
@@ -198,8 +200,8 @@ async function expectBuilder() {
expect(await screen.findByText('Label filters')).toBeInTheDocument(); expect(await screen.findByText('Label filters')).toBeInTheDocument();
} }
function expectRunQueriesButton() { async function expectRunQueriesButton() {
expect(screen.getByRole('button', { name: /run queries/i })).toBeInTheDocument(); expect(await screen.findByRole('button', { name: /run queries/i })).toBeInTheDocument();
} }
function expectNoRunQueriesButton() { function expectNoRunQueriesButton() {
@@ -1,4 +1,4 @@
import { act, render, screen } from '@testing-library/react'; import { render, screen } from '@testing-library/react';
import React from 'react'; import React from 'react';
import { DataSourcePluginMeta } from '@grafana/data'; import { DataSourcePluginMeta } from '@grafana/data';
@@ -39,9 +39,7 @@ describe('LokiQueryBuilderContainer', () => {
render(<LokiQueryBuilderContainer {...props} />); render(<LokiQueryBuilderContainer {...props} />);
const selector = await screen.findByLabelText('selector'); const selector = await screen.findByLabelText('selector');
expect(selector.textContent).toBe('{job="testjob"}'); expect(selector.textContent).toBe('{job="testjob"}');
await act(async () => { await addOperation('Range functions', 'Rate');
await addOperation('Range functions', 'Rate');
});
expect(await screen.findByText('Rate')).toBeInTheDocument(); expect(await screen.findByText('Rate')).toBeInTheDocument();
expect(props.onChange).toBeCalledWith({ expect(props.onChange).toBeCalledWith({
expr: 'rate({job="testjob"} [$__interval])', expr: 'rate({job="testjob"} [$__interval])',
@@ -1,16 +1,18 @@
import { screen, fireEvent } from '@testing-library/react'; import { screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event'; import userEvent from '@testing-library/user-event';
export async function addOperation(section: string, op: string) { export async function addOperation(section: string, op: string) {
const addOperationButton = screen.getByTitle('Add operation'); const addOperationButton = screen.getByTitle('Add operation');
expect(addOperationButton).toBeInTheDocument(); expect(addOperationButton).toBeInTheDocument();
await userEvent.click(addOperationButton); await userEvent.click(addOperationButton);
const sectionItem = screen.getByTitle(section); const sectionItem = await screen.findByTitle(section);
expect(sectionItem).toBeInTheDocument(); expect(sectionItem).toBeInTheDocument();
// Weirdly the await userEvent.click doesn't work here, it reports the item has pointer-events: none. Don't see that // Weirdly the await userEvent.click doesn't work here, it reports the item has pointer-events: none. Don't see that
// anywhere when debugging so not sure what style is it picking up. // anywhere when debugging so not sure what style is it picking up.
fireEvent.click(sectionItem.children[0]); await userEvent.click(sectionItem.children[0], { pointerEventsCheck: 0 });
const opItem = screen.getByTitle(op); const opItem = screen.getByTitle(op);
expect(opItem).toBeInTheDocument(); expect(opItem).toBeInTheDocument();
fireEvent.click(opItem); // Weirdly the await userEvent.click doesn't work here, it reports the item has pointer-events: none. Don't see that
// anywhere when debugging so not sure what style is it picking up.
await userEvent.click(opItem, { pointerEventsCheck: 0 });
} }
@@ -1,5 +1,5 @@
import '@testing-library/jest-dom';
import { render, screen } from '@testing-library/react'; import { render, screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import React from 'react'; import React from 'react';
import { CoreApp, MutableDataFrame } from '@grafana/data'; import { CoreApp, MutableDataFrame } from '@grafana/data';
@@ -20,6 +20,7 @@ describe('FlameGraphContainer', () => {
// Needed for AutoSizer to work in test // Needed for AutoSizer to work in test
Object.defineProperty(HTMLElement.prototype, 'offsetHeight', { value: 500 }); Object.defineProperty(HTMLElement.prototype, 'offsetHeight', { value: 500 });
Object.defineProperty(HTMLElement.prototype, 'offsetWidth', { value: 500 }); Object.defineProperty(HTMLElement.prototype, 'offsetWidth', { value: 500 });
Object.defineProperty(HTMLElement.prototype, 'clientWidth', { value: 500 });
const FlameGraphContainerWithProps = () => { const FlameGraphContainerWithProps = () => {
const flameGraphData = new MutableDataFrame(data); const flameGraphData = new MutableDataFrame(data);
@@ -38,11 +39,11 @@ describe('FlameGraphContainer', () => {
it('should update search when row selected in top table', async () => { it('should update search when row selected in top table', async () => {
render(<FlameGraphContainerWithProps />); render(<FlameGraphContainerWithProps />);
screen.getAllByRole('row')[1].click(); await userEvent.click((await screen.findAllByRole('row'))[1]);
expect(screen.getByDisplayValue('net/http.HandlerFunc.ServeHTTP')).toBeInTheDocument(); expect(screen.getByDisplayValue('net/http.HandlerFunc.ServeHTTP')).toBeInTheDocument();
screen.getAllByRole('row')[2].click(); await userEvent.click(screen.getAllByRole('row')[2]);
expect(screen.getByDisplayValue('total')).toBeInTheDocument(); expect(screen.getByDisplayValue('total')).toBeInTheDocument();
screen.getAllByRole('row')[2].click(); await userEvent.click(screen.getAllByRole('row')[2]);
expect(screen.queryByDisplayValue('total')).not.toBeInTheDocument(); expect(screen.queryByDisplayValue('total')).not.toBeInTheDocument();
}); });
@@ -59,15 +60,15 @@ describe('FlameGraphContainer', () => {
expect(screen.getByTestId('flameGraph')).toBeDefined(); expect(screen.getByTestId('flameGraph')).toBeDefined();
expect(screen.getByTestId('topTable')).toBeDefined(); expect(screen.getByTestId('topTable')).toBeDefined();
screen.getByText(/Top Table/).click(); await userEvent.click(screen.getByText(/Top Table/));
expect(screen.queryByTestId('flameGraph')).toBeNull(); expect(screen.queryByTestId('flameGraph')).toBeNull();
expect(screen.getByTestId('topTable')).toBeDefined(); expect(screen.getByTestId('topTable')).toBeDefined();
screen.getByText(/Flame Graph/).click(); await userEvent.click(screen.getByText(/Flame Graph/));
expect(screen.getByTestId('flameGraph')).toBeDefined(); expect(screen.getByTestId('flameGraph')).toBeDefined();
expect(screen.queryByTestId('topTable')).toBeNull(); expect(screen.queryByTestId('topTable')).toBeNull();
screen.getByText(/Both/).click(); await userEvent.click(screen.getByText(/Both/));
expect(screen.getByTestId('flameGraph')).toBeDefined(); expect(screen.getByTestId('flameGraph')).toBeDefined();
expect(screen.getByTestId('topTable')).toBeDefined(); expect(screen.getByTestId('topTable')).toBeDefined();
}); });