Migrated to testing-library/user-event for complex events in tests

This commit is contained in:
Alejandro Celaya 2022-05-10 20:54:14 +02:00
parent 686fe5abbe
commit 7f059c3f3b
6 changed files with 76 additions and 33 deletions

21
package-lock.json generated
View file

@ -57,6 +57,7 @@
"@stryker-mutator/typescript-checker": "^6.0.2",
"@testing-library/jest-dom": "^5.16.4",
"@testing-library/react": "^13.1.1",
"@testing-library/user-event": "^14.1.1",
"@types/classnames": "^2.3.1",
"@types/enzyme": "^3.10.11",
"@types/jest": "^27.4.1",
@ -5494,6 +5495,19 @@
"react-dom": "^18.0.0"
}
},
"node_modules/@testing-library/user-event": {
"version": "14.1.1",
"resolved": "https://registry.npmjs.org/@testing-library/user-event/-/user-event-14.1.1.tgz",
"integrity": "sha512-XrjH/iEUqNl9lF2HX9YhPNV7Amntkcnpw0Bo1KkRzowNDcgSN9i0nm4Q8Oi5wupgdfPaJNMAWa61A+voD6Kmwg==",
"dev": true,
"engines": {
"node": ">=12",
"npm": ">=6"
},
"peerDependencies": {
"@testing-library/dom": ">=7.21.4"
}
},
"node_modules/@tootallnate/once": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz",
@ -31968,6 +31982,13 @@
"@types/react-dom": "^18.0.0"
}
},
"@testing-library/user-event": {
"version": "14.1.1",
"resolved": "https://registry.npmjs.org/@testing-library/user-event/-/user-event-14.1.1.tgz",
"integrity": "sha512-XrjH/iEUqNl9lF2HX9YhPNV7Amntkcnpw0Bo1KkRzowNDcgSN9i0nm4Q8Oi5wupgdfPaJNMAWa61A+voD6Kmwg==",
"dev": true,
"requires": {}
},
"@tootallnate/once": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz",

View file

@ -73,6 +73,7 @@
"@stryker-mutator/typescript-checker": "^6.0.2",
"@testing-library/jest-dom": "^5.16.4",
"@testing-library/react": "^13.1.1",
"@testing-library/user-event": "^14.1.1",
"@types/classnames": "^2.3.1",
"@types/enzyme": "^3.10.11",
"@types/jest": "^27.4.1",

View file

@ -1,29 +1,38 @@
import { fireEvent, render, screen } from '@testing-library/react';
import { render, screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { AppUpdateBanner } from '../../src/common/AppUpdateBanner';
describe('<AppUpdateBanner />', () => {
const toggle = jest.fn();
const forceUpdate = jest.fn();
beforeEach(() => render(<AppUpdateBanner isOpen toggle={toggle} forceUpdate={forceUpdate} />));
const setUp = () => ({
user: userEvent.setup(),
...render(<AppUpdateBanner isOpen toggle={toggle} forceUpdate={forceUpdate} />),
});
afterEach(jest.clearAllMocks);
it('renders initial state', () => {
setUp();
expect(screen.getByRole('heading')).toHaveTextContent('This app has just been updated!');
expect(screen.queryByText('Restarting...')).not.toBeInTheDocument();
expect(screen.getByText('Restart now')).not.toHaveAttribute('disabled');
});
it('invokes toggle when alert is closed', () => {
it('invokes toggle when alert is closed', async () => {
const { user } = setUp();
expect(toggle).not.toHaveBeenCalled();
fireEvent.click(screen.getByLabelText('Close'));
await user.click(screen.getByLabelText('Close'));
expect(toggle).toHaveBeenCalled();
});
it('triggers the update when clicking the button', async () => {
const { user } = setUp();
expect(forceUpdate).not.toHaveBeenCalled();
fireEvent.click(screen.getByText(/^Restart now/));
await user.click(screen.getByText(/^Restart now/));
expect(forceUpdate).toHaveBeenCalled();
expect(await screen.findByText('Restarting...')).toBeInTheDocument();
expect(screen.queryByText(/^Restart now/)).not.toBeInTheDocument();

View file

@ -1,4 +1,5 @@
import { fireEvent, render, screen, waitFor } from '@testing-library/react';
import { render, screen, waitFor } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { Mock } from 'ts-mockery';
import { DomainsList } from '../../src/domains/reducers/domainsList';
import { ManageDomains } from '../../src/domains/ManageDomains';
@ -8,7 +9,9 @@ import { SelectedServer } from '../../src/servers/data';
describe('<ManageDomains />', () => {
const listDomains = jest.fn();
const filterDomains = jest.fn();
const setUp = (domainsList: DomainsList) => render(
const setUp = (domainsList: DomainsList) => ({
user: userEvent.setup(),
...render(
<ManageDomains
listDomains={listDomains}
filterDomains={filterDomains}
@ -17,7 +20,8 @@ describe('<ManageDomains />', () => {
domainsList={domainsList}
selectedServer={Mock.all<SelectedServer>()}
/>,
);
),
});
afterEach(jest.clearAllMocks);
@ -40,11 +44,11 @@ describe('<ManageDomains />', () => {
});
it('filters domains when SearchField changes', async () => {
setUp(Mock.of<DomainsList>({ loading: false, error: false, filteredDomains: [] }));
const { user } = setUp(Mock.of<DomainsList>({ loading: false, error: false, filteredDomains: [] }));
expect(filterDomains).not.toHaveBeenCalled();
fireEvent.change(screen.getByPlaceholderText('Search...'), { target: { value: 'Foo' } });
await waitFor(() => expect(filterDomains).toHaveBeenCalledTimes(1));
await user.type(screen.getByPlaceholderText('Search...'), 'Foo');
await waitFor(() => expect(filterDomains).toHaveBeenCalledWith('Foo'));
});
it('shows expected headers and one row when list of domains is empty', () => {

View file

@ -1,11 +1,15 @@
import { fireEvent, render, screen } from '@testing-library/react';
import { render, screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { Mock } from 'ts-mockery';
import { DomainStatus } from '../../../src/domains/data';
import { DomainStatusIcon } from '../../../src/domains/helpers/DomainStatusIcon';
describe('<DomainStatusIcon />', () => {
const matchMedia = jest.fn().mockReturnValue(Mock.of<MediaQueryList>({ matches: false }));
const setUp = (status: DomainStatus) => render(<DomainStatusIcon status={status} matchMedia={matchMedia} />);
const setUp = (status: DomainStatus) => ({
user: userEvent.setup(),
...render(<DomainStatusIcon status={status} matchMedia={matchMedia} />),
});
beforeEach(jest.clearAllMocks);
@ -22,9 +26,9 @@ describe('<DomainStatusIcon />', () => {
['invalid' as DomainStatus],
['valid' as DomainStatus],
])('renders proper tooltip based on state', async (status) => {
const { container } = setUp(status);
const { container, user } = setUp(status);
container.firstChild && fireEvent.mouseOver(container.firstChild);
container.firstElementChild && await user.hover(container.firstElementChild);
expect(await screen.findByRole('tooltip')).toMatchSnapshot();
});
});

View file

@ -1,4 +1,5 @@
import { fireEvent, render, screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { Mock } from 'ts-mockery';
import { useNavigate } from 'react-router-dom';
import { EditServer as editServerConstruct } from '../../src/servers/EditServer';
@ -17,9 +18,10 @@ describe('<EditServer />', () => {
apiKey: 'the_api_key',
});
const EditServer = editServerConstruct(ServerError);
const setUp = (selectedServer: SelectedServer = defaultSelectedServer) => render(
<EditServer editServer={editServerMock} selectedServer={selectedServer} selectServer={jest.fn()} />,
);
const setUp = (selectedServer: SelectedServer = defaultSelectedServer) => ({
user: userEvent.setup(),
...render(<EditServer editServer={editServerMock} selectedServer={selectedServer} selectServer={jest.fn()} />),
});
beforeEach(() => {
(useNavigate as any).mockReturnValue(navigate);
@ -48,16 +50,18 @@ describe('<EditServer />', () => {
expect(screen.getByDisplayValue('the_api_key')).toBeInTheDocument();
});
it('edits server and redirects to it when form is submitted', () => {
setUp();
it('edits server and redirects to it when form is submitted', async () => {
const { user } = setUp();
fireEvent.change(screen.getByDisplayValue('the_name'), { target: { value: 'the_new_name' } });
fireEvent.change(screen.getByDisplayValue('the_url'), { target: { value: 'the_new_url' } });
await user.type(screen.getByDisplayValue('the_name'), ' edited');
await user.type(screen.getByDisplayValue('the_url'), ' edited');
// TODO Using fire event because userEvent.click on the Submit button does not submit the form
// await user.click(screen.getByRole('button', { name: 'Save' }));
fireEvent.submit(screen.getByRole('form'));
expect(editServerMock).toHaveBeenCalledWith('abc123', {
name: 'the_new_name',
url: 'the_new_url',
name: 'the_name edited',
url: 'the_url edited',
apiKey: 'the_api_key',
});
expect(navigate).toHaveBeenCalledWith(-1);