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

adjust unit tests to work with react 18
pull/64808/head
Ashley Harrison 2 years ago committed by GitHub
parent b6f77bdfdb
commit e0e6165f70
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 5
      .betterer.results
  2. 4
      packages/grafana-ui/src/components/Table/Table.test.tsx
  3. 6
      public/app/core/components/SharedPreferences/SharedPreferences.test.tsx
  4. 3
      public/app/features/alerting/unified/NotificationPolicies.test.tsx
  5. 6
      public/app/features/alerting/unified/RuleEditorExisting.test.tsx
  6. 129
      public/app/features/correlations/CorrelationsPage.test.tsx
  7. 23
      public/app/features/explore/ExplorePage.test.tsx
  8. 14
      public/app/features/explore/spec/query.test.tsx
  9. 14
      public/app/features/plugins/admin/pages/PluginDetails.test.tsx
  10. 37
      public/app/features/query/components/QueryGroup.test.tsx
  11. 26
      public/app/plugins/datasource/azuremonitor/components/LogsQueryEditor/LogsQueryEditor.test.tsx
  12. 43
      public/app/plugins/datasource/azuremonitor/components/ResourcePicker/ResourcePicker.test.tsx
  13. 6
      public/app/plugins/datasource/azuremonitor/components/VariableEditor/VariableEditor.test.tsx
  14. 56
      public/app/plugins/datasource/cloud-monitoring/components/VisualMetricQueryEditor.test.tsx
  15. 106
      public/app/plugins/datasource/cloudwatch/components/QueryEditor.test.tsx
  16. 14
      public/app/plugins/datasource/loki/components/LokiQueryEditor.test.tsx
  17. 6
      public/app/plugins/datasource/loki/querybuilder/components/LokiQueryBuilderContainer.test.tsx
  18. 10
      public/app/plugins/datasource/prometheus/querybuilder/shared/OperationList.testUtils.ts
  19. 15
      public/app/plugins/panel/flamegraph/components/FlameGraphContainer.test.tsx

@ -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.", "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": [
[0, 0, 0, "Unexpected any. Specify a different type.", "0"]
],

@ -548,7 +548,7 @@ describe('Table', () => {
});
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({
subData: new Array(getDefaultDataFrame().length).fill(0).map((i) =>
toDataFrame({
@ -588,7 +588,7 @@ describe('Table', () => {
{ 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');
expect(within(rowsAfterClick[1]).getByRole('table')).toBeInTheDocument();
expect(within(rowsAfterClick[1]).getByText(/number0/)).toBeInTheDocument();

@ -133,9 +133,11 @@ describe('SharedPreferences', () => {
expect(lightThemeRadio.checked).toBeTruthy();
});
it('renders the home dashboard preference', () => {
it('renders the home dashboard preference', async () => {
const dashboardSelect = getSelectParent(screen.getByLabelText('Home Dashboard'));
expect(dashboardSelect).toHaveTextContent('My Dashboard');
await waitFor(() => {
expect(dashboardSelect).toHaveTextContent('My Dashboard');
});
});
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) =>
[AccessControlAction.AlertingNotificationsRead, AccessControlAction.AlertingNotificationsRead].includes(
action as AccessControlAction
@ -387,6 +387,7 @@ describe('NotificationPolicies', () => {
);
renderNotificationPolicies();
await waitFor(() => expect(mocks.api.fetchAlertManagerConfig).toHaveBeenCalledTimes(1));
expect(ui.newPolicyButton.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 React from 'react';
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
const emptyFolderInput = await ui.inputs.folderContainer.find();
mocks.searchFolders.mockResolvedValue([] as DashboardSearchHit[]);
await renderRuleEditor(uid);
await act(async () => {
renderRuleEditor(uid);
});
await userEvent.click(within(emptyFolderInput).getByRole('combobox'));
expect(screen.getByText(ADD_NEW_FOLER_OPTION)).toBeInTheDocument();

@ -1,13 +1,5 @@
import {
render,
waitFor,
screen,
fireEvent,
waitForElementToBeRemoved,
within,
Matcher,
getByRole,
} from '@testing-library/react';
import { render, waitFor, screen, fireEvent, within, Matcher, getByRole } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { merge, uniqueId } from 'lodash';
import React from 'react';
import { DeepPartial } from 'react-hook-form';
@ -280,6 +272,9 @@ describe('CorrelationsPage', () => {
});
it('shows CTA', async () => {
const CTAButton = await screen.findByRole('button', { name: /add correlation/i });
expect(CTAButton).toBeInTheDocument();
// insert form should not be present
expect(screen.queryByRole('button', { name: /add$/i })).not.toBeInTheDocument();
@ -289,51 +284,43 @@ describe('CorrelationsPage', () => {
// there's no table in the page
expect(screen.queryByRole('table')).not.toBeInTheDocument();
const CTAButton = screen.getByRole('button', { name: /add correlation/i });
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));
await userEvent.click(CTAButton);
// 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 () => {
const CTAButton = screen.getByRole('button', { name: /add correlation/i });
const CTAButton = await screen.findByRole('button', { name: /add correlation/i });
expect(CTAButton).toBeInTheDocument();
// there's no table in the page, as we are adding the first correlation
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' } });
fireEvent.change(screen.getByRole('textbox', { name: /description/i }), { target: { value: 'A Description' } });
await userEvent.clear(screen.getByRole('textbox', { name: /label/i }));
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
fireEvent.keyDown(screen.getByLabelText(/^source$/i), { keyCode: 40 });
fireEvent.click(screen.getByText('loki'));
await userEvent.click(screen.getByText('loki'));
// set target datasource picker value
fireEvent.keyDown(screen.getByLabelText(/^target$/i), { keyCode: 40 });
fireEvent.click(screen.getByText('prometheus'));
fireEvent.change(screen.getByRole('textbox', { name: /target field/i }), { target: { value: 'Line' } });
await userEvent.click(screen.getByText('prometheus'));
await waitForElementToBeRemoved(() => screen.queryByText(/loading query editor/i));
await userEvent.clear(screen.getByRole('textbox', { name: /target field/i }));
await userEvent.type(screen.getByRole('textbox', { name: /target field/i }), 'Line');
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 }));
await userEvent.click(await screen.findByRole('button', { name: /add$/i }));
expect(mocks.reportInteraction).toHaveBeenLastCalledWith('grafana_correlations_added');
// 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 () => {
expect(screen.getByRole('table')).toBeInTheDocument();
expect(await screen.findByRole('table')).toBeInTheDocument();
});
it('correctly sorts by source', async () => {
// wait for table to appear
await screen.findByRole('table');
const sourceHeader = getByRole(getHeaderByName('Source'), 'button');
fireEvent.click(sourceHeader);
await userEvent.click(sourceHeader);
let cells = queryCellsByColumnName('Source');
cells.forEach((cell, i, allCells) => {
const prevCell = allCells[i - 1];
@ -427,7 +417,7 @@ describe('CorrelationsPage', () => {
}
});
fireEvent.click(sourceHeader);
await userEvent.click(sourceHeader);
cells = queryCellsByColumnName('Source');
cells.forEach((cell, i, allCells) => {
const prevCell = allCells[i - 1];
@ -438,46 +428,47 @@ describe('CorrelationsPage', () => {
});
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();
fireEvent.click(addNewButton);
await userEvent.click(addNewButton);
fireEvent.change(screen.getByRole('textbox', { name: /label/i }), { target: { value: 'A Label' } });
fireEvent.change(screen.getByRole('textbox', { name: /description/i }), { target: { value: 'A Description' } });
await userEvent.clear(screen.getByRole('textbox', { name: /label/i }));
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
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
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));
fireEvent.click(screen.getByRole('button', { name: /add$/i }));
// the form should get removed after successful submissions
await waitForElementToBeRemoved(() => screen.queryByRole('button', { name: /add$/i }));
await userEvent.click(screen.getByRole('button', { name: /add$/i }));
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 () => {
const addNewButton = screen.getByRole('button', { name: /add new/i });
const addNewButton = await screen.findByRole('button', { name: /add new/i });
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();
});
it('correctly deletes correlations', async () => {
// 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');
@ -485,36 +476,37 @@ describe('CorrelationsPage', () => {
expect(deleteButton).toBeInTheDocument();
fireEvent.click(deleteButton);
await userEvent.click(deleteButton);
const confirmButton = within(tableRows[0]).getByRole('button', { name: /delete$/i });
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');
});
it('correctly edits correlations', async () => {
// wait for table to appear
await screen.findByRole('table');
const tableRows = queryRowsByCellValue('Source', 'loki');
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');
await waitForElementToBeRemoved(() => screen.queryByText(/loading query editor/i));
fireEvent.change(screen.getByRole('textbox', { name: /label/i }), { target: { value: 'edited label' } });
fireEvent.change(screen.getByRole('textbox', { name: /description/i }), {
target: { value: 'edited description' },
});
await userEvent.clear(screen.getByRole('textbox', { name: /label/i }));
await userEvent.type(screen.getByRole('textbox', { name: /label/i }), 'edited label');
await userEvent.clear(screen.getByRole('textbox', { name: /description/i }));
await userEvent.type(screen.getByRole('textbox', { name: /description/i }), 'edited description');
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(() => {
expect(screen.queryByRole('cell', { name: /edited label$/i })).toBeInTheDocument();
@ -554,24 +546,21 @@ describe('CorrelationsPage', () => {
it("doesn't render delete button", async () => {
// 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();
});
it('edit form is read only', async () => {
// 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');
// 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
const labelInput = screen.getByRole('textbox', { name: /label/i });
const labelInput = await screen.findByRole('textbox', { name: /label/i });
expect(labelInput).toBeInTheDocument();
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 React, { ComponentProps } from 'react';
import AutoSizer from 'react-virtualized-auto-sizer';
@ -43,7 +43,7 @@ describe('ExplorePage', () => {
setupExplore();
// Wait for rendering the editor
const splitButton = await screen.findByText(/split/i);
fireEvent.click(splitButton);
await userEvent.click(splitButton);
await waitFor(() => {
const editors = screen.getAllByText('loki Editor input:');
expect(editors.length).toBe(2);
@ -123,9 +123,11 @@ describe('ExplorePage', () => {
jest.mocked(datasources.loki.query).mockReturnValue(makeLogsQueryResponse());
jest.mocked(datasources.elastic.query).mockReturnValue(makeLogsQueryResponse());
locationService.partial({
left: JSON.stringify(['now-1h', 'now', 'loki', { expr: '{ label="value"}' }]),
right: JSON.stringify(['now-1h', 'now', 'elastic', { expr: 'error' }]),
act(() => {
locationService.partial({
left: JSON.stringify(['now-1h', 'now', 'loki', { expr: '{ label="value"}' }]),
right: JSON.stringify(['now-1h', 'now', 'elastic', { expr: 'error' }]),
});
});
// Editor renders the new query
@ -145,7 +147,9 @@ describe('ExplorePage', () => {
// to work
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
await screen.findByText(`elastic Editor input: error`);
@ -155,7 +159,7 @@ describe('ExplorePage', () => {
it('handles split size events and sets relevant variables', async () => {
setupExplore();
const splitButton = await screen.findByText(/split/i);
fireEvent.click(splitButton);
await userEvent.click(splitButton);
await waitForExplore(undefined, true);
let widenButton = await screen.findAllByLabelText('Widen pane');
let narrowButton = await screen.queryAllByLabelText('Narrow pane');
@ -202,7 +206,9 @@ describe('ExplorePage', () => {
// to work
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'));
});
});
@ -404,6 +410,7 @@ describe('ExplorePage', () => {
it('removes `from` and `to` parameters from url when first mounted', async () => {
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.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 { locationService } from '@grafana/runtime';
@ -70,8 +70,10 @@ describe('Explore: handle running/not running query', () => {
jest.mocked(datasources.loki.query).mockReturnValueOnce(makeLogsQueryResponse('different log'));
locationService.partial({
left: JSON.stringify(['now-1h', 'now', 'loki', { expr: '{ label="different"}' }]),
act(() => {
locationService.partial({
left: JSON.stringify(['now-1h', 'now', 'loki', { expr: '{ label="different"}' }]),
});
});
// Editor renders the new query
@ -89,8 +91,10 @@ describe('Explore: handle running/not running query', () => {
jest.mocked(datasources.elastic.query).mockReturnValueOnce(makeMetricsQueryResponse());
locationService.partial({
left: JSON.stringify(['now-1h', 'now', 'elastic', { expr: 'other query' }]),
act(() => {
locationService.partial({
left: JSON.stringify(['now-1h', 'now', 'elastic', { expr: 'other query' }]),
});
});
// Editor renders the new query

@ -465,17 +465,17 @@ describe('Plugin details page', () => {
// Does not show an Install button
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();
// Does not show a Uninstall button
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();
// Does not show an Update button
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
// 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
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
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
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 () => {

@ -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 config from 'app/core/config';
@ -37,10 +38,13 @@ jest.mock('@grafana/runtime/src/services/dataSourceSrv', () => {
});
describe('QueryGroup', () => {
// QueryGroup relies on this being present
Object.defineProperty(HTMLElement.prototype, 'scrollTo', { value: jest.fn() });
beforeEach(() => {
jest.useFakeTimers();
config.expressionsEnabled = true;
});
it('Should add expression on click', async () => {
renderScenario({});
@ -48,8 +52,10 @@ describe('QueryGroup', () => {
const queryRowsContainer = await screen.findByTestId('query-editor-rows');
expect(queryRowsContainer.children.length).toBe(2);
await addExpressionButton.click();
expect(queryRowsContainer.children.length).toBe(3);
await userEvent.click(addExpressionButton);
await waitFor(() => {
expect(queryRowsContainer.children.length).toBe(3);
});
});
it('Should add query on click', async () => {
@ -59,9 +65,11 @@ describe('QueryGroup', () => {
const queryRowsContainer = await screen.findByTestId('query-editor-rows');
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 () => {
@ -69,14 +77,16 @@ describe('QueryGroup', () => {
const addExpressionButton = await screen.findByTestId('query-tab-add-expression');
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 lastEditorToggleRow = (await screen.findAllByLabelText('toggle collapse and expand query row')).at(-1);
expect(lastEditorToggleRow?.getAttribute('aria-expanded')).toBe('true');
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 () => {
@ -84,23 +94,23 @@ describe('QueryGroup', () => {
const addQueryButton = await screen.findByTestId('query-tab-add-query');
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 lastEditorToggleRow = (await screen.findAllByLabelText('toggle collapse and expand query row')).at(-1);
expect(lastEditorToggleRow?.getAttribute('aria-expanded')).toBe('true');
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 () => {
renderScenario({});
const openHelpButton = await screen.findByTestId('query-tab-help-button');
await act(async () => {
await openHelpButton.click();
});
await userEvent.click(openHelpButton);
const helpModal = await screen.findByRole('dialog');
expect(helpModal).toBeInTheDocument();
@ -109,6 +119,7 @@ describe('QueryGroup', () => {
it('Should not show add expression button when expressions are disabled', async () => {
config.expressionsEnabled = false;
renderScenario({});
await screen.findByTestId('query-tab-add-query');
const addExpressionButton = screen.queryByTestId('query-tab-add-expression');
expect(addExpressionButton).not.toBeInTheDocument();
});

@ -22,7 +22,7 @@ const variableOptionGroup = {
options: [],
};
describe('LogsQueryEdiutor', () => {
describe('LogsQueryEditor', () => {
const originalScrollIntoView = window.HTMLElement.prototype.scrollIntoView;
beforeEach(() => {
@ -50,13 +50,13 @@ describe('LogsQueryEdiutor', () => {
);
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' });
subscriptionButton.click();
await userEvent.click(subscriptionButton);
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');
await userEvent.click(checkbox);
@ -98,13 +98,13 @@ describe('LogsQueryEdiutor', () => {
);
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' });
subscriptionButton.click();
await userEvent.click(subscriptionButton);
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');
await userEvent.click(checkbox);
@ -131,13 +131,13 @@ describe('LogsQueryEdiutor', () => {
);
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' });
subscriptionButton.click();
await userEvent.click(subscriptionButton);
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');
await userEvent.click(checkbox);
@ -164,17 +164,17 @@ describe('LogsQueryEdiutor', () => {
);
const resourcePickerButton = await screen.findByRole('button', { name: 'Select a resource' });
resourcePickerButton.click();
await userEvent.click(resourcePickerButton);
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.findByLabelText('Resource URI(s)');
await userEvent.type(advancedInput, '/subscriptions/def-123');
const applyButton = screen.getByRole('button', { name: 'Apply' });
applyButton.click();
await userEvent.click(applyButton);
expect(onChange).toBeCalledWith(
expect.objectContaining({

@ -89,6 +89,10 @@ describe('AzureMonitor ResourcePicker', () => {
it('should show a subscription as selected if there is one saved', async () => {
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');
expect(subscriptionCheckboxes.length).toBe(2);
expect(subscriptionCheckboxes[0]).toBeChecked();
@ -133,7 +137,7 @@ describe('AzureMonitor ResourcePicker', () => {
const expandSubscriptionButton = await screen.findByLabelText('Expand Primary Subscription');
expect(expandSubscriptionButton).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();
});
@ -143,10 +147,10 @@ describe('AzureMonitor ResourcePicker', () => {
const subscriptionCheckbox = await screen.findByLabelText('Primary Subscription');
expect(subscriptionCheckbox).toBeInTheDocument();
expect(subscriptionCheckbox).not.toBeChecked();
subscriptionCheckbox.click();
await userEvent.click(subscriptionCheckbox);
const applyButton = screen.getByRole('button', { name: 'Apply' });
expect(applyButton).toBeEnabled();
applyButton.click();
await userEvent.click(applyButton);
expect(onApply).toBeCalledTimes(1);
expect(onApply).toBeCalledWith(['/subscriptions/def-123']);
});
@ -157,9 +161,9 @@ describe('AzureMonitor ResourcePicker', () => {
const subscriptionCheckbox = await screen.findAllByLabelText('Primary Subscription');
expect(subscriptionCheckbox).toHaveLength(2);
expect(subscriptionCheckbox.at(0)).toBeChecked();
subscriptionCheckbox.at(0)?.click();
await userEvent.click(subscriptionCheckbox.at(0)!);
const applyButton = screen.getByRole('button', { name: 'Apply' });
applyButton.click();
await userEvent.click(applyButton);
expect(onApply).toBeCalledTimes(1);
expect(onApply).toBeCalledWith([]);
});
@ -172,9 +176,9 @@ describe('AzureMonitor ResourcePicker', () => {
const subscriptionCheckbox = await screen.findAllByLabelText('A Great Resource Group');
expect(subscriptionCheckbox).toHaveLength(2);
expect(subscriptionCheckbox.at(0)).toBeChecked();
subscriptionCheckbox.at(0)?.click();
await userEvent.click(subscriptionCheckbox.at(0)!);
const applyButton = screen.getByRole('button', { name: 'Apply' });
applyButton.click();
await userEvent.click(applyButton);
expect(onApply).toBeCalledTimes(1);
expect(onApply).toBeCalledWith([]);
});
@ -186,15 +190,15 @@ describe('AzureMonitor ResourcePicker', () => {
const subscriptionButton = await screen.findByRole('button', { name: 'Expand Primary Subscription' });
expect(subscriptionButton).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' });
resourceGroupButton.click();
await userEvent.click(resourceGroupButton);
const checkbox = await screen.findByLabelText('web-server');
await userEvent.click(checkbox);
expect(checkbox).toBeChecked();
const applyButton = screen.getByRole('button', { name: 'Apply' });
applyButton.click();
await userEvent.click(applyButton);
expect(onApply).toBeCalledTimes(1);
expect(onApply).toBeCalledWith([
@ -231,9 +235,9 @@ describe('AzureMonitor ResourcePicker', () => {
const checkbox = await screen.findAllByLabelText('web-server');
expect(checkbox).toHaveLength(2);
expect(checkbox.at(0)).toBeChecked();
checkbox.at(0)?.click();
await userEvent.click(checkbox.at(0)!);
const applyButton = screen.getByRole('button', { name: 'Apply' });
applyButton.click();
await userEvent.click(applyButton);
expect(onApply).toBeCalledTimes(1);
expect(onApply).toBeCalledWith([]);
});
@ -269,13 +273,11 @@ describe('AzureMonitor ResourcePicker', () => {
it('renders a loading state while waiting for search results', async () => {
const rpd = createMockResourcePickerData();
rpd.search = jest.fn().mockImplementation(() => {
return new Promise((resolve) => {
setTimeout(() => {
return resolve(mockSearchResults());
}, 1); // purposely slow down call by a tick so as to force a loading state
});
let promiseResolver: (value: unknown) => void = () => {};
const promiseToResolve = new Promise((resolve) => {
promiseResolver = resolve;
});
rpd.search = jest.fn().mockImplementation(() => promiseToResolve);
render(<ResourcePicker {...defaultProps} resourcePickerData={rpd} />);
@ -287,6 +289,9 @@ describe('AzureMonitor ResourcePicker', () => {
const loading = await screen.findByText('Loading...');
expect(loading).toBeInTheDocument();
// resolve the promise
promiseResolver(mockSearchResults());
const searchResult = await screen.findByLabelText('search-result');
expect(searchResult).toBeInTheDocument();
@ -330,7 +335,7 @@ describe('AzureMonitor ResourcePicker', () => {
/>
);
const subscriptionExpand = await screen.findByLabelText('Expand Primary Subscription');
await subscriptionExpand.click();
await userEvent.click(subscriptionExpand);
const error = await screen.findByRole('alert');
expect(error).toHaveTextContent('An error occurred while requesting resources from Azure Monitor');
expect(error).toHaveTextContent(

@ -47,7 +47,7 @@ describe('VariableEditor:', () => {
render(<VariableEditor {...defaultProps} onChange={onChange} query={legacyQuery} />);
await waitFor(() => screen.getByLabelText('select query type'));
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', {
container: document.body,
});
@ -185,7 +185,7 @@ describe('VariableEditor:', () => {
rerender: (ui: React.ReactElement) => void
) => {
openMenu(screen.getByLabelText(label));
screen.getByText(text).click();
await userEvent.click(screen.getByText(text));
// Simulate onChange behavior
const newQuery = onChange.mock.calls.at(-1)[0];
rerender(<VariableEditor {...defaultProps} query={newQuery} onChange={onChange} />);
@ -226,7 +226,7 @@ describe('VariableEditor:', () => {
// Select a subscription
openMenu(screen.getByLabelText('select subscription'));
await waitFor(() => expect(screen.getByText('Primary Subscription')).toBeInTheDocument());
screen.getByText('Template Variables').click();
await userEvent.click(screen.getByText('Template Variables'));
// Simulate onChange behavior
const lastQuery = onChange.mock.calls.at(-1)[0];
rerender(<VariableEditor {...defaultProps} query={lastQuery} onChange={onChange} />);

@ -45,13 +45,13 @@ describe('VisualMetricQueryEditor', () => {
render(<VisualMetricQueryEditor {...defaultProps} onChange={onChange} datasource={datasource} query={query} />);
const service = await screen.findByLabelText('Service');
await openMenu(service);
openMenu(service);
await act(async () => {
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 () => {
@ -66,19 +66,19 @@ describe('VisualMetricQueryEditor', () => {
render(<VisualMetricQueryEditor {...defaultProps} onChange={onChange} datasource={datasource} query={query} />);
const service = await screen.findByLabelText('Service');
await openMenu(service);
openMenu(service);
await act(async () => {
await select(service, 'Srv', { container: document.body });
});
const metricName = await screen.findByLabelText('Metric name');
await openMenu(metricName);
openMenu(metricName);
await waitFor(() => expect(document.body).toHaveTextContent('metricName_test'));
await act(async () => {
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 () => {
@ -114,12 +114,12 @@ describe('VisualMetricQueryEditor', () => {
render(<VisualMetricQueryEditor {...defaultProps} onChange={onChange} datasource={datasource} query={query} />);
const service = await screen.findByLabelText('Service');
await openMenu(service);
openMenu(service);
await act(async () => {
await select(service, 'Srv A', { container: document.body });
});
const metricName = await screen.findByLabelText('Metric name');
await openMenu(metricName);
openMenu(metricName);
const metricNameOptions = screen.getByLabelText('Select options menu');
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('description_metric3')).not.toBeInTheDocument();
await openMenu(service);
openMenu(service);
await act(async () => {
await select(service, 'Srv B', { container: document.body });
});
@ -172,7 +172,7 @@ describe('VisualMetricQueryEditor', () => {
render(<VisualMetricQueryEditor {...defaultProps} onChange={onChange} datasource={datasource} query={query} />);
const service = await screen.findByLabelText('Service');
await openMenu(service);
openMenu(service);
expect(screen.getAllByLabelText('Select option').length).toEqual(2);
});
@ -233,8 +233,8 @@ describe('VisualMetricQueryEditor', () => {
);
expect(query).toEqual(defaultQuery);
expect(document.body).toHaveTextContent('metric.test_label');
expect(await screen.queryByText('Delta')).not.toBeInTheDocument();
expect(await screen.queryByText('metric.test_groupby')).not.toBeInTheDocument();
expect(screen.queryByText('Delta')).not.toBeInTheDocument();
expect(screen.queryByText('metric.test_groupby')).not.toBeInTheDocument();
});
it('updates labels on time range change', async () => {
@ -257,30 +257,28 @@ describe('VisualMetricQueryEditor', () => {
);
const service = await screen.findByLabelText('Service');
await openMenu(service);
openMenu(service);
await act(async () => {
await select(service, 'Srv', { container: document.body });
});
const metricName = await screen.findByLabelText('Metric name');
await openMenu(metricName);
openMenu(metricName);
await waitFor(() => expect(document.body).toHaveTextContent('metricName'));
await act(async () => {
await select(metricName, 'metricName', { container: document.body });
});
const groupBy = await screen.findByLabelText('Group by');
await openMenu(groupBy);
openMenu(groupBy);
await waitFor(() => expect(document.body).toHaveTextContent('metric.test_groupby'));
await act(async () => {
timeSrv.setTime({ from: 'now-12h', to: 'now' });
const datasourceUpdated = createMockDatasource({
timeSrv,
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'));
timeSrv.setTime({ from: 'now-12h', to: 'now' });
const datasourceUpdated = createMockDatasource({
timeSrv,
getLabels: jest.fn().mockResolvedValue({ '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 { QueryEditorProps } from '@grafana/data';
@ -64,10 +65,8 @@ describe('QueryEditor should render right editor', () => {
region: 'default',
returnData: false,
};
await act(async () => {
render(<QueryEditor {...props} query={query} />);
});
expect(screen.getByText('Metric name')).toBeInTheDocument();
render(<QueryEditor {...props} query={query} />);
expect(await screen.findByText('Metric name')).toBeInTheDocument();
});
});
@ -91,11 +90,9 @@ describe('QueryEditor should render right editor', () => {
refId: 'A',
region: 'ap-northeast-2',
statistics: 'Average',
} as any;
await act(async () => {
render(<QueryEditor {...props} query={query} />);
});
expect(screen.getByText('Metric name')).toBeInTheDocument();
} as CloudWatchQuery;
render(<QueryEditor {...props} query={query} />);
expect(await screen.findByText('Metric name')).toBeInTheDocument();
});
});
@ -119,11 +116,9 @@ describe('QueryEditor should render right editor', () => {
refId: 'A',
region: 'ap-northeast-2',
statistic: 'Average',
} as any;
await act(async () => {
render(<QueryEditor {...props} query={query} />);
});
expect(screen.getByText('Select Log Groups')).toBeInTheDocument();
} as CloudWatchQuery;
render(<QueryEditor {...props} query={query} />);
expect(await screen.findByText('Select Log Groups')).toBeInTheDocument();
});
});
@ -146,11 +141,9 @@ describe('QueryEditor should render right editor', () => {
refId: 'B',
region: '$region',
statistic: 'Average',
} as any;
await act(async () => {
render(<QueryEditor {...props} query={query} />);
});
expect(screen.getByText('Metric name')).toBeInTheDocument();
} as CloudWatchQuery;
render(<QueryEditor {...props} query={query} />);
expect(await screen.findByText('Metric name')).toBeInTheDocument();
});
});
@ -191,10 +184,8 @@ describe('QueryEditor should render right editor', () => {
test.each(cases)('$name', async ({ query, toggle }) => {
config.featureToggles.cloudWatchCrossAccountQuerying = toggle;
await act(async () => {
render(<QueryEditor {...props} datasource={datasourceMock.datasource} query={query} />);
});
expect(await screen.getByText('Monitoring account')).toBeInTheDocument();
render(<QueryEditor {...props} datasource={datasourceMock.datasource} query={query} />);
expect(await screen.findByText('Monitoring account')).toBeInTheDocument();
});
});
@ -224,34 +215,29 @@ describe('QueryEditor should render right editor', () => {
];
test.each(cases)('$name', async ({ query, toggle }) => {
config.featureToggles.cloudWatchCrossAccountQuerying = toggle;
await act(async () => {
render(<QueryEditor {...props} datasource={datasourceMock.datasource} query={query} />);
});
expect(await screen.queryByText('Monitoring account')).toBeNull();
render(<QueryEditor {...props} datasource={datasourceMock.datasource} query={query} />);
expect(await screen.findByText('Run queries')).toBeInTheDocument();
expect(screen.queryByText('Monitoring account')).toBeNull();
});
});
});
describe('QueryHeader', () => {
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.getByText('CloudWatch Metrics')).toBeInTheDocument();
expect(screen.getByLabelText('Builder')).toBeInTheDocument();
expect(screen.getByLabelText('Code')).toBeInTheDocument();
expect(screen.getByText('Metric Query')).toBeInTheDocument();
});
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.getByText('CloudWatch Logs')).toBeInTheDocument();
expect(screen.queryByLabelText('Builder')).not.toBeInTheDocument();
expect(screen.queryByLabelText('Code')).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', () => {
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');
expect(radio instanceof HTMLInputElement && radio.checked).toBeTruthy();
});
it('when metric query type is metric search and editor mode is raw', async () => {
await act(async () => {
render(<QueryEditor {...props} query={validMetricSearchCodeQuery} />);
});
expect(screen.getByText('Metric Search')).toBeInTheDocument();
render(<QueryEditor {...props} query={validMetricSearchCodeQuery} />);
expect(await screen.findByText('Metric Search')).toBeInTheDocument();
const radio = screen.getByLabelText('Code');
expect(radio instanceof HTMLInputElement && radio.checked).toBeTruthy();
});
it('when metric query type is metric query and editor mode is builder', async () => {
await act(async () => {
await act(async () => {
render(<QueryEditor {...props} query={validMetricQueryBuilderQuery} />);
});
expect(screen.getByText('Metric Query')).toBeInTheDocument();
const radio = screen.getByLabelText('Builder');
expect(radio instanceof HTMLInputElement && radio.checked).toBeTruthy();
});
render(<QueryEditor {...props} query={validMetricQueryBuilderQuery} />);
expect(await screen.findByText('Metric Query')).toBeInTheDocument();
const radio = screen.getByLabelText('Builder');
expect(radio instanceof HTMLInputElement && radio.checked).toBeTruthy();
});
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');
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
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');
expect(builderElement).toBeInTheDocument();
await act(async () => {
await builderElement.click();
});
await userEvent.click(builderElement);
const modalTitleElem = screen.getByText('Are you sure?');
expect(modalTitleElem).toBeInTheDocument();
@ -332,9 +308,7 @@ describe('QueryEditor should render right editor', () => {
);
const builderElement = screen.getByLabelText('Builder');
expect(builderElement).toBeInTheDocument();
await act(async () => {
await builderElement.click();
});
await userEvent.click(builderElement);
expect(screen.queryByText('Are you sure?')).toBeNull();
});
@ -343,9 +317,7 @@ describe('QueryEditor should render right editor', () => {
const builderElement = screen.getByLabelText('Builder');
expect(builderElement).toBeInTheDocument();
await act(async () => {
await builderElement.click();
});
await userEvent.click(builderElement);
expect(screen.queryByText('Are you sure?')).toBeNull();
});
});

@ -88,19 +88,21 @@ describe('LokiQueryEditorSelector', () => {
await expectBuilder();
});
it('shows Run Queries button in Dashboards', () => {
it('shows Run Queries button in Dashboards', async () => {
renderWithProps({}, { app: CoreApp.Dashboard });
expectRunQueriesButton();
await expectRunQueriesButton();
});
it('hides Run Queries button in Explore', async () => {
renderWithProps({}, { app: CoreApp.Explore });
await expectCodeEditor();
expectNoRunQueriesButton();
});
it('hides Run Queries button in Correlations Page', async () => {
renderWithProps({}, { app: CoreApp.Correlations });
await expectNoRunQueriesButton();
await expectCodeEditor();
expectNoRunQueriesButton();
});
it('changes to builder mode', async () => {
@ -128,7 +130,7 @@ describe('LokiQueryEditorSelector', () => {
it('Can enable explain', async () => {
renderWithMode(QueryEditorMode.Builder);
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();
});
@ -198,8 +200,8 @@ async function expectBuilder() {
expect(await screen.findByText('Label filters')).toBeInTheDocument();
}
function expectRunQueriesButton() {
expect(screen.getByRole('button', { name: /run queries/i })).toBeInTheDocument();
async function expectRunQueriesButton() {
expect(await screen.findByRole('button', { name: /run queries/i })).toBeInTheDocument();
}
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 { DataSourcePluginMeta } from '@grafana/data';
@ -39,9 +39,7 @@ describe('LokiQueryBuilderContainer', () => {
render(<LokiQueryBuilderContainer {...props} />);
const selector = await screen.findByLabelText('selector');
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(props.onChange).toBeCalledWith({
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';
export async function addOperation(section: string, op: string) {
const addOperationButton = screen.getByTitle('Add operation');
expect(addOperationButton).toBeInTheDocument();
await userEvent.click(addOperationButton);
const sectionItem = screen.getByTitle(section);
const sectionItem = await screen.findByTitle(section);
expect(sectionItem).toBeInTheDocument();
// 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.
fireEvent.click(sectionItem.children[0]);
await userEvent.click(sectionItem.children[0], { pointerEventsCheck: 0 });
const opItem = screen.getByTitle(op);
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 userEvent from '@testing-library/user-event';
import React from 'react';
import { CoreApp, MutableDataFrame } from '@grafana/data';
@ -20,6 +20,7 @@ describe('FlameGraphContainer', () => {
// Needed for AutoSizer to work in test
Object.defineProperty(HTMLElement.prototype, 'offsetHeight', { value: 500 });
Object.defineProperty(HTMLElement.prototype, 'offsetWidth', { value: 500 });
Object.defineProperty(HTMLElement.prototype, 'clientWidth', { value: 500 });
const FlameGraphContainerWithProps = () => {
const flameGraphData = new MutableDataFrame(data);
@ -38,11 +39,11 @@ describe('FlameGraphContainer', () => {
it('should update search when row selected in top table', async () => {
render(<FlameGraphContainerWithProps />);
screen.getAllByRole('row')[1].click();
await userEvent.click((await screen.findAllByRole('row'))[1]);
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();
screen.getAllByRole('row')[2].click();
await userEvent.click(screen.getAllByRole('row')[2]);
expect(screen.queryByDisplayValue('total')).not.toBeInTheDocument();
});
@ -59,15 +60,15 @@ describe('FlameGraphContainer', () => {
expect(screen.getByTestId('flameGraph')).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.getByTestId('topTable')).toBeDefined();
screen.getByText(/Flame Graph/).click();
await userEvent.click(screen.getByText(/Flame Graph/));
expect(screen.getByTestId('flameGraph')).toBeDefined();
expect(screen.queryByTestId('topTable')).toBeNull();
screen.getByText(/Both/).click();
await userEvent.click(screen.getByText(/Both/));
expect(screen.getByTestId('flameGraph')).toBeDefined();
expect(screen.getByTestId('topTable')).toBeDefined();
});

Loading…
Cancel
Save