From 3870752bbaee80339040bc853cfbca42fd314bda Mon Sep 17 00:00:00 2001 From: Alejandro Celaya Date: Wed, 11 May 2022 19:18:43 +0200 Subject: [PATCH] Replaced firEvent with userEvent as much as possible --- test/common/ErrorHandler.test.tsx | 8 ++-- test/common/MainHeader.test.tsx | 20 ++++++---- test/domains/DomainSelector.test.tsx | 27 +++++++------- test/domains/helpers/DomainDropdown.test.tsx | 34 +++++++++-------- .../ShortUrlCreationSettings.test.tsx | 37 ++++++++++--------- .../UseExistingIfFoundInfoIcon.test.tsx | 6 ++- test/utils/Checkbox.test.tsx | 8 ++-- test/visits/DomainVisits.test.tsx | 37 +++++++++++-------- test/visits/NonOrphanVisits.test.tsx | 37 +++++++++++-------- 9 files changed, 121 insertions(+), 93 deletions(-) diff --git a/test/common/ErrorHandler.test.tsx b/test/common/ErrorHandler.test.tsx index 69e72e47..e9afd6e3 100644 --- a/test/common/ErrorHandler.test.tsx +++ b/test/common/ErrorHandler.test.tsx @@ -1,4 +1,5 @@ -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 { ErrorHandler as createErrorHandler } from '../../src/common/ErrorHandler'; @@ -34,11 +35,12 @@ describe('', () => { expect(screen.getByRole('button')).toBeInTheDocument(); }); - it('reloads page on button click', () => { + it('reloads page on button click', async () => { + const user = userEvent.setup(); render(} />); expect(reload).not.toHaveBeenCalled(); - fireEvent.click(screen.getByRole('button')); + await user.click(screen.getByRole('button')); expect(reload).toHaveBeenCalled(); }); }); diff --git a/test/common/MainHeader.test.tsx b/test/common/MainHeader.test.tsx index 9d2a6c78..6aa280a8 100644 --- a/test/common/MainHeader.test.tsx +++ b/test/common/MainHeader.test.tsx @@ -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 { Router } from 'react-router-dom'; import { createMemoryHistory } from 'history'; import { MainHeader as createMainHeader } from '../../src/common/MainHeader'; @@ -9,11 +10,14 @@ describe('', () => { const history = createMemoryHistory(); history.push(pathname); - return render( + const user = userEvent.setup(); + const renderResult = render( , ); + + return { user, ...renderResult }; }; it('renders ServersDropdown', () => { @@ -37,29 +41,29 @@ describe('', () => { } }); - it('renders expected class based on the nav bar state', () => { - setUp(); + it('renders expected class based on the nav bar state', async () => { + const { user } = setUp(); const toggle = screen.getByLabelText('Toggle navigation'); const icon = toggle.firstChild; expect(icon).toHaveAttribute('class', expect.stringMatching(/main-header__toggle-icon$/)); - fireEvent.click(toggle); + await user.click(toggle); expect(icon).toHaveAttribute( 'class', expect.stringMatching(/main-header__toggle-icon main-header__toggle-icon--opened$/), ); - fireEvent.click(toggle); + await user.click(toggle); expect(icon).toHaveAttribute('class', expect.stringMatching(/main-header__toggle-icon$/)); }); it('opens Collapse when clicking toggle', async () => { - const { container } = setUp(); + const { container, user } = setUp(); const collapse = container.querySelector('.collapse'); const toggle = screen.getByLabelText('Toggle navigation'); expect(collapse).not.toHaveAttribute('class', expect.stringContaining('show')); - fireEvent.click(toggle); + await user.click(toggle); await waitFor(() => expect(collapse).toHaveAttribute('class', expect.stringContaining('show'))); }); }); diff --git a/test/domains/DomainSelector.test.tsx b/test/domains/DomainSelector.test.tsx index 3787f55f..c18e650b 100644 --- a/test/domains/DomainSelector.test.tsx +++ b/test/domains/DomainSelector.test.tsx @@ -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 { DomainSelector } from '../../src/domains/DomainSelector'; import { DomainsList } from '../../src/domains/reducers/domainsList'; @@ -12,9 +13,10 @@ describe('', () => { Mock.of({ domain: 'bar.com' }), ], }); - const setUp = (value = '') => render( - , - ); + const setUp = (value = '') => ({ + user: userEvent.setup(), + ...render(), + }); afterEach(jest.clearAllMocks); @@ -22,8 +24,7 @@ describe('', () => { ['', 'Domain', 'domains-dropdown__toggle-btn'], ['my-domain.com', 'Domain: my-domain.com', 'domains-dropdown__toggle-btn--active'], ])('shows dropdown by default', async (value, expectedText, expectedClassName) => { - setUp(value); - + const { user } = setUp(value); const btn = screen.getByRole('button', { name: expectedText }); expect(screen.queryByPlaceholderText('Domain')).not.toBeInTheDocument(); @@ -31,25 +32,25 @@ describe('', () => { 'class', `dropdown-btn__toggle btn-block ${expectedClassName} dropdown-toggle btn btn-primary`, ); - fireEvent.click(btn); + await user.click(btn); await waitFor(() => expect(screen.getByRole('menu')).toBeInTheDocument()); expect(screen.getAllByRole('menuitem')).toHaveLength(4); }); it('allows toggling between dropdown and input', async () => { - setUp(); + const { user } = setUp(); expect(screen.queryByPlaceholderText('Domain')).not.toBeInTheDocument(); expect(screen.getByRole('button', { name: 'Domain' })).toBeInTheDocument(); - fireEvent.click(screen.getByRole('button', { name: 'Domain' })); - fireEvent.click(await screen.findByText('New domain')); + await user.click(screen.getByRole('button', { name: 'Domain' })); + await user.click(await screen.findByText('New domain')); expect(screen.getByPlaceholderText('Domain')).toBeInTheDocument(); expect(screen.queryByRole('button', { name: 'Domain' })).not.toBeInTheDocument(); - fireEvent.click(screen.getByRole('button', { name: 'Back to domains list' })); + await user.click(screen.getByRole('button', { name: 'Back to domains list' })); expect(screen.queryByPlaceholderText('Domain')).not.toBeInTheDocument(); expect(screen.getByRole('button', { name: 'Domain' })).toBeInTheDocument(); @@ -60,9 +61,9 @@ describe('', () => { [1, 'foo.com'], [2, 'bar.com'], ])('shows expected content on every item', async (index, expectedContent) => { - setUp(); + const { user } = setUp(); - fireEvent.click(screen.getByRole('button', { name: 'Domain' })); + await user.click(screen.getByRole('button', { name: 'Domain' })); const items = await screen.findAllByRole('menuitem'); expect(items[index]).toHaveTextContent(expectedContent); diff --git a/test/domains/helpers/DomainDropdown.test.tsx b/test/domains/helpers/DomainDropdown.test.tsx index a9d92cf0..44ccbc58 100644 --- a/test/domains/helpers/DomainDropdown.test.tsx +++ b/test/domains/helpers/DomainDropdown.test.tsx @@ -1,4 +1,5 @@ -import { fireEvent, render, screen, waitForElementToBeRemoved } from '@testing-library/react'; +import { render, screen, waitForElementToBeRemoved } from '@testing-library/react'; +import userEvent from '@testing-library/user-event'; import { Mock } from 'ts-mockery'; import { MemoryRouter } from 'react-router-dom'; import { DomainDropdown } from '../../../src/domains/helpers/DomainDropdown'; @@ -8,15 +9,18 @@ import { SemVer } from '../../../src/utils/helpers/version'; describe('', () => { const editDomainRedirects = jest.fn().mockResolvedValue(undefined); - const setUp = (domain?: Domain, selectedServer?: SelectedServer) => render( - - ()} - selectedServer={selectedServer ?? Mock.all()} - editDomainRedirects={editDomainRedirects} - /> - , - ); + const setUp = (domain?: Domain, selectedServer?: SelectedServer) => ({ + user: userEvent.setup(), + ...render( + + ()} + selectedServer={selectedServer ?? Mock.all()} + editDomainRedirects={editDomainRedirects} + /> + , + ), + }); afterEach(jest.clearAllMocks); @@ -61,25 +65,25 @@ describe('', () => { ['bar.org'], ['baz.net'], ])('displays modal when editing redirects', async (domain) => { - setUp(Mock.of({ domain, isDefault: false })); + const { user } = setUp(Mock.of({ domain, isDefault: false })); expect(screen.queryByRole('dialog')).not.toBeInTheDocument(); expect(screen.queryByRole('form')).not.toBeInTheDocument(); - fireEvent.click(screen.getByText('Edit redirects')); + await user.click(screen.getByText('Edit redirects')); expect(await screen.findByRole('dialog')).toBeInTheDocument(); expect(editDomainRedirects).not.toHaveBeenCalled(); - fireEvent.click(screen.getByText('Save')); + await user.click(screen.getByText('Save')); expect(editDomainRedirects).toHaveBeenCalledWith(domain, expect.anything()); await waitForElementToBeRemoved(() => screen.queryByRole('dialog')); }); it('displays dropdown when clicked', async () => { - setUp(); + const { user } = setUp(); expect(screen.queryByRole('menu')).not.toBeInTheDocument(); - fireEvent.click(screen.getByRole('button', { expanded: false })); + await user.click(screen.getByRole('button', { expanded: false })); expect(await screen.findByRole('menu')).toBeInTheDocument(); }); }); diff --git a/test/settings/ShortUrlCreationSettings.test.tsx b/test/settings/ShortUrlCreationSettings.test.tsx index ac177e42..b98be1a1 100644 --- a/test/settings/ShortUrlCreationSettings.test.tsx +++ b/test/settings/ShortUrlCreationSettings.test.tsx @@ -1,16 +1,20 @@ -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 { ShortUrlCreationSettings as ShortUrlsSettings, Settings } from '../../src/settings/reducers/settings'; import { ShortUrlCreationSettings } from '../../src/settings/ShortUrlCreationSettings'; describe('', () => { const setShortUrlCreationSettings = jest.fn(); - const setUp = (shortUrlCreation?: ShortUrlsSettings) => render( - ({ shortUrlCreation })} - setShortUrlCreationSettings={setShortUrlCreationSettings} - />, - ); + const setUp = (shortUrlCreation?: ShortUrlsSettings) => ({ + user: userEvent.setup(), + ...render( + ({ shortUrlCreation })} + setShortUrlCreationSettings={setShortUrlCreationSettings} + />, + ), + }); afterEach(jest.clearAllMocks); @@ -75,28 +79,27 @@ describe('', () => { expect(screen.getByText(/^The list of suggested tags will contain those/)).toHaveTextContent(expectedHint); }); - it.each([[true], [false]])('invokes setShortUrlCreationSettings when URL validation toggle value changes', (validateUrls) => { - setUp({ validateUrls }); + it.each([[true], [false]])('invokes setShortUrlCreationSettings when URL validation toggle value changes', async (validateUrls) => { + const { user } = setUp({ validateUrls }); expect(setShortUrlCreationSettings).not.toHaveBeenCalled(); - fireEvent.click(screen.getByLabelText(/^Request validation on long URLs when creating new short URLs/)); + await user.click(screen.getByLabelText(/^Request validation on long URLs when creating new short URLs/)); expect(setShortUrlCreationSettings).toHaveBeenCalledWith({ validateUrls: !validateUrls }); }); - it.each([[true], [false]])('invokes setShortUrlCreationSettings when forward query toggle value changes', (forwardQuery) => { - setUp({ validateUrls: true, forwardQuery }); + it.each([[true], [false]])('invokes setShortUrlCreationSettings when forward query toggle value changes', async (forwardQuery) => { + const { user } = setUp({ validateUrls: true, forwardQuery }); expect(setShortUrlCreationSettings).not.toHaveBeenCalled(); - fireEvent.click(screen.getByLabelText(/^Make all new short URLs forward their query params to the long URL/)); + await user.click(screen.getByLabelText(/^Make all new short URLs forward their query params to the long URL/)); expect(setShortUrlCreationSettings).toHaveBeenCalledWith(expect.objectContaining({ forwardQuery: !forwardQuery })); }); it('invokes setShortUrlCreationSettings when dropdown value changes', async () => { - setUp(); - + const { user } = setUp(); const clickItem = async (name: string) => { - fireEvent.click(screen.getByRole('button', { name: 'Suggest tags starting with input' })); - fireEvent.click(await screen.findByRole('menuitem', { name })); + await user.click(screen.getByRole('button', { name: 'Suggest tags starting with input' })); + await user.click(await screen.findByRole('menuitem', { name })); }; expect(setShortUrlCreationSettings).not.toHaveBeenCalled(); diff --git a/test/short-urls/UseExistingIfFoundInfoIcon.test.tsx b/test/short-urls/UseExistingIfFoundInfoIcon.test.tsx index 86a792c7..9104f1c9 100644 --- a/test/short-urls/UseExistingIfFoundInfoIcon.test.tsx +++ b/test/short-urls/UseExistingIfFoundInfoIcon.test.tsx @@ -1,12 +1,14 @@ -import { fireEvent, render, screen } from '@testing-library/react'; +import { render, screen } from '@testing-library/react'; +import userEvent from '@testing-library/user-event'; import { UseExistingIfFoundInfoIcon } from '../../src/short-urls/UseExistingIfFoundInfoIcon'; describe('', () => { it('shows modal when icon is clicked', async () => { + const user = userEvent.setup(); render(); expect(screen.queryByRole('dialog')).not.toBeInTheDocument(); - fireEvent.click(screen.getByTitle('What does this mean?').firstChild as Node); + await user.click(screen.getByTitle('What does this mean?').firstElementChild as Element); expect(await screen.findByRole('dialog')).toBeInTheDocument(); }); }); diff --git a/test/utils/Checkbox.test.tsx b/test/utils/Checkbox.test.tsx index 3b28beb6..e98390f0 100644 --- a/test/utils/Checkbox.test.tsx +++ b/test/utils/Checkbox.test.tsx @@ -1,4 +1,5 @@ -import { fireEvent, render, screen } from '@testing-library/react'; +import { render, screen } from '@testing-library/react'; +import userEvent from '@testing-library/user-event'; import Checkbox from '../../src/utils/Checkbox'; describe('', () => { @@ -22,12 +23,13 @@ describe('', () => { expect(screen.getByText(children)).toHaveAttribute('class', 'form-check-label'); }); - it.each([[true], [false]])('changes checked status on input change', (checked) => { + it.each([[true], [false]])('changes checked status on input change', async (checked) => { + const user = userEvent.setup(); const onChange = jest.fn(); render(Foo); expect(onChange).not.toHaveBeenCalled(); - fireEvent.click(screen.getByLabelText('Foo')); + await user.click(screen.getByLabelText('Foo')); expect(onChange).toHaveBeenCalledWith(!checked, expect.anything()); }); diff --git a/test/visits/DomainVisits.test.tsx b/test/visits/DomainVisits.test.tsx index 7e9761d2..a7598e48 100644 --- a/test/visits/DomainVisits.test.tsx +++ b/test/visits/DomainVisits.test.tsx @@ -1,4 +1,5 @@ -import { fireEvent, render, screen } from '@testing-library/react'; +import { render, screen } from '@testing-library/react'; +import userEvent from '@testing-library/user-event'; import { MemoryRouter } from 'react-router-dom'; import { Mock } from 'ts-mockery'; import { formatISO } from 'date-fns'; @@ -21,32 +22,36 @@ describe('', () => { const cancelGetDomainVisits = jest.fn(); const domainVisits = Mock.of({ visits: [Mock.of({ date: formatISO(new Date()) })] }); const DomainVisits = createDomainVisits(Mock.of({ exportVisits })); - - beforeEach(() => render( - - ({ mercureInfo: {} })} - getDomainVisits={getDomainVisits} - cancelGetDomainVisits={cancelGetDomainVisits} - domainVisits={domainVisits} - settings={Mock.all()} - selectedServer={Mock.all()} - /> - , - )); + const setUp = () => ({ + user: userEvent.setup(), + ...render( + + ({ mercureInfo: {} })} + getDomainVisits={getDomainVisits} + cancelGetDomainVisits={cancelGetDomainVisits} + domainVisits={domainVisits} + settings={Mock.all()} + selectedServer={Mock.all()} + /> + , + ), + }); it('wraps visits stats and header', () => { + setUp(); expect(screen.getByRole('heading', { name: '"foo.com" visits' })).toBeInTheDocument(); expect(getDomainVisits).toHaveBeenCalledWith('DEFAULT', expect.anything(), expect.anything()); }); - it('exports visits when clicking the button', () => { + it('exports visits when clicking the button', async () => { + const { user } = setUp(); const btn = screen.getByRole('button', { name: 'Export (1)' }); expect(exportVisits).not.toHaveBeenCalled(); expect(btn).toBeInTheDocument(); - fireEvent.click(btn); + await user.click(btn); expect(exportVisits).toHaveBeenCalledWith('domain_foo.com_visits.csv', expect.anything()); }); }); diff --git a/test/visits/NonOrphanVisits.test.tsx b/test/visits/NonOrphanVisits.test.tsx index 121cdb59..646cd5a2 100644 --- a/test/visits/NonOrphanVisits.test.tsx +++ b/test/visits/NonOrphanVisits.test.tsx @@ -1,4 +1,5 @@ -import { fireEvent, render, screen } from '@testing-library/react'; +import { render, screen } from '@testing-library/react'; +import userEvent from '@testing-library/user-event'; import { MemoryRouter } from 'react-router-dom'; import { Mock } from 'ts-mockery'; import { formatISO } from 'date-fns'; @@ -15,32 +16,36 @@ describe('', () => { const cancelGetNonOrphanVisits = jest.fn(); const nonOrphanVisits = Mock.of({ visits: [Mock.of({ date: formatISO(new Date()) })] }); const NonOrphanVisits = createNonOrphanVisits(Mock.of({ exportVisits })); - - beforeEach(() => render( - - ({ mercureInfo: {} })} - getNonOrphanVisits={getNonOrphanVisits} - cancelGetNonOrphanVisits={cancelGetNonOrphanVisits} - nonOrphanVisits={nonOrphanVisits} - settings={Mock.all()} - selectedServer={Mock.all()} - /> - , - )); + const setUp = () => ({ + user: userEvent.setup(), + ...render( + + ({ mercureInfo: {} })} + getNonOrphanVisits={getNonOrphanVisits} + cancelGetNonOrphanVisits={cancelGetNonOrphanVisits} + nonOrphanVisits={nonOrphanVisits} + settings={Mock.all()} + selectedServer={Mock.all()} + /> + , + ), + }); it('wraps visits stats and header', () => { + setUp(); expect(screen.getByRole('heading', { name: 'Non-orphan visits' })).toBeInTheDocument(); expect(getNonOrphanVisits).toHaveBeenCalled(); }); - it('exports visits when clicking the button', () => { + it('exports visits when clicking the button', async () => { + const { user } = setUp(); const btn = screen.getByRole('button', { name: 'Export (1)' }); expect(exportVisits).not.toHaveBeenCalled(); expect(btn).toBeInTheDocument(); - fireEvent.click(btn); + await user.click(btn); expect(exportVisits).toHaveBeenCalledWith('non_orphan_visits.csv', expect.anything()); }); });