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/jest-dom": "5.11.5",
"@testing-library/react": "12.1.2", "@testing-library/react": "12.1.2",
"@testing-library/react-hooks": "^3.2.1", "@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": "1.6.56",
"@types/angular-route": "1.7.0", "@types/angular-route": "1.7.0",
"@types/classnames": "2.2.9", "@types/classnames": "2.2.9",

View File

@ -107,8 +107,9 @@ describe('Cascader', () => {
expect(screen.queryByDisplayValue('First/Second')).not.toBeInTheDocument(); expect(screen.queryByDisplayValue('First/Second')).not.toBeInTheDocument();
userEvent.click(screen.getByPlaceholderText(placeholder)); userEvent.click(screen.getByPlaceholderText(placeholder));
userEvent.click(screen.getByText('First')); // TODO remove skipPointerEventsCheck once https://github.com/jsdom/jsdom/issues/3232 is fixed
userEvent.click(screen.getByText('Second')); userEvent.click(screen.getByText('First'), undefined, { skipPointerEventsCheck: true });
userEvent.click(screen.getByText('Second'), undefined, { skipPointerEventsCheck: true });
expect(screen.getByDisplayValue('First/Second')).toBeInTheDocument(); expect(screen.getByDisplayValue('First/Second')).toBeInTheDocument();
}); });
@ -129,8 +130,9 @@ describe('Cascader', () => {
expect(screen.queryByDisplayValue('First/Second')).not.toBeInTheDocument(); expect(screen.queryByDisplayValue('First/Second')).not.toBeInTheDocument();
userEvent.click(screen.getByPlaceholderText(placeholder)); userEvent.click(screen.getByPlaceholderText(placeholder));
userEvent.click(screen.getByText('First')); // TODO remove skipPointerEventsCheck once https://github.com/jsdom/jsdom/issues/3232 is fixed
userEvent.click(screen.getByText('Second')); userEvent.click(screen.getByText('First'), undefined, { skipPointerEventsCheck: true });
userEvent.click(screen.getByText('Second'), undefined, { skipPointerEventsCheck: true });
expect(screen.getByDisplayValue(`First${separator}Second`)).toBeInTheDocument(); expect(screen.getByDisplayValue(`First${separator}Second`)).toBeInTheDocument();
}); });
@ -141,8 +143,9 @@ describe('Cascader', () => {
); );
userEvent.click(screen.getByPlaceholderText(placeholder)); userEvent.click(screen.getByPlaceholderText(placeholder));
userEvent.click(screen.getByText('First')); // TODO remove skipPointerEventsCheck once https://github.com/jsdom/jsdom/issues/3232 is fixed
userEvent.click(screen.getByText('Second')); userEvent.click(screen.getByText('First'), undefined, { skipPointerEventsCheck: true });
userEvent.click(screen.getByText('Second'), undefined, { skipPointerEventsCheck: true });
expect(screen.getByDisplayValue('Second')).toBeInTheDocument(); expect(screen.getByDisplayValue('Second')).toBeInTheDocument();
}); });
@ -151,8 +154,9 @@ describe('Cascader', () => {
render(<Cascader placeholder={placeholder} options={options} onSelect={jest.fn()} />); render(<Cascader placeholder={placeholder} options={options} onSelect={jest.fn()} />);
userEvent.click(screen.getByPlaceholderText(placeholder)); userEvent.click(screen.getByPlaceholderText(placeholder));
userEvent.click(screen.getByText('First')); // TODO remove skipPointerEventsCheck once https://github.com/jsdom/jsdom/issues/3232 is fixed
userEvent.click(screen.getByText('Second')); userEvent.click(screen.getByText('First'), undefined, { skipPointerEventsCheck: true });
userEvent.click(screen.getByText('Second'), undefined, { skipPointerEventsCheck: true });
expect(screen.getByDisplayValue('Second')).toBeInTheDocument(); expect(screen.getByDisplayValue('Second')).toBeInTheDocument();
}); });

View File

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

View File

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

View File

@ -1,5 +1,5 @@
import React from 'react'; 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 userEvent from '@testing-library/user-event';
import { SendResetMailPage } from './SendResetMailPage'; import { SendResetMailPage } from './SendResetMailPage';
@ -45,16 +45,14 @@ describe('VerifyEmail Page', () => {
fireEvent.click(screen.getByRole('button', { name: 'Send reset email' })); fireEvent.click(screen.getByRole('button', { name: 'Send reset email' }));
expect(await screen.findByText('Email or username is required')).toBeInTheDocument(); expect(await screen.findByText('Email or username is required')).toBeInTheDocument();
await act(async () => { 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());
expect(screen.queryByText('Email is invalid')).not.toBeInTheDocument();
});
}); });
it('should show success meessage if reset-password is successful', async () => { it('should show success meessage if reset-password is successful', async () => {
postMock.mockResolvedValueOnce({ message: 'Email sent' }); postMock.mockResolvedValueOnce({ message: 'Email sent' });
render(<SendResetMailPage />); 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' })); fireEvent.click(screen.getByRole('button', { name: 'Send reset email' }));
await waitFor(() => await waitFor(() =>
expect(postMock).toHaveBeenCalledWith('/api/user/password/send-reset-email', { expect(postMock).toHaveBeenCalledWith('/api/user/password/send-reset-email', {

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -194,37 +194,40 @@ describe('Silence edit', () => {
const endDateString = dateTime(end).format('YYYY-MM-DD'); const endDateString = dateTime(end).format('YYYY-MM-DD');
userEvent.clear(ui.editor.durationInput.get()); 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.durationInput.query()).toHaveValue('1d'));
await waitFor(() => expect(ui.editor.timeRange.get()).toHaveTextContent(startDateString)); await waitFor(() => expect(ui.editor.timeRange.get()).toHaveTextContent(startDateString));
await waitFor(() => expect(ui.editor.timeRange.get()).toHaveTextContent(endDateString)); await waitFor(() => expect(ui.editor.timeRange.get()).toHaveTextContent(endDateString));
await userEvent.type(ui.editor.matcherName.get(), 'foo'); userEvent.type(ui.editor.matcherName.get(), 'foo');
await userEvent.type(ui.editor.matcherOperatorSelect.get(), '='); userEvent.type(ui.editor.matcherOperatorSelect.get(), '=');
userEvent.tab(); userEvent.tab();
await userEvent.type(ui.editor.matcherValue.get(), 'bar'); userEvent.type(ui.editor.matcherValue.get(), 'bar');
userEvent.click(ui.editor.addMatcherButton.get()); // TODO remove skipPointerEventsCheck once https://github.com/jsdom/jsdom/issues/3232 is fixed
await userEvent.type(ui.editor.matcherName.getAll()[1], 'bar'); userEvent.click(ui.editor.addMatcherButton.get(), undefined, { skipPointerEventsCheck: true });
await userEvent.type(ui.editor.matcherOperatorSelect.getAll()[1], '!='); userEvent.type(ui.editor.matcherName.getAll()[1], 'bar');
userEvent.type(ui.editor.matcherOperatorSelect.getAll()[1], '!=');
userEvent.tab(); 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()); // TODO remove skipPointerEventsCheck once https://github.com/jsdom/jsdom/issues/3232 is fixed
await userEvent.type(ui.editor.matcherName.getAll()[2], 'region'); userEvent.click(ui.editor.addMatcherButton.get(), undefined, { skipPointerEventsCheck: true });
await userEvent.type(ui.editor.matcherOperatorSelect.getAll()[2], '=~'); userEvent.type(ui.editor.matcherName.getAll()[2], 'region');
userEvent.type(ui.editor.matcherOperatorSelect.getAll()[2], '=~');
userEvent.tab(); 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()); // TODO remove skipPointerEventsCheck once https://github.com/jsdom/jsdom/issues/3232 is fixed
await userEvent.type(ui.editor.matcherName.getAll()[3], 'env'); userEvent.click(ui.editor.addMatcherButton.get(), undefined, { skipPointerEventsCheck: true });
await userEvent.type(ui.editor.matcherOperatorSelect.getAll()[3], '!~'); userEvent.type(ui.editor.matcherName.getAll()[3], 'env');
userEvent.type(ui.editor.matcherOperatorSelect.getAll()[3], '!~');
userEvent.tab(); 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'); userEvent.type(ui.editor.comment.get(), 'Test');
await userEvent.type(ui.editor.createdBy.get(), 'Homer Simpson'); userEvent.type(ui.editor.createdBy.get(), 'Homer Simpson');
userEvent.click(ui.editor.submit.get()); userEvent.click(ui.editor.submit.get());

View File

@ -105,7 +105,7 @@ describe('ApiKeysPage', () => {
setSearchQueryMock.mockClear(); setSearchQueryMock.mockClear();
expect(screen.getByPlaceholderText(/search keys/i)).toBeInTheDocument(); 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); expect(setSearchQueryMock).toHaveBeenCalledTimes(5);
}); });
}); });
@ -125,7 +125,10 @@ describe('ApiKeysPage', () => {
expect(within(firstRow).getByRole('cell', { name: /cancel delete/i })).toBeInTheDocument(); expect(within(firstRow).getByRole('cell', { name: /cancel delete/i })).toBeInTheDocument();
userEvent.click(within(firstRow).getByRole('cell', { name: /cancel delete/i })); userEvent.click(within(firstRow).getByRole('cell', { name: /cancel delete/i }));
expect(within(firstRow).getByRole('button', { name: /delete$/i })).toBeInTheDocument(); 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).toHaveBeenCalledTimes(1);
expect(deleteApiKeyMock).toHaveBeenCalledWith(1, false); expect(deleteApiKeyMock).toHaveBeenCalledWith(1, false);
@ -135,7 +138,10 @@ describe('ApiKeysPage', () => {
expect(within(secondRow).getByRole('cell', { name: /cancel delete/i })).toBeInTheDocument(); expect(within(secondRow).getByRole('cell', { name: /cancel delete/i })).toBeInTheDocument();
userEvent.click(within(secondRow).getByRole('cell', { name: /cancel delete/i })); userEvent.click(within(secondRow).getByRole('cell', { name: /cancel delete/i }));
expect(within(secondRow).getByRole('button', { name: /delete$/i })).toBeInTheDocument(); 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).toHaveBeenCalledTimes(1);
expect(deleteApiKeyMock).toHaveBeenCalledWith(2, true); expect(deleteApiKeyMock).toHaveBeenCalledWith(2, true);
}); });
@ -176,8 +182,8 @@ describe('ApiKeysPage', () => {
addApiKeyMock.mockClear(); addApiKeyMock.mockClear();
userEvent.click(screen.getByRole('button', { name: /add api key/i })); userEvent.click(screen.getByRole('button', { name: /add api key/i }));
await userEvent.type(screen.getByPlaceholderText(/name/i), 'Test'); userEvent.type(screen.getByPlaceholderText(/name/i), 'Test');
await userEvent.type(screen.getByPlaceholderText(/1d/i), '60x'); userEvent.type(screen.getByPlaceholderText(/1d/i), '60x');
expect(screen.queryByText(/not a valid duration/i)).not.toBeInTheDocument(); expect(screen.queryByText(/not a valid duration/i)).not.toBeInTheDocument();
userEvent.click(screen.getByRole('button', { name: /^add$/i })); userEvent.click(screen.getByRole('button', { name: /^add$/i }));
expect(screen.getByText(/not a valid duration/i)).toBeInTheDocument(); 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.getByPlaceholderText(/1d/i)).toBeInTheDocument();
expect(screen.getByRole('button', { name: /^add$/i })).toBeInTheDocument(); expect(screen.getByRole('button', { name: /^add$/i })).toBeInTheDocument();
await userEvent.type(screen.getByPlaceholderText(/name/i), 'Test'); userEvent.type(screen.getByPlaceholderText(/name/i), 'Test');
await userEvent.type(screen.getByPlaceholderText(/1d/i), '60s'); userEvent.type(screen.getByPlaceholderText(/1d/i), '60s');
userEvent.click(screen.getByRole('button', { name: /^add$/i })); userEvent.click(screen.getByRole('button', { name: /^add$/i }));
expect(addApiKeyMock).toHaveBeenCalledTimes(1); expect(addApiKeyMock).toHaveBeenCalledTimes(1);
expect(addApiKeyMock).toHaveBeenCalledWith( expect(addApiKeyMock).toHaveBeenCalledWith(

View File

@ -148,7 +148,8 @@ describe('AnnotationsSettings', () => {
).toBeInTheDocument(); ).toBeInTheDocument();
expect(screen.queryByRole('button', { name: /new query/i })).not.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(screen.queryAllByRole('row').length).toBe(0);
expect( expect(
@ -251,7 +252,8 @@ describe('AnnotationsSettings', () => {
expect(within(screen.getAllByRole('rowgroup')[1]).getAllByRole('row').length).toBe(3); 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); 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); 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(getTableBodyRows().length).toBe(links.length - 1);
expect(within(getTableBody()).queryByText(links[0].title)).not.toBeInTheDocument(); expect(within(getTableBody()).queryByText(links[0].title)).not.toBeInTheDocument();

View File

@ -95,7 +95,7 @@ describe('LibraryPanelsSearch', () => {
const { getLibraryPanelsSpy } = await getTestContext(); const { getLibraryPanelsSpy } = await getTestContext();
getLibraryPanelsSpy.mockClear(); 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()); await waitFor(() => expect(getLibraryPanelsSpy).toHaveBeenCalled());
expect(getLibraryPanelsSpy).toHaveBeenCalledTimes(1); expect(getLibraryPanelsSpy).toHaveBeenCalledTimes(1);
expect(getLibraryPanelsSpy).toHaveBeenCalledWith({ expect(getLibraryPanelsSpy).toHaveBeenCalledWith({
@ -123,7 +123,7 @@ describe('LibraryPanelsSearch', () => {
const { getLibraryPanelsSpy } = await getTestContext({ showSort: true }); const { getLibraryPanelsSpy } = await getTestContext({ showSort: true });
getLibraryPanelsSpy.mockClear(); 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)); await waitFor(() => expect(getLibraryPanelsSpy).toHaveBeenCalledTimes(1));
expect(getLibraryPanelsSpy).toHaveBeenCalledWith({ expect(getLibraryPanelsSpy).toHaveBeenCalledWith({
searchString: '', searchString: '',
@ -151,8 +151,8 @@ describe('LibraryPanelsSearch', () => {
const { getLibraryPanelsSpy } = await getTestContext({ showPanelFilter: true }); const { getLibraryPanelsSpy } = await getTestContext({ showPanelFilter: true });
getLibraryPanelsSpy.mockClear(); getLibraryPanelsSpy.mockClear();
await userEvent.type(screen.getByRole('textbox', { name: /panel type filter/i }), 'Graph{enter}'); 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 }), 'Time Series{enter}');
await waitFor(() => expect(getLibraryPanelsSpy).toHaveBeenCalledTimes(1)); await waitFor(() => expect(getLibraryPanelsSpy).toHaveBeenCalledTimes(1));
expect(getLibraryPanelsSpy).toHaveBeenCalledWith({ expect(getLibraryPanelsSpy).toHaveBeenCalledWith({
searchString: '', searchString: '',
@ -180,7 +180,7 @@ describe('LibraryPanelsSearch', () => {
getLibraryPanelsSpy.mockClear(); getLibraryPanelsSpy.mockClear();
userEvent.click(screen.getByRole('textbox', { name: /folder filter/i })); 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, skipClick: true,
}); });
await waitFor(() => expect(getLibraryPanelsSpy).toHaveBeenCalledTimes(1)); await waitFor(() => expect(getLibraryPanelsSpy).toHaveBeenCalledTimes(1));

View File

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

View File

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

View File

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

View File

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

View File

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