Skip to content

Commit

Permalink
Merge pull request #5872 from facebook/chore/userEvent-cleanup
Browse files Browse the repository at this point in the history
Frontend Tests: Standardize `userEvent` usage to conform with upstream recomendations
  • Loading branch information
HelNershingThapa committed Jun 22, 2023
2 parents 88fbf57 + ac644e0 commit c097ed8
Show file tree
Hide file tree
Showing 73 changed files with 784 additions and 751 deletions.
13 changes: 8 additions & 5 deletions frontend/src/components/comments/tests/hashtagPaste.test.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
import React from 'react';
import { render, screen, fireEvent } from '@testing-library/react';
import { render, screen } from '@testing-library/react';
import '@testing-library/jest-dom';

import { ReduxIntlProviders } from '../../../utils/testWithIntl';
import HashtagPaste from '../hashtagPaste';
import userEvent from '@testing-library/user-event';

test('HashtagPaste with an empty text string', () => {
test('HashtagPaste with an empty text string', async () => {
const setFn = jest.fn();
const user = userEvent.setup();
render(
<ReduxIntlProviders>
<HashtagPaste text="" setFn={setFn} hashtag="#managers" className="pt2 f6" />
Expand All @@ -15,19 +17,20 @@ test('HashtagPaste with an empty text string', () => {
expect(screen.getByText('#managers').className).toBe('bb pointer pt2 f6');
expect(screen.getByText('#managers').style.borderBottomStyle).toBe('dashed');
expect(screen.getByText('#managers').title).toBeTruthy();
fireEvent.click(screen.getByText('#managers'));
await user.click(screen.getByText('#managers'));
expect(setFn).toHaveBeenCalledWith('#managers ');
});

test('HashtagPaste with a text string', () => {
test('HashtagPaste with a text string', async () => {
const setFn = jest.fn();
const user = userEvent.setup();
render(
<ReduxIntlProviders>
<HashtagPaste text="My comment" setFn={setFn} hashtag="#managers" className="pt2 f6" />
</ReduxIntlProviders>,
);
expect(screen.getByText('#managers').className).toBe('bb pointer pt2 f6');
expect(screen.getByText('#managers').style.borderBottomStyle).toBe('dashed');
fireEvent.click(screen.getByText('#managers'));
await user.click(screen.getByText('#managers'));
expect(setFn).toHaveBeenCalledWith('My comment #managers');
});
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
import '@testing-library/jest-dom';
import { screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';

import MyTasksOrderDropdown from '../myTasksOrderDropdown';
import { IntlProviders, renderWithRouter } from '../../../utils/testWithIntl';

describe('MyTasksOrderDropdown', () => {
const setQueryMock = jest.fn();
const setup = async () => {
renderWithRouter(
const { user } = renderWithRouter(
<IntlProviders>
<MyTasksOrderDropdown
allQueryParams={{
Expand All @@ -27,7 +26,8 @@ describe('MyTasksOrderDropdown', () => {
const dropdownBtn = screen.getByRole('button', {
name: /sort by/i,
});
await userEvent.click(dropdownBtn);
await user.click(dropdownBtn);
return { user };
};

it('displays dropdown options after button is clicked', async () => {
Expand All @@ -37,8 +37,8 @@ describe('MyTasksOrderDropdown', () => {
});

it('should set query when an option is selected', async () => {
await setup();
await userEvent.click(screen.getByText(/recently edited/i));
const { user } = await setup();
await user.click(screen.getByText(/recently edited/i));
expect(setQueryMock).toHaveBeenCalled();
});

Expand Down
41 changes: 20 additions & 21 deletions frontend/src/components/contributions/tests/taskCard.test.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
import React from 'react';
import { screen, fireEvent } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { screen } from '@testing-library/react';
import '@testing-library/jest-dom';

import { ReduxIntlProviders, renderWithRouter } from '../../../utils/testWithIntl';
import { TaskCard } from '../taskCard';

describe('TaskCard', () => {
it('on MAPPED state with comments', () => {
const { container } = renderWithRouter(
it('on MAPPED state with comments', async () => {
const { user, container } = renderWithRouter(
<ReduxIntlProviders>
<TaskCard
taskId={987}
Expand All @@ -28,12 +27,12 @@ describe('TaskCard', () => {
expect(container.querySelectorAll('svg').length).toBe(2);
expect(screen.queryByText('Resume task')).not.toBeInTheDocument();
// hovering on the card should not change anything
userEvent.hover(screen.getByText('Ready for validation'));
await user.hover(screen.getByText('Ready for validation'));
expect(screen.queryByText('Resume task')).not.toBeInTheDocument();
});

it('on VALIDATED state without comments', () => {
const { container } = renderWithRouter(
it('on VALIDATED state without comments', async () => {
const { user, container } = renderWithRouter(
<ReduxIntlProviders>
<TaskCard
taskId={987}
Expand All @@ -51,12 +50,12 @@ describe('TaskCard', () => {
expect(screen.queryByText('0')).not.toBeInTheDocument();
expect(container.querySelectorAll('svg').length).toBe(1);
// hovering on the card should not change anything
userEvent.hover(screen.getByText('Finished'));
await user.hover(screen.getByText('Finished'));
expect(screen.queryByText('Resume task')).not.toBeInTheDocument();
});

it('on BADIMAGERY state', () => {
renderWithRouter(
it('on BADIMAGERY state', async () => {
const { user } = renderWithRouter(
<ReduxIntlProviders>
<TaskCard
taskId={987}
Expand All @@ -71,12 +70,12 @@ describe('TaskCard', () => {
expect(screen.getByText('Unavailable')).toBeInTheDocument();
expect(screen.queryByText('Resume task')).not.toBeInTheDocument();
// hovering on the card should not change anything
userEvent.hover(screen.getByText('Unavailable'));
await user.hover(screen.getByText('Unavailable'));
expect(screen.queryByText('Resume task')).not.toBeInTheDocument();
});

it('on LOCKED_FOR_VALIDATION state', () => {
const { container } = renderWithRouter(
it('on LOCKED_FOR_VALIDATION state', async () => {
const { user, container } = renderWithRouter(
<ReduxIntlProviders>
<TaskCard
taskId={987}
Expand All @@ -92,13 +91,13 @@ describe('TaskCard', () => {
expect(screen.getByText('Locked for validation by user_1')).toBeInTheDocument();
expect(screen.queryByText('Resume task')).not.toBeInTheDocument();
// hovering on the card should show the resume task button
fireEvent.mouseOver(screen.getByText('Locked for validation by user_1'));
await user.hover(screen.getByText('Locked for validation by user_1'));
expect(screen.getByText('Resume task')).toBeInTheDocument();
expect(container.querySelectorAll('a')[1].href).toContain('/projects/4321/tasks?search=987');
});

it('on INVALIDATED state', () => {
renderWithRouter(
it('on INVALIDATED state', async () => {
const { user } = renderWithRouter(
<ReduxIntlProviders>
<TaskCard
taskId={987}
Expand All @@ -112,12 +111,12 @@ describe('TaskCard', () => {
expect(screen.getByText('More mapping needed')).toBeInTheDocument();
expect(screen.queryByText('Resume task')).not.toBeInTheDocument();
// hovering on the card should show the resume task button
fireEvent.mouseOver(screen.getByText('More mapping needed'));
await user.hover(screen.getByText('More mapping needed'));
expect(screen.getByText('Resume task')).toBeInTheDocument();
});

it('on READY state', () => {
const { container } = renderWithRouter(
it('on READY state', async () => {
const { user, container } = renderWithRouter(
<ReduxIntlProviders>
<TaskCard
taskId={543}
Expand All @@ -134,14 +133,14 @@ describe('TaskCard', () => {
expect(screen.getByText('Available for mapping')).toBeInTheDocument();
expect(screen.queryByText('Resume task')).not.toBeInTheDocument();
// hover on the card
fireEvent.mouseOver(screen.getByText('Available for mapping'));
await user.hover(screen.getByText('Available for mapping'));
expect(screen.getByText('Resume task')).toBeInTheDocument();
expect(screen.getByText('Resume task').className).toBe(
'dn dib-l link pv2 ph3 mh3 mv1 bg-red white f7 fr',
);
expect(container.querySelectorAll('a')[1].href).toContain('/projects/9983/tasks?search=543');
// unhover
fireEvent.mouseOut(screen.getByText('Available for mapping'));
await user.unhover(screen.getByText('Available for mapping'));
expect(screen.queryByText('Resume task')).not.toBeInTheDocument();
});
});
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import '@testing-library/jest-dom';
import { screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';

import { IntlProviders, renderWithRouter } from '../../../utils/testWithIntl';
import { userTasks } from '../../../network/tests/mockData/tasksStats';
Expand All @@ -19,7 +18,7 @@ describe('Task Results Component', () => {

it('should prompt user to retry on failure to fetch tasks', async () => {
const retryFnMock = jest.fn();
renderWithRouter(
const { user } = renderWithRouter(
<IntlProviders>
<TaskResults state={{ isError: true, isLoading: false, tasks: [] }} retryFn={retryFnMock} />
</IntlProviders>,
Expand All @@ -29,7 +28,7 @@ describe('Task Results Component', () => {
name: messages.retry.defaultMessage,
});
expect(retryBtn).toBeInTheDocument();
await userEvent.click(retryBtn);
await user.click(retryBtn);
expect(retryFnMock).toHaveBeenCalled();
});

Expand Down
31 changes: 16 additions & 15 deletions frontend/src/components/deleteModal/tests/index.test.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React from 'react';
import { screen, fireEvent, waitFor, within } from '@testing-library/react';
import { screen, waitFor, within } from '@testing-library/react';
import '@testing-library/jest-dom';

import {
Expand All @@ -12,7 +12,7 @@ import { DeleteModal } from '../index';

describe('Delete Interest', () => {
const setup = () => {
const { history } = renderWithRouter(
const { user, history } = renderWithRouter(
<ReduxIntlProviders>
<DeleteModal id={interest.id} name={interest.name} type="interests" />
</ReduxIntlProviders>,
Expand All @@ -22,24 +22,25 @@ describe('Delete Interest', () => {
});

return {
user,
deleteButton,
history,
};
};

it('should ask for confirmation when user tries to delete an interest', () => {
const { deleteButton } = setup();
fireEvent.click(deleteButton);
it('should ask for confirmation when user tries to delete an interest', async () => {
const { user, deleteButton } = setup();
await user.click(deleteButton);
expect(screen.getByText('Are you sure you want to delete this category?')).toBeInTheDocument();
});

it('should close the confirmation popup when cancel is clicked', () => {
const { deleteButton } = setup();
fireEvent.click(deleteButton);
it('should close the confirmation popup when cancel is clicked', async () => {
const { user, deleteButton } = setup();
await user.click(deleteButton);
const cancelButton = screen.getByRole('button', {
name: /cancel/i,
});
fireEvent.click(cancelButton);
await user.click(cancelButton);
expect(
screen.queryByRole('heading', {
name: 'Are you sure you want to delete this category?',
Expand All @@ -48,7 +49,7 @@ describe('Delete Interest', () => {
});

it('should direct to passed type list page on successful deletion of an interest', async () => {
const { router } = createComponentWithMemoryRouter(
const { user, router } = createComponentWithMemoryRouter(
<ReduxIntlProviders>
<DeleteModal id={interest.id} name={interest.name} type="campaigns" />
</ReduxIntlProviders>,
Expand All @@ -58,20 +59,20 @@ describe('Delete Interest', () => {
name: 'Delete',
});

fireEvent.click(deleteButton);
await user.click(deleteButton);
const dialog = screen.getByRole('dialog');
const deleteConfirmationButton = within(dialog).getByRole('button', {
name: /delete/i,
});
fireEvent.click(deleteConfirmationButton);
await user.click(deleteConfirmationButton);
expect(
await screen.findByRole('heading', { name: /campaign deleted successfully./i }),
).toBeInTheDocument();
await waitFor(() => expect(router.state.location.pathname).toBe('/manage/campaigns'));
});

it('should direct to categories list page on successful deletion of an interest', async () => {
const { router } = createComponentWithMemoryRouter(
const { user, router } = createComponentWithMemoryRouter(
<ReduxIntlProviders>
<DeleteModal id={interest.id} name={interest.name} type="interests" />
</ReduxIntlProviders>,
Expand All @@ -81,12 +82,12 @@ describe('Delete Interest', () => {
name: 'Delete',
});

fireEvent.click(deleteButton);
await user.click(deleteButton);
const dialog = screen.getByRole('dialog');
const deleteConfirmationButton = within(dialog).getByRole('button', {
name: /delete/i,
});
fireEvent.click(deleteConfirmationButton);
await user.click(deleteConfirmationButton);
expect(
await screen.findByRole('heading', { name: /interest deleted successfully./i }),
).toBeInTheDocument();
Expand Down
13 changes: 8 additions & 5 deletions frontend/src/components/header/tests/authButtons.test.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
import React from 'react';
import { render, screen, fireEvent } from '@testing-library/react';
import { render, screen } from '@testing-library/react';
import '@testing-library/jest-dom';

import { ReduxIntlProviders } from '../../../utils/testWithIntl';
import { AuthButtons } from '../index';
import userEvent from '@testing-library/user-event';

describe('AuthButtons', () => {
it('without alternativeSignUpText', () => {
it('without alternativeSignUpText', async () => {
const user = userEvent.setup();
render(
<ReduxIntlProviders>
<AuthButtons
Expand All @@ -20,12 +22,13 @@ describe('AuthButtons', () => {
expect(screen.getByText('Sign up').className).toContain('bg-blue-dark white ml1 v-mid');
expect(screen.queryByText('Create an account')).not.toBeInTheDocument();
expect(screen.queryByText('Name')).not.toBeInTheDocument();
fireEvent.click(screen.getByText('Sign up'));
await user.click(screen.getByText('Sign up'));
expect(screen.getByText('Name')).toBeInTheDocument();
expect(screen.getByText('Email')).toBeInTheDocument();
expect(screen.getByText('Next')).toBeInTheDocument();
});
it('with alternativeSignUpText', () => {
it('with alternativeSignUpText', async () => {
const user = userEvent.setup();
render(
<ReduxIntlProviders>
<AuthButtons
Expand All @@ -40,7 +43,7 @@ describe('AuthButtons', () => {
expect(screen.getByText('Create an account').className).toContain('bg-orange black ml1 v-mid');
expect(screen.queryByText('Sign up')).not.toBeInTheDocument();
expect(screen.queryByText('Name')).not.toBeInTheDocument();
fireEvent.click(screen.getByText('Create an account'));
await user.click(screen.getByText('Create an account'));
expect(screen.getByText('Name')).toBeInTheDocument();
expect(screen.getByText('Email')).toBeInTheDocument();
expect(screen.getByText('Next')).toBeInTheDocument();
Expand Down
Loading

0 comments on commit c097ed8

Please sign in to comment.