diff --git a/package.json b/package.json
index b3cc652ef93..2d374394048 100644
--- a/package.json
+++ b/package.json
@@ -113,7 +113,7 @@
"@testing-library/jest-dom": "5.16.2",
"@testing-library/react": "12.1.4",
"@testing-library/react-hooks": "7.0.2",
- "@testing-library/user-event": "13.5.0",
+ "@testing-library/user-event": "14.0.0",
"@types/angular": "1.8.4",
"@types/angular-route": "1.7.2",
"@types/classnames": "2.3.0",
diff --git a/packages/grafana-data/package.json b/packages/grafana-data/package.json
index b4252fa7bb3..aeabae904ef 100644
--- a/packages/grafana-data/package.json
+++ b/packages/grafana-data/package.json
@@ -51,7 +51,7 @@
"@testing-library/jest-dom": "5.16.2",
"@testing-library/react": "12.1.4",
"@testing-library/react-hooks": "7.0.2",
- "@testing-library/user-event": "13.5.0",
+ "@testing-library/user-event": "14.0.0",
"@types/history": "4.7.11",
"@types/jest": "27.4.1",
"@types/jquery": "3.5.14",
diff --git a/packages/grafana-runtime/package.json b/packages/grafana-runtime/package.json
index 5f22ae36d8c..db4c9296007 100644
--- a/packages/grafana-runtime/package.json
+++ b/packages/grafana-runtime/package.json
@@ -40,7 +40,7 @@
"@rollup/plugin-node-resolve": "13.1.3",
"@testing-library/dom": "8.13.0",
"@testing-library/react": "12.1.4",
- "@testing-library/user-event": "^13.5.0",
+ "@testing-library/user-event": "14.0.0",
"@types/angular": "1.8.4",
"@types/history": "4.7.11",
"@types/jest": "27.4.1",
diff --git a/packages/grafana-runtime/src/components/DataSourcePicker.test.tsx b/packages/grafana-runtime/src/components/DataSourcePicker.test.tsx
index 6f18fe2141a..10a2cbd7b17 100644
--- a/packages/grafana-runtime/src/components/DataSourcePicker.test.tsx
+++ b/packages/grafana-runtime/src/components/DataSourcePicker.test.tsx
@@ -12,7 +12,7 @@ describe('DataSourcePicker', () => {
const select = render();
const clearButton = select.getByLabelText('select-clear-value');
- userEvent.click(clearButton);
+ await userEvent.click(clearButton);
expect(onClear).toHaveBeenCalled();
});
diff --git a/packages/grafana-ui/package.json b/packages/grafana-ui/package.json
index d73b877eb70..a36db9237a8 100644
--- a/packages/grafana-ui/package.json
+++ b/packages/grafana-ui/package.json
@@ -118,7 +118,7 @@
"@testing-library/jest-dom": "5.16.2",
"@testing-library/react": "12.1.4",
"@testing-library/react-hooks": "7.0.2",
- "@testing-library/user-event": "13.5.0",
+ "@testing-library/user-event": "14.0.0",
"@types/classnames": "2.3.0",
"@types/common-tags": "^1.8.0",
"@types/d3": "7.1.0",
diff --git a/packages/grafana-ui/src/components/Cascader/Cascader.test.tsx b/packages/grafana-ui/src/components/Cascader/Cascader.test.tsx
index 048756a565f..b0f36e10610 100644
--- a/packages/grafana-ui/src/components/Cascader/Cascader.test.tsx
+++ b/packages/grafana-ui/src/components/Cascader/Cascader.test.tsx
@@ -1,7 +1,8 @@
import React from 'react';
import { Cascader, CascaderOption, CascaderProps } from './Cascader';
import { act, render, screen } from '@testing-library/react';
-import userEvent from '@testing-library/user-event';
+import userEvent, { PointerEventsCheckLevel } from '@testing-library/user-event';
+import { UserEvent } from '@testing-library/user-event/dist/types/setup';
const options = [
{
@@ -45,78 +46,86 @@ describe('Cascader', () => {
const placeholder = 'cascader-placeholder';
describe('options from state change', () => {
+ let user: UserEvent;
+
beforeEach(() => {
jest.useFakeTimers('modern');
+ // Need to use delay: null here to work with fakeTimers
+ // see https://github.com/testing-library/user-event/issues/833
+ user = userEvent.setup({ delay: null });
});
- it('displays updated options', () => {
+ afterEach(() => {
+ jest.useRealTimers();
+ });
+
+ it('displays updated options', async () => {
render();
- act(() => {
- userEvent.click(screen.getByPlaceholderText(placeholder));
- });
+ await user.click(screen.getByPlaceholderText(placeholder));
expect(screen.getByText('Initial state option')).toBeInTheDocument();
expect(screen.queryByText('First')).not.toBeInTheDocument();
act(() => {
jest.runAllTimers();
- userEvent.click(screen.getByPlaceholderText(placeholder));
});
+ await user.click(screen.getByPlaceholderText(placeholder));
+
expect(screen.queryByText('Initial state option')).not.toBeInTheDocument();
expect(screen.getByText('First')).toBeInTheDocument();
});
- it('filters updated results when searching', () => {
+ it('filters updated results when searching', async () => {
render();
act(() => {
jest.runAllTimers();
});
- userEvent.type(screen.getByPlaceholderText(placeholder), 'Third');
+ await user.type(screen.getByPlaceholderText(placeholder), 'Third');
expect(screen.queryByText('Second')).not.toBeInTheDocument();
expect(screen.getByText('First / Third')).toBeInTheDocument();
});
});
- it('filters results when searching', () => {
+ it('filters results when searching', async () => {
render();
- userEvent.type(screen.getByPlaceholderText(placeholder), 'Third');
+ await userEvent.type(screen.getByPlaceholderText(placeholder), 'Third');
expect(screen.queryByText('Second')).not.toBeInTheDocument();
expect(screen.getByText('First / Third')).toBeInTheDocument();
});
- it('displays selected value with all levels when displayAllSelectedLevels is true and selecting a value from the search', () => {
+ it('displays selected value with all levels when displayAllSelectedLevels is true and selecting a value from the search', async () => {
render(
);
- userEvent.type(screen.getByPlaceholderText(placeholder), 'Third');
- userEvent.click(screen.getByText('First / Third'));
+ await userEvent.type(screen.getByPlaceholderText(placeholder), 'Third');
+ await userEvent.click(screen.getByText('First / Third'));
expect(screen.getByDisplayValue('First / Third')).toBeInTheDocument();
});
- it('displays all levels selected with default separator when displayAllSelectedLevels is true', () => {
+ it('displays all levels selected with default separator when displayAllSelectedLevels is true', async () => {
render(
{}} />
);
expect(screen.queryByDisplayValue('First/Second')).not.toBeInTheDocument();
- userEvent.click(screen.getByPlaceholderText(placeholder));
+ await userEvent.click(screen.getByPlaceholderText(placeholder));
// TODO remove skipPointerEventsCheck once https://github.com/jsdom/jsdom/issues/3232 is fixed
- userEvent.click(screen.getByText('First'), undefined, { skipPointerEventsCheck: true });
- userEvent.click(screen.getByText('Second'), undefined, { skipPointerEventsCheck: true });
+ await userEvent.click(screen.getByText('First'), { pointerEventsCheck: PointerEventsCheckLevel.Never });
+ await userEvent.click(screen.getByText('Second'), { pointerEventsCheck: PointerEventsCheckLevel.Never });
expect(screen.getByDisplayValue('First/Second')).toBeInTheDocument();
});
- it('displays all levels selected with separator passed in when displayAllSelectedLevels is true', () => {
+ it('displays all levels selected with separator passed in when displayAllSelectedLevels is true', async () => {
const separator = ',';
render(
@@ -131,34 +140,34 @@ describe('Cascader', () => {
expect(screen.queryByDisplayValue('First/Second')).not.toBeInTheDocument();
- userEvent.click(screen.getByPlaceholderText(placeholder));
+ await userEvent.click(screen.getByPlaceholderText(placeholder));
// TODO remove skipPointerEventsCheck once https://github.com/jsdom/jsdom/issues/3232 is fixed
- userEvent.click(screen.getByText('First'), undefined, { skipPointerEventsCheck: true });
- userEvent.click(screen.getByText('Second'), undefined, { skipPointerEventsCheck: true });
+ await userEvent.click(screen.getByText('First'), { pointerEventsCheck: PointerEventsCheckLevel.Never });
+ await userEvent.click(screen.getByText('Second'), { pointerEventsCheck: PointerEventsCheckLevel.Never });
expect(screen.getByDisplayValue(`First${separator}Second`)).toBeInTheDocument();
});
- it('displays last level selected when displayAllSelectedLevels is false', () => {
+ it('displays last level selected when displayAllSelectedLevels is false', async () => {
render(
);
- userEvent.click(screen.getByPlaceholderText(placeholder));
+ await userEvent.click(screen.getByPlaceholderText(placeholder));
// TODO remove skipPointerEventsCheck once https://github.com/jsdom/jsdom/issues/3232 is fixed
- userEvent.click(screen.getByText('First'), undefined, { skipPointerEventsCheck: true });
- userEvent.click(screen.getByText('Second'), undefined, { skipPointerEventsCheck: true });
+ await userEvent.click(screen.getByText('First'), { pointerEventsCheck: PointerEventsCheckLevel.Never });
+ await userEvent.click(screen.getByText('Second'), { pointerEventsCheck: PointerEventsCheckLevel.Never });
expect(screen.getByDisplayValue('Second')).toBeInTheDocument();
});
- it('displays last level selected when displayAllSelectedLevels is not passed in', () => {
+ it('displays last level selected when displayAllSelectedLevels is not passed in', async () => {
render();
- userEvent.click(screen.getByPlaceholderText(placeholder));
+ await userEvent.click(screen.getByPlaceholderText(placeholder));
// TODO remove skipPointerEventsCheck once https://github.com/jsdom/jsdom/issues/3232 is fixed
- userEvent.click(screen.getByText('First'), undefined, { skipPointerEventsCheck: true });
- userEvent.click(screen.getByText('Second'), undefined, { skipPointerEventsCheck: true });
+ await userEvent.click(screen.getByText('First'), { pointerEventsCheck: PointerEventsCheckLevel.Never });
+ await userEvent.click(screen.getByText('Second'), { pointerEventsCheck: PointerEventsCheckLevel.Never });
expect(screen.getByDisplayValue('Second')).toBeInTheDocument();
});
diff --git a/packages/grafana-ui/src/components/ColorPicker/ColorPickerPopover.test.tsx b/packages/grafana-ui/src/components/ColorPicker/ColorPickerPopover.test.tsx
index 1c0ab924223..d4f22689b04 100644
--- a/packages/grafana-ui/src/components/ColorPicker/ColorPickerPopover.test.tsx
+++ b/packages/grafana-ui/src/components/ColorPicker/ColorPickerPopover.test.tsx
@@ -1,5 +1,5 @@
import React from 'react';
-import { act, render, screen } from '@testing-library/react';
+import { render, screen } from '@testing-library/react';
import { ColorPickerPopover } from './ColorPickerPopover';
import { createTheme } from '@grafana/data';
import userEvent from '@testing-library/user-event';
@@ -7,24 +7,20 @@ import userEvent from '@testing-library/user-event';
describe('ColorPickerPopover', () => {
const theme = createTheme();
- it('should be tabbable', () => {
+ it('should be tabbable', async () => {
render( {}} />);
const color = screen.getByRole('button', { name: 'dark-red color' });
const customTab = screen.getByRole('button', { name: 'Custom' });
- act(() => {
- userEvent.tab();
- });
+ await userEvent.tab();
expect(customTab).toHaveFocus();
- act(() => {
- userEvent.tab();
- });
+ await userEvent.tab();
expect(color).toHaveFocus();
});
describe('rendering', () => {
- it('should render provided color as selected if color provided by name', () => {
+ it('should render provided color as selected if color provided by name', async () => {
render( {}} />);
const color = screen.getByRole('button', { name: 'green color' });
const colorSwatchWrapper = screen.getAllByTestId('data-testid-colorswatch');
@@ -32,9 +28,7 @@ describe('ColorPickerPopover', () => {
expect(color).toBeInTheDocument();
expect(colorSwatchWrapper[0]).toBeInTheDocument();
- act(() => {
- userEvent.click(colorSwatchWrapper[0]);
- });
+ await userEvent.click(colorSwatchWrapper[0]);
expect(color).toHaveStyle('box-shadow: inset 0 0 0 2px #73BF69,inset 0 0 0 4px #000000');
});
});
@@ -42,23 +36,19 @@ describe('ColorPickerPopover', () => {
describe('named colors support', () => {
const onChangeSpy = jest.fn();
- it('should pass hex color value to onChange prop by default', () => {
+ it('should pass hex color value to onChange prop by default', async () => {
render();
const color = screen.getByRole('button', { name: 'red color' });
- act(() => {
- userEvent.click(color);
- });
+ await userEvent.click(color);
expect(onChangeSpy).toBeCalledTimes(1);
expect(onChangeSpy).toBeCalledWith(theme.visualization.getColorByName('red'));
});
- it('should pass color name to onChange prop when named colors enabled', () => {
+ it('should pass color name to onChange prop when named colors enabled', async () => {
render();
const color = screen.getByRole('button', { name: 'red color' });
- act(() => {
- userEvent.click(color);
- });
+ await userEvent.click(color);
expect(onChangeSpy).toBeCalledTimes(2);
expect(onChangeSpy).toBeCalledWith(theme.visualization.getColorByName('red'));
diff --git a/packages/grafana-ui/src/components/ConfirmButton/ConfirmButton.test.tsx b/packages/grafana-ui/src/components/ConfirmButton/ConfirmButton.test.tsx
index c9e4d9cd4f3..3fd006dc194 100644
--- a/packages/grafana-ui/src/components/ConfirmButton/ConfirmButton.test.tsx
+++ b/packages/grafana-ui/src/components/ConfirmButton/ConfirmButton.test.tsx
@@ -6,7 +6,7 @@ import { ConfirmButton } from './ConfirmButton';
import { expect } from '../../../../../public/test/lib/common';
describe('ConfirmButton', () => {
- it('should show confirm delete when clicked', () => {
+ it('should show confirm delete when clicked', async () => {
const onConfirm = jest.fn();
render(
@@ -17,18 +17,18 @@ describe('ConfirmButton', () => {
// Confirm button should not be visible before clicking the Delete button
expect(screen.queryByRole('button', { name: 'Confirm delete' })).not.toBeInTheDocument();
- userEvent.click(screen.getByRole('button', { name: 'Delete' }));
+ await userEvent.click(screen.getByRole('button', { name: 'Delete' }));
// Confirm button should now be visible
expect(screen.getByRole('button', { name: 'Confirm delete' })).toBeInTheDocument();
- userEvent.click(screen.getByRole('button', { name: 'Confirm delete' }));
+ await userEvent.click(screen.getByRole('button', { name: 'Confirm delete' }));
expect(onConfirm).toHaveBeenCalled();
// Confirm button should be visible if closeOnConfirm is false
expect(screen.queryByRole('button', { name: 'Confirm delete' })).toBeInTheDocument();
});
- it('should hide confirm delete when closeOnConfirm is true', () => {
+ it('should hide confirm delete when closeOnConfirm is true', async () => {
render(
{}} closeOnConfirm={true}>
Delete
@@ -38,17 +38,17 @@ describe('ConfirmButton', () => {
// Confirm button should not be visible before clicking the Delete button
expect(screen.queryByRole('button', { name: 'Confirm delete' })).not.toBeInTheDocument();
- userEvent.click(screen.getByRole('button', { name: 'Delete' }));
+ await userEvent.click(screen.getByRole('button', { name: 'Delete' }));
// Confirm button should now be visible
expect(screen.getByRole('button', { name: 'Confirm delete' })).toBeInTheDocument();
- userEvent.click(screen.getByRole('button', { name: 'Confirm delete' }));
+ await userEvent.click(screen.getByRole('button', { name: 'Confirm delete' }));
// Confirm button should not be visible if closeOnConfirm is true
expect(screen.queryByRole('button', { name: 'Confirm delete' })).not.toBeInTheDocument();
});
- it('should show cancel when clicked', () => {
+ it('should show cancel when clicked', async () => {
const onCancel = jest.fn();
render(
{}}>
@@ -59,11 +59,11 @@ describe('ConfirmButton', () => {
// Cancel button should not be visible before clicking the Delete button
expect(screen.queryByRole('button', { name: 'Cancel' })).not.toBeInTheDocument();
- userEvent.click(screen.getByRole('button', { name: 'Delete' }));
+ await userEvent.click(screen.getByRole('button', { name: 'Delete' }));
// Cancel button should now be visible
expect(screen.getByRole('button', { name: 'Cancel' })).toBeInTheDocument();
- userEvent.click(screen.getByRole('button', { name: 'Cancel' }));
+ await userEvent.click(screen.getByRole('button', { name: 'Cancel' }));
expect(onCancel).toHaveBeenCalled();
// Cancel button should not be visible after click
diff --git a/packages/grafana-ui/src/components/DataSourceSettings/CustomHeadersSettings.test.tsx b/packages/grafana-ui/src/components/DataSourceSettings/CustomHeadersSettings.test.tsx
index c7205d4fb09..75dcefc6e2e 100644
--- a/packages/grafana-ui/src/components/DataSourceSettings/CustomHeadersSettings.test.tsx
+++ b/packages/grafana-ui/src/components/DataSourceSettings/CustomHeadersSettings.test.tsx
@@ -54,13 +54,13 @@ function assertRowCount(configuredInputCount: number, passwordInputCount: number
}
describe('Render', () => {
- it('should add a new header', () => {
+ it('should add a new header', async () => {
setup();
const b = screen.getByRole('button', { name: 'Add header' });
expect(b).toBeInTheDocument();
assertRowCount(0, 0);
- userEvent.click(b);
+ await userEvent.click(b);
assertRowCount(0, 1);
});
@@ -71,7 +71,7 @@ describe('Render', () => {
expect(b.getAttribute('type')).toBe('button');
});
- it('should remove a header', () => {
+ it('should remove a header', async () => {
const { onChange } = setup({
dataSourceConfig: {
jsonData: {
@@ -87,14 +87,14 @@ describe('Render', () => {
assertRowCount(1, 0);
- userEvent.click(b);
+ await userEvent.click(b);
assertRowCount(0, 0);
expect(onChange).toHaveBeenCalledTimes(1);
expect(onChange.mock.calls[0][0].jsonData).toStrictEqual({});
});
- it('when removing a just-created header, it should clean up secureJsonData', () => {
+ it('when removing a just-created header, it should clean up secureJsonData', async () => {
const { onChange } = setup({
dataSourceConfig: {
jsonData: {
@@ -109,7 +109,7 @@ describe('Render', () => {
// we remove the row
const removeButton = screen.getByRole('button', { name: 'Remove header' });
expect(removeButton).toBeInTheDocument();
- userEvent.click(removeButton);
+ await userEvent.click(removeButton);
assertRowCount(0, 0);
expect(onChange).toHaveBeenCalled();
@@ -119,7 +119,7 @@ describe('Render', () => {
expect(lastCall[0].secureJsonData).not.toHaveProperty('httpHeaderValue1');
});
- it('should reset a header', () => {
+ it('should reset a header', async () => {
setup({
dataSourceConfig: {
jsonData: {
@@ -135,7 +135,7 @@ describe('Render', () => {
expect(b).toBeInTheDocument();
assertRowCount(1, 0);
- userEvent.click(b);
+ await userEvent.click(b);
assertRowCount(0, 1);
});
});
diff --git a/packages/grafana-ui/src/components/SecretInput/SecretInput.test.tsx b/packages/grafana-ui/src/components/SecretInput/SecretInput.test.tsx
index 010ed2fdf59..fb525e93a1b 100644
--- a/packages/grafana-ui/src/components/SecretInput/SecretInput.test.tsx
+++ b/packages/grafana-ui/src/components/SecretInput/SecretInput.test.tsx
@@ -33,7 +33,7 @@ describe('', () => {
expect(screen.queryByRole('button', { name: RESET_BUTTON_TEXT })).toBeInTheDocument();
});
- it('should be possible to reset a configured secret', () => {
+ it('should be possible to reset a configured secret', async () => {
const onReset = jest.fn();
render( {}} onReset={onReset} placeholder={PLACEHOLDER_TEXT} />);
@@ -43,12 +43,12 @@ describe('', () => {
expect(screen.queryByRole('button', { name: RESET_BUTTON_TEXT })).toBeInTheDocument();
// Click on "Reset"
- userEvent.click(screen.getByRole('button', { name: RESET_BUTTON_TEXT }));
+ await userEvent.click(screen.getByRole('button', { name: RESET_BUTTON_TEXT }));
expect(onReset).toHaveBeenCalledTimes(1);
});
- it('should be possible to change the value of the secret', () => {
+ it('should be possible to change the value of the secret', async () => {
const onChange = jest.fn();
render( {}} placeholder={PLACEHOLDER_TEXT} />);
@@ -57,7 +57,7 @@ describe('', () => {
expect(input).toHaveValue('');
- userEvent.type(input, 'Foo');
+ await userEvent.type(input, 'Foo');
expect(onChange).toHaveBeenCalled();
expect(input).toHaveValue('Foo');
diff --git a/packages/grafana-ui/src/components/Select/SelectBase.test.tsx b/packages/grafana-ui/src/components/Select/SelectBase.test.tsx
index 81033a3de78..680d07ffc2c 100644
--- a/packages/grafana-ui/src/components/Select/SelectBase.test.tsx
+++ b/packages/grafana-ui/src/components/Select/SelectBase.test.tsx
@@ -22,9 +22,9 @@ describe('SelectBase', () => {
render();
});
- it('renders empty options information', () => {
+ it('renders empty options information', async () => {
render();
- userEvent.click(screen.getByText(/choose/i));
+ await userEvent.click(screen.getByText(/choose/i));
expect(screen.queryByText(/no options found/i)).toBeVisible();
});
@@ -54,7 +54,7 @@ describe('SelectBase', () => {
render();
expect(screen.queryByText('Test label')).toBeInTheDocument();
- userEvent.click(screen.getByText('clear value'));
+ await userEvent.click(screen.getByText('clear value'));
expect(screen.queryByText('Test label')).not.toBeInTheDocument();
});
@@ -186,9 +186,9 @@ describe('SelectBase', () => {
});
describe('options', () => {
- it('renders menu with provided options', () => {
+ it('renders menu with provided options', async () => {
render();
- userEvent.click(screen.getByText(/choose/i));
+ await userEvent.click(screen.getByText(/choose/i));
const menuOptions = screen.getAllByLabelText('Select option');
expect(menuOptions).toHaveLength(2);
});
diff --git a/packages/grafana-ui/src/components/Table/Table.test.tsx b/packages/grafana-ui/src/components/Table/Table.test.tsx
index eeb86e323f7..91d8bab44e9 100644
--- a/packages/grafana-ui/src/components/Table/Table.test.tsx
+++ b/packages/grafana-ui/src/components/Table/Table.test.tsx
@@ -159,11 +159,11 @@ describe('Table', () => {
});
describe('when sorting with column header', () => {
- it('then correct rows should be rendered', () => {
+ it('then correct rows should be rendered', async () => {
getTestContext();
- userEvent.click(within(getColumnHeader(/temperature/)).getByText(/temperature/i));
- userEvent.click(within(getColumnHeader(/temperature/)).getByText(/temperature/i));
+ await userEvent.click(within(getColumnHeader(/temperature/)).getByText(/temperature/i));
+ await userEvent.click(within(getColumnHeader(/temperature/)).getByText(/temperature/i));
const rows = within(getTable()).getAllByRole('row');
expect(rows).toHaveLength(5);
diff --git a/public/app/core/components/ForgottenPassword/ChangePasswordPage.test.tsx b/public/app/core/components/ForgottenPassword/ChangePasswordPage.test.tsx
index 5021e7cf081..0c558f6eadd 100644
--- a/public/app/core/components/ForgottenPassword/ChangePasswordPage.test.tsx
+++ b/public/app/core/components/ForgottenPassword/ChangePasswordPage.test.tsx
@@ -48,11 +48,11 @@ describe('ChangePassword Page', () => {
expect(await screen.findByText('New Password is required')).toBeInTheDocument();
expect(screen.getByText('Confirmed Password is required')).toBeInTheDocument();
- userEvent.type(screen.getByLabelText('New password'), 'admin');
- userEvent.type(screen.getByLabelText('Confirm new password'), 'a');
+ await userEvent.type(screen.getByLabelText('New password'), 'admin');
+ await userEvent.type(screen.getByLabelText('Confirm new password'), 'a');
await waitFor(() => expect(screen.getByText('Passwords must match!')).toBeInTheDocument());
- userEvent.type(screen.getByLabelText('Confirm new password'), 'dmin');
+ await userEvent.type(screen.getByLabelText('Confirm new password'), 'dmin');
await waitFor(() => expect(screen.queryByText('Passwords must match!')).not.toBeInTheDocument());
});
it('should navigate to default url if change password is successful', async () => {
@@ -64,8 +64,8 @@ describe('ChangePassword Page', () => {
postMock.mockResolvedValueOnce({ message: 'Logged in' });
render();
- userEvent.type(screen.getByLabelText('New password'), 'test');
- userEvent.type(screen.getByLabelText('Confirm new password'), 'test');
+ await userEvent.type(screen.getByLabelText('New password'), 'test');
+ await userEvent.type(screen.getByLabelText('Confirm new password'), 'test');
fireEvent.click(screen.getByRole('button', { name: 'Submit' }));
await waitFor(() =>
expect(postMock).toHaveBeenCalledWith('/api/user/password/reset', {
diff --git a/public/app/core/components/ForgottenPassword/SendResetMailPage.test.tsx b/public/app/core/components/ForgottenPassword/SendResetMailPage.test.tsx
index f9bb024ae40..ff50fde844f 100644
--- a/public/app/core/components/ForgottenPassword/SendResetMailPage.test.tsx
+++ b/public/app/core/components/ForgottenPassword/SendResetMailPage.test.tsx
@@ -41,14 +41,14 @@ describe('VerifyEmail Page', () => {
fireEvent.click(screen.getByRole('button', { name: 'Send reset email' }));
expect(await screen.findByText('Email or username is required')).toBeInTheDocument();
- userEvent.type(screen.getByRole('textbox', { name: /User Enter your information/i }), 'test@gmail.com');
+ await userEvent.type(screen.getByRole('textbox', { name: /User Enter your information/i }), 'test@gmail.com');
await waitFor(() => expect(screen.queryByText('Email is invalid')).not.toBeInTheDocument());
});
it('should show success meessage if reset-password is successful', async () => {
postMock.mockResolvedValueOnce({ message: 'Email sent' });
render();
- userEvent.type(screen.getByRole('textbox', { name: /User Enter your information/i }), 'test@gmail.com');
+ await userEvent.type(screen.getByRole('textbox', { name: /User Enter your information/i }), 'test@gmail.com');
fireEvent.click(screen.getByRole('button', { name: 'Send reset email' }));
await waitFor(() =>
expect(postMock).toHaveBeenCalledWith('/api/user/password/send-reset-email', {
diff --git a/public/app/core/components/Login/LoginPage.test.tsx b/public/app/core/components/Login/LoginPage.test.tsx
index 3d5161182df..3791f5dac87 100644
--- a/public/app/core/components/Login/LoginPage.test.tsx
+++ b/public/app/core/components/Login/LoginPage.test.tsx
@@ -56,7 +56,7 @@ describe('Login Page', () => {
fireEvent.click(screen.getByRole('button', { name: 'Login button' }));
expect(await screen.findByText('Email or username is required')).toBeInTheDocument();
- userEvent.type(screen.getByRole('textbox', { name: 'Username input field' }), 'admin');
+ await userEvent.type(screen.getByRole('textbox', { name: 'Username input field' }), 'admin');
await waitFor(() => expect(screen.queryByText('Email or username is required')).not.toBeInTheDocument());
});
it('should pass validation checks for password field', async () => {
@@ -65,7 +65,7 @@ describe('Login Page', () => {
fireEvent.click(screen.getByRole('button', { name: 'Login button' }));
expect(await screen.findByText('Password is required')).toBeInTheDocument();
- userEvent.type(screen.getByLabelText('Password input field'), 'admin');
+ await userEvent.type(screen.getByLabelText('Password input field'), 'admin');
await waitFor(() => expect(screen.queryByText('Password is required')).not.toBeInTheDocument());
});
it('should navigate to default url if credentials is valid', async () => {
@@ -77,8 +77,8 @@ describe('Login Page', () => {
postMock.mockResolvedValueOnce({ message: 'Logged in' });
render();
- userEvent.type(screen.getByLabelText('Username input field'), 'admin');
- userEvent.type(screen.getByLabelText('Password input field'), 'test');
+ await userEvent.type(screen.getByLabelText('Username input field'), 'admin');
+ await userEvent.type(screen.getByLabelText('Password input field'), 'test');
fireEvent.click(screen.getByLabelText('Login button'));
await waitFor(() => expect(postMock).toHaveBeenCalledWith('/login', { password: 'test', user: 'admin' }));
diff --git a/public/app/core/components/NavBar/NavBarItem.test.tsx b/public/app/core/components/NavBar/NavBarItem.test.tsx
index 9425298a4ab..dd11a26d8ac 100644
--- a/public/app/core/components/NavBar/NavBarItem.test.tsx
+++ b/public/app/core/components/NavBar/NavBarItem.test.tsx
@@ -1,11 +1,21 @@
import React from 'react';
-import { act, render, screen, waitFor } from '@testing-library/react';
+import { render, screen, waitFor } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { BrowserRouter } from 'react-router-dom';
import { locationUtil } from '@grafana/data';
import { config, setLocationService } from '@grafana/runtime';
import TestProvider from '../../../../test/helpers/TestProvider';
+// Need to mock createBrowserHistory here to avoid errors
+jest.mock('history', () => ({
+ ...jest.requireActual('history'),
+ createBrowserHistory: () => ({
+ listen: jest.fn(),
+ location: {},
+ createHref: jest.fn(),
+ }),
+}));
+
import NavBarItem, { Props } from './NavBarItem';
const onClickMock = jest.fn();
@@ -21,7 +31,7 @@ const defaults: Props = {
},
};
-function getTestContext(overrides: Partial = {}, subUrl = '') {
+async function getTestContext(overrides: Partial = {}, subUrl = '') {
jest.clearAllMocks();
config.appSubUrl = subUrl;
locationUtil.initialize({ config, getTimeRangeForUrl: jest.fn(), getVariablesUrlParams: jest.fn() });
@@ -38,33 +48,34 @@ function getTestContext(overrides: Partial = {}, subUrl = '') {
);
+ // Need to click this first to set the correct selection range
+ // see https://github.com/testing-library/user-event/issues/901#issuecomment-1087192424
+ await userEvent.click(document.body);
return { rerender, pushMock };
}
describe('NavBarItem', () => {
describe('when url property is not set', () => {
- it('then it renders the menu trigger as a button', () => {
- getTestContext();
+ it('then it renders the menu trigger as a button', async () => {
+ await getTestContext();
expect(screen.getAllByRole('button')).toHaveLength(1);
});
describe('and clicking on the menu trigger button', () => {
- it('then the onClick handler should be called', () => {
- getTestContext();
+ it('then the onClick handler should be called', async () => {
+ await getTestContext();
- act(() => {
- userEvent.click(screen.getByRole('button'));
- });
+ await userEvent.click(screen.getByRole('button'));
expect(onClickMock).toHaveBeenCalledTimes(1);
});
});
describe('and hovering over the menu trigger button', () => {
- it('then the menu items should be visible', () => {
- getTestContext();
+ it('then the menu items should be visible', async () => {
+ await getTestContext();
- userEvent.hover(screen.getByRole('button'));
+ await userEvent.hover(screen.getByRole('button'));
expect(screen.getByRole('menuitem', { name: 'Parent Node' })).toBeInTheDocument();
expect(screen.getByText('Child Node 1')).toBeInTheDocument();
@@ -73,10 +84,10 @@ describe('NavBarItem', () => {
});
describe('and tabbing to the menu trigger button', () => {
- it('then the menu items should be visible', () => {
- getTestContext();
+ it('then the menu items should be visible', async () => {
+ await getTestContext();
- userEvent.tab();
+ await userEvent.tab();
expect(screen.getByText('Parent Node')).toBeInTheDocument();
expect(screen.getByText('Child Node 1')).toBeInTheDocument();
@@ -85,16 +96,16 @@ describe('NavBarItem', () => {
});
describe('and pressing arrow right on the menu trigger button', () => {
- it('then the correct menu item should receive focus', () => {
- getTestContext();
+ it('then the correct menu item should receive focus', async () => {
+ await getTestContext();
- userEvent.tab();
+ await userEvent.tab();
expect(screen.getAllByRole('menuitem')).toHaveLength(3);
expect(screen.getByRole('menuitem', { name: 'Parent Node' })).toHaveAttribute('tabIndex', '-1');
expect(screen.getAllByRole('menuitem')[1]).toHaveAttribute('tabIndex', '-1');
expect(screen.getAllByRole('menuitem')[2]).toHaveAttribute('tabIndex', '-1');
- userEvent.keyboard('{arrowright}');
+ await userEvent.keyboard('{ArrowRight}');
expect(screen.getAllByRole('menuitem')).toHaveLength(3);
expect(screen.getAllByRole('menuitem')[0]).toHaveAttribute('tabIndex', '0');
expect(screen.getAllByRole('menuitem')[1]).toHaveAttribute('tabIndex', '-1');
@@ -104,18 +115,18 @@ describe('NavBarItem', () => {
});
describe('when url property is set', () => {
- it('then it renders the menu trigger as a link', () => {
- getTestContext({ link: { ...defaults.link, url: 'https://www.grafana.com' } });
+ it('then it renders the menu trigger as a link', async () => {
+ await getTestContext({ link: { ...defaults.link, url: 'https://www.grafana.com' } });
expect(screen.getAllByRole('link')).toHaveLength(1);
expect(screen.getByRole('link')).toHaveAttribute('href', 'https://www.grafana.com');
});
describe('and hovering over the menu trigger link', () => {
- it('then the menu items should be visible', () => {
- getTestContext({ link: { ...defaults.link, url: 'https://www.grafana.com' } });
+ it('then the menu items should be visible', async () => {
+ await getTestContext({ link: { ...defaults.link, url: 'https://www.grafana.com' } });
- userEvent.hover(screen.getByRole('link'));
+ await userEvent.hover(screen.getByRole('link'));
expect(screen.getByText('Parent Node')).toBeInTheDocument();
expect(screen.getByText('Child Node 1')).toBeInTheDocument();
@@ -124,10 +135,10 @@ describe('NavBarItem', () => {
});
describe('and tabbing to the menu trigger link', () => {
- it('then the menu items should be visible', () => {
- getTestContext({ link: { ...defaults.link, url: 'https://www.grafana.com' } });
+ it('then the menu items should be visible', async () => {
+ await getTestContext({ link: { ...defaults.link, url: 'https://www.grafana.com' } });
- userEvent.tab();
+ await userEvent.tab();
expect(screen.getByText('Parent Node')).toBeInTheDocument();
expect(screen.getByText('Child Node 1')).toBeInTheDocument();
@@ -136,17 +147,17 @@ describe('NavBarItem', () => {
});
describe('and pressing arrow right on the menu trigger link', () => {
- it('then the correct menu item should receive focus', () => {
- getTestContext({ link: { ...defaults.link, url: 'https://www.grafana.com' } });
+ it('then the correct menu item should receive focus', async () => {
+ await getTestContext({ link: { ...defaults.link, url: 'https://www.grafana.com' } });
- userEvent.tab();
+ await userEvent.tab();
expect(screen.getAllByRole('link')[0]).toHaveFocus();
expect(screen.getAllByRole('menuitem')).toHaveLength(3);
expect(screen.getAllByRole('menuitem')[0]).toHaveAttribute('tabIndex', '-1');
expect(screen.getAllByRole('menuitem')[1]).toHaveAttribute('tabIndex', '-1');
expect(screen.getAllByRole('menuitem')[2]).toHaveAttribute('tabIndex', '-1');
- userEvent.keyboard('{arrowright}');
+ await userEvent.keyboard('{ArrowRight}');
expect(screen.getAllByRole('link')[0]).not.toHaveFocus();
expect(screen.getAllByRole('menuitem')).toHaveLength(3);
expect(screen.getAllByRole('menuitem')[0]).toHaveAttribute('tabIndex', '0');
@@ -156,18 +167,18 @@ describe('NavBarItem', () => {
});
describe('and pressing arrow left on a menu item', () => {
- it('then the nav bar item should receive focus', () => {
- getTestContext({ link: { ...defaults.link, url: 'https://www.grafana.com' } });
+ it('then the nav bar item should receive focus', async () => {
+ await getTestContext({ link: { ...defaults.link, url: 'https://www.grafana.com' } });
- userEvent.tab();
- userEvent.keyboard('{arrowright}');
+ await userEvent.tab();
+ await userEvent.keyboard('{ArrowRight}');
expect(screen.getAllByRole('link')[0]).not.toHaveFocus();
expect(screen.getAllByRole('menuitem')).toHaveLength(3);
expect(screen.getAllByRole('menuitem')[0]).toHaveAttribute('tabIndex', '0');
expect(screen.getAllByRole('menuitem')[1]).toHaveAttribute('tabIndex', '-1');
expect(screen.getAllByRole('menuitem')[2]).toHaveAttribute('tabIndex', '-1');
- userEvent.keyboard('{arrowleft}');
+ await userEvent.keyboard('{ArrowLeft}');
expect(screen.getAllByRole('link')[0]).toHaveFocus();
expect(screen.getAllByRole('menuitem')).toHaveLength(3);
expect(screen.getAllByRole('menuitem')[0]).toHaveAttribute('tabIndex', '-1');
@@ -178,7 +189,7 @@ describe('NavBarItem', () => {
describe('when appSubUrl is configured and user clicks on menuitem link', () => {
it('then location service should be called with correct url', async () => {
- const { pushMock } = getTestContext(
+ const { pushMock } = await getTestContext(
{
link: {
...defaults.link,
@@ -189,15 +200,13 @@ describe('NavBarItem', () => {
'/grafana'
);
- userEvent.hover(screen.getByRole('link'));
+ await userEvent.hover(screen.getByRole('link'));
await waitFor(() => {
expect(screen.getByText('Parent Node')).toBeInTheDocument();
expect(screen.getByText('New')).toBeInTheDocument();
});
- act(() => {
- userEvent.click(screen.getByText('New'));
- });
+ await userEvent.click(screen.getByText('New'));
await waitFor(() => {
expect(pushMock).toHaveBeenCalledTimes(1);
expect(pushMock).toHaveBeenCalledWith('/dashboard/new');
@@ -207,7 +216,7 @@ describe('NavBarItem', () => {
describe('when appSubUrl is not configured and user clicks on menuitem link', () => {
it('then location service should be called with correct url', async () => {
- const { pushMock } = getTestContext({
+ const { pushMock } = await getTestContext({
link: {
...defaults.link,
url: 'https://www.grafana.com',
@@ -215,15 +224,13 @@ describe('NavBarItem', () => {
},
});
- userEvent.hover(screen.getByRole('link'));
+ await userEvent.hover(screen.getByRole('link'));
await waitFor(() => {
expect(screen.getByText('Parent Node')).toBeInTheDocument();
expect(screen.getByText('New')).toBeInTheDocument();
});
- act(() => {
- userEvent.click(screen.getByText('New'));
- });
+ await userEvent.click(screen.getByText('New'));
await waitFor(() => {
expect(pushMock).toHaveBeenCalledTimes(1);
expect(pushMock).toHaveBeenCalledWith('/grafana/dashboard/new');
diff --git a/public/app/core/components/NavBar/NavBarMenu.test.tsx b/public/app/core/components/NavBar/NavBarMenu.test.tsx
index 10e4569e239..ce87a514863 100644
--- a/public/app/core/components/NavBar/NavBarMenu.test.tsx
+++ b/public/app/core/components/NavBar/NavBarMenu.test.tsx
@@ -23,10 +23,10 @@ describe('NavBarMenu', () => {
expect(closeButton).toBeInTheDocument();
});
- it('clicking the close button calls the onClose callback', () => {
+ it('clicking the close button calls the onClose callback', async () => {
const closeButton = screen.getByRole('button', { name: 'Close navigation menu' });
expect(closeButton).toBeInTheDocument();
- userEvent.click(closeButton);
+ await userEvent.click(closeButton);
expect(mockOnClose).toHaveBeenCalled();
});
});
diff --git a/public/app/core/components/Select/ReadonlyFolderPicker/ReadonlyFolderPicker.test.tsx b/public/app/core/components/Select/ReadonlyFolderPicker/ReadonlyFolderPicker.test.tsx
index d92d74df741..9a1ad8feb5d 100644
--- a/public/app/core/components/Select/ReadonlyFolderPicker/ReadonlyFolderPicker.test.tsx
+++ b/public/app/core/components/Select/ReadonlyFolderPicker/ReadonlyFolderPicker.test.tsx
@@ -76,7 +76,7 @@ describe('ReadonlyFolderPicker', () => {
expect(within(selectors.container.get()).getByRole('combobox')).toBeInTheDocument();
getFoldersAsOptionsSpy.mockClear();
- userEvent.type(within(selectors.container.get()).getByRole('combobox'), 'A');
+ await userEvent.type(within(selectors.container.get()).getByRole('combobox'), 'A');
await waitFor(() => expect(getFoldersAsOptionsSpy).toHaveBeenCalledTimes(1));
expect(getFoldersAsOptionsSpy).toHaveBeenCalledWith({
diff --git a/public/app/core/components/Signup/SignupPage.test.tsx b/public/app/core/components/Signup/SignupPage.test.tsx
index e08bc005f0a..1a7be5066a2 100644
--- a/public/app/core/components/Signup/SignupPage.test.tsx
+++ b/public/app/core/components/Signup/SignupPage.test.tsx
@@ -60,10 +60,10 @@ describe('Signup Page', () => {
fireEvent.click(screen.getByRole('button', { name: 'Submit' }));
expect(await screen.findByText('Email is required')).toBeInTheDocument();
- userEvent.type(screen.getByRole('textbox', { name: 'Email' }), 'test');
+ await userEvent.type(screen.getByRole('textbox', { name: 'Email' }), 'test');
await waitFor(() => expect(screen.queryByText('Email is invalid')).toBeInTheDocument());
- userEvent.type(screen.getByRole('textbox', { name: 'Email' }), 'test@gmail.com');
+ await userEvent.type(screen.getByRole('textbox', { name: 'Email' }), 'test@gmail.com');
await waitFor(() => expect(screen.queryByText('Email is invalid')).not.toBeInTheDocument());
});
it('should pass validation checks for password and confirm password field', async () => {
@@ -73,11 +73,11 @@ describe('Signup Page', () => {
expect(await screen.findByText('Password is required')).toBeInTheDocument();
expect(await screen.findByText('Confirmed password is required')).toBeInTheDocument();
- userEvent.type(screen.getByLabelText('Password'), 'admin');
- userEvent.type(screen.getByLabelText('Confirm password'), 'a');
+ await userEvent.type(screen.getByLabelText('Password'), 'admin');
+ await userEvent.type(screen.getByLabelText('Confirm password'), 'a');
await waitFor(() => expect(screen.queryByText('Passwords must match!')).toBeInTheDocument());
- userEvent.type(screen.getByLabelText('Confirm password'), 'dmin');
+ await userEvent.type(screen.getByLabelText('Confirm password'), 'dmin');
await waitFor(() => expect(screen.queryByText('Passwords must match!')).not.toBeInTheDocument());
});
it('should navigate to default url if signup is successful', async () => {
@@ -89,10 +89,10 @@ describe('Signup Page', () => {
postMock.mockResolvedValueOnce({ message: 'Logged in' });
render();
- userEvent.type(screen.getByRole('textbox', { name: 'Your name' }), 'test-user');
- userEvent.type(screen.getByRole('textbox', { name: 'Email' }), 'test@gmail.com');
- userEvent.type(screen.getByLabelText('Password'), 'admin');
- userEvent.type(screen.getByLabelText('Confirm password'), 'admin');
+ await userEvent.type(screen.getByRole('textbox', { name: 'Your name' }), 'test-user');
+ await userEvent.type(screen.getByRole('textbox', { name: 'Email' }), 'test@gmail.com');
+ await userEvent.type(screen.getByLabelText('Password'), 'admin');
+ await userEvent.type(screen.getByLabelText('Confirm password'), 'admin');
fireEvent.click(screen.getByRole('button', { name: 'Submit' }));
await waitFor(() =>
diff --git a/public/app/core/components/Signup/VerifyEmailPage.test.tsx b/public/app/core/components/Signup/VerifyEmailPage.test.tsx
index f03435676b7..637f43ee75a 100644
--- a/public/app/core/components/Signup/VerifyEmailPage.test.tsx
+++ b/public/app/core/components/Signup/VerifyEmailPage.test.tsx
@@ -44,17 +44,17 @@ describe('VerifyEmail Page', () => {
fireEvent.click(screen.getByRole('button', { name: 'Send verification email' }));
expect(await screen.findByText('Email is required')).toBeInTheDocument();
- userEvent.type(screen.getByRole('textbox', { name: /Email/i }), 'test');
+ await userEvent.type(screen.getByRole('textbox', { name: /Email/i }), 'test');
await waitFor(() => expect(screen.queryByText('Email is invalid')).toBeInTheDocument());
- userEvent.type(screen.getByRole('textbox', { name: /Email/i }), 'test@gmail.com');
+ await userEvent.type(screen.getByRole('textbox', { name: /Email/i }), 'test@gmail.com');
await waitFor(() => expect(screen.queryByText('Email is invalid')).not.toBeInTheDocument());
});
it('should show complete signup if email-verification is successful', async () => {
postMock.mockResolvedValueOnce({ message: 'SignUpCreated' });
render();
- userEvent.type(screen.getByRole('textbox', { name: /Email/i }), 'test@gmail.com');
+ await userEvent.type(screen.getByRole('textbox', { name: /Email/i }), 'test@gmail.com');
fireEvent.click(screen.getByRole('button', { name: 'Send verification email' }));
await waitFor(() =>
diff --git a/public/app/core/specs/OrgSwitcher.test.tsx b/public/app/core/specs/OrgSwitcher.test.tsx
index 829fa3ac9c0..b99b44de1da 100644
--- a/public/app/core/specs/OrgSwitcher.test.tsx
+++ b/public/app/core/specs/OrgSwitcher.test.tsx
@@ -53,7 +53,7 @@ describe('OrgSwitcher', () => {
it('should switch orgId in call to backend', async () => {
const row = screen.getByRole('row', { name: /org 2 admin switch to/i });
const switchToButton = within(row).getByText(/switch to/i);
- userEvent.click(switchToButton);
+ await userEvent.click(switchToButton);
await waitFor(() => expect(setUserOrgSpy).toBeCalledWith({ orgId: 2, name: 'Org 2', role: 'Admin' }));
});
@@ -63,7 +63,7 @@ describe('OrgSwitcher', () => {
const row = screen.getByRole('row', { name: /org 2 admin switch to/i });
const switchToButton = within(row).getByText(/switch to/i);
- userEvent.click(switchToButton);
+ await userEvent.click(switchToButton);
await waitFor(() => expect(window.location.href).toEqual('/subUrl/?orgId=2'));
});
diff --git a/public/app/features/alerting/components/UnifiedAlertingPromotion.test.tsx b/public/app/features/alerting/components/UnifiedAlertingPromotion.test.tsx
index 1a5df7e6527..3fa5f2a330a 100644
--- a/public/app/features/alerting/components/UnifiedAlertingPromotion.test.tsx
+++ b/public/app/features/alerting/components/UnifiedAlertingPromotion.test.tsx
@@ -14,12 +14,12 @@ describe('Unified Alerting promotion', () => {
expect(screen.queryByText('Try out the Grafana 8 alerting!')).toBeInTheDocument();
});
- it('should be hidden if dismissed', () => {
+ it('should be hidden if dismissed', async () => {
const promotion = render();
expect(window.localStorage.getItem(LOCAL_STORAGE_KEY)).toBe('true');
const dismissButton = promotion.getByRole('button');
- userEvent.click(dismissButton);
+ await userEvent.click(dismissButton);
expect(screen.queryByText('Try out the Grafana 8 alerting!')).not.toBeInTheDocument();
expect(window.localStorage.getItem(LOCAL_STORAGE_KEY)).toBe('false');
diff --git a/public/app/features/alerting/unified/AlertGroups.test.tsx b/public/app/features/alerting/unified/AlertGroups.test.tsx
index 765af678612..40fecd2d7bf 100644
--- a/public/app/features/alerting/unified/AlertGroups.test.tsx
+++ b/public/app/features/alerting/unified/AlertGroups.test.tsx
@@ -83,10 +83,10 @@ describe('AlertGroups', () => {
expect(groups[0]).toHaveTextContent('No grouping');
expect(groups[1]).toHaveTextContent('severity=warningregion=US-Central');
- userEvent.click(ui.groupCollapseToggle.get(groups[0]));
+ await userEvent.click(ui.groupCollapseToggle.get(groups[0]));
expect(ui.groupTable.get()).toBeDefined();
- userEvent.click(ui.collapseToggle.get(ui.groupTable.get()));
+ await userEvent.click(ui.collapseToggle.get(ui.groupTable.get()));
expect(ui.silenceButton.get(ui.groupTable.get())).toBeDefined();
expect(ui.sourceButton.get(ui.groupTable.get())).toBeDefined();
});
@@ -118,7 +118,7 @@ describe('AlertGroups', () => {
expect(groups[1]).toHaveTextContent('region=EMEA');
expect(groups[2]).toHaveTextContent('region=APAC');
- userEvent.type(groupByInput, 'appName{enter}');
+ await userEvent.type(groupByInput, 'appName{enter}');
await waitFor(() => expect(groupByWrapper).toHaveTextContent('appName'));
@@ -130,10 +130,10 @@ describe('AlertGroups', () => {
expect(groups[1]).toHaveTextContent('appName=auth');
expect(groups[2]).toHaveTextContent('appName=frontend');
- userEvent.click(ui.clearButton.get());
+ await userEvent.click(ui.clearButton.get());
await waitFor(() => expect(groupByWrapper).not.toHaveTextContent('appName'));
- userEvent.type(groupByInput, 'env{enter}');
+ await userEvent.type(groupByInput, 'env{enter}');
await waitFor(() => expect(groupByWrapper).toHaveTextContent('env'));
groups = ui.group.getAll();
@@ -142,10 +142,10 @@ describe('AlertGroups', () => {
expect(groups[0]).toHaveTextContent('env=production');
expect(groups[1]).toHaveTextContent('env=staging');
- userEvent.click(ui.clearButton.get());
+ await userEvent.click(ui.clearButton.get());
await waitFor(() => expect(groupByWrapper).not.toHaveTextContent('env'));
- userEvent.type(groupByInput, 'uniqueLabel{enter}');
+ await userEvent.type(groupByInput, 'uniqueLabel{enter}');
await waitFor(() => expect(groupByWrapper).toHaveTextContent('uniqueLabel'));
groups = ui.group.getAll();
diff --git a/public/app/features/alerting/unified/AlertsFolderView.test.tsx b/public/app/features/alerting/unified/AlertsFolderView.test.tsx
index 940bd63d141..39793a96677 100644
--- a/public/app/features/alerting/unified/AlertsFolderView.test.tsx
+++ b/public/app/features/alerting/unified/AlertsFolderView.test.tsx
@@ -116,7 +116,7 @@ describe('AlertsFolderView tests', () => {
expect(ui.ruleList.row.queryAll()).toHaveLength(0);
});
- it('Should filter alert rules by the name, case insensitive', () => {
+ it('Should filter alert rules by the name, case insensitive', async () => {
// Arrange
const store = configureStore();
const folder = mockFolder();
@@ -143,14 +143,14 @@ describe('AlertsFolderView tests', () => {
);
- userEvent.type(ui.filter.name.get(), 'cpu');
+ await userEvent.type(ui.filter.name.get(), 'cpu');
// Assert
expect(ui.ruleList.row.queryAll()).toHaveLength(1);
expect(ui.ruleList.row.get()).toHaveTextContent('CPU Alert');
});
- it('Should filter alert rule by labels', () => {
+ it('Should filter alert rule by labels', async () => {
// Arrange
const store = configureStore();
const folder = mockFolder();
@@ -180,7 +180,7 @@ describe('AlertsFolderView tests', () => {
);
- userEvent.type(ui.filter.label.get(), 'severity=critical');
+ await userEvent.type(ui.filter.label.get(), 'severity=critical');
// Assert
expect(ui.ruleList.row.queryAll()).toHaveLength(1);
diff --git a/public/app/features/alerting/unified/AmRoutes.test.tsx b/public/app/features/alerting/unified/AmRoutes.test.tsx
index 85a561165ba..414f90b6cf4 100644
--- a/public/app/features/alerting/unified/AmRoutes.test.tsx
+++ b/public/app/features/alerting/unified/AmRoutes.test.tsx
@@ -273,24 +273,24 @@ describe('AmRoutes', () => {
// open root route for editing
const rootRouteContainer = await ui.rootRouteContainer.find();
- userEvent.click(ui.editButton.get(rootRouteContainer));
+ await userEvent.click(ui.editButton.get(rootRouteContainer));
// configure receiver & group by
const receiverSelect = await ui.receiverSelect.find();
await clickSelectOption(receiverSelect, 'critical');
const groupSelect = ui.groupSelect.get();
- userEvent.type(byRole('combobox').get(groupSelect), 'namespace{enter}');
+ await userEvent.type(byRole('combobox').get(groupSelect), 'namespace{enter}');
// configure timing intervals
- userEvent.click(byText('Timing options').get(rootRouteContainer));
+ await userEvent.click(byText('Timing options').get(rootRouteContainer));
await updateTiming(ui.groupWaitContainer.get(), '1', 'Minutes');
await updateTiming(ui.groupIntervalContainer.get(), '4', 'Minutes');
await updateTiming(ui.groupRepeatContainer.get(), '5', 'Hours');
//save
- userEvent.click(ui.saveButton.get(rootRouteContainer));
+ await userEvent.click(ui.saveButton.get(rootRouteContainer));
// wait for it to go out of edit mode
await waitFor(() => expect(ui.editButton.query(rootRouteContainer)).not.toBeInTheDocument());
@@ -333,17 +333,17 @@ describe('AmRoutes', () => {
// open root route for editing
const rootRouteContainer = await ui.rootRouteContainer.find();
- userEvent.click(ui.editButton.get(rootRouteContainer));
+ await userEvent.click(ui.editButton.get(rootRouteContainer));
// configure receiver & group by
const receiverSelect = await ui.receiverSelect.find();
await clickSelectOption(receiverSelect, 'default');
const groupSelect = ui.groupSelect.get();
- userEvent.type(byRole('combobox').get(groupSelect), 'severity{enter}');
- userEvent.type(byRole('combobox').get(groupSelect), 'namespace{enter}');
+ await userEvent.type(byRole('combobox').get(groupSelect), 'severity{enter}');
+ await userEvent.type(byRole('combobox').get(groupSelect), 'namespace{enter}');
//save
- userEvent.click(ui.saveButton.get(rootRouteContainer));
+ await userEvent.click(ui.saveButton.get(rootRouteContainer));
// wait for it to go out of edit mode
await waitFor(() => expect(ui.editButton.query(rootRouteContainer)).not.toBeInTheDocument());
@@ -426,8 +426,8 @@ describe('AmRoutes', () => {
// Toggle a save to test new object_matchers
const rootRouteContainer = await ui.rootRouteContainer.find();
- userEvent.click(ui.editButton.get(rootRouteContainer));
- userEvent.click(ui.saveButton.get(rootRouteContainer));
+ await userEvent.click(ui.editButton.get(rootRouteContainer));
+ await userEvent.click(ui.saveButton.get(rootRouteContainer));
await waitFor(() => expect(ui.editButton.query(rootRouteContainer)).not.toBeInTheDocument());
@@ -497,8 +497,8 @@ describe('AmRoutes', () => {
// Toggle a save to test new object_matchers
const rootRouteContainer = await ui.rootRouteContainer.find();
- userEvent.click(ui.editButton.get(rootRouteContainer));
- userEvent.click(ui.saveButton.get(rootRouteContainer));
+ await userEvent.click(ui.editButton.get(rootRouteContainer));
+ await userEvent.click(ui.saveButton.get(rootRouteContainer));
await waitFor(() => expect(ui.editButton.query(rootRouteContainer)).not.toBeInTheDocument());
@@ -599,7 +599,7 @@ describe('AmRoutes', () => {
await renderAmRoutes(dataSources.am.name);
const rows = await ui.row.findAll();
expect(rows).toHaveLength(1);
- userEvent.click(ui.editRouteButton.get(rows[0]));
+ await userEvent.click(ui.editRouteButton.get(rows[0]));
const muteTimingSelect = ui.muteTimingSelect.get();
await clickSelectOption(muteTimingSelect, 'default-mute');
@@ -608,7 +608,7 @@ describe('AmRoutes', () => {
const savePolicyButton = ui.savePolicyButton.get();
expect(savePolicyButton).toBeInTheDocument();
- userEvent.click(savePolicyButton);
+ await userEvent.click(savePolicyButton);
await waitFor(() => expect(savePolicyButton).not.toBeInTheDocument());
@@ -637,14 +637,14 @@ describe('AmRoutes', () => {
});
const clickSelectOption = async (selectElement: HTMLElement, optionText: string): Promise => {
- userEvent.click(byRole('combobox').get(selectElement));
+ await userEvent.click(byRole('combobox').get(selectElement));
await selectOptionInTest(selectElement, optionText);
};
const updateTiming = async (selectElement: HTMLElement, value: string, timeUnit: string): Promise => {
const input = byRole('textbox').get(selectElement);
const select = byRole('combobox').get(selectElement);
- userEvent.type(input, value);
- userEvent.click(select);
+ await userEvent.type(input, value);
+ await userEvent.click(select);
await selectOptionInTest(selectElement, timeUnit);
};
diff --git a/public/app/features/alerting/unified/MuteTimings.test.tsx b/public/app/features/alerting/unified/MuteTimings.test.tsx
index d5248e923c8..0a8c494d2c4 100644
--- a/public/app/features/alerting/unified/MuteTimings.test.tsx
+++ b/public/app/features/alerting/unified/MuteTimings.test.tsx
@@ -118,11 +118,11 @@ describe('Mute timings', () => {
await waitFor(() => expect(mocks.api.fetchAlertManagerConfig).toHaveBeenCalled());
expect(ui.nameField.get()).toBeInTheDocument();
- userEvent.type(ui.nameField.get(), 'maintenance period');
- userEvent.type(ui.startsAt.get(), '22:00');
- userEvent.type(ui.endsAt.get(), '24:00');
- userEvent.type(ui.days.get(), '-1');
- userEvent.type(ui.months.get(), 'january, july');
+ await userEvent.type(ui.nameField.get(), 'maintenance period');
+ await userEvent.type(ui.startsAt.get(), '22:00');
+ await userEvent.type(ui.endsAt.get(), '24:00');
+ await userEvent.type(ui.days.get(), '-1');
+ await userEvent.type(ui.months.get(), 'january, july');
fireEvent.submit(ui.form.get());
@@ -163,17 +163,17 @@ describe('Mute timings', () => {
expect(ui.nameField.get()).toHaveValue(muteTimeInterval.name);
expect(ui.months.get()).toHaveValue(muteTimeInterval.time_intervals[0].months?.join(', '));
- userEvent.clear(ui.startsAt.getAll()?.[0]);
- userEvent.clear(ui.endsAt.getAll()?.[0]);
- userEvent.clear(ui.weekdays.get());
- userEvent.clear(ui.days.get());
- userEvent.clear(ui.months.get());
- userEvent.clear(ui.years.get());
+ await userEvent.clear(ui.startsAt.getAll()?.[0]);
+ await userEvent.clear(ui.endsAt.getAll()?.[0]);
+ await userEvent.clear(ui.weekdays.get());
+ await userEvent.clear(ui.days.get());
+ await userEvent.clear(ui.months.get());
+ await userEvent.clear(ui.years.get());
- userEvent.type(ui.weekdays.get(), 'monday');
- userEvent.type(ui.days.get(), '-7:-1');
- userEvent.type(ui.months.get(), '3, 6, 9, 12');
- userEvent.type(ui.years.get(), '2021:2024');
+ await userEvent.type(ui.weekdays.get(), 'monday');
+ await userEvent.type(ui.days.get(), '-7:-1');
+ await userEvent.type(ui.months.get(), '3, 6, 9, 12');
+ await userEvent.type(ui.years.get(), '2021:2024');
fireEvent.submit(ui.form.get());
@@ -243,8 +243,8 @@ describe('Mute timings', () => {
expect(ui.nameField.get()).toBeInTheDocument();
expect(ui.nameField.get()).toHaveValue(muteTimeInterval.name);
- userEvent.clear(ui.nameField.get());
- userEvent.type(ui.nameField.get(), 'Lunch breaks');
+ await userEvent.clear(ui.nameField.get());
+ await userEvent.type(ui.nameField.get(), 'Lunch breaks');
fireEvent.submit(ui.form.get());
diff --git a/public/app/features/alerting/unified/Receivers.test.tsx b/public/app/features/alerting/unified/Receivers.test.tsx
index 0b335b3c5f1..0f5c6af28bf 100644
--- a/public/app/features/alerting/unified/Receivers.test.tsx
+++ b/public/app/features/alerting/unified/Receivers.test.tsx
@@ -4,7 +4,7 @@ import { Router } from 'react-router-dom';
import Receivers from './Receivers';
import React from 'react';
import { locationService, setDataSourceSrv } from '@grafana/runtime';
-import { act, render, waitFor } from '@testing-library/react';
+import { render, waitFor } from '@testing-library/react';
import { getAllDataSources } from './utils/config';
import { updateAlertManagerConfig, fetchAlertManagerConfig, fetchStatus, testReceivers } from './api/alertmanager';
import {
@@ -116,7 +116,7 @@ const ui = {
};
const clickSelectOption = async (selectElement: HTMLElement, optionText: string): Promise => {
- userEvent.click(byRole('combobox').get(selectElement));
+ await userEvent.click(byRole('combobox').get(selectElement));
await selectOptionInTest(selectElement, optionText);
};
@@ -194,29 +194,25 @@ describe('Receivers', () => {
await renderReceivers();
// go to new contact point page
- await act(async () => {
- userEvent.click(await ui.newContactPointButton.find());
- });
+ await userEvent.click(await ui.newContactPointButton.find());
await byRole('heading', { name: /create contact point/i }).find();
expect(locationService.getLocation().pathname).toEqual('/alerting/notifications/receivers/new');
- await act(async () => {
- // type in a name for the new receiver
- userEvent.type(ui.inputs.name.get(), 'my new receiver');
+ // type in a name for the new receiver
+ await userEvent.type(ui.inputs.name.get(), 'my new receiver');
- // enter some email
- const email = ui.inputs.email.addresses.get();
- userEvent.clear(email);
- userEvent.type(email, 'tester@grafana.com');
+ // enter some email
+ const email = ui.inputs.email.addresses.get();
+ await userEvent.clear(email);
+ await userEvent.type(email, 'tester@grafana.com');
- // try to test the contact point
- userEvent.click(await ui.testContactPointButton.find());
- });
+ // try to test the contact point
+ await userEvent.click(await ui.testContactPointButton.find());
await waitFor(() => expect(ui.testContactPointModal.get()).toBeInTheDocument(), { timeout: 1000 });
- userEvent.click(ui.customContactPointOption.get());
+ await userEvent.click(ui.customContactPointOption.get());
await waitFor(() => expect(ui.contactPointAnnotationSelect(0).get()).toBeInTheDocument());
// enter custom annotations and labels
@@ -224,7 +220,7 @@ describe('Receivers', () => {
await userEvent.type(ui.contactPointAnnotationValue(0).get(), 'Test contact point');
await userEvent.type(ui.contactPointLabelKey(0).get(), 'foo');
await userEvent.type(ui.contactPointLabelValue(0).get(), 'bar');
- userEvent.click(ui.testContactPoint.get());
+ await userEvent.click(ui.testContactPoint.get());
await waitFor(() => expect(mocks.api.testReceivers).toHaveBeenCalled());
@@ -260,7 +256,7 @@ describe('Receivers', () => {
expect(locationService.getLocation().pathname).toEqual('/alerting/notifications/receivers/new');
// type in a name for the new receiver
- userEvent.type(byPlaceholderText('Name').get(), 'my new receiver');
+ await userEvent.type(byPlaceholderText('Name').get(), 'my new receiver');
// check that default email form is rendered
await ui.inputs.email.addresses.find();
@@ -274,13 +270,10 @@ describe('Receivers', () => {
const urlInput = ui.inputs.hipchat.url.get();
const apiKeyInput = ui.inputs.hipchat.apiKey.get();
- userEvent.type(urlInput, 'http://hipchat');
- userEvent.type(apiKeyInput, 'foobarbaz');
+ await userEvent.type(urlInput, 'http://hipchat');
+ await userEvent.type(apiKeyInput, 'foobarbaz');
- // it seems react-hook-form does some async state updates after submit
- await act(async () => {
- userEvent.click(await ui.saveContactButton.find());
- });
+ await userEvent.click(await ui.saveContactButton.find());
// see that we're back to main page and proper api calls have been made
await ui.receiversTable.find();
@@ -350,13 +343,13 @@ describe('Receivers', () => {
// modify webhook url
const slackContainer = ui.channelFormContainer.get();
await userEvent.click(byText('Optional Slack settings').get(slackContainer));
- userEvent.type(ui.inputs.slack.webhookURL.get(slackContainer), 'http://newgreaturl');
+ await userEvent.type(ui.inputs.slack.webhookURL.get(slackContainer), 'http://newgreaturl');
// add confirm button to action
await userEvent.click(byText(/Actions \(1\)/i).get(slackContainer));
await userEvent.click(await byTestId('items.1.settings.actions.0.confirm.add-button').find());
const confirmSubform = byTestId('items.1.settings.actions.0.confirm.container').get();
- userEvent.type(byLabelText('Text').get(confirmSubform), 'confirm this');
+ await userEvent.type(byLabelText('Text').get(confirmSubform), 'confirm this');
// delete a field
await userEvent.click(byText(/Fields \(2\)/i).get(slackContainer));
@@ -366,12 +359,9 @@ describe('Receivers', () => {
// add another channel
await userEvent.click(ui.newContactPointTypeButton.get());
await clickSelectOption(await byTestId('items.2.type').find(), 'Webhook');
- userEvent.type(await ui.inputs.webhook.URL.find(), 'http://webhookurl');
+ await userEvent.type(await ui.inputs.webhook.URL.find(), 'http://webhookurl');
- // it seems react-hook-form does some async state updates after submit
- await act(async () => {
- await userEvent.click(ui.saveContactButton.get());
- });
+ await userEvent.click(ui.saveContactButton.get());
// see that we're back to main page and proper api calls have been made
await ui.receiversTable.find();
@@ -438,7 +428,7 @@ describe('Receivers', () => {
const receiverRows = receiversTable.querySelectorAll('tbody tr');
expect(receiverRows[0]).toHaveTextContent('cloud-receiver');
expect(byTestId('edit').query(receiverRows[0])).not.toBeInTheDocument();
- userEvent.click(byTestId('view').get(receiverRows[0]));
+ await userEvent.click(byTestId('view').get(receiverRows[0]));
// check that form is open
await byRole('heading', { name: /contact point/i }).find();
diff --git a/public/app/features/alerting/unified/RuleEditor.test.tsx b/public/app/features/alerting/unified/RuleEditor.test.tsx
index fc860ea5669..dc1fa82d5ef 100644
--- a/public/app/features/alerting/unified/RuleEditor.test.tsx
+++ b/public/app/features/alerting/unified/RuleEditor.test.tsx
@@ -9,7 +9,7 @@ import { byLabelText, byRole, byTestId, byText } from 'testing-library-selector'
import { selectOptionInTest } from '@grafana/ui';
import { contextSrv } from 'app/core/services/context_srv';
import { mockDataSource, MockDataSourceSrv } from './mocks';
-import userEvent from '@testing-library/user-event';
+import userEvent, { PointerEventsCheckLevel } from '@testing-library/user-event';
import { DataSourceInstanceSettings } from '@grafana/data';
import { getAllDataSources } from './utils/config';
import { fetchRulerRules, fetchRulerRulesGroup, fetchRulerRulesNamespace, setRulerRuleGroup } from './api/ruler';
@@ -144,30 +144,30 @@ describe('RuleEditor', () => {
await waitFor(() => expect(mocks.searchFolders).toHaveBeenCalled());
await waitFor(() => expect(mocks.api.fetchBuildInfo).toHaveBeenCalled());
- userEvent.type(await ui.inputs.name.find(), 'my great new rule');
- userEvent.click(await ui.buttons.lotexAlert.get());
+ await userEvent.type(await ui.inputs.name.find(), 'my great new rule');
+ await userEvent.click(await ui.buttons.lotexAlert.get());
const dataSourceSelect = ui.inputs.dataSource.get();
- userEvent.click(byRole('combobox').get(dataSourceSelect));
+ await userEvent.click(byRole('combobox').get(dataSourceSelect));
await clickSelectOption(dataSourceSelect, 'Prom (default)');
await waitFor(() => expect(mocks.api.fetchRulerRules).toHaveBeenCalled());
await clickSelectOption(ui.inputs.namespace.get(), 'namespace2');
await clickSelectOption(ui.inputs.group.get(), 'group2');
- userEvent.type(ui.inputs.expr.get(), 'up == 1');
+ await userEvent.type(ui.inputs.expr.get(), 'up == 1');
- userEvent.type(ui.inputs.annotationValue(0).get(), 'some summary');
- userEvent.type(ui.inputs.annotationValue(1).get(), 'some description');
+ await userEvent.type(ui.inputs.annotationValue(0).get(), 'some summary');
+ await userEvent.type(ui.inputs.annotationValue(1).get(), 'some description');
// TODO remove skipPointerEventsCheck once https://github.com/jsdom/jsdom/issues/3232 is fixed
- userEvent.click(ui.buttons.addLabel.get(), undefined, { skipPointerEventsCheck: true });
+ await userEvent.click(ui.buttons.addLabel.get(), { pointerEventsCheck: PointerEventsCheckLevel.Never });
- userEvent.type(ui.inputs.labelKey(0).get(), 'severity');
- userEvent.type(ui.inputs.labelValue(0).get(), 'warn');
- userEvent.type(ui.inputs.labelKey(1).get(), 'team');
- userEvent.type(ui.inputs.labelValue(1).get(), 'the a-team');
+ await userEvent.type(ui.inputs.labelKey(0).get(), 'severity');
+ await userEvent.type(ui.inputs.labelValue(0).get(), 'warn');
+ await userEvent.type(ui.inputs.labelKey(1).get(), 'team');
+ await userEvent.type(ui.inputs.labelValue(1).get(), 'the a-team');
// save and check what was sent to backend
- userEvent.click(ui.buttons.save.get());
+ await userEvent.click(ui.buttons.save.get());
await waitFor(() => expect(mocks.api.setRulerRuleGroup).toHaveBeenCalled());
expect(mocks.api.setRulerRuleGroup).toHaveBeenCalledWith(
{ dataSourceName: 'Prom', apiVersion: 'legacy' },
@@ -244,27 +244,27 @@ describe('RuleEditor', () => {
await waitFor(() => expect(mocks.searchFolders).toHaveBeenCalled());
await waitFor(() => expect(mocks.api.fetchBuildInfo).toHaveBeenCalled());
- userEvent.type(await ui.inputs.name.find(), 'my great new rule');
+ await userEvent.type(await ui.inputs.name.find(), 'my great new rule');
const folderInput = await ui.inputs.folder.find();
await clickSelectOption(folderInput, 'Folder A');
const groupInput = screen.getByRole('textbox', { name: /^Group/ });
- userEvent.type(groupInput, 'my group');
+ await userEvent.type(groupInput, 'my group');
- userEvent.type(ui.inputs.annotationValue(0).get(), 'some summary');
- userEvent.type(ui.inputs.annotationValue(1).get(), 'some description');
+ await userEvent.type(ui.inputs.annotationValue(0).get(), 'some summary');
+ await userEvent.type(ui.inputs.annotationValue(1).get(), 'some description');
// TODO remove skipPointerEventsCheck once https://github.com/jsdom/jsdom/issues/3232 is fixed
- userEvent.click(ui.buttons.addLabel.get(), undefined, { skipPointerEventsCheck: true });
+ await userEvent.click(ui.buttons.addLabel.get(), { pointerEventsCheck: PointerEventsCheckLevel.Never });
- userEvent.type(ui.inputs.labelKey(0).get(), 'severity');
- userEvent.type(ui.inputs.labelValue(0).get(), 'warn');
- userEvent.type(ui.inputs.labelKey(1).get(), 'team');
- userEvent.type(ui.inputs.labelValue(1).get(), 'the a-team');
+ await userEvent.type(ui.inputs.labelKey(0).get(), 'severity');
+ await userEvent.type(ui.inputs.labelValue(0).get(), 'warn');
+ await userEvent.type(ui.inputs.labelKey(1).get(), 'team');
+ await userEvent.type(ui.inputs.labelValue(1).get(), 'the a-team');
// save and check what was sent to backend
- userEvent.click(ui.buttons.save.get());
+ await userEvent.click(ui.buttons.save.get());
await waitFor(() => expect(mocks.api.setRulerRuleGroup).toHaveBeenCalled());
expect(mocks.api.setRulerRuleGroup).toHaveBeenCalledWith(
{ dataSourceName: GRAFANA_RULES_SOURCE_NAME, apiVersion: 'legacy' },
@@ -336,27 +336,27 @@ describe('RuleEditor', () => {
await renderRuleEditor();
await waitFor(() => expect(mocks.searchFolders).toHaveBeenCalled());
await waitFor(() => expect(mocks.api.fetchBuildInfo).toHaveBeenCalled());
- userEvent.type(await ui.inputs.name.find(), 'my great new recording rule');
- userEvent.click(await ui.buttons.lotexRecordingRule.get());
+ await userEvent.type(await ui.inputs.name.find(), 'my great new recording rule');
+ await userEvent.click(await ui.buttons.lotexRecordingRule.get());
const dataSourceSelect = ui.inputs.dataSource.get();
- userEvent.click(byRole('combobox').get(dataSourceSelect));
+ await userEvent.click(byRole('combobox').get(dataSourceSelect));
await clickSelectOption(dataSourceSelect, 'Prom (default)');
await waitFor(() => expect(mocks.api.fetchRulerRules).toHaveBeenCalled());
await clickSelectOption(ui.inputs.namespace.get(), 'namespace2');
await clickSelectOption(ui.inputs.group.get(), 'group2');
- userEvent.type(ui.inputs.expr.get(), 'up == 1');
+ await userEvent.type(ui.inputs.expr.get(), 'up == 1');
// TODO remove skipPointerEventsCheck once https://github.com/jsdom/jsdom/issues/3232 is fixed
- userEvent.click(ui.buttons.addLabel.get(), undefined, { skipPointerEventsCheck: true });
+ await userEvent.click(ui.buttons.addLabel.get(), { pointerEventsCheck: PointerEventsCheckLevel.Never });
- userEvent.type(ui.inputs.labelKey(1).get(), 'team');
- userEvent.type(ui.inputs.labelValue(1).get(), 'the a-team');
+ await userEvent.type(ui.inputs.labelKey(1).get(), 'team');
+ await userEvent.type(ui.inputs.labelValue(1).get(), 'the a-team');
// try to save, find out that recording rule name is invalid
- userEvent.click(ui.buttons.save.get());
+ await userEvent.click(ui.buttons.save.get());
await waitFor(() =>
expect(
byText(
@@ -367,11 +367,11 @@ describe('RuleEditor', () => {
expect(mocks.api.setRulerRuleGroup).not.toBeCalled();
// fix name and re-submit
- userEvent.type(await ui.inputs.name.find(), '{selectall}{del}my:great:new:recording:rule');
- userEvent.click(ui.buttons.save.get());
+ await userEvent.clear(await ui.inputs.name.find());
+ await userEvent.type(await ui.inputs.name.find(), 'my:great:new:recording:rule');
// save and check what was sent to backend
- userEvent.click(ui.buttons.save.get());
+ await userEvent.click(ui.buttons.save.get());
await waitFor(() => expect(mocks.api.setRulerRuleGroup).toHaveBeenCalled());
expect(mocks.api.setRulerRuleGroup).toHaveBeenCalledWith(
{ dataSourceName: 'Prom', apiVersion: 'legacy' },
@@ -458,15 +458,15 @@ describe('RuleEditor', () => {
// add an annotation
await clickSelectOption(ui.inputs.annotationKey(2).get(), /Add new/);
- userEvent.type(byRole('textbox').get(ui.inputs.annotationKey(2).get()), 'custom');
- userEvent.type(ui.inputs.annotationValue(2).get(), 'value');
+ await userEvent.type(byRole('textbox').get(ui.inputs.annotationKey(2).get()), 'custom');
+ await userEvent.type(ui.inputs.annotationValue(2).get(), 'value');
//add a label
- userEvent.type(ui.inputs.labelKey(2).get(), 'custom');
- userEvent.type(ui.inputs.labelValue(2).get(), 'value');
+ await userEvent.type(ui.inputs.labelKey(2).get(), 'custom');
+ await userEvent.type(ui.inputs.labelValue(2).get(), 'value');
// save and check what was sent to backend
- userEvent.click(ui.buttons.save.get());
+ await userEvent.click(ui.buttons.save.get());
await waitFor(() => expect(mocks.api.setRulerRuleGroup).toHaveBeenCalled());
expect(mocks.api.setRulerRuleGroup).toHaveBeenCalledWith(
@@ -614,11 +614,11 @@ describe('RuleEditor', () => {
await waitFor(() => expect(mocks.searchFolders).toHaveBeenCalled());
await ui.inputs.name.find();
- userEvent.click(await ui.buttons.lotexAlert.get());
+ await userEvent.click(await ui.buttons.lotexAlert.get());
// check that only rules sources that have ruler available are there
const dataSourceSelect = ui.inputs.dataSource.get();
- userEvent.click(byRole('combobox').get(dataSourceSelect));
+ await userEvent.click(byRole('combobox').get(dataSourceSelect));
expect(await byText('loki with ruler').query()).toBeInTheDocument();
expect(byText('cortex with ruler').query()).toBeInTheDocument();
expect(byText('loki with local rule store').query()).not.toBeInTheDocument();
@@ -629,6 +629,6 @@ describe('RuleEditor', () => {
});
const clickSelectOption = async (selectElement: HTMLElement, optionText: Matcher): Promise => {
- userEvent.click(byRole('combobox').get(selectElement));
+ await userEvent.click(byRole('combobox').get(selectElement));
await selectOptionInTest(selectElement, optionText as string);
};
diff --git a/public/app/features/alerting/unified/RuleList.test.tsx b/public/app/features/alerting/unified/RuleList.test.tsx
index 72cdcc1a3a8..3a198bc403c 100644
--- a/public/app/features/alerting/unified/RuleList.test.tsx
+++ b/public/app/features/alerting/unified/RuleList.test.tsx
@@ -202,7 +202,7 @@ describe('RuleList', () => {
expect(errors).not.toHaveTextContent(
'Failed to load rules state from Prometheus-broken: this datasource is broken'
);
- userEvent.click(ui.moreErrorsButton.get());
+ await userEvent.click(ui.moreErrorsButton.get());
expect(errors).toHaveTextContent('Failed to load rules state from Prometheus-broken: this datasource is broken');
});
@@ -293,7 +293,7 @@ describe('RuleList', () => {
// expand second group to see rules table
expect(ui.rulesTable.query()).not.toBeInTheDocument();
- userEvent.click(ui.groupCollapseToggle.get(groups[1]));
+ await userEvent.click(ui.groupCollapseToggle.get(groups[1]));
const table = await ui.rulesTable.find(groups[1]);
// check that rule rows are rendered properly
@@ -315,7 +315,7 @@ describe('RuleList', () => {
expect(byText('Labels').query()).not.toBeInTheDocument();
// expand alert details
- userEvent.click(ui.ruleCollapseToggle.get(ruleRows[1]));
+ await userEvent.click(ui.ruleCollapseToggle.get(ruleRows[1]));
const ruleDetails = ui.expandedContent.get(ruleRows[1]);
@@ -334,17 +334,17 @@ describe('RuleList', () => {
expect(instanceRows![1]).toHaveTextContent('Firingfoo=bazseverity=error2021-03-18 13:47:05');
// expand details of an instance
- userEvent.click(ui.ruleCollapseToggle.get(instanceRows![0]));
+ await userEvent.click(ui.ruleCollapseToggle.get(instanceRows![0]));
const alertDetails = byTestId('expanded-content').get(instanceRows[0]);
expect(alertDetails).toHaveTextContent('Value2e+10');
expect(alertDetails).toHaveTextContent('messagefirst alert message');
// collapse everything again
- userEvent.click(ui.ruleCollapseToggle.get(instanceRows![0]));
+ await userEvent.click(ui.ruleCollapseToggle.get(instanceRows![0]));
expect(byTestId('expanded-content').query(instanceRows[0])).not.toBeInTheDocument();
- userEvent.click(ui.ruleCollapseToggle.getAll(ruleRows[1])[0]);
- userEvent.click(ui.groupCollapseToggle.get(groups[1]));
+ await userEvent.click(ui.ruleCollapseToggle.getAll(ruleRows[1])[0]);
+ await userEvent.click(ui.groupCollapseToggle.get(groups[1]));
expect(ui.rulesTable.query()).not.toBeInTheDocument();
});
@@ -456,33 +456,36 @@ describe('RuleList', () => {
expect(groups).toHaveLength(2);
const filterInput = ui.rulesFilterInput.get();
- userEvent.type(filterInput, '{{foo="bar"}');
+ await userEvent.type(filterInput, '{{foo="bar"}');
// Input is debounced so wait for it to be visible
await waitFor(() => expect(filterInput).toHaveValue('{foo="bar"}'));
// Group doesn't contain matching labels
await waitFor(() => expect(ui.ruleGroup.queryAll()).toHaveLength(1));
- userEvent.click(ui.groupCollapseToggle.get(groups[0]));
+ await userEvent.click(ui.groupCollapseToggle.get(groups[0]));
const ruleRows = ui.ruleRow.getAll(groups[0]);
expect(ruleRows).toHaveLength(1);
- userEvent.click(ui.ruleCollapseToggle.get(ruleRows[0]));
+ await userEvent.click(ui.ruleCollapseToggle.get(ruleRows[0]));
const ruleDetails = ui.expandedContent.get(ruleRows[0]);
expect(ruleDetails).toHaveTextContent('Labelsseverity=warningfoo=bar');
// Check for different label matchers
- userEvent.type(filterInput, '{selectall}{del}{{foo!="bar",foo!="baz"}');
+ await userEvent.clear(filterInput);
+ await userEvent.type(filterInput, '{{foo!="bar",foo!="baz"}');
// Group doesn't contain matching labels
await waitFor(() => expect(ui.ruleGroup.queryAll()).toHaveLength(1));
await waitFor(() => expect(ui.ruleGroup.get()).toHaveTextContent('group-2'));
- userEvent.type(filterInput, '{selectall}{del}{{foo=~"b.+"}');
+ await userEvent.clear(filterInput);
+ await userEvent.type(filterInput, '{{foo=~"b.+"}');
await waitFor(() => expect(ui.ruleGroup.queryAll()).toHaveLength(2));
- userEvent.type(filterInput, '{selectall}{del}{{region="US"}');
+ await userEvent.clear(filterInput);
+ await userEvent.type(filterInput, '{{region="US"}');
await waitFor(() => expect(ui.ruleGroup.queryAll()).toHaveLength(1));
await waitFor(() => expect(ui.ruleGroup.get()).toHaveTextContent('group-2'));
});
@@ -521,7 +524,7 @@ describe('RuleList', () => {
expect(groups).toHaveLength(3);
// open edit dialog
- userEvent.click(ui.editCloudGroupIcon.get(groups[0]));
+ await userEvent.click(ui.editCloudGroupIcon.get(groups[0]));
expect(ui.editGroupModal.namespaceInput.get()).toHaveValue('namespace1');
expect(ui.editGroupModal.ruleGroupInput.get()).toHaveValue('group1');
@@ -531,16 +534,16 @@ describe('RuleList', () => {
testCase('rename both lotex namespace and group', async () => {
// make changes to form
- userEvent.clear(ui.editGroupModal.namespaceInput.get());
- userEvent.type(ui.editGroupModal.namespaceInput.get(), 'super namespace');
+ await userEvent.clear(ui.editGroupModal.namespaceInput.get());
+ await userEvent.type(ui.editGroupModal.namespaceInput.get(), 'super namespace');
- userEvent.clear(ui.editGroupModal.ruleGroupInput.get());
- userEvent.type(ui.editGroupModal.ruleGroupInput.get(), 'super group');
+ await userEvent.clear(ui.editGroupModal.ruleGroupInput.get());
+ await userEvent.type(ui.editGroupModal.ruleGroupInput.get(), 'super group');
- userEvent.type(ui.editGroupModal.intervalInput.get(), '5m');
+ await userEvent.type(ui.editGroupModal.intervalInput.get(), '5m');
// submit, check that appropriate calls were made
- userEvent.click(ui.editGroupModal.saveButton.get());
+ await userEvent.click(ui.editGroupModal.saveButton.get());
await waitFor(() => expect(ui.editGroupModal.namespaceInput.query()).not.toBeInTheDocument());
@@ -572,12 +575,12 @@ describe('RuleList', () => {
testCase('rename just the lotex group', async () => {
// make changes to form
- userEvent.clear(ui.editGroupModal.ruleGroupInput.get());
- userEvent.type(ui.editGroupModal.ruleGroupInput.get(), 'super group');
- userEvent.type(ui.editGroupModal.intervalInput.get(), '5m');
+ await userEvent.clear(ui.editGroupModal.ruleGroupInput.get());
+ await userEvent.type(ui.editGroupModal.ruleGroupInput.get(), 'super group');
+ await userEvent.type(ui.editGroupModal.intervalInput.get(), '5m');
// submit, check that appropriate calls were made
- userEvent.click(ui.editGroupModal.saveButton.get());
+ await userEvent.click(ui.editGroupModal.saveButton.get());
await waitFor(() => expect(ui.editGroupModal.namespaceInput.query()).not.toBeInTheDocument());
@@ -604,10 +607,10 @@ describe('RuleList', () => {
testCase('edit lotex group eval interval, no renaming', async () => {
// make changes to form
- userEvent.type(ui.editGroupModal.intervalInput.get(), '5m');
+ await userEvent.type(ui.editGroupModal.intervalInput.get(), '5m');
// submit, check that appropriate calls were made
- userEvent.click(ui.editGroupModal.saveButton.get());
+ await userEvent.click(ui.editGroupModal.saveButton.get());
await waitFor(() => expect(ui.editGroupModal.namespaceInput.query()).not.toBeInTheDocument());
diff --git a/public/app/features/alerting/unified/Silences.test.tsx b/public/app/features/alerting/unified/Silences.test.tsx
index 13d91f7449e..1b3b01bd9b1 100644
--- a/public/app/features/alerting/unified/Silences.test.tsx
+++ b/public/app/features/alerting/unified/Silences.test.tsx
@@ -12,7 +12,7 @@ import { DataSourceType } from './utils/datasource';
import { parseMatchers } from './utils/alertmanager';
import { AlertState, MatcherOperator } from 'app/plugins/datasource/alertmanager/types';
import { byLabelText, byPlaceholderText, byRole, byTestId, byText } from 'testing-library-selector';
-import userEvent from '@testing-library/user-event';
+import userEvent, { PointerEventsCheckLevel } from '@testing-library/user-event';
import { contextSrv } from 'app/core/services/context_srv';
import { AccessControlAction } from 'app/types';
@@ -171,7 +171,8 @@ describe('Silences', () => {
await waitFor(() => expect(mocks.api.fetchAlerts).toHaveBeenCalled());
const queryBar = ui.queryBar.get();
- userEvent.paste(queryBar, 'foo=bar');
+ await userEvent.click(queryBar);
+ await userEvent.paste('foo=bar');
await waitFor(() => expect(ui.silenceRow.getAll()).toHaveLength(1));
},
@@ -254,40 +255,40 @@ describe('Silence edit', () => {
const startDateString = dateTime(start).format('YYYY-MM-DD');
const endDateString = dateTime(end).format('YYYY-MM-DD');
- userEvent.clear(ui.editor.durationInput.get());
- userEvent.type(ui.editor.durationInput.get(), '1d');
+ await userEvent.clear(ui.editor.durationInput.get());
+ await userEvent.type(ui.editor.durationInput.get(), '1d');
await waitFor(() => expect(ui.editor.durationInput.query()).toHaveValue('1d'));
await waitFor(() => expect(ui.editor.timeRange.get()).toHaveTextContent(startDateString));
await waitFor(() => expect(ui.editor.timeRange.get()).toHaveTextContent(endDateString));
- userEvent.type(ui.editor.matcherName.get(), 'foo');
- userEvent.type(ui.editor.matcherOperatorSelect.get(), '=');
- userEvent.tab();
- userEvent.type(ui.editor.matcherValue.get(), 'bar');
+ await userEvent.type(ui.editor.matcherName.get(), 'foo');
+ await userEvent.type(ui.editor.matcherOperatorSelect.get(), '=');
+ await userEvent.tab();
+ await userEvent.type(ui.editor.matcherValue.get(), 'bar');
// TODO remove skipPointerEventsCheck once https://github.com/jsdom/jsdom/issues/3232 is fixed
- userEvent.click(ui.editor.addMatcherButton.get(), undefined, { skipPointerEventsCheck: true });
- userEvent.type(ui.editor.matcherName.getAll()[1], 'bar');
- userEvent.type(ui.editor.matcherOperatorSelect.getAll()[1], '!=');
- userEvent.tab();
- userEvent.type(ui.editor.matcherValue.getAll()[1], 'buzz');
+ await userEvent.click(ui.editor.addMatcherButton.get(), { pointerEventsCheck: PointerEventsCheckLevel.Never });
+ await userEvent.type(ui.editor.matcherName.getAll()[1], 'bar');
+ await userEvent.type(ui.editor.matcherOperatorSelect.getAll()[1], '!=');
+ await userEvent.tab();
+ await userEvent.type(ui.editor.matcherValue.getAll()[1], 'buzz');
// TODO remove skipPointerEventsCheck once https://github.com/jsdom/jsdom/issues/3232 is fixed
- userEvent.click(ui.editor.addMatcherButton.get(), undefined, { skipPointerEventsCheck: true });
- userEvent.type(ui.editor.matcherName.getAll()[2], 'region');
- userEvent.type(ui.editor.matcherOperatorSelect.getAll()[2], '=~');
- userEvent.tab();
- userEvent.type(ui.editor.matcherValue.getAll()[2], 'us-west-.*');
+ await userEvent.click(ui.editor.addMatcherButton.get(), { pointerEventsCheck: PointerEventsCheckLevel.Never });
+ await userEvent.type(ui.editor.matcherName.getAll()[2], 'region');
+ await userEvent.type(ui.editor.matcherOperatorSelect.getAll()[2], '=~');
+ await userEvent.tab();
+ await userEvent.type(ui.editor.matcherValue.getAll()[2], 'us-west-.*');
// TODO remove skipPointerEventsCheck once https://github.com/jsdom/jsdom/issues/3232 is fixed
- userEvent.click(ui.editor.addMatcherButton.get(), undefined, { skipPointerEventsCheck: true });
- userEvent.type(ui.editor.matcherName.getAll()[3], 'env');
- userEvent.type(ui.editor.matcherOperatorSelect.getAll()[3], '!~');
- userEvent.tab();
- userEvent.type(ui.editor.matcherValue.getAll()[3], 'dev|staging');
+ await userEvent.click(ui.editor.addMatcherButton.get(), { pointerEventsCheck: PointerEventsCheckLevel.Never });
+ await userEvent.type(ui.editor.matcherName.getAll()[3], 'env');
+ await userEvent.type(ui.editor.matcherOperatorSelect.getAll()[3], '!~');
+ await userEvent.tab();
+ await userEvent.type(ui.editor.matcherValue.getAll()[3], 'dev|staging');
- userEvent.click(ui.editor.submit.get());
+ await userEvent.click(ui.editor.submit.get());
await waitFor(() =>
expect(mocks.api.createOrUpdateSilence).toHaveBeenCalledWith(
diff --git a/public/app/features/alerting/unified/components/admin/AlertmanagerConfig.test.tsx b/public/app/features/alerting/unified/components/admin/AlertmanagerConfig.test.tsx
index a4dbf55a55b..ed43711beaa 100644
--- a/public/app/features/alerting/unified/components/admin/AlertmanagerConfig.test.tsx
+++ b/public/app/features/alerting/unified/components/admin/AlertmanagerConfig.test.tsx
@@ -104,8 +104,8 @@ describe('Admin config', () => {
await renderAdminPage(dataSources.alertManager.name);
- userEvent.click(await ui.resetButton.find());
- userEvent.click(ui.confirmButton.get());
+ await userEvent.click(await ui.resetButton.find());
+ await userEvent.click(ui.confirmButton.get());
await waitFor(() => expect(mocks.api.deleteAlertManagerConfig).toHaveBeenCalled());
expect(ui.confirmButton.query()).not.toBeInTheDocument();
});
@@ -132,12 +132,12 @@ describe('Admin config', () => {
await renderAdminPage(dataSources.alertManager.name);
const input = await ui.configInput.find();
expect(input.value).toEqual(JSON.stringify(defaultConfig, null, 2));
- userEvent.clear(input);
+ await userEvent.clear(input);
// What is this regex replace doing? in userEvent v13, '{' and '[' are special characters.
// To get the literal character, you have to escape them by typing '{{' or '[['.
// See https://github.com/testing-library/user-event/issues/584.
- userEvent.type(input, JSON.stringify(newConfig, null, 2).replace(/[{[]/g, '$&$&'));
- userEvent.click(ui.saveButton.get());
+ await userEvent.type(input, JSON.stringify(newConfig, null, 2).replace(/[{[]/g, '$&$&'));
+ await userEvent.click(ui.saveButton.get());
await waitFor(() => expect(mocks.api.updateAlertManagerConfig).toHaveBeenCalled());
await waitFor(() => expect(mocks.api.fetchConfig).toHaveBeenCalledTimes(3));
expect(input.value).toEqual(JSON.stringify(newConfig, null, 2));
diff --git a/public/app/features/alerting/unified/components/rules/RulesGroup.test.tsx b/public/app/features/alerting/unified/components/rules/RulesGroup.test.tsx
index a9eafa81ed3..79bde001d75 100644
--- a/public/app/features/alerting/unified/components/rules/RulesGroup.test.tsx
+++ b/public/app/features/alerting/unified/components/rules/RulesGroup.test.tsx
@@ -95,13 +95,13 @@ describe('Rules group tests', () => {
expect(ui.editGroupButton.query()).not.toBeInTheDocument();
});
- it('Delete button click should display confirmation modal', () => {
+ it('Delete button click should display confirmation modal', async () => {
// Arrange
hasRulerMock.mockReturnValue(true);
// Act
renderRulesGroup(namespace, group);
- userEvent.click(ui.deleteGroupButton.get());
+ await userEvent.click(ui.deleteGroupButton.get());
// Assert
expect(ui.confirmDeleteModal.header.get()).toBeInTheDocument();
diff --git a/public/app/features/api-keys/ApiKeysPage.test.tsx b/public/app/features/api-keys/ApiKeysPage.test.tsx
index 4b33ab79096..eb97929c5a3 100644
--- a/public/app/features/api-keys/ApiKeysPage.test.tsx
+++ b/public/app/features/api-keys/ApiKeysPage.test.tsx
@@ -7,7 +7,7 @@ import { setSearchQuery } from './state/reducers';
import { mockToolkitActionCreator } from '../../../test/core/redux/mocks';
import { getMultipleMockKeys } from './__mocks__/apiKeysMock';
import { selectors } from '@grafana/e2e-selectors';
-import userEvent from '@testing-library/user-event';
+import userEvent, { PointerEventsCheckLevel } from '@testing-library/user-event';
import { silenceConsoleOutput } from '../../../test/core/utils/silenceConsoleOutput';
const setup = (propOverrides: Partial) => {
@@ -100,7 +100,7 @@ describe('ApiKeysPage', () => {
const apiKeys = getMultipleMockKeys(3);
const { toggleIncludeExpiredMock } = setup({ apiKeys, apiKeysCount: apiKeys.length, hasFetched: true });
- toggleShowExpired();
+ await toggleShowExpired();
expect(toggleIncludeExpiredMock).toHaveBeenCalledTimes(1);
});
});
@@ -112,7 +112,7 @@ describe('ApiKeysPage', () => {
setSearchQueryMock.mockClear();
expect(screen.getByPlaceholderText(/search keys/i)).toBeInTheDocument();
- userEvent.type(screen.getByPlaceholderText(/search keys/i), 'First');
+ await userEvent.type(screen.getByPlaceholderText(/search keys/i), 'First');
expect(setSearchQueryMock).toHaveBeenCalledTimes(5);
});
});
@@ -130,21 +130,21 @@ describe('ApiKeysPage', () => {
deleteApiKeyMock.mockClear();
expect(within(firstRow).getByLabelText('Delete API key')).toBeInTheDocument();
- userEvent.click(within(firstRow).getByLabelText('Delete API key'));
+ await userEvent.click(within(firstRow).getByLabelText('Delete API key'));
expect(within(firstRow).getByRole('button', { name: /delete$/i })).toBeInTheDocument();
- userEvent.click(within(firstRow).getByRole('button', { name: /delete$/i }));
+ await userEvent.click(within(firstRow).getByRole('button', { name: /delete$/i }));
expect(deleteApiKeyMock).toHaveBeenCalledTimes(1);
expect(deleteApiKeyMock).toHaveBeenCalledWith(1);
- toggleShowExpired();
+ await toggleShowExpired();
deleteApiKeyMock.mockClear();
expect(within(secondRow).getByLabelText('Delete API key')).toBeInTheDocument();
- userEvent.click(within(secondRow).getByLabelText('Delete API key'));
+ await userEvent.click(within(secondRow).getByLabelText('Delete API key'));
expect(within(secondRow).getByRole('button', { name: /delete$/i })).toBeInTheDocument();
- userEvent.click(within(secondRow).getByRole('button', { name: /delete$/i }), undefined, {
- skipPointerEventsCheck: true,
+ await userEvent.click(within(secondRow).getByRole('button', { name: /delete$/i }), {
+ pointerEventsCheck: PointerEventsCheckLevel.Never,
});
expect(deleteApiKeyMock).toHaveBeenCalledTimes(1);
expect(deleteApiKeyMock).toHaveBeenCalledWith(2);
@@ -157,7 +157,7 @@ describe('ApiKeysPage', () => {
const { addApiKeyMock } = setup({ apiKeys, apiKeysCount: apiKeys.length, hasFetched: true });
addApiKeyMock.mockClear();
- userEvent.click(screen.getByTestId(selectors.components.CallToActionCard.buttonV2('New API key')));
+ await userEvent.click(screen.getByTestId(selectors.components.CallToActionCard.buttonV2('New API key')));
await addAndVerifyApiKey(addApiKeyMock);
});
});
@@ -168,13 +168,13 @@ describe('ApiKeysPage', () => {
const { addApiKeyMock } = setup({ apiKeys, apiKeysCount: apiKeys.length, hasFetched: true });
addApiKeyMock.mockClear();
- userEvent.click(screen.getByRole('button', { name: /add api key/i }));
+ await userEvent.click(screen.getByRole('button', { name: /add api key/i }));
await addAndVerifyApiKey(addApiKeyMock);
- toggleShowExpired();
+ await toggleShowExpired();
addApiKeyMock.mockClear();
- userEvent.click(screen.getByRole('button', { name: /add api key/i }));
+ await userEvent.click(screen.getByRole('button', { name: /add api key/i }));
await addAndVerifyApiKey(addApiKeyMock);
});
});
@@ -185,20 +185,20 @@ describe('ApiKeysPage', () => {
const { addApiKeyMock } = setup({ apiKeys, apiKeysCount: apiKeys.length, hasFetched: true });
addApiKeyMock.mockClear();
- userEvent.click(screen.getByRole('button', { name: /add api key/i }));
- userEvent.type(screen.getByPlaceholderText(/name/i), 'Test');
- userEvent.type(screen.getByPlaceholderText(/1d/i), '60x');
+ await userEvent.click(screen.getByRole('button', { name: /add api key/i }));
+ await userEvent.type(screen.getByPlaceholderText(/name/i), 'Test');
+ await userEvent.type(screen.getByPlaceholderText(/1d/i), '60x');
expect(screen.queryByText(/not a valid duration/i)).not.toBeInTheDocument();
- userEvent.click(screen.getByRole('button', { name: /^add$/i }));
+ await userEvent.click(screen.getByRole('button', { name: /^add$/i }));
expect(screen.getByText(/not a valid duration/i)).toBeInTheDocument();
expect(addApiKeyMock).toHaveBeenCalledTimes(0);
});
});
});
-function toggleShowExpired() {
+async function toggleShowExpired() {
expect(screen.queryByLabelText(/include expired keys/i)).toBeInTheDocument();
- userEvent.click(screen.getByLabelText(/include expired keys/i));
+ await userEvent.click(screen.getByLabelText(/include expired keys/i));
}
async function addAndVerifyApiKey(addApiKeyMock: jest.Mock) {
@@ -207,9 +207,9 @@ async function addAndVerifyApiKey(addApiKeyMock: jest.Mock) {
expect(screen.getByPlaceholderText(/1d/i)).toBeInTheDocument();
expect(screen.getByRole('button', { name: /^add$/i })).toBeInTheDocument();
- userEvent.type(screen.getByPlaceholderText(/name/i), 'Test');
- userEvent.type(screen.getByPlaceholderText(/1d/i), '60s');
- userEvent.click(screen.getByRole('button', { name: /^add$/i }));
+ await userEvent.type(screen.getByPlaceholderText(/name/i), 'Test');
+ await userEvent.type(screen.getByPlaceholderText(/1d/i), '60s');
+ await userEvent.click(screen.getByRole('button', { name: /^add$/i }));
expect(addApiKeyMock).toHaveBeenCalledTimes(1);
expect(addApiKeyMock).toHaveBeenCalledWith({ name: 'Test', role: 'Viewer', secondsToLive: 60 }, expect.anything());
}
diff --git a/public/app/features/dashboard/components/DashboardSettings/AnnotationsSettings.test.tsx b/public/app/features/dashboard/components/DashboardSettings/AnnotationsSettings.test.tsx
index 07c3d3d2b76..bdd4a660c37 100644
--- a/public/app/features/dashboard/components/DashboardSettings/AnnotationsSettings.test.tsx
+++ b/public/app/features/dashboard/components/DashboardSettings/AnnotationsSettings.test.tsx
@@ -76,7 +76,7 @@ describe('AnnotationsSettings', () => {
};
});
- test('it renders a header and cta if no annotations or only builtIn annotation', () => {
+ test('it renders a header and cta if no annotations or only builtIn annotation', async () => {
render();
expect(screen.getByRole('heading', { name: /annotations/i })).toBeInTheDocument();
@@ -87,7 +87,7 @@ describe('AnnotationsSettings', () => {
).toBeInTheDocument();
expect(screen.queryByRole('link', { name: /annotations documentation/i })).toBeInTheDocument();
- userEvent.click(screen.getByRole('cell', { name: /annotations & alerts \(built\-in\)/i }));
+ await userEvent.click(screen.getByRole('cell', { name: /annotations & alerts \(built\-in\)/i }));
const heading = screen.getByRole('heading', {
name: /annotations edit/i,
@@ -96,13 +96,13 @@ describe('AnnotationsSettings', () => {
expect(heading).toBeInTheDocument();
- userEvent.clear(nameInput);
- userEvent.type(nameInput, 'My Annotation');
+ await userEvent.clear(nameInput);
+ await userEvent.type(nameInput, 'My Annotation');
expect(screen.queryByText(/grafana/i)).toBeInTheDocument();
expect(screen.getByRole('checkbox', { name: /hidden/i })).toBeChecked();
- userEvent.click(within(heading).getByText(/annotations/i));
+ await userEvent.click(within(heading).getByText(/annotations/i));
expect(screen.getByRole('table')).toBeInTheDocument();
expect(screen.getByRole('row', { name: /my annotation \(built\-in\) grafana/i })).toBeInTheDocument();
@@ -111,8 +111,8 @@ describe('AnnotationsSettings', () => {
).toBeInTheDocument();
expect(screen.queryByRole('button', { name: /new query/i })).not.toBeInTheDocument();
- userEvent.click(screen.getAllByLabelText(/Delete query with title/)[0]);
- userEvent.click(screen.getByRole('button', { name: 'Delete' }));
+ await userEvent.click(screen.getAllByLabelText(/Delete query with title/)[0]);
+ await userEvent.click(screen.getByRole('button', { name: 'Delete' }));
expect(screen.queryAllByRole('row').length).toBe(0);
expect(
@@ -120,7 +120,7 @@ describe('AnnotationsSettings', () => {
).toBeInTheDocument();
});
- test('it renders a sortable table of annotations', () => {
+ test('it renders a sortable table of annotations', async () => {
const annotationsList = [
...dashboard.annotations.list,
{
@@ -164,9 +164,9 @@ describe('AnnotationsSettings', () => {
expect(within(getTableBodyRows()[1]).queryByText(/annotation 2/i)).toBeInTheDocument();
expect(within(getTableBodyRows()[2]).queryByText(/annotation 3/i)).toBeInTheDocument();
- userEvent.click(within(getTableBody()).getAllByRole('button', { name: 'arrow-down' })[0]);
- userEvent.click(within(getTableBody()).getAllByRole('button', { name: 'arrow-down' })[1]);
- userEvent.click(within(getTableBody()).getAllByRole('button', { name: 'arrow-up' })[0]);
+ await userEvent.click(within(getTableBody()).getAllByRole('button', { name: 'arrow-down' })[0]);
+ await userEvent.click(within(getTableBody()).getAllByRole('button', { name: 'arrow-down' })[1]);
+ await userEvent.click(within(getTableBody()).getAllByRole('button', { name: 'arrow-up' })[0]);
// Checking if it has changed the sorting accordingly
expect(within(getTableBodyRows()[0]).queryByText(/annotation 3/i)).toBeInTheDocument();
@@ -177,7 +177,7 @@ describe('AnnotationsSettings', () => {
test('it renders a form for adding/editing annotations', async () => {
render();
- userEvent.click(screen.getByTestId(selectors.components.CallToActionCard.buttonV2('Add annotation query')));
+ await userEvent.click(screen.getByTestId(selectors.components.CallToActionCard.buttonV2('Add annotation query')));
const heading = screen.getByRole('heading', {
name: /annotations edit/i,
@@ -186,19 +186,19 @@ describe('AnnotationsSettings', () => {
expect(heading).toBeInTheDocument();
- userEvent.clear(nameInput);
- userEvent.type(nameInput, 'My Prometheus Annotation');
+ await userEvent.clear(nameInput);
+ await userEvent.type(nameInput, 'My Prometheus Annotation');
- userEvent.click(screen.getByText(/testdata/i));
+ await userEvent.click(screen.getByText(/testdata/i));
expect(await screen.findByText(/Prometheus/i)).toBeVisible();
expect(screen.queryAllByText(/testdata/i)).toHaveLength(2);
- userEvent.click(screen.getByText(/prometheus/i));
+ await userEvent.click(screen.getByText(/prometheus/i));
expect(screen.getByRole('checkbox', { name: /hidden/i })).not.toBeChecked();
- userEvent.click(within(heading).getByText(/annotations/i));
+ await userEvent.click(within(heading).getByText(/annotations/i));
expect(within(screen.getAllByRole('rowgroup')[1]).getAllByRole('row').length).toBe(2);
expect(screen.queryByRole('row', { name: /my prometheus annotation prometheus/i })).toBeInTheDocument();
@@ -207,14 +207,14 @@ describe('AnnotationsSettings', () => {
screen.queryByTestId(selectors.components.CallToActionCard.buttonV2('Add annotation query'))
).not.toBeInTheDocument();
- userEvent.click(screen.getByRole('button', { name: /new query/i }));
+ await userEvent.click(screen.getByRole('button', { name: /new query/i }));
- userEvent.click(within(screen.getByRole('heading', { name: /annotations edit/i })).getByText(/annotations/i));
+ await userEvent.click(within(screen.getByRole('heading', { name: /annotations edit/i })).getByText(/annotations/i));
expect(within(screen.getAllByRole('rowgroup')[1]).getAllByRole('row').length).toBe(3);
- userEvent.click(screen.getAllByLabelText(/Delete query with title/)[0]);
- userEvent.click(screen.getByRole('button', { name: 'Delete' }));
+ await userEvent.click(screen.getAllByLabelText(/Delete query with title/)[0]);
+ await userEvent.click(screen.getByRole('button', { name: 'Delete' }));
expect(within(screen.getAllByRole('rowgroup')[1]).getAllByRole('row').length).toBe(2);
});
diff --git a/public/app/features/dashboard/components/DashboardSettings/AutoRefreshIntervals.test.tsx b/public/app/features/dashboard/components/DashboardSettings/AutoRefreshIntervals.test.tsx
index 948dfd93c15..da52654bfb6 100644
--- a/public/app/features/dashboard/components/DashboardSettings/AutoRefreshIntervals.test.tsx
+++ b/public/app/features/dashboard/components/DashboardSettings/AutoRefreshIntervals.test.tsx
@@ -49,11 +49,11 @@ describe('AutoRefreshIntervals', () => {
});
describe('when input loses focus and intervals are valid', () => {
- it('then onRefreshIntervalChange should be called', () => {
+ it('then onRefreshIntervalChange should be called', async () => {
const { props } = setupTestContext({ validateIntervalsFunc: () => null });
- userEvent.type(screen.getByRole('textbox'), ',30s');
- userEvent.tab();
+ await userEvent.type(screen.getByRole('textbox'), ',30s');
+ await userEvent.tab();
expect(screen.getByRole('textbox')).toHaveValue('1s,5s,10s,30s');
expect(props.onRefreshIntervalChange).toHaveBeenCalledTimes(1);
@@ -62,11 +62,11 @@ describe('AutoRefreshIntervals', () => {
});
describe('when input loses focus and intervals are invalid', () => {
- it('then onRefreshIntervalChange should not be called', () => {
+ it('then onRefreshIntervalChange should not be called', async () => {
const { props } = setupTestContext({ validateIntervalsFunc: () => 'Not valid' });
- userEvent.type(screen.getByRole('textbox'), ',30q');
- userEvent.tab();
+ await userEvent.type(screen.getByRole('textbox'), ',30q');
+ await userEvent.tab();
expect(screen.getByRole('textbox')).toHaveValue('1s,5s,10s,30q');
expect(props.onRefreshIntervalChange).toHaveBeenCalledTimes(0);
@@ -74,14 +74,14 @@ describe('AutoRefreshIntervals', () => {
});
describe('when input loses focus and previous intervals were invalid', () => {
- it('then onRefreshIntervalChange should be called', () => {
+ it('then onRefreshIntervalChange should be called', async () => {
const validateIntervalsFunc = jest.fn().mockReturnValueOnce('Not valid').mockReturnValue(null);
const { props } = setupTestContext({ validateIntervalsFunc });
- userEvent.type(screen.getByRole('textbox'), ',30q');
- userEvent.tab();
- userEvent.type(screen.getByRole('textbox'), '{backspace}s');
- userEvent.tab();
+ await userEvent.type(screen.getByRole('textbox'), ',30q');
+ await userEvent.tab();
+ await userEvent.type(screen.getByRole('textbox'), '{backspace}s');
+ await userEvent.tab();
expect(screen.getByRole('textbox')).toHaveValue('1s,5s,10s,30s');
expect(props.onRefreshIntervalChange).toHaveBeenCalledTimes(1);
diff --git a/public/app/features/dashboard/components/DashboardSettings/GeneralSettings.test.tsx b/public/app/features/dashboard/components/DashboardSettings/GeneralSettings.test.tsx
index dbec19a2961..97bf20e1f50 100644
--- a/public/app/features/dashboard/components/DashboardSettings/GeneralSettings.test.tsx
+++ b/public/app/features/dashboard/components/DashboardSettings/GeneralSettings.test.tsx
@@ -48,9 +48,9 @@ describe('General Settings', () => {
describe('when timezone is changed', () => {
it('should call update function', async () => {
const { props } = setupTestContext({});
- userEvent.click(screen.getByTestId(selectors.components.TimeZonePicker.containerV2));
+ await userEvent.click(screen.getByTestId(selectors.components.TimeZonePicker.containerV2));
const timeZonePicker = screen.getByTestId(selectors.components.TimeZonePicker.containerV2);
- userEvent.click(byRole('combobox').get(timeZonePicker));
+ await userEvent.click(byRole('combobox').get(timeZonePicker));
await selectOptionInTest(timeZonePicker, 'Browser Time');
expect(props.updateTimeZone).toHaveBeenCalledWith('browser');
expect(props.dashboard.timezone).toBe('browser');
diff --git a/public/app/features/dashboard/components/DashboardSettings/LinksSettings.test.tsx b/public/app/features/dashboard/components/DashboardSettings/LinksSettings.test.tsx
index a2646974940..db38118db3a 100644
--- a/public/app/features/dashboard/components/DashboardSettings/LinksSettings.test.tsx
+++ b/public/app/features/dashboard/components/DashboardSettings/LinksSettings.test.tsx
@@ -84,7 +84,7 @@ describe('LinksSettings', () => {
).not.toBeInTheDocument();
});
- test('it rearranges the order of dashboard links', () => {
+ test('it rearranges the order of dashboard links', async () => {
// @ts-ignore
render();
@@ -103,9 +103,9 @@ describe('LinksSettings', () => {
assertRowHasText(1, links[1].title);
assertRowHasText(2, links[2].url);
- userEvent.click(within(getTableBody()).getAllByRole('button', { name: 'arrow-down' })[0]);
- userEvent.click(within(getTableBody()).getAllByRole('button', { name: 'arrow-down' })[1]);
- userEvent.click(within(getTableBody()).getAllByRole('button', { name: 'arrow-up' })[0]);
+ await userEvent.click(within(getTableBody()).getAllByRole('button', { name: 'arrow-down' })[0]);
+ await userEvent.click(within(getTableBody()).getAllByRole('button', { name: 'arrow-down' })[1]);
+ await userEvent.click(within(getTableBody()).getAllByRole('button', { name: 'arrow-up' })[0]);
// Checking if it has changed the sorting accordingly
assertRowHasText(0, links[2].url);
@@ -113,35 +113,35 @@ describe('LinksSettings', () => {
assertRowHasText(2, links[0].title);
});
- test('it duplicates dashboard links', () => {
+ test('it duplicates dashboard links', async () => {
// @ts-ignore
render();
expect(getTableBodyRows().length).toBe(links.length);
- userEvent.click(within(getTableBody()).getAllByRole('button', { name: /copy/i })[0]);
+ await userEvent.click(within(getTableBody()).getAllByRole('button', { name: /copy/i })[0]);
expect(getTableBodyRows().length).toBe(links.length + 1);
expect(within(getTableBody()).getAllByText(links[0].title).length).toBe(2);
});
- test('it deletes dashboard links', () => {
+ test('it deletes dashboard links', async () => {
// @ts-ignore
render();
expect(getTableBodyRows().length).toBe(links.length);
- userEvent.click(within(getTableBody()).getAllByLabelText(/Delete link with title/)[0]);
- userEvent.click(within(getTableBody()).getByRole('button', { name: 'Delete' }));
+ await userEvent.click(within(getTableBody()).getAllByLabelText(/Delete link with title/)[0]);
+ await userEvent.click(within(getTableBody()).getByRole('button', { name: 'Delete' }));
expect(getTableBodyRows().length).toBe(links.length - 1);
expect(within(getTableBody()).queryByText(links[0].title)).not.toBeInTheDocument();
});
- test('it renders a form which modifies dashboard links', () => {
+ test('it renders a form which modifies dashboard links', async () => {
// @ts-ignore
render();
- userEvent.click(screen.getByRole('button', { name: /new/i }));
+ await userEvent.click(screen.getByRole('button', { name: /new/i }));
expect(screen.queryByText('Type')).toBeInTheDocument();
expect(screen.queryByText('Title')).toBeInTheDocument();
@@ -151,29 +151,29 @@ describe('LinksSettings', () => {
expect(screen.queryByText('Tooltip')).not.toBeInTheDocument();
expect(screen.queryByText('Icon')).not.toBeInTheDocument();
- userEvent.click(screen.getByText('Dashboards'));
+ await userEvent.click(screen.getByText('Dashboards'));
expect(screen.queryAllByText('Dashboards')).toHaveLength(2);
expect(screen.queryByText('Link')).toBeVisible();
- userEvent.click(screen.getByText('Link'));
+ await userEvent.click(screen.getByText('Link'));
expect(screen.queryByText('URL')).toBeInTheDocument();
expect(screen.queryByText('Tooltip')).toBeInTheDocument();
expect(screen.queryByText('Icon')).toBeInTheDocument();
- userEvent.clear(screen.getByRole('textbox', { name: /title/i }));
- userEvent.type(screen.getByRole('textbox', { name: /title/i }), 'New Dashboard Link');
- userEvent.click(
+ await userEvent.clear(screen.getByRole('textbox', { name: /title/i }));
+ await userEvent.type(screen.getByRole('textbox', { name: /title/i }), 'New Dashboard Link');
+ await userEvent.click(
within(screen.getByRole('heading', { name: /dashboard links edit/i })).getByText(/dashboard links/i)
);
expect(getTableBodyRows().length).toBe(links.length + 1);
expect(within(getTableBody()).queryByText('New Dashboard Link')).toBeInTheDocument();
- userEvent.click(screen.getAllByText(links[0].type)[0]);
- userEvent.clear(screen.getByRole('textbox', { name: /title/i }));
- userEvent.type(screen.getByRole('textbox', { name: /title/i }), 'The first dashboard link');
- userEvent.click(
+ await userEvent.click(screen.getAllByText(links[0].type)[0]);
+ await userEvent.clear(screen.getByRole('textbox', { name: /title/i }));
+ await userEvent.type(screen.getByRole('textbox', { name: /title/i }), 'The first dashboard link');
+ await userEvent.click(
within(screen.getByRole('heading', { name: /dashboard links edit/i })).getByText(/dashboard links/i)
);
diff --git a/public/app/features/dashboard/components/DashboardSettings/VersionsSettings.test.tsx b/public/app/features/dashboard/components/DashboardSettings/VersionsSettings.test.tsx
index 00788bbe65d..2c312ec181c 100644
--- a/public/app/features/dashboard/components/DashboardSettings/VersionsSettings.test.tsx
+++ b/public/app/features/dashboard/components/DashboardSettings/VersionsSettings.test.tsx
@@ -6,6 +6,7 @@ import userEvent from '@testing-library/user-event';
import { historySrv } from '../VersionHistory/HistorySrv';
import { VersionsSettings, VERSIONS_FETCH_LIMIT } from './VersionsSettings';
import { versions, diffs } from './__mocks__/versions';
+import { UserEvent } from '@testing-library/user-event/dist/types/setup';
jest.mock('../VersionHistory/HistorySrv');
@@ -28,8 +29,18 @@ describe('VersionSettings', () => {
getRelativeTime: jest.fn(() => 'time ago'),
};
+ let user: UserEvent;
+
beforeEach(() => {
+ // Need to use delay: null here to work with fakeTimers
+ // see https://github.com/testing-library/user-event/issues/833
+ user = userEvent.setup({ delay: null });
jest.resetAllMocks();
+ jest.useFakeTimers();
+ });
+
+ afterEach(() => {
+ jest.useRealTimers();
});
test('renders a header and a loading indicator followed by results in a table', async () => {
@@ -102,7 +113,9 @@ describe('VersionSettings', () => {
historySrv.getHistoryList
// @ts-ignore
.mockImplementationOnce(() => Promise.resolve(versions.slice(0, VERSIONS_FETCH_LIMIT)))
- .mockImplementationOnce(() => Promise.resolve(versions.slice(VERSIONS_FETCH_LIMIT, versions.length)));
+ .mockImplementationOnce(
+ () => new Promise((resolve) => setTimeout(() => resolve(versions.slice(VERSIONS_FETCH_LIMIT)), 1000))
+ );
render();
@@ -113,14 +126,16 @@ describe('VersionSettings', () => {
expect(within(screen.getAllByRole('rowgroup')[1]).getAllByRole('row').length).toBe(VERSIONS_FETCH_LIMIT);
const showMoreButton = screen.getByRole('button', { name: /show more versions/i });
- userEvent.click(showMoreButton);
+ await user.click(showMoreButton);
expect(historySrv.getHistoryList).toBeCalledTimes(2);
- expect(screen.queryByText(/Fetching more entries/i)).toBeInTheDocument();
+ expect(screen.getByText(/Fetching more entries/i)).toBeInTheDocument();
+ jest.advanceTimersByTime(1000);
- await waitFor(() =>
- expect(within(screen.getAllByRole('rowgroup')[1]).getAllByRole('row').length).toBe(versions.length)
- );
+ await waitFor(() => {
+ expect(screen.queryByText(/Fetching more entries/i)).not.toBeInTheDocument();
+ expect(within(screen.getAllByRole('rowgroup')[1]).getAllByRole('row').length).toBe(versions.length);
+ });
});
test('selecting two versions and clicking compare button should render compare view', async () => {
@@ -139,17 +154,17 @@ describe('VersionSettings', () => {
const compareButton = screen.getByRole('button', { name: /compare versions/i });
const tableBody = screen.getAllByRole('rowgroup')[1];
- userEvent.click(within(tableBody).getAllByRole('checkbox')[0]);
- userEvent.click(within(tableBody).getAllByRole('checkbox')[VERSIONS_FETCH_LIMIT - 1]);
+ await user.click(within(tableBody).getAllByRole('checkbox')[0]);
+ await user.click(within(tableBody).getAllByRole('checkbox')[VERSIONS_FETCH_LIMIT - 1]);
expect(compareButton).toBeEnabled();
- userEvent.click(within(tableBody).getAllByRole('checkbox')[1]);
+ await user.click(within(tableBody).getAllByRole('checkbox')[1]);
expect(compareButton).toBeDisabled();
- userEvent.click(within(tableBody).getAllByRole('checkbox')[1]);
- userEvent.click(compareButton);
+ await user.click(within(tableBody).getAllByRole('checkbox')[1]);
+ await user.click(compareButton);
await waitFor(() => expect(screen.getByRole('heading', { name: /versions comparing 2 11/i })).toBeInTheDocument());
@@ -170,7 +185,7 @@ describe('VersionSettings', () => {
expect(queryByFullText('version changed')).toBeInTheDocument();
expect(screen.queryByText(/view json diff/i)).toBeInTheDocument();
- userEvent.click(screen.getByText(/view json diff/i));
+ await user.click(screen.getByText(/view json diff/i));
await waitFor(() => expect(screen.getByRole('table')).toBeInTheDocument());
});
diff --git a/public/app/features/dashboard/components/PanelEditor/PanelNotSupported.test.tsx b/public/app/features/dashboard/components/PanelEditor/PanelNotSupported.test.tsx
index 3140999328a..7c61a20373d 100644
--- a/public/app/features/dashboard/components/PanelEditor/PanelNotSupported.test.tsx
+++ b/public/app/features/dashboard/components/PanelEditor/PanelNotSupported.test.tsx
@@ -28,9 +28,9 @@ describe('PanelNotSupported', () => {
});
describe('when the back to queries button is clicked', () => {
- it('then correct action should be dispatched', () => {
+ it('then correct action should be dispatched', async () => {
setupTestContext({});
- userEvent.click(screen.getByRole('button', { name: /go back to queries/i }));
+ await userEvent.click(screen.getByRole('button', { name: /go back to queries/i }));
expect(locationService.getSearchObject().tab).toBe(PanelEditorTabId.Query);
});
});
diff --git a/public/app/features/dashboard/components/TransformationsEditor/TransformationsEditor.test.tsx b/public/app/features/dashboard/components/TransformationsEditor/TransformationsEditor.test.tsx
index da6ff1462fd..617d4f9f86b 100644
--- a/public/app/features/dashboard/components/TransformationsEditor/TransformationsEditor.test.tsx
+++ b/public/app/features/dashboard/components/TransformationsEditor/TransformationsEditor.test.tsx
@@ -33,13 +33,13 @@ describe('TransformationsEditor', () => {
options: {},
},
]);
- const editors = screen.getAllByLabelText(/^Transformation editor/g);
+ const editors = screen.getAllByLabelText(/^Transformation editor/);
expect(editors).toHaveLength(1);
});
});
describe('when Add transformation clicked', () => {
- it('renders transformations picker', () => {
+ it('renders transformations picker', async () => {
const buttonLabel = 'Add transformation';
setup([
{
@@ -49,7 +49,7 @@ describe('TransformationsEditor', () => {
]);
const addTransformationButton = screen.getByText(buttonLabel);
- userEvent.click(addTransformationButton);
+ await userEvent.click(addTransformationButton);
const search = screen.getByLabelText(selectors.components.Transforms.searchInput);
expect(search).toBeDefined();
@@ -58,7 +58,7 @@ describe('TransformationsEditor', () => {
describe('actions', () => {
describe('debug', () => {
- it('should show/hide debugger', () => {
+ it('should show/hide debugger', async () => {
setup([
{
id: 'reduce',
@@ -70,7 +70,7 @@ describe('TransformationsEditor', () => {
expect(screen.queryByLabelText(debuggerSelector)).toBeNull();
const debugButton = screen.getByLabelText(selectors.components.QueryEditorRow.actionButton('Debug'));
- userEvent.click(debugButton);
+ await userEvent.click(debugButton);
expect(screen.getByLabelText(debuggerSelector)).toBeInTheDocument();
});
diff --git a/public/app/features/explore/AddToDashboard/index.test.tsx b/public/app/features/explore/AddToDashboard/index.test.tsx
index fe265e71545..e3da2cf30e7 100644
--- a/public/app/features/explore/AddToDashboard/index.test.tsx
+++ b/public/app/features/explore/AddToDashboard/index.test.tsx
@@ -28,7 +28,7 @@ const setup = (children: ReactNode, queries: DataQuery[] = [{ refId: 'A' }]) =>
};
const openModal = async () => {
- userEvent.click(screen.getByRole('button', { name: /add to dashboard/i }));
+ await userEvent.click(screen.getByRole('button', { name: /add to dashboard/i }));
expect(await screen.findByRole('dialog', { name: 'Add panel to dashboard' })).toBeInTheDocument();
};
@@ -44,7 +44,7 @@ describe('AddToDashboardButton', () => {
const button = await screen.findByRole('button', { name: /add to dashboard/i });
expect(button).toBeDisabled();
- userEvent.click(button);
+ await userEvent.click(button);
expect(screen.queryByRole('dialog')).not.toBeInTheDocument();
});
@@ -71,7 +71,7 @@ describe('AddToDashboardButton', () => {
await openModal();
- userEvent.click(screen.getByRole('button', { name: /cancel/i }));
+ await userEvent.click(screen.getByRole('button', { name: /cancel/i }));
expect(screen.queryByRole('dialog')).not.toBeInTheDocument();
});
@@ -86,7 +86,7 @@ describe('AddToDashboardButton', () => {
await openModal();
- userEvent.click(screen.getByRole('button', { name: /open dashboard$/i }));
+ await userEvent.click(screen.getByRole('button', { name: /open dashboard$/i }));
await waitForAddToDashboardResponse();
@@ -105,7 +105,7 @@ describe('AddToDashboardButton', () => {
await openModal();
- userEvent.click(screen.getByRole('button', { name: /open in new tab/i }));
+ await userEvent.click(screen.getByRole('button', { name: /open in new tab/i }));
await waitForAddToDashboardResponse();
@@ -124,7 +124,7 @@ describe('AddToDashboardButton', () => {
await openModal();
- userEvent.click(screen.getByRole('button', { name: /open in new tab/i }));
+ await userEvent.click(screen.getByRole('button', { name: /open in new tab/i }));
await waitForAddToDashboardResponse();
@@ -138,7 +138,7 @@ describe('AddToDashboardButton', () => {
await openModal();
- userEvent.click(screen.getByRole('button', { name: /open dashboard$/i }));
+ await userEvent.click(screen.getByRole('button', { name: /open dashboard$/i }));
await waitForAddToDashboardResponse();
@@ -157,7 +157,7 @@ describe('AddToDashboardButton', () => {
expect(screen.queryByRole('combobox', { name: /dashboard/ })).not.toBeInTheDocument();
- userEvent.click(screen.getByRole('radio', { name: /existing dashboard/i }));
+ await userEvent.click(screen.getByRole('radio', { name: /existing dashboard/i }));
expect(screen.getByRole('combobox', { name: /dashboard/ })).toBeInTheDocument();
});
@@ -168,9 +168,9 @@ describe('AddToDashboardButton', () => {
await openModal();
- userEvent.click(screen.getByRole('radio', { name: /existing dashboard/i }));
+ await userEvent.click(screen.getByRole('radio', { name: /existing dashboard/i }));
- userEvent.click(screen.getByRole('button', { name: /open dashboard$/i }));
+ await userEvent.click(screen.getByRole('button', { name: /open dashboard$/i }));
await waitForAddToDashboardResponse();
expect(locationService.push).not.toHaveBeenCalled();
@@ -203,16 +203,16 @@ describe('AddToDashboardButton', () => {
await openModal();
- userEvent.click(screen.getByRole('radio', { name: /existing dashboard/i }));
+ await userEvent.click(screen.getByRole('radio', { name: /existing dashboard/i }));
- userEvent.click(screen.getByRole('combobox', { name: /dashboard/i }));
+ await userEvent.click(screen.getByRole('combobox', { name: /dashboard/i }));
await waitFor(async () => {
await screen.findByLabelText('Select option');
});
- userEvent.click(screen.getByLabelText('Select option'));
+ await userEvent.click(screen.getByLabelText('Select option'));
- userEvent.click(screen.getByRole('button', { name: /open in new tab/i }));
+ await userEvent.click(screen.getByRole('button', { name: /open in new tab/i }));
await waitFor(async () => {
expect(screen.queryByRole('dialog')).not.toBeInTheDocument();
@@ -246,16 +246,16 @@ describe('AddToDashboardButton', () => {
await openModal();
- userEvent.click(screen.getByRole('radio', { name: /existing dashboard/i }));
+ await userEvent.click(screen.getByRole('radio', { name: /existing dashboard/i }));
- userEvent.click(screen.getByRole('combobox', { name: /dashboard/i }));
+ await userEvent.click(screen.getByRole('combobox', { name: /dashboard/i }));
await waitFor(async () => {
await screen.findByLabelText('Select option');
});
- userEvent.click(screen.getByLabelText('Select option'));
+ await userEvent.click(screen.getByLabelText('Select option'));
- userEvent.click(screen.getByRole('button', { name: /open dashboard$/i }));
+ await userEvent.click(screen.getByRole('button', { name: /open dashboard$/i }));
await waitFor(async () => {
expect(screen.queryByRole('dialog')).not.toBeInTheDocument();
@@ -281,7 +281,7 @@ describe('AddToDashboardButton', () => {
await openModal();
expect(screen.queryByRole('alert')).not.toBeInTheDocument();
- userEvent.click(screen.getByRole('button', { name: /open in new tab/i }));
+ await userEvent.click(screen.getByRole('button', { name: /open in new tab/i }));
await waitFor(async () => {
expect(await screen.findByRole('alert')).toBeInTheDocument();
@@ -300,7 +300,7 @@ describe('AddToDashboardButton', () => {
await openModal();
expect(screen.queryByRole('alert')).not.toBeInTheDocument();
- userEvent.click(screen.getByRole('button', { name: /open in new tab/i }));
+ await userEvent.click(screen.getByRole('button', { name: /open in new tab/i }));
await waitFor(async () => {
expect(await screen.findByRole('alert')).toBeInTheDocument();
@@ -328,16 +328,16 @@ describe('AddToDashboardButton', () => {
await openModal();
expect(screen.queryByRole('alert')).not.toBeInTheDocument();
- userEvent.click(screen.getByRole('radio', { name: /existing dashboard/i }));
+ await userEvent.click(screen.getByRole('radio', { name: /existing dashboard/i }));
- userEvent.click(screen.getByRole('combobox', { name: /dashboard/i }));
+ await userEvent.click(screen.getByRole('combobox', { name: /dashboard/i }));
await waitFor(async () => {
await screen.findByLabelText('Select option');
});
- userEvent.click(screen.getByLabelText('Select option'));
+ await userEvent.click(screen.getByLabelText('Select option'));
- userEvent.click(screen.getByRole('button', { name: /open in new tab/i }));
+ await userEvent.click(screen.getByRole('button', { name: /open in new tab/i }));
await waitFor(async () => {
expect(await screen.findByRole('alert')).toBeInTheDocument();
@@ -352,7 +352,7 @@ describe('AddToDashboardButton', () => {
await openModal();
expect(screen.queryByRole('alert')).not.toBeInTheDocument();
- userEvent.click(screen.getByRole('button', { name: /open in new tab/i }));
+ await userEvent.click(screen.getByRole('button', { name: /open in new tab/i }));
await waitFor(async () => {
expect(await screen.findByRole('alert')).toBeInTheDocument();
diff --git a/public/app/features/explore/TraceView/TraceView.test.tsx b/public/app/features/explore/TraceView/TraceView.test.tsx
index 240d90bcb40..82718889de6 100644
--- a/public/app/features/explore/TraceView/TraceView.test.tsx
+++ b/public/app/features/explore/TraceView/TraceView.test.tsx
@@ -92,10 +92,10 @@ describe('TraceView', () => {
renderTraceViewNew();
expect(screen.queryByText(/Tags/)).toBeFalsy();
const spanView = screen.getAllByText('', { selector: 'div[data-test-id="span-view"]' })[0];
- userEvent.click(spanView);
+ await userEvent.click(spanView);
expect(screen.queryByText(/Tags/)).toBeTruthy();
- userEvent.click(spanView);
+ await userEvent.click(spanView);
screen.debug(screen.queryAllByText(/Tags/));
expect(screen.queryByText(/Tags/)).toBeFalsy();
});
@@ -109,36 +109,36 @@ describe('TraceView', () => {
expect(ticks()).toBe('0μs274.5μs549μs823.5μs1.1ms');
});
- it('correctly shows processes for each span', () => {
+ it('correctly shows processes for each span', async () => {
renderTraceView();
let table: HTMLElement;
expect(screen.queryAllByText('', { selector: 'div[data-test-id="span-view"]' }).length).toBe(3);
const firstSpan = screen.getAllByText('', { selector: 'div[data-test-id="span-view"]' })[0];
- userEvent.click(firstSpan);
- userEvent.click(screen.getByText(/Process/));
+ await userEvent.click(firstSpan);
+ await userEvent.click(screen.getByText(/Process/));
table = screen.getByText('', { selector: 'div[data-test-id="KeyValueTable"]' });
expect(table.innerHTML).toContain('client-uuid-1');
- userEvent.click(firstSpan);
+ await userEvent.click(firstSpan);
const secondSpan = screen.getAllByText('', { selector: 'div[data-test-id="span-view"]' })[1];
- userEvent.click(secondSpan);
- userEvent.click(screen.getByText(/Process/));
+ await userEvent.click(secondSpan);
+ await userEvent.click(screen.getByText(/Process/));
table = screen.getByText('', { selector: 'div[data-test-id="KeyValueTable"]' });
expect(table.innerHTML).toContain('client-uuid-2');
- userEvent.click(secondSpan);
+ await userEvent.click(secondSpan);
const thirdSpan = screen.getAllByText('', { selector: 'div[data-test-id="span-view"]' })[2];
- userEvent.click(thirdSpan);
- userEvent.click(screen.getByText(/Process/));
+ await userEvent.click(thirdSpan);
+ await userEvent.click(screen.getByText(/Process/));
table = screen.getByText('', { selector: 'div[data-test-id="KeyValueTable"]' });
expect(table.innerHTML).toContain('client-uuid-3');
});
- it('resets detail view for new trace with the identical spanID', () => {
+ it('resets detail view for new trace with the identical spanID', async () => {
const { rerender } = render(getTraceView([frameOld]));
const span = screen.getAllByText('', { selector: 'div[data-test-id="span-view"]' })[2];
- userEvent.click(span);
+ await userEvent.click(span);
//Process is in detail view
expect(screen.getByText(/Process/)).toBeInTheDocument();
diff --git a/public/app/features/explore/TraceView/TraceViewContainer.test.tsx b/public/app/features/explore/TraceView/TraceViewContainer.test.tsx
index 68725bb429b..f9ef0719237 100644
--- a/public/app/features/explore/TraceView/TraceViewContainer.test.tsx
+++ b/public/app/features/explore/TraceView/TraceViewContainer.test.tsx
@@ -35,75 +35,75 @@ function renderTraceViewContainer(frames = [frameOld]) {
}
describe('TraceViewContainer', () => {
- it('toggles children visibility', () => {
+ it('toggles children visibility', async () => {
renderTraceViewContainer();
expect(screen.queryAllByText('', { selector: 'div[data-test-id="span-view"]' }).length).toBe(3);
- userEvent.click(screen.getAllByText('', { selector: 'span[data-test-id="SpanTreeOffset--indentGuide"]' })[0]);
+ await userEvent.click(screen.getAllByText('', { selector: 'span[data-test-id="SpanTreeOffset--indentGuide"]' })[0]);
expect(screen.queryAllByText('', { selector: 'div[data-test-id="span-view"]' }).length).toBe(1);
- userEvent.click(screen.getAllByText('', { selector: 'span[data-test-id="SpanTreeOffset--indentGuide"]' })[0]);
+ await userEvent.click(screen.getAllByText('', { selector: 'span[data-test-id="SpanTreeOffset--indentGuide"]' })[0]);
expect(screen.queryAllByText('', { selector: 'div[data-test-id="span-view"]' }).length).toBe(3);
});
- it('toggles collapses and expands one level of spans', () => {
+ it('toggles collapses and expands one level of spans', async () => {
renderTraceViewContainer();
expect(screen.queryAllByText('', { selector: 'div[data-test-id="span-view"]' }).length).toBe(3);
- userEvent.click(screen.getByLabelText('Collapse +1'));
+ await userEvent.click(screen.getByLabelText('Collapse +1'));
expect(screen.queryAllByText('', { selector: 'div[data-test-id="span-view"]' }).length).toBe(2);
- userEvent.click(screen.getByLabelText('Expand +1'));
+ await userEvent.click(screen.getByLabelText('Expand +1'));
expect(screen.queryAllByText('', { selector: 'div[data-test-id="span-view"]' }).length).toBe(3);
});
- it('toggles collapses and expands all levels', () => {
+ it('toggles collapses and expands all levels', async () => {
renderTraceViewContainer();
expect(screen.queryAllByText('', { selector: 'div[data-test-id="span-view"]' }).length).toBe(3);
- userEvent.click(screen.getByLabelText('Collapse All'));
+ await userEvent.click(screen.getByLabelText('Collapse All'));
expect(screen.queryAllByText('', { selector: 'div[data-test-id="span-view"]' }).length).toBe(1);
- userEvent.click(screen.getByLabelText('Expand All'));
+ await userEvent.click(screen.getByLabelText('Expand All'));
expect(screen.queryAllByText('', { selector: 'div[data-test-id="span-view"]' }).length).toBe(3);
});
- it('searches for spans', () => {
+ it('searches for spans', async () => {
renderTraceViewContainer();
- userEvent.type(screen.getByPlaceholderText('Find...'), '1ed38015486087ca');
+ await userEvent.type(screen.getByPlaceholderText('Find...'), '1ed38015486087ca');
expect(
(screen.queryAllByText('', { selector: 'div[data-test-id="span-view"]' })[0].parentNode! as HTMLElement).className
).toContain('rowMatchingFilter');
});
- it('can select next/prev results', () => {
+ it('can select next/prev results', async () => {
renderTraceViewContainer();
- userEvent.type(screen.getByPlaceholderText('Find...'), 'logproto');
+ await userEvent.type(screen.getByPlaceholderText('Find...'), 'logproto');
const nextResultButton = screen.getByTestId('trace-page-search-bar-next-result-button');
const prevResultButton = screen.getByTestId('trace-page-search-bar-prev-result-button');
const suffix = screen.getByTestId('trace-page-search-bar-suffix');
- userEvent.click(nextResultButton);
+ await userEvent.click(nextResultButton);
expect(suffix.textContent).toBe('1 of 2');
expect(
(screen.queryAllByText('', { selector: 'div[data-test-id="span-view"]' })[1].parentNode! as HTMLElement).className
).toContain('rowFocused');
- userEvent.click(nextResultButton);
+ await userEvent.click(nextResultButton);
expect(suffix.textContent).toBe('2 of 2');
expect(
(screen.queryAllByText('', { selector: 'div[data-test-id="span-view"]' })[2].parentNode! as HTMLElement).className
).toContain('rowFocused');
- userEvent.click(nextResultButton);
+ await userEvent.click(nextResultButton);
expect(suffix.textContent).toBe('1 of 2');
expect(
(screen.queryAllByText('', { selector: 'div[data-test-id="span-view"]' })[1].parentNode! as HTMLElement).className
).toContain('rowFocused');
- userEvent.click(prevResultButton);
+ await userEvent.click(prevResultButton);
expect(suffix.textContent).toBe('2 of 2');
expect(
(screen.queryAllByText('', { selector: 'div[data-test-id="span-view"]' })[2].parentNode! as HTMLElement).className
).toContain('rowFocused');
- userEvent.click(prevResultButton);
+ await userEvent.click(prevResultButton);
expect(suffix.textContent).toBe('1 of 2');
expect(
(screen.queryAllByText('', { selector: 'div[data-test-id="span-view"]' })[1].parentNode! as HTMLElement).className
).toContain('rowFocused');
- userEvent.click(prevResultButton);
+ await userEvent.click(prevResultButton);
expect(suffix.textContent).toBe('2 of 2');
expect(
(screen.queryAllByText('', { selector: 'div[data-test-id="span-view"]' })[2].parentNode! as HTMLElement).className
diff --git a/public/app/features/explore/Wrapper.test.tsx b/public/app/features/explore/Wrapper.test.tsx
index d26b026620b..75c8f9576d6 100644
--- a/public/app/features/explore/Wrapper.test.tsx
+++ b/public/app/features/explore/Wrapper.test.tsx
@@ -217,7 +217,7 @@ describe('Wrapper', () => {
};
setupExplore({ urlParams });
const closeButtons = await screen.findAllByTitle(/Close split pane/i);
- userEvent.click(closeButtons[1]);
+ await userEvent.click(closeButtons[1]);
await waitFor(() => {
const logsPanels = screen.queryAllByTitle(/Close split pane/i);
diff --git a/public/app/features/explore/spec/helper/interactions.ts b/public/app/features/explore/spec/helper/interactions.ts
index f1ed4542cc4..46e806a00b9 100644
--- a/public/app/features/explore/spec/helper/interactions.ts
+++ b/public/app/features/explore/spec/helper/interactions.ts
@@ -11,23 +11,23 @@ export const changeDatasource = async (name: string) => {
fireEvent.click(option);
};
-export const inputQuery = (query: string, exploreId: ExploreId = ExploreId.left) => {
+export const inputQuery = async (query: string, exploreId: ExploreId = ExploreId.left) => {
const input = withinExplore(exploreId).getByRole('textbox', { name: 'query' });
- userEvent.clear(input);
- userEvent.type(input, query);
+ await userEvent.clear(input);
+ await userEvent.type(input, query);
};
-export const runQuery = (exploreId: ExploreId = ExploreId.left) => {
+export const runQuery = async (exploreId: ExploreId = ExploreId.left) => {
const explore = withinExplore(exploreId);
const toolbar = within(explore.getByLabelText('Explore toolbar'));
const button = toolbar.getByRole('button', { name: /run query/i });
- userEvent.click(button);
+ await userEvent.click(button);
};
export const openQueryHistory = async (exploreId: ExploreId = ExploreId.left) => {
const selector = withinExplore(exploreId);
const button = selector.getByRole('button', { name: 'Rich history button' });
- userEvent.click(button);
+ await userEvent.click(button);
expect(
await selector.findByText('The history is local to your browser and is not shared with others.')
).toBeInTheDocument();
@@ -35,26 +35,26 @@ export const openQueryHistory = async (exploreId: ExploreId = ExploreId.left) =>
export const closeQueryHistory = async (exploreId: ExploreId = ExploreId.left) => {
const closeButton = withinExplore(exploreId).getByRole('button', { name: 'Close query history' });
- userEvent.click(closeButton);
+ await userEvent.click(closeButton);
};
export const switchToQueryHistoryTab = async (
name: 'Settings' | 'Query History',
exploreId: ExploreId = ExploreId.left
) => {
- userEvent.click(withinExplore(exploreId).getByRole('tab', { name: `Tab ${name}` }));
+ await userEvent.click(withinExplore(exploreId).getByRole('tab', { name: `Tab ${name}` }));
};
-export const selectStarredTabFirst = (exploreId: ExploreId = ExploreId.left) => {
+export const selectStarredTabFirst = async (exploreId: ExploreId = ExploreId.left) => {
const checkbox = withinExplore(exploreId).getByRole('checkbox', {
name: 'Change the default active tab from “Query history” to “Starred”',
});
- userEvent.click(checkbox);
+ await userEvent.click(checkbox);
};
-export const selectOnlyActiveDataSource = (exploreId: ExploreId = ExploreId.left) => {
+export const selectOnlyActiveDataSource = async (exploreId: ExploreId = ExploreId.left) => {
const checkbox = withinExplore(exploreId).getByLabelText(/Only show queries for data source currently active.*/);
- userEvent.click(checkbox);
+ await userEvent.click(checkbox);
};
export const starQueryHistory = (queryIndex: number, exploreId: ExploreId = ExploreId.left) => {
@@ -65,8 +65,8 @@ export const deleteQueryHistory = (queryIndex: number, exploreId: ExploreId = Ex
invokeAction(queryIndex, 'Delete query', exploreId);
};
-const invokeAction = (queryIndex: number, actionAccessibleName: string, exploreId: ExploreId) => {
+const invokeAction = async (queryIndex: number, actionAccessibleName: string, exploreId: ExploreId) => {
const selector = withinExplore(exploreId);
const buttons = selector.getAllByRole('button', { name: actionAccessibleName });
- userEvent.click(buttons[queryIndex]);
+ await userEvent.click(buttons[queryIndex]);
};
diff --git a/public/app/features/explore/spec/queryHistory.test.tsx b/public/app/features/explore/spec/queryHistory.test.tsx
index b62c8d2558d..291cc78cfbe 100644
--- a/public/app/features/explore/spec/queryHistory.test.tsx
+++ b/public/app/features/explore/spec/queryHistory.test.tsx
@@ -49,8 +49,8 @@ describe('Explore: Query History', () => {
await waitForExplore();
// and a user runs a query and opens query history
- inputQuery(USER_INPUT);
- runQuery();
+ await inputQuery(USER_INPUT);
+ await runQuery();
await openQueryHistory();
// the query that was run is in query history
@@ -80,8 +80,8 @@ describe('Explore: Query History', () => {
await waitForExplore();
await openQueryHistory();
- inputQuery('query #2');
- runQuery();
+ await inputQuery('query #2');
+ await runQuery();
await assertQueryHistory(['{"expr":"query #2"}', '{"expr":"query #1"}']);
});
@@ -135,8 +135,8 @@ describe('Explore: Query History', () => {
await switchToQueryHistoryTab('Settings');
// change settings
- selectStarredTabFirst();
- selectOnlyActiveDataSource();
+ await selectStarredTabFirst();
+ await selectOnlyActiveDataSource();
await closeQueryHistory();
await openQueryHistory();
diff --git a/public/app/features/inspector/InspectDataTab.test.tsx b/public/app/features/inspector/InspectDataTab.test.tsx
index 5e8459b9ea1..15e8d2591db 100644
--- a/public/app/features/inspector/InspectDataTab.test.tsx
+++ b/public/app/features/inspector/InspectDataTab.test.tsx
@@ -50,19 +50,19 @@ describe('InspectDataTab', () => {
render();
expect(screen.getByText(/Data options/i)).toBeInTheDocument();
});
- it('should show available options', () => {
+ it('should show available options', async () => {
render();
const dataOptions = screen.getByText(/Data options/i);
- userEvent.click(dataOptions);
+ await userEvent.click(dataOptions);
expect(screen.getByText(/Show data frame/i)).toBeInTheDocument();
expect(screen.getByText(/Download for Excel/i)).toBeInTheDocument();
});
- it('should show available dataFrame options', () => {
+ it('should show available dataFrame options', async () => {
render();
const dataOptions = screen.getByText(/Data options/i);
- userEvent.click(dataOptions);
+ await userEvent.click(dataOptions);
const dataFrameInput = screen.getByRole('combobox', { name: /Select dataframe/i });
- userEvent.click(dataFrameInput);
+ await userEvent.click(dataFrameInput);
expect(screen.getByText(/Second data frame/i)).toBeInTheDocument();
});
it('should show download logs button if logs data', () => {
diff --git a/public/app/features/invites/SignupInvited.test.tsx b/public/app/features/invites/SignupInvited.test.tsx
index e5ed872e224..c5202a15eac 100644
--- a/public/app/features/invites/SignupInvited.test.tsx
+++ b/public/app/features/invites/SignupInvited.test.tsx
@@ -103,7 +103,7 @@ describe('SignupInvitedPage', () => {
it('then required fields should show error messages and nothing should be posted', async () => {
const { postSpy } = await setupTestContext({ get: { email: '', invitedBy: '', name: '', username: '' } });
- userEvent.click(screen.getByRole('button', { name: /sign up/i }));
+ await userEvent.click(screen.getByRole('button', { name: /sign up/i }));
await waitFor(() => expect(screen.getByText(/email is required/i)).toBeInTheDocument());
expect(screen.getByText(/username is required/i)).toBeInTheDocument();
@@ -116,8 +116,8 @@ describe('SignupInvitedPage', () => {
it('then correct form data should be posted', async () => {
const { postSpy } = await setupTestContext();
- userEvent.type(screen.getByPlaceholderText(/password/i), 'pass@word1');
- userEvent.click(screen.getByRole('button', { name: /sign up/i }));
+ await userEvent.type(screen.getByPlaceholderText(/password/i), 'pass@word1');
+ await userEvent.click(screen.getByRole('button', { name: /sign up/i }));
await waitFor(() => expect(postSpy).toHaveBeenCalledTimes(1));
expect(postSpy).toHaveBeenCalledWith('/api/user/invite/complete', {
diff --git a/public/app/features/library-panels/components/LibraryPanelsSearch/LibraryPanelsSearch.test.tsx b/public/app/features/library-panels/components/LibraryPanelsSearch/LibraryPanelsSearch.test.tsx
index 5c9c4ca4b06..04466176e03 100644
--- a/public/app/features/library-panels/components/LibraryPanelsSearch/LibraryPanelsSearch.test.tsx
+++ b/public/app/features/library-panels/components/LibraryPanelsSearch/LibraryPanelsSearch.test.tsx
@@ -75,6 +75,7 @@ async function getTestContext(
await waitFor(() => expect(getLibraryPanelsSpy).toHaveBeenCalled());
expect(getLibraryPanelsSpy).toHaveBeenCalledTimes(1);
+ jest.clearAllMocks();
return { rerender, getLibraryPanelsSpy, getSpy, getAllPanelPluginMetaSpy };
}
@@ -91,9 +92,8 @@ describe('LibraryPanelsSearch', () => {
describe('and user searches for library panel by name or description', () => {
it('should call api with correct params', async () => {
const { getLibraryPanelsSpy } = await getTestContext();
- getLibraryPanelsSpy.mockClear();
- userEvent.type(screen.getByPlaceholderText(/search by name/i), 'a');
+ await userEvent.type(screen.getByPlaceholderText(/search by name/i), 'a');
await waitFor(() => expect(getLibraryPanelsSpy).toHaveBeenCalled());
expect(getLibraryPanelsSpy).toHaveBeenCalledTimes(1);
expect(getLibraryPanelsSpy).toHaveBeenCalledWith({
@@ -119,18 +119,18 @@ describe('LibraryPanelsSearch', () => {
describe('and user changes sorting', () => {
it('should call api with correct params', async () => {
const { getLibraryPanelsSpy } = await getTestContext({ showSort: true });
- getLibraryPanelsSpy.mockClear();
- userEvent.type(screen.getByText(/sort \(default a–z\)/i), 'Desc{enter}');
- await waitFor(() => expect(getLibraryPanelsSpy).toHaveBeenCalledTimes(1));
- expect(getLibraryPanelsSpy).toHaveBeenCalledWith({
- searchString: '',
- sortDirection: 'alpha-desc',
- folderFilter: [],
- page: 0,
- typeFilter: [],
- perPage: 40,
- });
+ await userEvent.type(screen.getByText(/sort \(default a–z\)/i), 'Desc{enter}');
+ await waitFor(() =>
+ expect(getLibraryPanelsSpy).toHaveBeenCalledWith({
+ searchString: '',
+ sortDirection: 'alpha-desc',
+ folderFilter: [],
+ page: 0,
+ typeFilter: [],
+ perPage: 40,
+ })
+ );
});
});
});
@@ -147,18 +147,18 @@ describe('LibraryPanelsSearch', () => {
describe('and user changes panel filter', () => {
it('should call api with correct params', async () => {
const { getLibraryPanelsSpy } = await getTestContext({ showPanelFilter: true });
- getLibraryPanelsSpy.mockClear();
- userEvent.type(screen.getByRole('combobox', { name: /panel type filter/i }), 'Graph{enter}');
- userEvent.type(screen.getByRole('combobox', { name: /panel type filter/i }), 'Time Series{enter}');
- await waitFor(() => expect(getLibraryPanelsSpy).toHaveBeenCalledTimes(1));
- expect(getLibraryPanelsSpy).toHaveBeenCalledWith({
- searchString: '',
- folderFilter: [],
- page: 0,
- typeFilter: ['graph', 'timeseries'],
- perPage: 40,
- });
+ await userEvent.type(screen.getByRole('combobox', { name: /panel type filter/i }), 'Graph{enter}');
+ await userEvent.type(screen.getByRole('combobox', { name: /panel type filter/i }), 'Time Series{enter}');
+ await waitFor(() =>
+ expect(getLibraryPanelsSpy).toHaveBeenCalledWith({
+ searchString: '',
+ folderFilter: [],
+ page: 0,
+ typeFilter: ['graph', 'timeseries'],
+ perPage: 40,
+ })
+ );
});
});
});
@@ -175,20 +175,20 @@ describe('LibraryPanelsSearch', () => {
describe('and user changes folder filter', () => {
it('should call api with correct params', async () => {
const { getLibraryPanelsSpy } = await getTestContext({ showFolderFilter: true });
- getLibraryPanelsSpy.mockClear();
- userEvent.click(screen.getByRole('combobox', { name: /folder filter/i }));
- userEvent.type(screen.getByRole('combobox', { name: /folder filter/i }), '{enter}', {
+ await userEvent.click(screen.getByRole('combobox', { name: /folder filter/i }));
+ await userEvent.type(screen.getByRole('combobox', { name: /folder filter/i }), '{enter}', {
skipClick: true,
});
- await waitFor(() => expect(getLibraryPanelsSpy).toHaveBeenCalledTimes(1));
- expect(getLibraryPanelsSpy).toHaveBeenCalledWith({
- searchString: '',
- folderFilter: ['0'],
- page: 0,
- typeFilter: [],
- perPage: 40,
- });
+ await waitFor(() =>
+ expect(getLibraryPanelsSpy).toHaveBeenCalledWith({
+ searchString: '',
+ folderFilter: ['0'],
+ page: 0,
+ typeFilter: [],
+ perPage: 40,
+ })
+ );
});
});
});
diff --git a/public/app/features/playlist/PlaylistEditPage.test.tsx b/public/app/features/playlist/PlaylistEditPage.test.tsx
index 2766c0fe6c4..b72ab02eb0a 100644
--- a/public/app/features/playlist/PlaylistEditPage.test.tsx
+++ b/public/app/features/playlist/PlaylistEditPage.test.tsx
@@ -69,10 +69,10 @@ describe('PlaylistEditPage', () => {
const { putMock } = await getTestContext();
expect(locationService.getLocation().pathname).toEqual('/');
- userEvent.clear(screen.getByRole('textbox', { name: /playlist name/i }));
- userEvent.type(screen.getByRole('textbox', { name: /playlist name/i }), 'A Name');
- userEvent.clear(screen.getByRole('textbox', { name: /playlist interval/i }));
- userEvent.type(screen.getByRole('textbox', { name: /playlist interval/i }), '10s');
+ await userEvent.clear(screen.getByRole('textbox', { name: /playlist name/i }));
+ await userEvent.type(screen.getByRole('textbox', { name: /playlist name/i }), 'A Name');
+ await userEvent.clear(screen.getByRole('textbox', { name: /playlist interval/i }));
+ await userEvent.type(screen.getByRole('textbox', { name: /playlist interval/i }), '10s');
fireEvent.submit(screen.getByRole('button', { name: /save/i }));
await waitFor(() => expect(putMock).toHaveBeenCalledTimes(1));
expect(putMock).toHaveBeenCalledWith('/api/playlists/1', {
diff --git a/public/app/features/playlist/PlaylistForm.test.tsx b/public/app/features/playlist/PlaylistForm.test.tsx
index b401838b698..2786ae0006a 100644
--- a/public/app/features/playlist/PlaylistForm.test.tsx
+++ b/public/app/features/playlist/PlaylistForm.test.tsx
@@ -96,11 +96,11 @@ describe('PlaylistForm', () => {
});
describe('when deleting a playlist item', () => {
- it('then the item should be removed and other items should be correct', () => {
+ it('then the item should be removed and other items should be correct', async () => {
getTestContext(playlist);
expect(rows()).toHaveLength(3);
- userEvent.click(within(rows()[2]).getByRole('button', { name: /delete playlist item/i }));
+ await userEvent.click(within(rows()[2]).getByRole('button', { name: /delete playlist item/i }));
expect(rows()).toHaveLength(2);
expectCorrectRow({ index: 0, type: 'id', title: 'first item', first: true });
expectCorrectRow({ index: 1, type: 'id', title: 'middle item', last: true });
@@ -108,10 +108,10 @@ describe('PlaylistForm', () => {
});
describe('when moving a playlist item up', () => {
- it('then the item should be removed and other items should be correct', () => {
+ it('then the item should be removed and other items should be correct', async () => {
getTestContext(playlist);
- userEvent.click(within(rows()[2]).getByRole('button', { name: /move playlist item order up/i }));
+ await userEvent.click(within(rows()[2]).getByRole('button', { name: /move playlist item order up/i }));
expectCorrectRow({ index: 0, type: 'id', title: 'first item', first: true });
expectCorrectRow({ index: 1, type: 'tag', title: 'last item' });
expectCorrectRow({ index: 2, type: 'id', title: 'middle item', last: true });
@@ -119,10 +119,10 @@ describe('PlaylistForm', () => {
});
describe('when moving a playlist item down', () => {
- it('then the item should be removed and other items should be correct', () => {
+ it('then the item should be removed and other items should be correct', async () => {
getTestContext(playlist);
- userEvent.click(within(rows()[0]).getByRole('button', { name: /move playlist item order down/i }));
+ await userEvent.click(within(rows()[0]).getByRole('button', { name: /move playlist item order down/i }));
expectCorrectRow({ index: 0, type: 'id', title: 'middle item', first: true });
expectCorrectRow({ index: 1, type: 'id', title: 'first item' });
expectCorrectRow({ index: 2, type: 'tag', title: 'last item', last: true });
@@ -152,7 +152,7 @@ describe('PlaylistForm', () => {
it('then an alert should appear and nothing should be submitted', async () => {
const { onSubmitMock } = getTestContext(playlist);
- userEvent.clear(screen.getByRole('textbox', { name: /playlist interval/i }));
+ await userEvent.clear(screen.getByRole('textbox', { name: /playlist interval/i }));
fireEvent.submit(screen.getByRole('button', { name: /save/i }));
expect(await screen.findAllByRole('alert')).toHaveLength(1);
expect(onSubmitMock).not.toHaveBeenCalled();
diff --git a/public/app/features/playlist/PlaylistNewPage.test.tsx b/public/app/features/playlist/PlaylistNewPage.test.tsx
index 487bd152607..c7011b41414 100644
--- a/public/app/features/playlist/PlaylistNewPage.test.tsx
+++ b/public/app/features/playlist/PlaylistNewPage.test.tsx
@@ -66,7 +66,7 @@ describe('PlaylistNewPage', () => {
const { backendSrvMock } = getTestContext();
expect(locationService.getLocation().pathname).toEqual('/');
- userEvent.type(screen.getByRole('textbox', { name: /playlist name/i }), 'A Name');
+ await userEvent.type(screen.getByRole('textbox', { name: /playlist name/i }), 'A Name');
fireEvent.submit(screen.getByRole('button', { name: /save/i }));
await waitFor(() => expect(backendSrvMock).toHaveBeenCalledTimes(1));
expect(backendSrvMock).toHaveBeenCalledWith('/api/playlists', {
diff --git a/public/app/features/plugins/admin/pages/Browse.test.tsx b/public/app/features/plugins/admin/pages/Browse.test.tsx
index 0e9cbc4d86a..b1c4e5cab7e 100644
--- a/public/app/features/plugins/admin/pages/Browse.test.tsx
+++ b/public/app/features/plugins/admin/pages/Browse.test.tsx
@@ -349,7 +349,7 @@ describe('Browse list of plugins', () => {
expect(listOption).not.toBeChecked();
// Switch to "list" view
- userEvent.click(listOption);
+ await userEvent.click(listOption);
expect(gridOption).not.toBeChecked();
expect(listOption).toBeChecked();
diff --git a/public/app/features/plugins/admin/pages/PluginDetails.test.tsx b/public/app/features/plugins/admin/pages/PluginDetails.test.tsx
index 8d0e8d367f0..6f24844251f 100644
--- a/public/app/features/plugins/admin/pages/PluginDetails.test.tsx
+++ b/public/app/features/plugins/admin/pages/PluginDetails.test.tsx
@@ -447,14 +447,14 @@ describe('Plugin details page', () => {
await waitFor(() => expect(queryByText(PluginTabLabels.OVERVIEW)).toBeInTheDocument());
// Open the confirmation modal
- userEvent.click(getByRole('button', { name: /uninstall/i }));
+ await userEvent.click(getByRole('button', { name: /uninstall/i }));
expect(queryByText('Uninstall Akumuli')).toBeInTheDocument();
expect(queryByText('Are you sure you want to uninstall this plugin?')).toBeInTheDocument();
expect(api.uninstallPlugin).toHaveBeenCalledTimes(0);
// Confirm the uninstall
- userEvent.click(getByRole('button', { name: /confirm/i }));
+ await userEvent.click(getByRole('button', { name: /confirm/i }));
expect(api.uninstallPlugin).toHaveBeenCalledTimes(1);
expect(api.uninstallPlugin).toHaveBeenCalledWith(id);
@@ -635,7 +635,7 @@ describe('Plugin details page', () => {
await waitFor(() => queryByText('Uninstall'));
// Click on "Enable"
- userEvent.click(getByRole('button', { name: /enable/i }));
+ await userEvent.click(getByRole('button', { name: /enable/i }));
// Check if the API request was initiated
expect(api.updatePluginSettings).toHaveBeenCalledTimes(1);
@@ -675,7 +675,7 @@ describe('Plugin details page', () => {
await waitFor(() => queryByText('Uninstall'));
// Click on "Disable"
- userEvent.click(getByRole('button', { name: /disable/i }));
+ await userEvent.click(getByRole('button', { name: /disable/i }));
// Check if the API request was initiated
expect(api.updatePluginSettings).toHaveBeenCalledTimes(1);
diff --git a/public/app/features/profile/ChangePasswordPage.test.tsx b/public/app/features/profile/ChangePasswordPage.test.tsx
index eebd890fa11..3fc936793b6 100644
--- a/public/app/features/profile/ChangePasswordPage.test.tsx
+++ b/public/app/features/profile/ChangePasswordPage.test.tsx
@@ -83,9 +83,9 @@ describe('ChangePasswordPage', () => {
it('should call changePassword if change password is valid', async () => {
const { props } = await getTestContext();
- userEvent.type(screen.getByLabelText('Old password'), 'test');
- userEvent.type(screen.getByLabelText('New password'), 'admin');
- userEvent.type(screen.getByLabelText('Confirm password'), 'admin');
+ await userEvent.type(screen.getByLabelText('Old password'), 'test');
+ await userEvent.type(screen.getByLabelText('New password'), 'admin');
+ await userEvent.type(screen.getByLabelText('Confirm password'), 'admin');
fireEvent.click(screen.getByRole('button', { name: 'Change Password' }));
await waitFor(() => {
expect(props.changePassword).toHaveBeenCalledTimes(1);
diff --git a/public/app/features/profile/UserProfileEditPage.test.tsx b/public/app/features/profile/UserProfileEditPage.test.tsx
index b8f3c476de6..bc31d02c8c6 100644
--- a/public/app/features/profile/UserProfileEditPage.test.tsx
+++ b/public/app/features/profile/UserProfileEditPage.test.tsx
@@ -1,6 +1,6 @@
import React from 'react';
import { render, screen, waitFor } from '@testing-library/react';
-import userEvent from '@testing-library/user-event';
+import userEvent, { PointerEventsCheckLevel } from '@testing-library/user-event';
import { within } from '@testing-library/dom';
import { OrgRole } from '@grafana/data';
import { selectors } from '@grafana/e2e-selectors';
@@ -239,10 +239,10 @@ describe('UserProfileEditPage', () => {
const { props } = await getTestContext();
const { email, saveProfile } = getSelectors();
- userEvent.clear(email());
- userEvent.type(email(), 'test@test.se');
+ await userEvent.clear(email());
+ await userEvent.type(email(), 'test@test.se');
// TODO remove skipPointerEventsCheck once https://github.com/jsdom/jsdom/issues/3232 is fixed
- userEvent.click(saveProfile(), undefined, { skipPointerEventsCheck: true });
+ await userEvent.click(saveProfile(), { pointerEventsCheck: PointerEventsCheckLevel.Never });
await waitFor(() => expect(props.updateUserProfile).toHaveBeenCalledTimes(1));
expect(props.updateUserProfile).toHaveBeenCalledWith({
@@ -261,7 +261,7 @@ describe('UserProfileEditPage', () => {
name: /select organisation/i,
});
- userEvent.click(orgsAdminSelectButton());
+ await userEvent.click(orgsAdminSelectButton());
await waitFor(() => expect(props.changeUserOrg).toHaveBeenCalledTimes(1));
expect(props.changeUserOrg).toHaveBeenCalledWith({
@@ -280,7 +280,7 @@ describe('UserProfileEditPage', () => {
name: /revoke user session/i,
});
- userEvent.click(sessionsRevokeButton());
+ await userEvent.click(sessionsRevokeButton());
await waitFor(() => expect(props.revokeUserSession).toHaveBeenCalledTimes(1));
expect(props.revokeUserSession).toHaveBeenCalledWith(0);
diff --git a/public/app/features/variables/adhoc/picker/AdHocFilter.test.tsx b/public/app/features/variables/adhoc/picker/AdHocFilter.test.tsx
index cccdc3f8a1c..526c76f353d 100644
--- a/public/app/features/variables/adhoc/picker/AdHocFilter.test.tsx
+++ b/public/app/features/variables/adhoc/picker/AdHocFilter.test.tsx
@@ -20,13 +20,13 @@ describe('AdHocFilter', () => {
const { addFilter } = setup();
// Select key
- userEvent.click(screen.getByLabelText('Add Filter'));
+ await userEvent.click(screen.getByLabelText('Add Filter'));
const selectEl = screen.getByTestId('AdHocFilterKey-add-key-wrapper');
expect(selectEl).toBeInTheDocument();
await selectEvent.select(selectEl, 'key3', { container: document.body });
// Select value
- userEvent.click(screen.getByText('select value'));
+ await userEvent.click(screen.getByText('select value'));
// There are already some filters rendered
const selectEl2 = screen.getAllByTestId('AdHocFilterValue-value-wrapper')[2];
await selectEvent.select(selectEl2, 'val3', { container: document.body });
@@ -39,7 +39,7 @@ describe('AdHocFilter', () => {
const { removeFilter } = setup();
// Select key
- userEvent.click(screen.getByText('key1'));
+ await userEvent.click(screen.getByText('key1'));
const selectEl = screen.getAllByTestId('AdHocFilterKey-key-wrapper')[0];
expect(selectEl).toBeInTheDocument();
await selectEvent.select(selectEl, '-- remove filter --', { container: document.body });
@@ -52,7 +52,7 @@ describe('AdHocFilter', () => {
const { changeFilter } = setup();
// Select key
- userEvent.click(screen.getByText('val1'));
+ await userEvent.click(screen.getByText('val1'));
const selectEl = screen.getAllByTestId('AdHocFilterValue-value-wrapper')[0];
expect(selectEl).toBeInTheDocument();
await selectEvent.select(selectEl, 'val4', { container: document.body });
diff --git a/public/app/features/variables/inspect/VariablesUnknownTable.test.tsx b/public/app/features/variables/inspect/VariablesUnknownTable.test.tsx
index 0173b108dc0..be9a286e80f 100644
--- a/public/app/features/variables/inspect/VariablesUnknownTable.test.tsx
+++ b/public/app/features/variables/inspect/VariablesUnknownTable.test.tsx
@@ -1,6 +1,6 @@
import React from 'react';
import * as runtime from '@grafana/runtime';
-import { render, screen, waitFor, waitForElementToBeRemoved } from '@testing-library/react';
+import { act, render, screen, waitFor } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { VariablesUnknownTable, VariablesUnknownTableProps } from './VariablesUnknownTable';
@@ -36,25 +36,17 @@ describe('VariablesUnknownTable', () => {
});
describe('when expanding the section', () => {
- it('then it should show loading spinner', async () => {
- await getTestContext();
-
- userEvent.click(screen.getByRole('heading', { name: /renamed or missing variables/i }));
- await waitFor(() => expect(screen.getByText('Loading...')).toBeInTheDocument());
- });
-
it('then it should call getUnknownsNetwork', async () => {
const { getUnknownsNetworkSpy } = await getTestContext();
- userEvent.click(screen.getByRole('heading', { name: /renamed or missing variables/i }));
+ await userEvent.click(screen.getByRole('heading', { name: /renamed or missing variables/i }));
await waitFor(() => expect(getUnknownsNetworkSpy).toHaveBeenCalledTimes(1));
});
it('then it should report the interaction', async () => {
const { reportInteractionSpy } = await getTestContext();
- userEvent.click(screen.getByRole('heading', { name: /renamed or missing variables/i }));
- await waitFor(() => expect(screen.getByText('Loading...')).toBeInTheDocument());
+ await userEvent.click(screen.getByRole('heading', { name: /renamed or missing variables/i }));
expect(reportInteractionSpy).toHaveBeenCalledTimes(1);
expect(reportInteractionSpy).toHaveBeenCalledWith('Unknown variables section expanded');
@@ -64,14 +56,14 @@ describe('VariablesUnknownTable', () => {
it('then it should not call getUnknownsNetwork', async () => {
const { getUnknownsNetworkSpy } = await getTestContext();
- userEvent.click(screen.getByRole('heading', { name: /renamed or missing variables/i }));
+ await userEvent.click(screen.getByRole('heading', { name: /renamed or missing variables/i }));
await waitFor(() => expect(screen.getByRole('button')).toHaveAttribute('aria-expanded', 'true'));
expect(getUnknownsNetworkSpy).toHaveBeenCalledTimes(1);
- userEvent.click(screen.getByRole('heading', { name: /renamed or missing variables/i }));
+ await userEvent.click(screen.getByRole('heading', { name: /renamed or missing variables/i }));
await waitFor(() => expect(screen.getByRole('button')).toHaveAttribute('aria-expanded', 'false'));
- userEvent.click(screen.getByRole('heading', { name: /renamed or missing variables/i }));
+ await userEvent.click(screen.getByRole('heading', { name: /renamed or missing variables/i }));
await waitFor(() => expect(screen.getByRole('button')).toHaveAttribute('aria-expanded', 'true'));
expect(getUnknownsNetworkSpy).toHaveBeenCalledTimes(1);
@@ -82,8 +74,7 @@ describe('VariablesUnknownTable', () => {
it('then it should render the correct message', async () => {
await getTestContext();
- userEvent.click(screen.getByRole('heading', { name: /renamed or missing variables/i }));
- await waitForElementToBeRemoved(() => screen.getByText('Loading...'));
+ await userEvent.click(screen.getByRole('heading', { name: /renamed or missing variables/i }));
expect(screen.getByText('No renamed or missing variables found.')).toBeInTheDocument();
});
@@ -95,8 +86,7 @@ describe('VariablesUnknownTable', () => {
const usages = [{ variable, nodes: [], edges: [], showGraph: false }];
const { reportInteractionSpy } = await getTestContext({}, usages);
- userEvent.click(screen.getByRole('heading', { name: /renamed or missing variables/i }));
- await waitForElementToBeRemoved(() => screen.getByText('Loading...'));
+ await userEvent.click(screen.getByRole('heading', { name: /renamed or missing variables/i }));
expect(screen.queryByText('No renamed or missing variables found.')).not.toBeInTheDocument();
expect(screen.getByText('Renamed Variable')).toBeInTheDocument();
@@ -117,16 +107,22 @@ describe('VariablesUnknownTable', () => {
it('then it should report slow expansion', async () => {
const variable = customBuilder().withId('Renamed Variable').withName('Renamed Variable').build();
const usages = [{ variable, nodes: [], edges: [], showGraph: false }];
- const { reportInteractionSpy } = await getTestContext({}, usages);
+ const { reportInteractionSpy, rerender } = await getTestContext({}, usages);
const dateNowStart = 1000;
const dateNowStop = 2000;
Date.now = jest.fn().mockReturnValueOnce(dateNowStart).mockReturnValue(dateNowStop);
- userEvent.click(screen.getByRole('heading', { name: /renamed or missing variables/i }));
- await waitForElementToBeRemoved(() => screen.getByText('Loading...'));
+ await userEvent.click(screen.getByRole('heading', { name: /renamed or missing variables/i }));
+ const props: VariablesUnknownTableProps = {
+ variables: [],
+ dashboard: null,
+ };
+ await act(async () => {
+ rerender();
+ });
// make sure we report the interaction for slow expansion
- expect(reportInteractionSpy).toHaveBeenCalledTimes(2);
+ await waitFor(() => expect(reportInteractionSpy).toHaveBeenCalledTimes(2));
expect(reportInteractionSpy.mock.calls[0][0]).toEqual('Unknown variables section expanded');
expect(reportInteractionSpy.mock.calls[1][0]).toEqual('Slow unknown variables expansion');
expect(reportInteractionSpy.mock.calls[1][1]).toEqual({ elapsed: 1000 });
diff --git a/public/app/features/variables/pickers/OptionsPicker/OptionPicker.test.tsx b/public/app/features/variables/pickers/OptionsPicker/OptionPicker.test.tsx
index 36a1a50e17e..8806a3a6231 100644
--- a/public/app/features/variables/pickers/OptionsPicker/OptionPicker.test.tsx
+++ b/public/app/features/variables/pickers/OptionsPicker/OptionPicker.test.tsx
@@ -71,11 +71,11 @@ describe('OptionPicker', () => {
expect(getSubMenu('A + C')).toBeInTheDocument();
});
- it('link text should be clickable', () => {
+ it('link text should be clickable', async () => {
const { dispatch } = setupTestContext();
dispatch.mockClear();
- userEvent.click(getSubMenu('A + C'));
+ await userEvent.click(getSubMenu('A + C'));
expect(dispatch).toHaveBeenCalledTimes(1);
});
});
@@ -89,14 +89,14 @@ describe('OptionPicker', () => {
expect(getSubMenu('A + C')).toBeInTheDocument();
});
- it('link text should be clickable', () => {
+ it('link text should be clickable', async () => {
const { dispatch } = setupTestContext({
variable: defaultVariable,
pickerState: { id: 'Other' },
});
dispatch.mockClear();
- userEvent.click(getSubMenu('A + C'));
+ await userEvent.click(getSubMenu('A + C'));
expect(dispatch).toHaveBeenCalledTimes(1);
});
});
@@ -110,13 +110,13 @@ describe('OptionPicker', () => {
expect(screen.getByLabelText(selectors.components.LoadingIndicator.icon)).toBeInTheDocument();
});
- it('link text should not be clickable', () => {
+ it('link text should not be clickable', async () => {
const { dispatch } = setupTestContext({
variable: { ...defaultVariable, state: LoadingState.Loading },
});
dispatch.mockClear();
- userEvent.click(getSubMenu('A + C'));
+ await userEvent.click(getSubMenu('A + C'));
expect(dispatch).toHaveBeenCalledTimes(0);
});
});
diff --git a/public/app/features/variables/query/QueryVariableEditor.test.tsx b/public/app/features/variables/query/QueryVariableEditor.test.tsx
index 987446dd904..b8a79ce6f52 100644
--- a/public/app/features/variables/query/QueryVariableEditor.test.tsx
+++ b/public/app/features/variables/query/QueryVariableEditor.test.tsx
@@ -69,13 +69,13 @@ describe('QueryVariableEditor', () => {
${'regex'} | ${'onPropChange'} | ${[{ propName: 'regex', propValue: 't', updateOptions: true }]}
`(
'$fieldName field and tabs away then $propName should be called with correct args',
- ({ fieldName, propName, expectedArgs }) => {
+ async ({ fieldName, propName, expectedArgs }) => {
const { props } = setupTestContext({});
const propUnderTest = props[propName];
const fieldAccessor = fieldAccessors[fieldName];
- userEvent.type(fieldAccessor(), 't');
- userEvent.tab();
+ await userEvent.type(fieldAccessor(), 't');
+ await userEvent.tab();
expect(propUnderTest).toHaveBeenCalledTimes(1);
expect(propUnderTest).toHaveBeenCalledWith(...expectedArgs);
@@ -90,14 +90,14 @@ describe('QueryVariableEditor', () => {
${'regex'} | ${'onPropChange'}
`(
'$fieldName field but reverts the change and tabs away then $propName should not be called',
- ({ fieldName, propName }) => {
+ async ({ fieldName, propName }) => {
const { props } = setupTestContext({});
const propUnderTest = props[propName];
const fieldAccessor = fieldAccessors[fieldName];
- userEvent.type(fieldAccessor(), 't');
- userEvent.type(fieldAccessor(), '{backspace}');
- userEvent.tab();
+ await userEvent.type(fieldAccessor(), 't');
+ await userEvent.type(fieldAccessor(), '{backspace}');
+ await userEvent.tab();
expect(propUnderTest).not.toHaveBeenCalled();
}
diff --git a/public/app/plugins/datasource/cloudwatch/components/Dimensions/Dimensions.test.tsx b/public/app/plugins/datasource/cloudwatch/components/Dimensions/Dimensions.test.tsx
index 671cb909f90..7e38c356722 100644
--- a/public/app/plugins/datasource/cloudwatch/components/Dimensions/Dimensions.test.tsx
+++ b/public/app/plugins/datasource/cloudwatch/components/Dimensions/Dimensions.test.tsx
@@ -1,5 +1,5 @@
import React from 'react';
-import { fireEvent, render, screen, act, within } from '@testing-library/react';
+import { fireEvent, render, screen, within } from '@testing-library/react';
import { setupMockedDataSource } from '../../__mocks__/CloudWatchDataSource';
import { CloudWatchMetricsQuery } from '../../types';
import userEvent from '@testing-library/user-event';
@@ -60,7 +60,7 @@ describe('Dimensions', () => {
const onChange = jest.fn();
render();
- userEvent.click(screen.getByLabelText('Add'));
+ await userEvent.click(screen.getByLabelText('Add'));
expect(screen.getByTestId('cloudwatch-dimensions-filter-item')).toBeInTheDocument();
expect(onChange).not.toHaveBeenCalled();
});
@@ -74,13 +74,13 @@ describe('Dimensions', () => {
);
- userEvent.click(screen.getByLabelText('Add'));
+ await userEvent.click(screen.getByLabelText('Add'));
const filterItemElement = screen.getByTestId('cloudwatch-dimensions-filter-item');
expect(filterItemElement).toBeInTheDocument();
const keyElement = container.querySelector('#cloudwatch-dimensions-filter-item-key');
expect(keyElement).toBeInTheDocument();
- userEvent.type(keyElement!, 'my-key');
+ await userEvent.type(keyElement!, 'my-key');
fireEvent.keyDown(keyElement!, { keyCode: 13 });
expect(onChange).not.toHaveBeenCalled();
});
@@ -95,24 +95,20 @@ describe('Dimensions', () => {
);
const label = await screen.findByLabelText('Add');
- userEvent.click(label);
+ await userEvent.click(label);
const filterItemElement = screen.getByTestId('cloudwatch-dimensions-filter-item');
expect(filterItemElement).toBeInTheDocument();
const keyElement = container.querySelector('#cloudwatch-dimensions-filter-item-key');
expect(keyElement).toBeInTheDocument();
- await act(async () => {
- userEvent.type(keyElement!, 'my-key');
- fireEvent.keyDown(keyElement!, { keyCode: 13 });
- });
+ await userEvent.type(keyElement!, 'my-key');
+ fireEvent.keyDown(keyElement!, { keyCode: 13 });
expect(onChange).not.toHaveBeenCalled();
const valueElement = container.querySelector('#cloudwatch-dimensions-filter-item-value');
expect(valueElement).toBeInTheDocument();
- await act(async () => {
- userEvent.type(valueElement!, 'my-value');
- fireEvent.keyDown(valueElement!, { keyCode: 13 });
- });
+ await userEvent.type(valueElement!, 'my-value');
+ fireEvent.keyDown(valueElement!, { keyCode: 13 });
expect(onChange).not.toHaveBeenCalledWith({
...props.query,
dimensions: {
diff --git a/public/app/plugins/datasource/cloudwatch/components/MetricStatEditor/MetricStatEditor.test.tsx b/public/app/plugins/datasource/cloudwatch/components/MetricStatEditor/MetricStatEditor.test.tsx
index 4dbf411b2ec..09b053731ae 100644
--- a/public/app/plugins/datasource/cloudwatch/components/MetricStatEditor/MetricStatEditor.test.tsx
+++ b/public/app/plugins/datasource/cloudwatch/components/MetricStatEditor/MetricStatEditor.test.tsx
@@ -47,7 +47,7 @@ describe('MetricStatEditor', () => {
const statisticElement = await screen.findByLabelText('Statistic');
expect(statisticElement).toBeInTheDocument();
- userEvent.type(statisticElement, statistic);
+ await userEvent.type(statisticElement, statistic);
fireEvent.keyDown(statisticElement, { keyCode: 13 });
expect(onChange).toHaveBeenCalledWith({ ...props.query, statistic });
expect(onRunQuery).toHaveBeenCalled();
@@ -62,7 +62,7 @@ describe('MetricStatEditor', () => {
const statisticElement = await screen.findByLabelText('Statistic');
expect(statisticElement).toBeInTheDocument();
- userEvent.type(statisticElement, statistic);
+ await userEvent.type(statisticElement, statistic);
fireEvent.keyDown(statisticElement, { keyCode: 13 });
expect(onChange).not.toHaveBeenCalled();
expect(onRunQuery).not.toHaveBeenCalled();
diff --git a/public/app/plugins/datasource/dashboard/DashboardQueryEditor.test.tsx b/public/app/plugins/datasource/dashboard/DashboardQueryEditor.test.tsx
index afef996aff0..2d8ad850609 100644
--- a/public/app/plugins/datasource/dashboard/DashboardQueryEditor.test.tsx
+++ b/public/app/plugins/datasource/dashboard/DashboardQueryEditor.test.tsx
@@ -79,7 +79,7 @@ describe('DashboardQueryEditor', () => {
);
const select = screen.getByText('Choose panel');
- userEvent.click(select);
+ await userEvent.click(select);
const myFirstPanel = await screen.findByText('My first panel');
expect(myFirstPanel).toBeInTheDocument();
@@ -102,7 +102,7 @@ describe('DashboardQueryEditor', () => {
);
const select = screen.getByText('Choose panel');
- userEvent.click(select);
+ await userEvent.click(select);
expect(screen.queryByText('My first panel')).not.toBeInTheDocument();
diff --git a/public/app/plugins/datasource/elasticsearch/components/hooks/useCreatableSelectPersistedBehaviour.test.tsx b/public/app/plugins/datasource/elasticsearch/components/hooks/useCreatableSelectPersistedBehaviour.test.tsx
index 8b5f9cb5ede..c8a2e756467 100644
--- a/public/app/plugins/datasource/elasticsearch/components/hooks/useCreatableSelectPersistedBehaviour.test.tsx
+++ b/public/app/plugins/datasource/elasticsearch/components/hooks/useCreatableSelectPersistedBehaviour.test.tsx
@@ -5,7 +5,7 @@ import { useCreatableSelectPersistedBehaviour } from './useCreatableSelectPersis
import userEvent from '@testing-library/user-event';
describe('useCreatableSelectPersistedBehaviour', () => {
- it('Should make a Select accept custom values', () => {
+ it('Should make a Select accept custom values', async () => {
const MyComp = (_: { force?: boolean }) => (