mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Chore: adjust more unit tests to work with react 18 (#64759)
adjust unit tests to work with react 18
This commit is contained in:
@@ -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'));
|
||||
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));
|
||||
|
||||
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} />);
|
||||
});
|
||||
render(<QueryEditor {...props} query={validMetricQueryBuilderQuery} />);
|
||||
|
||||
expect(screen.getByText('Metric Query')).toBeInTheDocument();
|
||||
const radio = screen.getByLabelText('Builder');
|
||||
expect(radio instanceof HTMLInputElement && radio.checked).toBeTruthy();
|
||||
});
|
||||
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();
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user