Update dependency @testing-library/user-event to v13 (#40394)

* Update dependency @testing-library/user-event to v13

* Changes needed for userEvent v13

* Ignore pointer-event checks until jsdom issue is fixed

* Remove unused act imports

Co-authored-by: Renovate Bot <bot@renovateapp.com>
Co-authored-by: Ashley Harrison <ashley.harrison@grafana.com>
This commit is contained in:
renovate[bot] 2021-10-14 13:29:41 +01:00 committed by GitHub
parent c0bd9fe551
commit 4565fcd0df
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
24 changed files with 174 additions and 162 deletions

View File

@ -91,7 +91,7 @@
"@testing-library/jest-dom": "5.11.5",
"@testing-library/react": "12.1.2",
"@testing-library/react-hooks": "^3.2.1",
"@testing-library/user-event": "^12.1.3",
"@testing-library/user-event": "13.3.0",
"@types/angular": "1.6.56",
"@types/angular-route": "1.7.0",
"@types/classnames": "2.2.9",

View File

@ -107,8 +107,9 @@ describe('Cascader', () => {
expect(screen.queryByDisplayValue('First/Second')).not.toBeInTheDocument();
userEvent.click(screen.getByPlaceholderText(placeholder));
userEvent.click(screen.getByText('First'));
userEvent.click(screen.getByText('Second'));
// 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 });
expect(screen.getByDisplayValue('First/Second')).toBeInTheDocument();
});
@ -129,8 +130,9 @@ describe('Cascader', () => {
expect(screen.queryByDisplayValue('First/Second')).not.toBeInTheDocument();
userEvent.click(screen.getByPlaceholderText(placeholder));
userEvent.click(screen.getByText('First'));
userEvent.click(screen.getByText('Second'));
// 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 });
expect(screen.getByDisplayValue(`First${separator}Second`)).toBeInTheDocument();
});
@ -141,8 +143,9 @@ describe('Cascader', () => {
);
userEvent.click(screen.getByPlaceholderText(placeholder));
userEvent.click(screen.getByText('First'));
userEvent.click(screen.getByText('Second'));
// 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 });
expect(screen.getByDisplayValue('Second')).toBeInTheDocument();
});
@ -151,8 +154,9 @@ describe('Cascader', () => {
render(<Cascader placeholder={placeholder} options={options} onSelect={jest.fn()} />);
userEvent.click(screen.getByPlaceholderText(placeholder));
userEvent.click(screen.getByText('First'));
userEvent.click(screen.getByText('Second'));
// 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 });
expect(screen.getByDisplayValue('Second')).toBeInTheDocument();
});

View File

@ -135,7 +135,6 @@ export class AngularLocationWrapper {
} else if (newUrl.startsWith('?')) {
locationService.push({ ...locationService.getLocation(), search: newUrl });
} else if (newUrl.trim().length === 0) {
console.log('pushing emptu');
locationService.push('/');
} else {
locationService.push(newUrl);

View File

@ -1,5 +1,5 @@
import React from 'react';
import { act, fireEvent, render, screen, waitFor } from '@testing-library/react';
import { fireEvent, render, screen, waitFor } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { getRouteComponentProps } from 'app/core/navigation/__mocks__/routeProps';
@ -51,14 +51,12 @@ describe('ChangePassword Page', () => {
expect(await screen.findByText('New Password is required')).toBeInTheDocument();
expect(screen.getByText('Confirmed Password is required')).toBeInTheDocument();
await act(async () => {
await userEvent.type(screen.getByLabelText('New password'), 'admin');
await userEvent.type(screen.getByLabelText('Confirm new password'), 'a');
expect(screen.getByText('Passwords must match!')).toBeInTheDocument();
userEvent.type(screen.getByLabelText('New password'), 'admin');
userEvent.type(screen.getByLabelText('Confirm new password'), 'a');
await waitFor(() => expect(screen.getByText('Passwords must match!')).toBeInTheDocument());
await userEvent.type(screen.getByLabelText('Confirm new password'), 'dmin');
expect(screen.queryByText('Passwords must match!')).not.toBeInTheDocument();
});
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 () => {
Object.defineProperty(window, 'location', {
@ -69,8 +67,8 @@ describe('ChangePassword Page', () => {
postMock.mockResolvedValueOnce({ message: 'Logged in' });
render(<ChangePasswordPage {...props} />);
await userEvent.type(screen.getByLabelText('New password'), 'test');
await userEvent.type(screen.getByLabelText('Confirm new password'), 'test');
userEvent.type(screen.getByLabelText('New password'), 'test');
userEvent.type(screen.getByLabelText('Confirm new password'), 'test');
fireEvent.click(screen.getByRole('button', { name: 'Submit' }));
await waitFor(() =>
expect(postMock).toHaveBeenCalledWith('/api/user/password/reset', {

View File

@ -1,5 +1,5 @@
import React from 'react';
import { act, fireEvent, render, screen, waitFor } from '@testing-library/react';
import { fireEvent, render, screen, waitFor } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { SendResetMailPage } from './SendResetMailPage';
@ -45,16 +45,14 @@ describe('VerifyEmail Page', () => {
fireEvent.click(screen.getByRole('button', { name: 'Send reset email' }));
expect(await screen.findByText('Email or username is required')).toBeInTheDocument();
await act(async () => {
await userEvent.type(screen.getByRole('textbox', { name: /User Enter your information/i }), 'test@gmail.com');
expect(screen.queryByText('Email is invalid')).not.toBeInTheDocument();
});
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(<SendResetMailPage />);
await userEvent.type(screen.getByRole('textbox', { name: /User Enter your information/i }), 'test@gmail.com');
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', {

View File

@ -1,5 +1,5 @@
import React from 'react';
import { act, fireEvent, render, screen, waitFor } from '@testing-library/react';
import { fireEvent, render, screen, waitFor } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { LoginPage } from './LoginPage';
@ -56,10 +56,8 @@ describe('Login Page', () => {
fireEvent.click(screen.getByRole('button', { name: 'Login button' }));
expect(await screen.findByText('Email or username is required')).toBeInTheDocument();
await act(async () => {
await userEvent.type(screen.getByRole('textbox', { name: 'Username input field' }), 'admin');
expect(screen.queryByText('Email or username is required')).not.toBeInTheDocument();
});
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 () => {
render(<LoginPage />);
@ -67,10 +65,8 @@ describe('Login Page', () => {
fireEvent.click(screen.getByRole('button', { name: 'Login button' }));
expect(await screen.findByText('Password is required')).toBeInTheDocument();
await act(async () => {
await userEvent.type(screen.getByLabelText('Password input field'), 'admin');
expect(screen.queryByText('Password is required')).not.toBeInTheDocument();
});
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 () => {
Object.defineProperty(window, 'location', {
@ -81,8 +77,8 @@ describe('Login Page', () => {
postMock.mockResolvedValueOnce({ message: 'Logged in' });
render(<LoginPage />);
await userEvent.type(screen.getByLabelText('Username input field'), 'admin');
await userEvent.type(screen.getByLabelText('Password input field'), 'test');
userEvent.type(screen.getByLabelText('Username input field'), 'admin');
userEvent.type(screen.getByLabelText('Password input field'), 'test');
fireEvent.click(screen.getByLabelText('Login button'));
await waitFor(() => expect(postMock).toHaveBeenCalledWith('/login', { password: 'test', user: 'admin' }));

View File

@ -76,7 +76,7 @@ describe('ReadonlyFolderPicker', () => {
expect(within(selectors.container.get()).getByRole('textbox')).toBeInTheDocument();
getFoldersAsOptionsSpy.mockClear();
await userEvent.type(within(selectors.container.get()).getByRole('textbox'), 'A');
userEvent.type(within(selectors.container.get()).getByRole('textbox'), 'A');
await waitFor(() => expect(getFoldersAsOptionsSpy).toHaveBeenCalledTimes(1));
expect(getFoldersAsOptionsSpy).toHaveBeenCalledWith({

View File

@ -1,5 +1,5 @@
import React from 'react';
import { act, fireEvent, render, screen, waitFor } from '@testing-library/react';
import { fireEvent, render, screen, waitFor } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { getRouteComponentProps } from 'app/core/navigation/__mocks__/routeProps';
@ -65,13 +65,11 @@ describe('Signup Page', () => {
fireEvent.click(screen.getByRole('button', { name: 'Submit' }));
expect(await screen.findByText('Email is required')).toBeInTheDocument();
await act(async () => {
await userEvent.type(screen.getByRole('textbox', { name: 'Email' }), 'test');
expect(screen.queryByText('Email is invalid')).toBeInTheDocument();
userEvent.type(screen.getByRole('textbox', { name: 'Email' }), 'test');
await waitFor(() => expect(screen.queryByText('Email is invalid')).toBeInTheDocument());
await userEvent.type(screen.getByRole('textbox', { name: 'Email' }), 'test@gmail.com');
expect(screen.queryByText('Email is invalid')).not.toBeInTheDocument();
});
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 () => {
render(<SignupPage {...props} />);
@ -80,14 +78,12 @@ describe('Signup Page', () => {
expect(await screen.findByText('Password is required')).toBeInTheDocument();
expect(await screen.findByText('Confirmed password is required')).toBeInTheDocument();
await act(async () => {
await userEvent.type(screen.getByLabelText('Password'), 'admin');
await userEvent.type(screen.getByLabelText('Confirm password'), 'a');
expect(screen.queryByText('Passwords must match!')).toBeInTheDocument();
userEvent.type(screen.getByLabelText('Password'), 'admin');
userEvent.type(screen.getByLabelText('Confirm password'), 'a');
await waitFor(() => expect(screen.queryByText('Passwords must match!')).toBeInTheDocument());
await userEvent.type(screen.getByLabelText('Confirm password'), 'dmin');
expect(screen.queryByText('Passwords must match!')).not.toBeInTheDocument();
});
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 () => {
Object.defineProperty(window, 'location', {
@ -98,10 +94,10 @@ describe('Signup Page', () => {
postMock.mockResolvedValueOnce({ message: 'Logged in' });
render(<SignupPage {...props} />);
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');
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');
fireEvent.click(screen.getByRole('button', { name: 'Submit' }));
await waitFor(() =>

View File

@ -1,5 +1,5 @@
import React from 'react';
import { act, fireEvent, render, screen, waitFor } from '@testing-library/react';
import { fireEvent, render, screen, waitFor } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { VerifyEmailPage } from './VerifyEmailPage';
@ -48,19 +48,17 @@ describe('VerifyEmail Page', () => {
fireEvent.click(screen.getByRole('button', { name: 'Send verification email' }));
expect(await screen.findByText('Email is required')).toBeInTheDocument();
await act(async () => {
await userEvent.type(screen.getByRole('textbox', { name: /Email/i }), 'test');
expect(screen.queryByText('Email is invalid')).toBeInTheDocument();
userEvent.type(screen.getByRole('textbox', { name: /Email/i }), 'test');
await waitFor(() => expect(screen.queryByText('Email is invalid')).toBeInTheDocument());
await userEvent.type(screen.getByRole('textbox', { name: /Email/i }), 'test@gmail.com');
expect(screen.queryByText('Email is invalid')).not.toBeInTheDocument();
});
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(<VerifyEmailPage />);
await userEvent.type(screen.getByRole('textbox', { name: /Email/i }), 'test@gmail.com');
userEvent.type(screen.getByRole('textbox', { name: /Email/i }), 'test@gmail.com');
fireEvent.click(screen.getByRole('button', { name: 'Send verification email' }));
await waitFor(() =>

View File

@ -129,7 +129,10 @@ describe('Alerting Admin', () => {
const input = await ui.configInput.find();
expect(input.value).toEqual(JSON.stringify(defaultConfig, null, 2));
userEvent.clear(input);
await userEvent.type(input, JSON.stringify(newConfig, null, 2));
// 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 waitFor(() => expect(mocks.api.updateAlertManagerConfig).toHaveBeenCalled());
await waitFor(() => expect(mocks.api.fetchConfig).toHaveBeenCalledTimes(3));

View File

@ -257,7 +257,7 @@ describe('AmRoutes', () => {
await clickSelectOption(receiverSelect, 'critical');
const groupSelect = ui.groupSelect.get();
await userEvent.type(byRole('textbox').get(groupSelect), 'namespace{enter}');
userEvent.type(byRole('textbox').get(groupSelect), 'namespace{enter}');
// configure timing intervals
userEvent.click(byText('Timing options').get(rootRouteContainer));
@ -316,8 +316,8 @@ describe('AmRoutes', () => {
await clickSelectOption(receiverSelect, 'default');
const groupSelect = ui.groupSelect.get();
await userEvent.type(byRole('textbox').get(groupSelect), 'severity{enter}');
await userEvent.type(byRole('textbox').get(groupSelect), 'namespace{enter}');
userEvent.type(byRole('textbox').get(groupSelect), 'severity{enter}');
userEvent.type(byRole('textbox').get(groupSelect), 'namespace{enter}');
//save
userEvent.click(ui.saveButton.get(rootRouteContainer));
@ -518,7 +518,7 @@ const clickSelectOption = async (selectElement: HTMLElement, optionText: string)
const updateTiming = async (selectElement: HTMLElement, value: string, timeUnit: string): Promise<void> => {
const inputs = byRole('textbox').queryAll(selectElement);
expect(inputs).toHaveLength(2);
await userEvent.type(inputs[0], value);
userEvent.type(inputs[0], value);
userEvent.click(inputs[1]);
await selectOptionInTest(selectElement, timeUnit);
};

View File

@ -173,12 +173,12 @@ describe('Receivers', () => {
expect(locationService.getLocation().pathname).toEqual('/alerting/notifications/receivers/new');
// type in a name for the new receiver
await userEvent.type(ui.inputs.name.get(), 'my new receiver');
userEvent.type(ui.inputs.name.get(), 'my new receiver');
// enter some email
const email = ui.inputs.email.addresses.get();
userEvent.clear(email);
await userEvent.type(email, 'tester@grafana.com');
userEvent.type(email, 'tester@grafana.com');
// try to test the contact point
userEvent.click(ui.testContactPointButton.get());
@ -213,7 +213,7 @@ describe('Receivers', () => {
expect(locationService.getLocation().pathname).toEqual('/alerting/notifications/receivers/new');
// type in a name for the new receiver
await userEvent.type(byPlaceholderText('Name').get(), 'my new receiver');
userEvent.type(byPlaceholderText('Name').get(), 'my new receiver');
// check that default email form is rendered
await ui.inputs.email.addresses.find();
@ -227,8 +227,8 @@ describe('Receivers', () => {
const urlInput = ui.inputs.hipchat.url.get();
const apiKeyInput = ui.inputs.hipchat.apiKey.get();
await userEvent.type(urlInput, 'http://hipchat');
await userEvent.type(apiKeyInput, 'foobarbaz');
userEvent.type(urlInput, 'http://hipchat');
userEvent.type(apiKeyInput, 'foobarbaz');
// it seems react-hook-form does some async state updates after submit
await act(async () => {
@ -296,7 +296,7 @@ describe('Receivers', () => {
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();
await userEvent.type(byLabelText('Text').get(confirmSubform), 'confirm this');
userEvent.type(byLabelText('Text').get(confirmSubform), 'confirm this');
// delete a field
await userEvent.click(byText(/Fields \(2\)/i).get(slackContainer));
@ -306,7 +306,7 @@ describe('Receivers', () => {
// add another channel
await userEvent.click(ui.newContactPointTypeButton.get());
await clickSelectOption(await byTestId('items.2.type').find(), 'Webhook');
await userEvent.type(await ui.inputs.webhook.URL.find(), 'http://webhookurl');
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 () => {

View File

@ -126,7 +126,7 @@ describe('RuleEditor', () => {
});
await renderRuleEditor();
await userEvent.type(await ui.inputs.name.find(), 'my great new rule');
userEvent.type(await ui.inputs.name.find(), 'my great new rule');
await clickSelectOption(ui.inputs.alertType.get(), /Cortex\/Loki managed alert/);
const dataSourceSelect = ui.inputs.dataSource.get();
userEvent.click(byRole('textbox').get(dataSourceSelect));
@ -135,17 +135,18 @@ describe('RuleEditor', () => {
await clickSelectOption(ui.inputs.namespace.get(), 'namespace2');
await clickSelectOption(ui.inputs.group.get(), 'group2');
await userEvent.type(ui.inputs.expr.get(), 'up == 1');
userEvent.type(ui.inputs.expr.get(), 'up == 1');
await userEvent.type(ui.inputs.annotationValue(0).get(), 'some summary');
await userEvent.type(ui.inputs.annotationValue(1).get(), 'some description');
userEvent.type(ui.inputs.annotationValue(0).get(), 'some summary');
userEvent.type(ui.inputs.annotationValue(1).get(), 'some description');
userEvent.click(ui.buttons.addLabel.get());
// TODO remove skipPointerEventsCheck once https://github.com/jsdom/jsdom/issues/3232 is fixed
userEvent.click(ui.buttons.addLabel.get(), undefined, { skipPointerEventsCheck: true });
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');
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');
// save and check what was sent to backend
userEvent.click(ui.buttons.save.get());
@ -196,15 +197,16 @@ describe('RuleEditor', () => {
await waitFor(() => expect(searchFolderMock).toHaveBeenCalled());
await clickSelectOption(folderInput, 'Folder A');
await userEvent.type(ui.inputs.annotationValue(0).get(), 'some summary');
await userEvent.type(ui.inputs.annotationValue(1).get(), 'some description');
userEvent.type(ui.inputs.annotationValue(0).get(), 'some summary');
userEvent.type(ui.inputs.annotationValue(1).get(), 'some description');
userEvent.click(ui.buttons.addLabel.get());
// TODO remove skipPointerEventsCheck once https://github.com/jsdom/jsdom/issues/3232 is fixed
userEvent.click(ui.buttons.addLabel.get(), undefined, { skipPointerEventsCheck: true });
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');
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');
// save and check what was sent to backend
userEvent.click(ui.buttons.save.get());
@ -265,7 +267,7 @@ describe('RuleEditor', () => {
});
await renderRuleEditor();
await userEvent.type(await ui.inputs.name.find(), 'my great new recording rule');
userEvent.type(await ui.inputs.name.find(), 'my great new recording rule');
await clickSelectOption(ui.inputs.alertType.get(), /Cortex\/Loki managed recording rule/);
const dataSourceSelect = ui.inputs.dataSource.get();
userEvent.click(byRole('textbox').get(dataSourceSelect));
@ -274,24 +276,27 @@ describe('RuleEditor', () => {
await clickSelectOption(ui.inputs.namespace.get(), 'namespace2');
await clickSelectOption(ui.inputs.group.get(), 'group2');
await userEvent.type(ui.inputs.expr.get(), 'up == 1');
userEvent.type(ui.inputs.expr.get(), 'up == 1');
userEvent.click(ui.buttons.addLabel.get());
// TODO remove skipPointerEventsCheck once https://github.com/jsdom/jsdom/issues/3232 is fixed
userEvent.click(ui.buttons.addLabel.get(), undefined, { skipPointerEventsCheck: true });
await userEvent.type(ui.inputs.labelKey(1).get(), 'team');
await userEvent.type(ui.inputs.labelValue(1).get(), 'the a-team');
userEvent.type(ui.inputs.labelKey(1).get(), 'team');
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());
expect(
await byText(
'Recording rule name must be valid metric name. It may only contain letters, numbers, and colons. It may not contain whitespace.'
).find()
).toBeInTheDocument();
await waitFor(() =>
expect(
byText(
'Recording rule name must be valid metric name. It may only contain letters, numbers, and colons. It may not contain whitespace.'
).get()
).toBeInTheDocument()
);
expect(mocks.api.setRulerRuleGroup).not.toBeCalled();
// fix name and re-submit
await userEvent.type(await ui.inputs.name.find(), '{selectall}{del}my:great:new:recording:rule');
userEvent.type(await ui.inputs.name.find(), '{selectall}{del}my:great:new:recording:rule');
userEvent.click(ui.buttons.save.get());
// save and check what was sent to backend
@ -374,12 +379,12 @@ describe('RuleEditor', () => {
// add an annotation
await clickSelectOption(ui.inputs.annotationKey(2).get(), /Add new/);
await userEvent.type(byRole('textbox').get(ui.inputs.annotationKey(2).get()), 'custom');
await userEvent.type(ui.inputs.annotationValue(2).get(), 'value');
userEvent.type(byRole('textbox').get(ui.inputs.annotationKey(2).get()), 'custom');
userEvent.type(ui.inputs.annotationValue(2).get(), 'value');
//add a label
await userEvent.type(ui.inputs.labelKey(2).get(), 'custom');
await userEvent.type(ui.inputs.labelValue(2).get(), 'value');
userEvent.type(ui.inputs.labelKey(2).get(), 'custom');
userEvent.type(ui.inputs.labelValue(2).get(), 'value');
// save and check what was sent to backend
userEvent.click(ui.buttons.save.get());

View File

@ -431,7 +431,7 @@ describe('RuleList', () => {
expect(groups).toHaveLength(2);
const filterInput = ui.rulesFilterInput.get();
await userEvent.type(filterInput, '{foo="bar"}');
userEvent.type(filterInput, '{{foo="bar"}');
// Input is debounced so wait for it to be visible
await waitFor(() => expect(filterInput).toHaveValue('{foo="bar"}'));
@ -449,15 +449,15 @@ describe('RuleList', () => {
expect(ruleDetails).toHaveTextContent('Labelsseverity=warningfoo=bar');
// Check for different label matchers
await userEvent.type(filterInput, '{selectall}{del}{foo!="bar",foo!="baz"}');
userEvent.type(filterInput, '{selectall}{del}{{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'));
await userEvent.type(filterInput, '{selectall}{del}{foo=~"b.+"}');
userEvent.type(filterInput, '{selectall}{del}{{foo=~"b.+"}');
await waitFor(() => expect(ui.ruleGroup.queryAll()).toHaveLength(2));
await userEvent.type(filterInput, '{selectall}{del}{region="US"}');
userEvent.type(filterInput, '{selectall}{del}{{region="US"}');
await waitFor(() => expect(ui.ruleGroup.queryAll()).toHaveLength(1));
await waitFor(() => expect(ui.ruleGroup.get()).toHaveTextContent('group-2'));
});
@ -499,12 +499,12 @@ describe('RuleList', () => {
testCase('rename both lotex namespace and group', async () => {
// make changes to form
userEvent.clear(ui.editGroupModal.namespaceInput.get());
await userEvent.type(ui.editGroupModal.namespaceInput.get(), 'super namespace');
userEvent.type(ui.editGroupModal.namespaceInput.get(), 'super namespace');
userEvent.clear(ui.editGroupModal.ruleGroupInput.get());
await userEvent.type(ui.editGroupModal.ruleGroupInput.get(), 'super group');
userEvent.type(ui.editGroupModal.ruleGroupInput.get(), 'super group');
await userEvent.type(ui.editGroupModal.intervalInput.get(), '5m');
userEvent.type(ui.editGroupModal.intervalInput.get(), '5m');
// submit, check that appropriate calls were made
userEvent.click(ui.editGroupModal.saveButton.get());
@ -532,8 +532,8 @@ describe('RuleList', () => {
testCase('rename just the lotex group', async () => {
// make changes to form
userEvent.clear(ui.editGroupModal.ruleGroupInput.get());
await userEvent.type(ui.editGroupModal.ruleGroupInput.get(), 'super group');
await userEvent.type(ui.editGroupModal.intervalInput.get(), '5m');
userEvent.type(ui.editGroupModal.ruleGroupInput.get(), 'super group');
userEvent.type(ui.editGroupModal.intervalInput.get(), '5m');
// submit, check that appropriate calls were made
userEvent.click(ui.editGroupModal.saveButton.get());
@ -554,7 +554,7 @@ describe('RuleList', () => {
testCase('edit lotex group eval interval, no renaming', async () => {
// make changes to form
await userEvent.type(ui.editGroupModal.intervalInput.get(), '5m');
userEvent.type(ui.editGroupModal.intervalInput.get(), '5m');
// submit, check that appropriate calls were made
userEvent.click(ui.editGroupModal.saveButton.get());

View File

@ -194,37 +194,40 @@ describe('Silence edit', () => {
const endDateString = dateTime(end).format('YYYY-MM-DD');
userEvent.clear(ui.editor.durationInput.get());
await userEvent.type(ui.editor.durationInput.get(), '1d');
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));
await userEvent.type(ui.editor.matcherName.get(), 'foo');
await userEvent.type(ui.editor.matcherOperatorSelect.get(), '=');
userEvent.type(ui.editor.matcherName.get(), 'foo');
userEvent.type(ui.editor.matcherOperatorSelect.get(), '=');
userEvent.tab();
await userEvent.type(ui.editor.matcherValue.get(), 'bar');
userEvent.type(ui.editor.matcherValue.get(), 'bar');
userEvent.click(ui.editor.addMatcherButton.get());
await userEvent.type(ui.editor.matcherName.getAll()[1], 'bar');
await userEvent.type(ui.editor.matcherOperatorSelect.getAll()[1], '!=');
// 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();
await userEvent.type(ui.editor.matcherValue.getAll()[1], 'buzz');
userEvent.type(ui.editor.matcherValue.getAll()[1], 'buzz');
userEvent.click(ui.editor.addMatcherButton.get());
await userEvent.type(ui.editor.matcherName.getAll()[2], 'region');
await userEvent.type(ui.editor.matcherOperatorSelect.getAll()[2], '=~');
// 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();
await userEvent.type(ui.editor.matcherValue.getAll()[2], 'us-west-.*');
userEvent.type(ui.editor.matcherValue.getAll()[2], 'us-west-.*');
userEvent.click(ui.editor.addMatcherButton.get());
await userEvent.type(ui.editor.matcherName.getAll()[3], 'env');
await userEvent.type(ui.editor.matcherOperatorSelect.getAll()[3], '!~');
// 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();
await userEvent.type(ui.editor.matcherValue.getAll()[3], 'dev|staging');
userEvent.type(ui.editor.matcherValue.getAll()[3], 'dev|staging');
await userEvent.type(ui.editor.comment.get(), 'Test');
await userEvent.type(ui.editor.createdBy.get(), 'Homer Simpson');
userEvent.type(ui.editor.comment.get(), 'Test');
userEvent.type(ui.editor.createdBy.get(), 'Homer Simpson');
userEvent.click(ui.editor.submit.get());

View File

@ -105,7 +105,7 @@ describe('ApiKeysPage', () => {
setSearchQueryMock.mockClear();
expect(screen.getByPlaceholderText(/search keys/i)).toBeInTheDocument();
await userEvent.type(screen.getByPlaceholderText(/search keys/i), 'First');
userEvent.type(screen.getByPlaceholderText(/search keys/i), 'First');
expect(setSearchQueryMock).toHaveBeenCalledTimes(5);
});
});
@ -125,7 +125,10 @@ describe('ApiKeysPage', () => {
expect(within(firstRow).getByRole('cell', { name: /cancel delete/i })).toBeInTheDocument();
userEvent.click(within(firstRow).getByRole('cell', { name: /cancel delete/i }));
expect(within(firstRow).getByRole('button', { name: /delete$/i })).toBeInTheDocument();
userEvent.click(within(firstRow).getByRole('button', { name: /delete$/i }));
// TODO remove skipPointerEventsCheck once https://github.com/jsdom/jsdom/issues/3232 is fixed
userEvent.click(within(firstRow).getByRole('button', { name: /delete$/i }), undefined, {
skipPointerEventsCheck: true,
});
expect(deleteApiKeyMock).toHaveBeenCalledTimes(1);
expect(deleteApiKeyMock).toHaveBeenCalledWith(1, false);
@ -135,7 +138,10 @@ describe('ApiKeysPage', () => {
expect(within(secondRow).getByRole('cell', { name: /cancel delete/i })).toBeInTheDocument();
userEvent.click(within(secondRow).getByRole('cell', { name: /cancel delete/i }));
expect(within(secondRow).getByRole('button', { name: /delete$/i })).toBeInTheDocument();
userEvent.click(within(secondRow).getByRole('button', { name: /delete$/i }));
// TODO remove skipPointerEventsCheck once https://github.com/jsdom/jsdom/issues/3232 is fixed
userEvent.click(within(secondRow).getByRole('button', { name: /delete$/i }), undefined, {
skipPointerEventsCheck: true,
});
expect(deleteApiKeyMock).toHaveBeenCalledTimes(1);
expect(deleteApiKeyMock).toHaveBeenCalledWith(2, true);
});
@ -176,8 +182,8 @@ describe('ApiKeysPage', () => {
addApiKeyMock.mockClear();
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');
userEvent.type(screen.getByPlaceholderText(/name/i), 'Test');
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 }));
expect(screen.getByText(/not a valid duration/i)).toBeInTheDocument();
@ -197,8 +203,8 @@ async function addAndVerifyApiKey(addApiKeyMock: jest.Mock, includeExpired: bool
expect(screen.getByPlaceholderText(/1d/i)).toBeInTheDocument();
expect(screen.getByRole('button', { name: /^add$/i })).toBeInTheDocument();
await userEvent.type(screen.getByPlaceholderText(/name/i), 'Test');
await userEvent.type(screen.getByPlaceholderText(/1d/i), '60s');
userEvent.type(screen.getByPlaceholderText(/name/i), 'Test');
userEvent.type(screen.getByPlaceholderText(/1d/i), '60s');
userEvent.click(screen.getByRole('button', { name: /^add$/i }));
expect(addApiKeyMock).toHaveBeenCalledTimes(1);
expect(addApiKeyMock).toHaveBeenCalledWith(

View File

@ -148,7 +148,8 @@ describe('AnnotationsSettings', () => {
).toBeInTheDocument();
expect(screen.queryByRole('button', { name: /new query/i })).not.toBeInTheDocument();
userEvent.click(screen.getByRole('button', { name: /^delete$/i }));
// TODO remove skipPointerEventsCheck once https://github.com/jsdom/jsdom/issues/3232 is fixed
userEvent.click(screen.getByRole('button', { name: /^delete$/i }), undefined, { skipPointerEventsCheck: true });
expect(screen.queryAllByRole('row').length).toBe(0);
expect(
@ -251,7 +252,8 @@ describe('AnnotationsSettings', () => {
expect(within(screen.getAllByRole('rowgroup')[1]).getAllByRole('row').length).toBe(3);
userEvent.click(screen.getAllByRole('button', { name: /delete/i })[1]);
// TODO remove skipPointerEventsCheck once https://github.com/jsdom/jsdom/issues/3232 is fixed
userEvent.click(screen.getAllByRole('button', { name: /delete/i })[1], undefined, { skipPointerEventsCheck: true });
expect(within(screen.getAllByRole('rowgroup')[1]).getAllByRole('row').length).toBe(2);
});

View File

@ -131,7 +131,10 @@ describe('LinksSettings', () => {
expect(getTableBodyRows().length).toBe(links.length);
userEvent.click(within(getTableBody()).getAllByRole('button', { name: /delete/i })[0]);
// TODO remove skipPointerEventsCheck once https://github.com/jsdom/jsdom/issues/3232 is fixed
userEvent.click(within(getTableBody()).getAllByRole('button', { name: /delete/i })[0], undefined, {
skipPointerEventsCheck: true,
});
expect(getTableBodyRows().length).toBe(links.length - 1);
expect(within(getTableBody()).queryByText(links[0].title)).not.toBeInTheDocument();

View File

@ -95,7 +95,7 @@ describe('LibraryPanelsSearch', () => {
const { getLibraryPanelsSpy } = await getTestContext();
getLibraryPanelsSpy.mockClear();
await userEvent.type(screen.getByPlaceholderText(/search by name/i), 'a');
userEvent.type(screen.getByPlaceholderText(/search by name/i), 'a');
await waitFor(() => expect(getLibraryPanelsSpy).toHaveBeenCalled());
expect(getLibraryPanelsSpy).toHaveBeenCalledTimes(1);
expect(getLibraryPanelsSpy).toHaveBeenCalledWith({
@ -123,7 +123,7 @@ describe('LibraryPanelsSearch', () => {
const { getLibraryPanelsSpy } = await getTestContext({ showSort: true });
getLibraryPanelsSpy.mockClear();
await userEvent.type(screen.getByText(/sort \(default az\)/i), 'Desc{enter}');
userEvent.type(screen.getByText(/sort \(default az\)/i), 'Desc{enter}');
await waitFor(() => expect(getLibraryPanelsSpy).toHaveBeenCalledTimes(1));
expect(getLibraryPanelsSpy).toHaveBeenCalledWith({
searchString: '',
@ -151,8 +151,8 @@ describe('LibraryPanelsSearch', () => {
const { getLibraryPanelsSpy } = await getTestContext({ showPanelFilter: true });
getLibraryPanelsSpy.mockClear();
await userEvent.type(screen.getByRole('textbox', { name: /panel type filter/i }), 'Graph{enter}');
await userEvent.type(screen.getByRole('textbox', { name: /panel type filter/i }), 'Time Series{enter}');
userEvent.type(screen.getByRole('textbox', { name: /panel type filter/i }), 'Graph{enter}');
userEvent.type(screen.getByRole('textbox', { name: /panel type filter/i }), 'Time Series{enter}');
await waitFor(() => expect(getLibraryPanelsSpy).toHaveBeenCalledTimes(1));
expect(getLibraryPanelsSpy).toHaveBeenCalledWith({
searchString: '',
@ -180,7 +180,7 @@ describe('LibraryPanelsSearch', () => {
getLibraryPanelsSpy.mockClear();
userEvent.click(screen.getByRole('textbox', { name: /folder filter/i }));
await userEvent.type(screen.getByRole('textbox', { name: /folder filter/i }), '{enter}', {
userEvent.type(screen.getByRole('textbox', { name: /folder filter/i }), '{enter}', {
skipClick: true,
});
await waitFor(() => expect(getLibraryPanelsSpy).toHaveBeenCalledTimes(1));

View File

@ -83,9 +83,9 @@ describe('ChangePasswordPage', () => {
it('should call changePassword if change password is valid', async () => {
const { props } = await getTestContext();
await userEvent.type(screen.getByLabelText('Old password'), 'test');
await userEvent.type(screen.getByLabelText('New password'), 'admin');
await userEvent.type(screen.getByLabelText('Confirm password'), 'admin');
userEvent.type(screen.getByLabelText('Old password'), 'test');
userEvent.type(screen.getByLabelText('New password'), 'admin');
userEvent.type(screen.getByLabelText('Confirm password'), 'admin');
fireEvent.click(screen.getByRole('button', { name: 'Change Password' }));
await waitFor(() => {
expect(props.changePassword).toHaveBeenCalledTimes(1);

View File

@ -235,8 +235,9 @@ describe('UserProfileEditPage', () => {
const { email, saveProfile } = getSelectors();
userEvent.clear(email());
await userEvent.type(email(), 'test@test.se');
userEvent.click(saveProfile());
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 waitFor(() => expect(props.updateUserProfile).toHaveBeenCalledTimes(1));
expect(props.updateUserProfile).toHaveBeenCalledWith({

View File

@ -116,7 +116,7 @@ describe('SignupInvitedPage', () => {
it('then correct form data should be posted', async () => {
const { postSpy } = await setupTestContext();
await userEvent.type(screen.getByPlaceholderText(/password/i), 'pass@word1');
userEvent.type(screen.getByPlaceholderText(/password/i), 'pass@word1');
userEvent.click(screen.getByRole('button', { name: /sign up/i }));
await waitFor(() => expect(postSpy).toHaveBeenCalledTimes(1));

View File

@ -270,7 +270,7 @@ describe('PrometheusMetricsBrowser', () => {
await screen.findByLabelText('Values for label2');
expect(await screen.findAllByRole('option', { name: /value/ })).toHaveLength(4);
// Typing '1' to filter for values
await userEvent.type(screen.getByLabelText('Filter expression for label values'), '1');
userEvent.type(screen.getByLabelText('Filter expression for label values'), '1');
expect(screen.getByLabelText('Filter expression for label values')).toHaveValue('1');
expect(await screen.findAllByRole('option', { name: /value/ })).toHaveLength(3);
expect(screen.queryByRole('option', { name: 'value2-2' })).not.toBeInTheDocument();

View File

@ -6651,14 +6651,14 @@ __metadata:
languageName: node
linkType: hard
"@testing-library/user-event@npm:^12.1.3":
version: 12.8.3
resolution: "@testing-library/user-event@npm:12.8.3"
"@testing-library/user-event@npm:13.3.0":
version: 13.3.0
resolution: "@testing-library/user-event@npm:13.3.0"
dependencies:
"@babel/runtime": ^7.12.5
peerDependencies:
"@testing-library/dom": ">=7.21.4"
checksum: c9fb5ee07cbe79ddf32d81e1a353e556d02a1f1619456ccfad6abcdf1b7db400fdc9d7a8e0be3994f456e7135a0dfb7fa10b29fb98a0f5fc417b99fce0ce8166
checksum: 0d17c47728aec71343fc4a8d8b594224c3031513ab59d5797695c53fdfcebef87797a7935ede68c0af896127b2a995e2feb20e64cbd0cd2b2af3f5240241af91
languageName: node
linkType: hard
@ -17825,7 +17825,7 @@ fsevents@~2.1.2:
"@testing-library/jest-dom": 5.11.5
"@testing-library/react": 12.1.2
"@testing-library/react-hooks": ^3.2.1
"@testing-library/user-event": ^12.1.3
"@testing-library/user-event": 13.3.0
"@types/angular": 1.6.56
"@types/angular-route": 1.7.0
"@types/classnames": 2.2.9