Skip to content

Commit

Permalink
test: migrate tests to react-testing-library (#2581)
Browse files Browse the repository at this point in the history
* refactor: move enzyme to react testing library

* feat: rewriting tests from Enzyme to RTL

* refactor: update tests 2

* refactor: rewrite tests using react testing library

* refactor: rewrite test using react testing library 2part

* refactor: refactor after review part 1

* refactor: replace fireEvent with userEvent where it is possible

* fix: fix console errors

---------

Co-authored-by: monteri <lansevermore>
Co-authored-by: PKulkoRaccoonGang <peter.kulko@raccoongang.com>
Co-authored-by: Kyrylo Hudym-Levkovych <kyr.hudym@kyrs-MacBook-Pro.local>
3 people authored Oct 12, 2023
1 parent acf452b commit c00d2c9
Showing 174 changed files with 5,206 additions and 4,943 deletions.
317 changes: 0 additions & 317 deletions package-lock.json

Large diffs are not rendered by default.

5 changes: 1 addition & 4 deletions package.json
Original file line number Diff line number Diff line change
@@ -103,21 +103,18 @@
"@testing-library/react": "^12.1.4",
"@testing-library/react-hooks": "^8.0.1",
"@testing-library/user-event": "^13.5.0",
"@types/enzyme": "^3.10.12",
"@types/jest": "^27.5.0",
"@types/react": "17.0.0",
"@types/react-dom": "17.0.11",
"@types/react-test-renderer": "^18.0.0",
"@types/uuid": "^9.0.0",
"@typescript-eslint/eslint-plugin": "^5.22.0",
"@typescript-eslint/parser": "^5.22.0",
"@wojtekmaj/enzyme-adapter-react-17": "^0.6.7",
"axios": "^0.27.2",
"axios-mock-adapter": "^1.21.1",
"babel-jest": "^28.1.2",
"babel-loader": "^8.2.4",
"commander": "^9.3.0",
"enzyme": "^3.9.0",
"eslint": "8.18.0",
"eslint-config-airbnb": "19.0.4",
"eslint-config-airbnb-typescript": "^17.0.0",
@@ -150,7 +147,7 @@
"^icons/index.js$": "babel-jest",
"^.+\\.tsx?$": "ts-jest"
},
"setupFiles": [
"setupFilesAfterEnv": [
"./src/setupTest.js"
],
"moduleNameMapper": {
23 changes: 11 additions & 12 deletions src/Alert/Alert.test.jsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
import React from 'react';
import { mount } from 'enzyme';
import { IntlProvider } from 'react-intl';
import renderer, { act } from 'react-test-renderer';
import { render, screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { Context as ResponsiveContext } from 'react-responsive';
import { Info } from '../../icons';
import breakpoints from '../utils/breakpoints';
import Button from '../Button';
import Alert from './index';
import Alert from '.';

// eslint-disable-next-line react/prop-types
function AlertWrapper({ children, ...props }) {
@@ -38,12 +39,11 @@ describe('<Alert />', () => {
)).toJSON();
expect(tree).toMatchSnapshot();
});
it('handles dismissible onClose', () => {
it('handles dismissible onClose', async () => {
const mockOnClose = jest.fn();
const wrapper = mount((
<AlertWrapper onClose={mockOnClose} dismissible>Alert</AlertWrapper>
));
wrapper.find('.btn').simulate('click');
render(<AlertWrapper onClose={mockOnClose} dismissible>Alert</AlertWrapper>);
const button = screen.getByRole('button');
await userEvent.click(button);
expect(mockOnClose).toHaveBeenCalledTimes(1);
});
it('renders with button prop', () => {
@@ -52,12 +52,11 @@ describe('<Alert />', () => {
)).toJSON();
expect(tree).toMatchSnapshot();
});
it('handles button onClick', () => {
it('handles button onClick', async () => {
const mockOnClick = jest.fn();
const wrapper = mount((
<AlertWrapper actions={[<Button onClick={mockOnClick}>Hello</Button>]}>Alert</AlertWrapper>
));
wrapper.find('.btn').simulate('click');
render(<AlertWrapper actions={[<Button onClick={mockOnClick}>Hello</Button>]}>Alert</AlertWrapper>);
const button = screen.getByRole('button');
await userEvent.click(button);
expect(mockOnClick).toHaveBeenCalledTimes(1);
});
it('renders with button and dismissible props', () => {
18 changes: 13 additions & 5 deletions src/Annotation/Annotation.test.jsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React from 'react';
import renderer from 'react-test-renderer';
import { mount } from 'enzyme';
import Annotation from './index';
import { render, screen } from '@testing-library/react';
import Annotation from '.';

const VARIANTS = ['error', 'success', 'warning', 'light', 'dark'];
const ARROW_PLACEMENTS = ['top', 'right', 'bottom', 'left'];
@@ -34,9 +34,17 @@ describe('Annotation', () => {
test.each(classNameTestData)(
'renders with correct className for variant: %s, with arrow placement: %s',
(variant, arrowPlacement, expectedClassName) => {
const wrapper = mount(<Annotation variant={variant} arrowPlacement={arrowPlacement}>Test text</Annotation>);
const annotation = wrapper.find('.pgn__annotation');
expect(annotation.hasClass(expectedClassName)).toEqual(true);
render(
<Annotation
variant={variant}
arrowPlacement={arrowPlacement}
data-testid="annotation"
>
Test text
</Annotation>,
);
const annotation = screen.getByTestId('annotation');
expect(annotation.className).toContain(expectedClassName);
},
);
});
2 changes: 2 additions & 0 deletions src/Annotation/index.jsx
Original file line number Diff line number Diff line change
@@ -7,6 +7,7 @@ const Annotation = React.forwardRef(({
variant,
children,
arrowPlacement,
...props
}, ref) => (
<span
className={classNames(
@@ -15,6 +16,7 @@ const Annotation = React.forwardRef(({
`pgn__annotation-${variant}-${arrowPlacement}`,
)}
ref={ref}
{...props}
>
{children}
</span>
2 changes: 1 addition & 1 deletion src/AvatarButton/AvatarButton.test.jsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React from 'react';
import renderer from 'react-test-renderer';
import AvatarButton from './index';
import AvatarButton from '.';

describe('AvatarButton', () => {
it('renders in all sizes', () => {
88 changes: 39 additions & 49 deletions src/Breadcrumb/Breadcrumb.test.jsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import React from 'react';
import { mount } from 'enzyme';
import { render, screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';

import Breadcrumb from './index';
import Breadcrumb from '.';

const baseProps = {
links: [
@@ -21,70 +22,61 @@ const baseProps = {
};

describe('<Breadcrumb />', () => {
let wrapper;

it('renders with just links', () => {
wrapper = mount(<Breadcrumb {...baseProps} />);

const list = wrapper.find('ol li');
expect(list.length).toEqual(5);
expect(list.find('a').length).toEqual(3);
render(<Breadcrumb {...baseProps} />);
expect(screen.queryAllByRole('list').length).toBe(1);
expect(screen.queryAllByRole('listitem').length).toBe(baseProps.links.length);
});

it('renders with links and active label', () => {
const label = 'Current Page';
wrapper = mount(<Breadcrumb {...baseProps} activeLabel={label} />);
render(<Breadcrumb {...baseProps} activeLabel={label} />);
const list = screen.queryAllByRole('list');
const listItems = screen.queryAllByRole('listitem');

const list = wrapper.find('ol li');
expect(list.length).toEqual(7);
expect(list.find('a').length).toEqual(3);
expect(list.last().text()).toEqual(label);
expect(list.length).toBe(1);
expect(listItems.length).toBe(baseProps.links.length + 1);
expect(listItems[listItems.length - 1].textContent).toBe(label);
});

it('renders custom spacer', () => {
wrapper = mount(<Breadcrumb
{...baseProps}
spacer={<span className="custom-spacer">/</span>}
/>);

const list = wrapper.find('ol li');
expect(list.length).toEqual(5);
expect(list.find('a').length).toEqual(3);
expect(list.find('.custom-spacer').length).toEqual(2);
render(
<Breadcrumb {...baseProps} spacer={<span>/</span>} />,
);
const listItems = screen.queryAllByRole('listitem');
expect(listItems.length).toBe(baseProps.links.length);
expect(screen.getAllByRole('presentation').length).toBe(2);
});

it('fires the passed in click handler', () => {
const clickHandler = jest.fn();
wrapper = mount(<Breadcrumb {...baseProps} clickHandler={clickHandler} />);

const list = wrapper.find('ol li');
expect(list.length).toEqual(5);
render(<Breadcrumb {...baseProps} clickHandler={clickHandler} />);

const links = list.find('a');
expect(links.length).toEqual(3);
const listItems = screen.queryAllByRole('listitem');
const links = screen.queryAllByRole('link');
expect(listItems.length).toBe(baseProps.links.length);

links.first().simulate('click');
userEvent.click(links[0]);
expect(clickHandler).toHaveBeenCalled();
});

it('renders in mobile view', () => {
wrapper = mount(<Breadcrumb {...baseProps} isMobile />);

const list = wrapper.find('ol');
const listElements = list.find('li');
expect(listElements.length).toEqual(2);
expect(list.hasClass('is-mobile')).toEqual(true);
render(<Breadcrumb {...baseProps} isMobile />);
const list = screen.getByRole('list');
const listItems = screen.getAllByRole('listitem');
expect(listItems.length).toBe(1);
expect(list.className).toContain('is-mobile');
});

it('renders links as custom elements', () => {
wrapper = mount(<Breadcrumb {...baseProps} linkAs="div" />);
render(<Breadcrumb {...baseProps} linkAs="div" />);
const list = screen.getByRole('list');

const list = wrapper.find('ol');
const anchors = list.find('a');
expect(anchors.length).toEqual(0);
const anchors = list.querySelectorAll('a');
expect(anchors.length).toBe(0);

const customLinks = list.find('div');
expect(customLinks.length).toEqual(3);
const customLinks = list.querySelectorAll('div');
expect(customLinks.length).toBe(3);
});

it('passes down link props to link elements', () => {
@@ -95,13 +87,11 @@ describe('<Breadcrumb />', () => {
target: '_blank',
};

wrapper = mount(<Breadcrumb links={[linkProps]} />);

const list = wrapper.find('ol');
const renderedLink = list.find('a').first();
render(<Breadcrumb links={[linkProps]} />);

expect(renderedLink.hasClass('my-link')).toEqual(true);
expect(renderedLink.prop('target')).toEqual('_blank');
expect(renderedLink.prop('href')).toEqual('/link-1');
const links = screen.getByRole('link');
expect(links.className).toContain('my-link');
expect(links.getAttribute('target')).toBe('_blank');
expect(links.getAttribute('href')).toBe('/link-1');
});
});
8 changes: 6 additions & 2 deletions src/Breadcrumb/index.jsx
Original file line number Diff line number Diff line change
@@ -8,13 +8,17 @@ import Icon from '../Icon';

function Breadcrumb({
links, activeLabel, spacer, clickHandler,
variant, isMobile, ariaLabel, linkAs,
variant, isMobile, ariaLabel, linkAs, ...props
}) {
const linkCount = links.length;
const displayLinks = isMobile ? [links[linkCount - 1]] : links;

return (
<nav aria-label={ariaLabel} className={classNames('pgn__breadcrumb', `pgn__breadcrumb-${variant}`)}>
<nav
aria-label={ariaLabel}
className={classNames('pgn__breadcrumb', `pgn__breadcrumb-${variant}`)}
{...props}
>
<ol className={classNames('list-inline', { 'is-mobile': isMobile })}>
{displayLinks.map((link, i) => (
<React.Fragment key={link.label}>
33 changes: 18 additions & 15 deletions src/Bubble/Bubble.test.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React from 'react';
import renderer from 'react-test-renderer';
import { mount } from 'enzyme';
import Bubble from './index';
import { render, screen } from '@testing-library/react';
import Bubble from '.';

describe('<Bubble />', () => {
describe('correct rendering', () => {
@@ -10,24 +10,27 @@ describe('<Bubble />', () => {
expect(tree).toMatchSnapshot();
});
it('renders with variant', () => {
const wrapper = mount(<Bubble variant="error">1</Bubble>);
const bubble = wrapper.find('.pgn__bubble');
expect(bubble.hasClass('pgn__bubble-error')).toEqual(true);
render(<Bubble variant="error">1</Bubble>);
const bubble = screen.getByText('1');
expect(bubble.className).toContain('pgn__bubble-error');
});

it('renders with default variant', () => {
const wrapper = mount(<Bubble>1</Bubble>);
const bubble = wrapper.find('.pgn__bubble');
expect(bubble.hasClass('pgn__bubble-primary')).toEqual(true);
render(<Bubble>1</Bubble>);
const bubble = screen.getByText('1');
expect(bubble.className).toContain('pgn__bubble-primary');
});

it('renders with disabled variant', () => {
const wrapper = mount(<Bubble disabled>1</Bubble>);
const bubble = wrapper.find('.pgn__bubble');
expect(bubble.hasClass('disabled')).toEqual(true);
render(<Bubble disabled>1</Bubble>);
const bubble = screen.getByText('1');
expect(bubble.className).toContain('disabled');
});
it('renders with disabled variant', () => {
const wrapper = mount(<Bubble expandable>1</Bubble>);
const bubble = wrapper.find('.pgn__bubble');
expect(bubble.hasClass('expandable')).toEqual(true);

it('renders with expandable variant', () => {
render(<Bubble expandable>1</Bubble>);
const bubble = screen.getByText('1');
expect(bubble.className).toContain('expandable');
});
});
});
Loading

0 comments on commit c00d2c9

Please sign in to comment.