diff --git a/components/_util/__tests__/util.test.js b/components/_util/__tests__/util.test.js index 5764e5f31248..ab67d5297af2 100644 --- a/components/_util/__tests__/util.test.js +++ b/components/_util/__tests__/util.test.js @@ -148,7 +148,9 @@ describe('Test utils function', () => { button , - ).instance(); + ) + .find(Wave) + .instance(); expect(wrapper.bindAnimationEvent()).toBe(undefined); }); @@ -159,7 +161,9 @@ describe('Test utils function', () => { button , - ).instance(); + ) + .find(Wave) + .instance(); expect(wrapper.bindAnimationEvent()).toBe(undefined); }); @@ -168,7 +172,9 @@ describe('Test utils function', () => { , - ).instance(); + ) + .find(Wave) + .instance(); expect(wrapper.bindAnimationEvent()).toBe(undefined); }); diff --git a/components/_util/devWarning.ts b/components/_util/devWarning.ts index 60403d293b03..34090ca30680 100644 --- a/components/_util/devWarning.ts +++ b/components/_util/devWarning.ts @@ -4,4 +4,9 @@ export { resetWarned }; export default (valid: boolean, component: string, message: string): void => { devWarning(valid, `[antd: ${component}] ${message}`); + + // StrictMode will inject console which will not throw warning in React 17. + if (process.env.NODE_ENV === 'test') { + resetWarned(); + } }; diff --git a/components/affix/__tests__/Affix.test.tsx b/components/affix/__tests__/Affix.test.tsx index 5c47a383f47b..0e56d99c98c0 100644 --- a/components/affix/__tests__/Affix.test.tsx +++ b/components/affix/__tests__/Affix.test.tsx @@ -5,7 +5,7 @@ import { getObserverEntities } from '../utils'; import Button from '../../button'; import rtlTest from '../../../tests/shared/rtlTest'; import accessibilityTest from '../../../tests/shared/accessibilityTest'; -import { sleep } from '../../../tests/utils'; +import { sleep, render } from '../../../tests/utils'; const events: Partial) => void>> = {}; @@ -97,57 +97,47 @@ describe('Affix Render', () => { }; it('Anchor render perfectly', async () => { - document.body.innerHTML = ''; - - affixMounterWrapper = mount(, { attachTo: document.getElementById('mounter') }); + const { container } = render(); await sleep(20); await movePlaceholder(0); - expect(affixMounterWrapper.instance().affix.state.affixStyle).toBeFalsy(); + expect(container.querySelector('.ant-affix')).toBeFalsy(); await movePlaceholder(-100); - expect(affixMounterWrapper.instance().affix.state.affixStyle).toBeTruthy(); + expect(container.querySelector('.ant-affix')).toBeTruthy(); await movePlaceholder(0); - expect(affixMounterWrapper.instance().affix.state.affixStyle).toBeFalsy(); + expect(container.querySelector('.ant-affix')).toBeFalsy(); }); it('support offsetBottom', async () => { - document.body.innerHTML = ''; - - affixMounterWrapper = mount(, { - attachTo: document.getElementById('mounter'), - }); + const { container } = render(); await sleep(20); await movePlaceholder(300); - expect(affixMounterWrapper.instance().affix.state.affixStyle).toBeTruthy(); + expect(container.querySelector('.ant-affix')).toBeTruthy(); await movePlaceholder(0); - expect(affixMounterWrapper.instance().affix.state.affixStyle).toBeFalsy(); + expect(container.querySelector('.ant-affix')).toBeFalsy(); await movePlaceholder(300); - expect(affixMounterWrapper.instance().affix.state.affixStyle).toBeTruthy(); + expect(container.querySelector('.ant-affix')).toBeTruthy(); }); it('updatePosition when offsetTop changed', async () => { - document.body.innerHTML = ''; const onChange = jest.fn(); - affixMounterWrapper = mount(, { - attachTo: document.getElementById('mounter'), - }); + const { container, rerender } = render(); await sleep(20); await movePlaceholder(-100); expect(onChange).toHaveBeenLastCalledWith(true); - expect(affixMounterWrapper.instance().affix.state.affixStyle?.top).toBe(0); - affixMounterWrapper.setProps({ - offsetTop: 10, - }); + expect(container.querySelector('.ant-affix')).toHaveStyle({ top: 0 }); + + rerender(); await sleep(20); - expect(affixMounterWrapper.instance().affix.state.affixStyle?.top).toBe(10); + expect(container.querySelector('.ant-affix')).toHaveStyle({ top: `10px` }); }); describe('updatePosition when target changed', () => { @@ -201,7 +191,9 @@ describe('Affix Render', () => { await sleep(20); await movePlaceholder(300); - expect(affixMounterWrapper.instance().affix.state.affixStyle).toBeTruthy(); + expect( + (affixMounterWrapper.find(AffixMounter).instance() as any).affix.state.affixStyle, + ).toBeTruthy(); await sleep(20); affixMounterWrapper.update(); diff --git a/components/anchor/__tests__/Anchor.test.tsx b/components/anchor/__tests__/Anchor.test.tsx index 0623021bd7f2..207b3b05ded2 100644 --- a/components/anchor/__tests__/Anchor.test.tsx +++ b/components/anchor/__tests__/Anchor.test.tsx @@ -1,7 +1,7 @@ import React from 'react'; import { mount } from 'enzyme'; import Anchor from '..'; -import { sleep } from '../../../tests/utils'; +import { sleep, render } from '../../../tests/utils'; const { Link } = Anchor; @@ -55,8 +55,8 @@ describe('Anchor Render', () => { wrapper.find(`a[href="#${hash}"]`).simulate('click'); - wrapper.instance().handleScroll(); - expect(wrapper.instance().state).not.toBe(null); + wrapper.find(Anchor).instance().handleScroll(); + expect(wrapper.find(Anchor).instance().state).not.toBe(null); }); it('Anchor render perfectly for complete href - click', () => { @@ -67,7 +67,9 @@ describe('Anchor Render', () => { , ); wrapper.find(`a[href="http://www.example.com/#${hash}"]`).simulate('click'); - expect(wrapper.instance().state.activeLink).toBe(`http://www.example.com/#${hash}`); + expect(wrapper.find(Anchor).instance().state.activeLink).toBe( + `http://www.example.com/#${hash}`, + ); }); it('Anchor render perfectly for complete href - hash router', async () => { @@ -80,8 +82,8 @@ describe('Anchor Render', () => { , ); - wrapper.instance().handleScrollTo('/#/faq?locale=en#Q1'); - expect(wrapper.instance().state.activeLink).toBe('/#/faq?locale=en#Q1'); + wrapper.find(Anchor).instance().handleScrollTo('/#/faq?locale=en#Q1'); + expect(wrapper.find(Anchor).instance().state.activeLink).toBe('/#/faq?locale=en#Q1'); expect(scrollToSpy).not.toHaveBeenCalled(); await sleep(1000); expect(scrollToSpy).toHaveBeenCalled(); @@ -96,8 +98,10 @@ describe('Anchor Render', () => { , ); - wrapper.instance().handleScroll(); - expect(wrapper.instance().state.activeLink).toBe(`http://www.example.com/#${hash}`); + wrapper.find(Anchor).instance().handleScroll(); + expect(wrapper.find(Anchor).instance().state.activeLink).toBe( + `http://www.example.com/#${hash}`, + ); }); it('Anchor render perfectly for complete href - scrollTo', async () => { @@ -110,8 +114,8 @@ describe('Anchor Render', () => { , ); - wrapper.instance().handleScrollTo(`##${hash}`); - expect(wrapper.instance().state.activeLink).toBe(`##${hash}`); + wrapper.find(Anchor).instance().handleScrollTo(`##${hash}`); + expect(wrapper.find(Anchor).instance().state.activeLink).toBe(`##${hash}`); const calls = scrollToSpy.mock.calls.length; await sleep(1000); expect(scrollToSpy.mock.calls.length).toBeGreaterThan(calls); @@ -124,21 +128,27 @@ describe('Anchor Render', () => { , ); - const removeListenerSpy = jest.spyOn((wrapper.instance() as any).scrollEvent, 'remove'); + const removeListenerSpy = jest.spyOn( + (wrapper.find(Anchor).instance() as any).scrollEvent, + 'remove', + ); wrapper.unmount(); expect(removeListenerSpy).toHaveBeenCalled(); }); - it('should unregister link when unmount children', async () => { + it('should unregister link when unmount children', () => { const hash = getHashUrl(); - const wrapper = mount( + const { container, rerender } = render( , ); - expect((wrapper.instance() as any).links).toEqual([`#${hash}`]); - wrapper.setProps({ children: null }); - expect((wrapper.instance() as any).links).toEqual([]); + + expect(container.querySelectorAll('.ant-anchor-link-title')).toHaveLength(1); + expect(container.querySelector('.ant-anchor-link-title')).toHaveAttribute('href', `#${hash}`); + + rerender(); + expect(container.querySelector('.ant-anchor-link-title')).toBeFalsy(); }); it('should update links when link href update', async () => { @@ -188,7 +198,7 @@ describe('Anchor Render', () => { wrapper.find(`a[href="${href}"]`).simulate('click'); - wrapper.instance().handleScroll(); + wrapper.find(Anchor).instance().handleScroll(); expect(event).not.toBe(undefined); expect(link).toEqual({ href, title }); }); @@ -205,7 +215,10 @@ describe('Anchor Render', () => { , ); - const removeListenerSpy = jest.spyOn((wrapper.instance() as any).scrollEvent, 'remove'); + const removeListenerSpy = jest.spyOn( + (wrapper.find(Anchor).instance() as any).scrollEvent, + 'remove', + ); await sleep(1000); wrapper.setProps({ getContainer: getContainerB }); expect(removeListenerSpy).not.toHaveBeenCalled(); @@ -230,7 +243,10 @@ describe('Anchor Render', () => { , ); - const removeListenerSpy = jest.spyOn((wrapper.instance() as any).scrollEvent, 'remove'); + const removeListenerSpy = jest.spyOn( + (wrapper.find(Anchor).instance() as any).scrollEvent, + 'remove', + ); expect(removeListenerSpy).not.toHaveBeenCalled(); await sleep(1000); wrapper.setProps({ getContainer: getContainerB }); @@ -248,8 +264,8 @@ describe('Anchor Render', () => { , ); wrapper.find(`a[href="#${hash}"]`).simulate('click'); - (wrapper.instance() as any).handleScroll(); - expect(wrapper.instance().state).not.toBe(null); + (wrapper.find(Anchor).instance() as any).handleScroll(); + expect(wrapper.find(Anchor).instance().state).not.toBe(null); }); it('Same function returns different DOM', async () => { @@ -278,7 +294,10 @@ describe('Anchor Render', () => { , ); - const removeListenerSpy = jest.spyOn((wrapper.instance() as any).scrollEvent, 'remove'); + const removeListenerSpy = jest.spyOn( + (wrapper.find(Anchor).instance() as any).scrollEvent, + 'remove', + ); expect(removeListenerSpy).not.toHaveBeenCalled(); await sleep(1000); holdContainer.container = document.getElementById(hash2); @@ -311,19 +330,19 @@ describe('Anchor Render', () => { , ); - wrapper.instance().handleScrollTo(`#${hash}`); + wrapper.find(Anchor).instance().handleScrollTo(`#${hash}`); await sleep(30); expect(scrollToSpy).toHaveBeenLastCalledWith(0, 1000); dateNowMock = dataNowMockFn(); wrapper.setProps({ offsetTop: 100 }); - wrapper.instance().handleScrollTo(`#${hash}`); + wrapper.find(Anchor).instance().handleScrollTo(`#${hash}`); await sleep(30); expect(scrollToSpy).toHaveBeenLastCalledWith(0, 900); dateNowMock = dataNowMockFn(); wrapper.setProps({ targetOffset: 200 }); - wrapper.instance().handleScrollTo(`#${hash}`); + wrapper.find(Anchor).instance().handleScrollTo(`#${hash}`); await sleep(30); expect(scrollToSpy).toHaveBeenLastCalledWith(0, 800); @@ -356,19 +375,19 @@ describe('Anchor Render', () => { , ); - wrapper.instance().handleScrollTo(`#${hash}`); + wrapper.find(Anchor).instance().handleScrollTo(`#${hash}`); await sleep(30); expect(scrollToSpy).toHaveBeenLastCalledWith(0, 1000); dateNowMock = dataNowMockFn(); wrapper.setProps({ offsetTop: 100 }); - wrapper.instance().handleScrollTo(`#${hash}`); + wrapper.find(Anchor).instance().handleScrollTo(`#${hash}`); await sleep(30); expect(scrollToSpy).toHaveBeenLastCalledWith(0, 900); dateNowMock = dataNowMockFn(); wrapper.setProps({ targetOffset: 200 }); - wrapper.instance().handleScrollTo(`#${hash}`); + wrapper.find(Anchor).instance().handleScrollTo(`#${hash}`); await sleep(30); expect(scrollToSpy).toHaveBeenLastCalledWith(0, 800); @@ -386,7 +405,7 @@ describe('Anchor Render', () => { , ); expect(onChange).toHaveBeenCalledTimes(1); - wrapper.instance().handleScrollTo(hash2); + wrapper.find(Anchor).instance().handleScrollTo(hash2); expect(onChange).toHaveBeenCalledTimes(2); expect(onChange).toHaveBeenCalledWith(hash2); }); @@ -400,8 +419,8 @@ describe('Anchor Render', () => { wrapper.find(`a[href="notexsited"]`).simulate('click'); - wrapper.instance().handleScrollTo('notexsited'); - expect(wrapper.instance().state).not.toBe(null); + wrapper.find(Anchor).instance().handleScrollTo('notexsited'); + expect(wrapper.find(Anchor).instance().state).not.toBe(null); }); it('test edge case when getBoundingClientRect return zero size', async () => { @@ -434,19 +453,19 @@ describe('Anchor Render', () => { , ); - wrapper.instance().handleScrollTo(`#${hash}`); + wrapper.find(Anchor).instance().handleScrollTo(`#${hash}`); await sleep(30); expect(scrollToSpy).toHaveBeenLastCalledWith(0, 1000); dateNowMock = dataNowMockFn(); wrapper.setProps({ offsetTop: 100 }); - wrapper.instance().handleScrollTo(`#${hash}`); + wrapper.find(Anchor).instance().handleScrollTo(`#${hash}`); await sleep(30); expect(scrollToSpy).toHaveBeenLastCalledWith(0, 900); dateNowMock = dataNowMockFn(); wrapper.setProps({ targetOffset: 200 }); - wrapper.instance().handleScrollTo(`#${hash}`); + wrapper.find(Anchor).instance().handleScrollTo(`#${hash}`); await sleep(30); expect(scrollToSpy).toHaveBeenLastCalledWith(0, 800); @@ -483,19 +502,19 @@ describe('Anchor Render', () => { , ); - wrapper.instance().handleScrollTo(`#${hash}`); + wrapper.find(Anchor).instance().handleScrollTo(`#${hash}`); await sleep(30); expect(scrollToSpy).toHaveBeenLastCalledWith(0, 800); dateNowMock = dataNowMockFn(); wrapper.setProps({ offsetTop: 100 }); - wrapper.instance().handleScrollTo(`#${hash}`); + wrapper.find(Anchor).instance().handleScrollTo(`#${hash}`); await sleep(30); expect(scrollToSpy).toHaveBeenLastCalledWith(0, 800); dateNowMock = dataNowMockFn(); wrapper.setProps({ targetOffset: 200 }); - wrapper.instance().handleScrollTo(`#${hash}`); + wrapper.find(Anchor).instance().handleScrollTo(`#${hash}`); await sleep(30); expect(scrollToSpy).toHaveBeenLastCalledWith(0, 800); @@ -513,7 +532,7 @@ describe('Anchor Render', () => { , ); - expect(wrapper.instance().state.activeLink).toBe(`#${hash2}`); + expect(wrapper.find(Anchor).instance().state.activeLink).toBe(`#${hash2}`); }); // https://github.com/ant-design/ant-design/issues/30584 @@ -528,7 +547,7 @@ describe('Anchor Render', () => { , ); expect(onChange).toHaveBeenCalledTimes(1); - wrapper.instance().handleScrollTo(hash2); + wrapper.find(Anchor).instance().handleScrollTo(hash2); expect(onChange).toHaveBeenCalledTimes(2); expect(onChange).toHaveBeenCalledWith(hash2); }); diff --git a/components/avatar/__tests__/Avatar.test.js b/components/avatar/__tests__/Avatar.test.js index 839e890ceebf..a755ad1b2991 100644 --- a/components/avatar/__tests__/Avatar.test.js +++ b/components/avatar/__tests__/Avatar.test.js @@ -2,7 +2,7 @@ import React from 'react'; import ReactDOM from 'react-dom'; import { act } from 'react-dom/test-utils'; import { mount } from 'enzyme'; -import { fireEvent, render } from '@testing-library/react'; +import { render, fireEvent } from '../../../tests/utils'; import Avatar from '..'; import mountTest from '../../../tests/shared/mountTest'; import rtlTest from '../../../tests/shared/rtlTest'; @@ -123,8 +123,8 @@ describe('Avatar Render', () => { }); it('should calculate scale of avatar children correctly', () => { - const wrapper = mount(Avatar); - expect(wrapper.find('.ant-avatar-string').render()).toMatchSnapshot(); + const { container, rerender } = render(Avatar); + expect(container.querySelector('.ant-avatar-string')).toMatchSnapshot(); Object.defineProperty(HTMLElement.prototype, 'offsetWidth', { get() { @@ -134,8 +134,9 @@ describe('Avatar Render', () => { return 40; }, }); - wrapper.setProps({ children: 'xx' }); - expect(wrapper.find('.ant-avatar-string').render()).toMatchSnapshot(); + + rerender(xx); + expect(container.querySelector('.ant-avatar-string')).toMatchSnapshot(); }); it('should calculate scale of avatar children correctly with gap', () => { diff --git a/components/breadcrumb/__tests__/Breadcrumb.test.js b/components/breadcrumb/__tests__/Breadcrumb.test.js index d9988d248941..23b1a12a86fa 100644 --- a/components/breadcrumb/__tests__/Breadcrumb.test.js +++ b/components/breadcrumb/__tests__/Breadcrumb.test.js @@ -1,6 +1,6 @@ import React from 'react'; import { mount } from 'enzyme'; -import { render } from '@testing-library/react'; +import { render } from '../../../tests/utils'; import Breadcrumb from '../index'; import mountTest from '../../../tests/shared/mountTest'; import rtlTest from '../../../tests/shared/rtlTest'; @@ -29,8 +29,7 @@ describe('Breadcrumb', () => { , ); - expect(errorSpy.mock.calls).toHaveLength(1); - expect(errorSpy.mock.calls[0][0]).toMatch( + expect(errorSpy).toHaveBeenCalledWith( "Warning: [antd: Breadcrumb] Only accepts Breadcrumb.Item and Breadcrumb.Separator as it's children", ); }); diff --git a/components/breadcrumb/__tests__/__snapshots__/router.test.js.snap b/components/breadcrumb/__tests__/__snapshots__/router.test.js.snap index 4e423c040221..faf2a7563b4b 100644 --- a/components/breadcrumb/__tests__/__snapshots__/router.test.js.snap +++ b/components/breadcrumb/__tests__/__snapshots__/router.test.js.snap @@ -1,166 +1,72 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`react router react router 3 1`] = ` - - - - + + - - - - Home - - - - / - - - - + Home + + + - - - - Application List - - - - / - - - - + + + - - - - Application1 - - - - / - - - - + Application List + + + - - - - Detail - - - - / - - - - - - + / + + + + + + Application1 + + + + / + + + + + + Detail + + + + / + + + + `; diff --git a/components/breadcrumb/__tests__/router.test.js b/components/breadcrumb/__tests__/router.test.js index e8022ffc0b24..ca718baa9a5e 100644 --- a/components/breadcrumb/__tests__/router.test.js +++ b/components/breadcrumb/__tests__/router.test.js @@ -144,6 +144,6 @@ describe('react router', () => { }, ]; const wrapper = mount(); - expect(wrapper).toMatchSnapshot(); + expect(wrapper.render()).toMatchSnapshot(); }); }); diff --git a/components/button/__tests__/index.test.tsx b/components/button/__tests__/index.test.tsx index 8269e56d3e47..7617fe922bb6 100644 --- a/components/button/__tests__/index.test.tsx +++ b/components/button/__tests__/index.test.tsx @@ -1,6 +1,5 @@ import React, { Component } from 'react'; import { mount } from 'enzyme'; -import { fireEvent, render } from '@testing-library/react'; import { act } from 'react-dom/test-utils'; import { SearchOutlined } from '@ant-design/icons'; import { resetWarned } from 'rc-util/lib/warning'; @@ -8,7 +7,7 @@ import Button from '..'; import ConfigProvider from '../../config-provider'; import mountTest from '../../../tests/shared/mountTest'; import rtlTest from '../../../tests/shared/rtlTest'; -import { sleep } from '../../../tests/utils'; +import { sleep, render, fireEvent } from '../../../tests/utils'; import { SizeType } from '../../config-provider/SizeContext'; describe('Button', () => { @@ -85,22 +84,26 @@ describe('Button', () => { it('renders Chinese characters correctly in HOC', () => { const Text = ({ children }: { children: React.ReactNode }) => {children}; - const wrapper = mount( + const { container, rerender } = render( 按钮 , ); - expect(wrapper.find('.ant-btn').hasClass('ant-btn-two-chinese-chars')).toBe(true); - wrapper.setProps({ - children: 大按钮, - }); - wrapper.update(); - expect(wrapper.find('.ant-btn').hasClass('ant-btn-two-chinese-chars')).toBe(false); - wrapper.setProps({ - children: 按钮, - }); - wrapper.update(); - expect(wrapper.find('.ant-btn').hasClass('ant-btn-two-chinese-chars')).toBe(true); + expect(container.querySelector('.ant-btn')).toHaveClass('ant-btn-two-chinese-chars'); + + rerender( + + 大按钮 + , + ); + expect(container.querySelector('.ant-btn')).not.toHaveClass('ant-btn-two-chinese-chars'); + + rerender( + + 按钮 + , + ); + expect(container.querySelector('.ant-btn')).toHaveClass('ant-btn-two-chinese-chars'); }); // https://github.com/ant-design/ant-design/issues/18118 @@ -123,7 +126,7 @@ describe('Button', () => { it('have static property for type detecting', () => { const wrapper = mount(Button Text); - expect((wrapper.type() as any).__ANT_BUTTON).toBe(true); + expect((wrapper.find(Button).type() as any).__ANT_BUTTON).toBe(true); }); it('should change loading state instantly by default', () => { diff --git a/components/card/__tests__/index.test.js b/components/card/__tests__/index.test.js index da9a0979c066..fc11bc5c7431 100644 --- a/components/card/__tests__/index.test.js +++ b/components/card/__tests__/index.test.js @@ -4,6 +4,7 @@ import Card from '../index'; import Button from '../../button/index'; import mountTest from '../../../tests/shared/mountTest'; import rtlTest from '../../../tests/shared/rtlTest'; +import { render } from '../../../tests/utils'; describe('Card', () => { mountTest(Card); @@ -84,20 +85,14 @@ describe('Card', () => { }); it('get ref of card', () => { - class WrapperComponent extends React.Component { - render() { - return ( - - Card content - - ); - } - } - const wrapper = mount(); - expect(wrapper.ref('firstRef').className.includes('ant-card')).toBe(true); + const cardRef = React.createRef(); + + render( + + Card content + , + ); + + expect(cardRef.current).toHaveClass('ant-card'); }); }); diff --git a/components/carousel/__tests__/index.test.js b/components/carousel/__tests__/index.test.js index 27b1c1d41809..d7dc07147c63 100644 --- a/components/carousel/__tests__/index.test.js +++ b/components/carousel/__tests__/index.test.js @@ -3,7 +3,7 @@ import { mount } from 'enzyme'; import Carousel from '..'; import mountTest from '../../../tests/shared/mountTest'; import rtlTest from '../../../tests/shared/rtlTest'; -import { sleep } from '../../../tests/utils'; +import { sleep, render } from '../../../tests/utils'; describe('Carousel', () => { mountTest(Carousel); @@ -99,21 +99,28 @@ describe('Carousel', () => { describe('should active when children change', () => { it('should active', () => { - const wrapper = mount(); - wrapper.setProps({ - children: , - }); - wrapper.update(); - expect(wrapper.find('.slick-active').length).toBeTruthy(); + const { rerender, container } = render(); + expect(container.querySelector('.slick-active')).toBeFalsy(); + + // Update children + rerender( + + + , + ); + expect(container.querySelector('.slick-active')).toBeTruthy(); }); it('should keep initialSlide', () => { - const wrapper = mount(); - wrapper.setProps({ - children: [, , ], - }); - wrapper.update(); - expect(wrapper.find('.slick-dots li').at(1).hasClass('slick-active')).toBeTruthy(); + const { rerender, container } = render(); + rerender( + + + + + , + ); + expect(container.querySelectorAll('.slick-dots li')[1]).toHaveClass('slick-active'); }); }); diff --git a/components/checkbox/__tests__/__snapshots__/group.test.js.snap b/components/checkbox/__tests__/__snapshots__/group.test.js.snap index f1e85edb7b3a..3b2365ae536f 100644 --- a/components/checkbox/__tests__/__snapshots__/group.test.js.snap +++ b/components/checkbox/__tests__/__snapshots__/group.test.js.snap @@ -25,7 +25,7 @@ exports[`CheckboxGroup passes prefixCls down to checkbox 1`] = ` { @@ -71,9 +72,9 @@ describe('CheckboxGroup', () => { { label: 'Orange', value: 'Orange', style: { fontSize: 12 } }, ]; - const wrapper = render(); + const wrapper = mount(); - expect(wrapper).toMatchSnapshot(); + expect(wrapper.render()).toMatchSnapshot(); }); it('should be controlled by value', () => { @@ -105,34 +106,38 @@ describe('CheckboxGroup', () => { // https://github.com/ant-design/ant-design/issues/16376 it('onChange should filter removed value', () => { const onChange = jest.fn(); - const wrapper = mount( + const { container, rerender } = render( , ); - wrapper.setProps({ - children: [], - }); - - wrapper.find('.ant-checkbox-input').at(0).simulate('change'); + rerender( + + + , + ); + fireEvent.click(container.querySelector('.ant-checkbox-input')); expect(onChange).toHaveBeenCalledWith([2]); }); it('checkbox should register value again after value changed', () => { const onChange = jest.fn(); - const wrapper = mount( + const { container, rerender } = render( , ); - wrapper.setProps({ - children: [], - }); - expect(wrapper.find('.ant-checkbox-input').at(0).prop('checked')).toBe(false); + rerender( + + + , + ); + + expect(container.querySelector('.ant-checkbox-input')).toHaveAttribute('checked'); }); // https://github.com/ant-design/ant-design/issues/17297 diff --git a/components/config-provider/__tests__/form.test.js b/components/config-provider/__tests__/form.test.js index d890e6a55207..7aaaeb1768bc 100644 --- a/components/config-provider/__tests__/form.test.js +++ b/components/config-provider/__tests__/form.test.js @@ -1,7 +1,7 @@ import React from 'react'; import { mount } from 'enzyme'; -import { render } from '@testing-library/react'; import { act } from 'react-dom/test-utils'; +import { render } from '../../../tests/utils'; import ConfigProvider from '..'; import zhCN from '../../locale/zh_CN'; import Form from '../../form'; diff --git a/components/config-provider/__tests__/locale.test.js b/components/config-provider/__tests__/locale.test.js index 63e1ce3f0ccb..25a855208871 100644 --- a/components/config-provider/__tests__/locale.test.js +++ b/components/config-provider/__tests__/locale.test.js @@ -70,22 +70,12 @@ describe('ConfigProvider.Locale', () => { // https://github.com/ant-design/ant-design/issues/31592 it('should not reset the component state when switching locale', () => { - class App extends React.Component { - state = { - locale: zhCN, - }; - - render() { - return ( - - - - - ); - } - } - - const wrapper = mount(); + const wrapper = mount( + + + + , + ); const datepickerInitProps = wrapper.find('.ant-picker-input input').props(); expect(datepickerInitProps.value).toBe(''); @@ -100,7 +90,7 @@ describe('ConfigProvider.Locale', () => { expect(wrapper.find('.ant-picker-input input').props().value).not.toBe(''); - wrapper.setState({ locale: {} }); + wrapper.setProps({ locale: {} }); wrapper.find('.ant-pagination-item-3').simulate('click'); const datepickerProps = wrapper.find('.ant-picker-input input').props(); diff --git a/components/date-picker/__tests__/RangePicker.test.js b/components/date-picker/__tests__/RangePicker.test.js index de0249f790ca..a1a3783ffd79 100644 --- a/components/date-picker/__tests__/RangePicker.test.js +++ b/components/date-picker/__tests__/RangePicker.test.js @@ -70,9 +70,7 @@ describe('RangePicker', () => { openPicker(wrapper, 1); selectCell(wrapper, 'Feb'); closePicker(wrapper, 1); - - const { value } = wrapper.state(); - + const { value } = wrapper.find(Test).state(); expect(value[0].isSame(value[1], 'date')).toBeTruthy(); }); }); diff --git a/components/drawer/__tests__/Drawer.test.js b/components/drawer/__tests__/Drawer.test.js index 8d23fe6dbc94..35ad2c9f6304 100644 --- a/components/drawer/__tests__/Drawer.test.js +++ b/components/drawer/__tests__/Drawer.test.js @@ -1,6 +1,6 @@ import React from 'react'; import { mount } from 'enzyme'; -import { render } from '@testing-library/react'; +import { render } from '../../../tests/utils'; import Drawer from '..'; import ConfigProvider from '../../config-provider'; import mountTest from '../../../tests/shared/mountTest'; diff --git a/components/drawer/__tests__/DrawerEvent.test.js b/components/drawer/__tests__/DrawerEvent.test.js index 07d94df43fb3..4e3969947882 100644 --- a/components/drawer/__tests__/DrawerEvent.test.js +++ b/components/drawer/__tests__/DrawerEvent.test.js @@ -1,118 +1,67 @@ import React from 'react'; -import { mount } from 'enzyme'; import Drawer from '..'; -import Button from '../../button'; - -class DrawerEventTester extends React.Component { - constructor(props) { - super(props); - this.state = { visible: false }; - } - - componentDidMount() { - this.setState({ visible: true }); // eslint-disable-line react/no-did-mount-set-state - } - - onClose = () => { - this.setState({ - visible: false, - }); - }; - - open = () => { - this.setState({ - visible: true, - }); - }; - - render() { - const { visible } = this.state; - return ( - - open - - Here is content of Drawer - - - ); - } -} +import { render, fireEvent } from '../../../tests/utils'; describe('Drawer', () => { + const getDrawer = props => ( + + Here is content of Drawer + + ); + it('render correctly', () => { - const wrapper = mount(); - const body = wrapper.find('.ant-drawer-body').exists(); + const { container, asFragment, rerender } = render(getDrawer()); + expect(container.querySelector('.ant-drawer-body')).toBeTruthy(); - expect(body).toBe(true); - wrapper.find('button.ant-btn').simulate('click'); + rerender(getDrawer({ visible: false })); - const content = wrapper.find('.ant-drawer-body').getDOMNode().innerHTML; - expect(content).toBe('Here is content of Drawer'); + expect(container.querySelector('.ant-drawer-body').textContent).toEqual( + 'Here is content of Drawer', + ); - expect(wrapper.render()).toMatchSnapshot(); + expect(asFragment().firstChild).toMatchSnapshot(); }); it('mask trigger onClose', () => { - const wrapper = mount(); + const onClose = jest.fn(); + const { container } = render(getDrawer({ onClose })); - wrapper.find('button.ant-btn').simulate('click'); - expect(wrapper.instance().state.visible).toBe(true); - - wrapper.find('.ant-drawer-mask').simulate('click'); - expect(wrapper.instance().state.visible).toBe(false); + fireEvent.click(container.querySelector('.ant-drawer-mask')); + expect(onClose).toHaveBeenCalled(); }); it('close button trigger onClose', () => { - const wrapper = mount(); - - wrapper.find('button.ant-btn').simulate('click'); - expect(wrapper.instance().state.visible).toBe(true); + const onClose = jest.fn(); + const { container } = render(getDrawer({ onClose })); - wrapper.find('.ant-drawer-close').simulate('click'); - expect(wrapper.instance().state.visible).toBe(false); + fireEvent.click(container.querySelector('.ant-drawer-close')); + expect(onClose).toHaveBeenCalled(); }); it('maskClosable no trigger onClose', () => { - const wrapper = mount(); + const onClose = jest.fn(); + const { container } = render(getDrawer({ onClose, maskClosable: false })); - wrapper.find('button.ant-btn').simulate('click'); - expect(wrapper.instance().state.visible).toBe(true); - - wrapper.find('.ant-drawer-mask').simulate('click'); - expect(wrapper.instance().state.visible).toBe(true); + fireEvent.click(container.querySelector('.ant-drawer-mask')); + expect(onClose).not.toHaveBeenCalled(); }); it('dom should be removed after close when destroyOnClose is true', () => { - const wrapper = mount(); - wrapper.find('button.ant-btn').simulate('click'); - expect(wrapper.find('.ant-drawer-wrapper-body').exists()).toBe(true); - - wrapper.setState({ - visible: false, - }); - wrapper.find('.ant-drawer-wrapper-body').simulate('transitionend'); - expect(wrapper.find('.ant-drawer-wrapper-body').exists()).toBe(false); - }); + const { container, rerender } = render(getDrawer({ destroyOnClose: true })); - it('dom should be existed after close when destroyOnClose is false', () => { - const wrapper = mount(); - wrapper.find('button.ant-btn').simulate('click'); - expect(wrapper.find('.ant-drawer-wrapper-body').exists()).toBe(true); - - wrapper.setState({ - visible: false, - }); - wrapper.find('.ant-drawer-wrapper-body').simulate('transitionend'); - expect(wrapper.find('.ant-drawer-wrapper-body').exists()).toBe(true); + rerender(getDrawer({ destroyOnClose: true, visible: false })); + fireEvent.transitionEnd(container.querySelector('.ant-drawer-wrapper-body')); + + expect(container.querySelector('.ant-drawer-wrapper-body')).toBeFalsy(); }); - it('no mask and no closable', () => { - const wrapper = mount(); + it('dom should be existed after close when destroyOnClose is false', () => { + const { container, rerender } = render(getDrawer()); + expect(container.querySelector('.ant-drawer-wrapper-body')).toBeTruthy(); - wrapper.find('button.ant-btn').simulate('click'); - expect(wrapper.instance().state.visible).toBe(true); + rerender(getDrawer({ visible: false })); + fireEvent.transitionEnd(container.querySelector('.ant-drawer-wrapper-body')); - wrapper.find('.ant-drawer-close').simulate('click'); - expect(wrapper.instance().state.visible).toBe(false); + expect(container.querySelector('.ant-drawer-wrapper-body')).toBeTruthy(); }); }); diff --git a/components/drawer/__tests__/MultiDrawer.test.js b/components/drawer/__tests__/MultiDrawer.test.js index 449cb3a4e738..601ac19a7fb4 100644 --- a/components/drawer/__tests__/MultiDrawer.test.js +++ b/components/drawer/__tests__/MultiDrawer.test.js @@ -101,6 +101,8 @@ class MultiDrawer extends React.Component { + + {String(childrenDrawer)} ); } @@ -124,7 +126,7 @@ describe('Drawer', () => { expect(translateX).toEqual('translateX(180px)'); expect(wrapper.find('#two_drawer_text').exists()).toBe(true); wrapper.find('.Two-level .ant-drawer-close').simulate('click'); - expect(wrapper.state().childrenDrawer).toBe(false); + expect(wrapper.find('.childrenDrawer').text()).toEqual('false'); }); it('render top MultiDrawer', () => { diff --git a/components/drawer/__tests__/__snapshots__/DrawerEvent.test.js.snap b/components/drawer/__tests__/__snapshots__/DrawerEvent.test.js.snap index f699b461b947..b9aff9a5e8e2 100644 --- a/components/drawer/__tests__/__snapshots__/DrawerEvent.test.js.snap +++ b/components/drawer/__tests__/__snapshots__/DrawerEvent.test.js.snap @@ -1,74 +1,64 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`Drawer render correctly 1`] = ` - - - - open - - + + - - - - - - - - - - - - - Here is content of Drawer + + + + + + Here is content of Drawer + diff --git a/components/dropdown/__tests__/dropdown-button.test.js b/components/dropdown/__tests__/dropdown-button.test.js index 6cbe9d276a3b..a87b222c6aee 100644 --- a/components/dropdown/__tests__/dropdown-button.test.js +++ b/components/dropdown/__tests__/dropdown-button.test.js @@ -62,7 +62,7 @@ describe('DropdownButton', () => { ); const wrapper = mount(); - expect(wrapper.type().__ANT_BUTTON).toBe(true); + expect(wrapper.find(Dropdown.Button).type().__ANT_BUTTON).toBe(true); }); it('should pass mouseEnterDelay and mouseLeaveDelay to Dropdown', () => { diff --git a/components/empty/__tests__/index.test.js b/components/empty/__tests__/index.test.js index 4c1487921b1a..cf627e0a0949 100644 --- a/components/empty/__tests__/index.test.js +++ b/components/empty/__tests__/index.test.js @@ -1,5 +1,5 @@ import React from 'react'; -import { render, mount } from 'enzyme'; +import { mount } from 'enzyme'; import Empty from '..'; import ConfigProvider from '../../config-provider'; import mountTest from '../../../tests/shared/mountTest'; @@ -25,6 +25,6 @@ describe('Empty', () => { , ); - expect(render(wrapper)).toMatchSnapshot(); + expect(wrapper.render()).toMatchSnapshot(); }); }); diff --git a/components/form/__tests__/index.test.js b/components/form/__tests__/index.test.js index fd4086545646..12c357d5d78f 100644 --- a/components/form/__tests__/index.test.js +++ b/components/form/__tests__/index.test.js @@ -1,7 +1,7 @@ import React, { Component, useState } from 'react'; import { mount } from 'enzyme'; -import { render, fireEvent } from '@testing-library/react'; import { act } from 'react-dom/test-utils'; +import { render as testingRender } from '@testing-library/react'; import scrollIntoView from 'scroll-into-view-if-needed'; import Form from '..'; import * as Util from '../util'; @@ -12,7 +12,7 @@ import Select from '../../select'; import mountTest from '../../../tests/shared/mountTest'; import rtlTest from '../../../tests/shared/rtlTest'; -import { sleep } from '../../../tests/utils'; +import { sleep, render, fireEvent } from '../../../tests/utils'; import ConfigProvider from '../../config-provider'; import zhCN from '../../locale/zh_CN'; @@ -128,7 +128,8 @@ describe('Form', () => { ); }; - const { container } = render(); + // FIXME: @zombieJ React 18 StrictMode + const { container } = testingRender(); await change(container, 0, '1', true); expect(container.querySelector('.ant-form-item-explain').textContent).toEqual('aaa'); await change(container, 0, '2', true); @@ -453,6 +454,9 @@ describe('Form', () => { , + { + strictMode: false, + }, ); expect(shouldNotRender).toHaveBeenCalledTimes(1); @@ -718,7 +722,9 @@ describe('Form', () => { ); }; - const wrapper = mount(); + const wrapper = mount(, { + strictMode: false, + }); for (let i = 0; i < 5; i += 1) { wrapper.find('button').simulate('click'); } @@ -741,7 +747,9 @@ describe('Form', () => { ); - const wrapper = mount(); + const wrapper = mount(, { + strictMode: false, + }); renderTimes = 0; wrapper.find('input').simulate('change', { @@ -771,33 +779,25 @@ describe('Form', () => { }); it('Remove Field should also reset error', async () => { - class Demo extends React.Component { - state = { - showA: true, - }; - - render() { - return ( - - {this.state.showA ? ( - - - - ) : ( - - - - )} - - ); - } - } + const Demo = ({ showA }) => ( + + {showA ? ( + + + + ) : ( + + + + )} + + ); - const wrapper = mount(); + const wrapper = mount(); await Promise.resolve(); expect(wrapper.find('.ant-form-item').last().hasClass('ant-form-item-with-help')).toBeTruthy(); - wrapper.setState({ showA: false }); + wrapper.setProps({ showA: false }); await Promise.resolve(); wrapper.update(); expect(wrapper.find('.ant-form-item').last().hasClass('ant-form-item-with-help')).toBeFalsy(); diff --git a/components/form/__tests__/list.test.js b/components/form/__tests__/list.test.js index a9643c6e982d..cab196449c99 100644 --- a/components/form/__tests__/list.test.js +++ b/components/form/__tests__/list.test.js @@ -1,10 +1,10 @@ import React from 'react'; import { act } from 'react-dom/test-utils'; -import { render, fireEvent } from '@testing-library/react'; +import { render as testingRender } from '@testing-library/react'; import Form from '..'; import Input from '../../input'; import Button from '../../button'; -import { sleep } from '../../../tests/utils'; +import { sleep, render, fireEvent } from '../../../tests/utils'; describe('Form.List', () => { async function change(wrapper, index, value) { @@ -16,7 +16,7 @@ describe('Form.List', () => { it(name, async () => { jest.useFakeTimers(); - const { container } = render( + const { container } = testingRender( {(fields, { add, remove }) => ( @@ -85,6 +85,7 @@ describe('Form.List', () => { )); + // FIXME: @zombieJ React 18 StrictMode testList('nest noStyle', field => ( diff --git a/components/grid/__tests__/gap.test.js b/components/grid/__tests__/gap.test.js index a61e3be74736..5a2b87abc02c 100644 --- a/components/grid/__tests__/gap.test.js +++ b/components/grid/__tests__/gap.test.js @@ -1,7 +1,7 @@ import React from 'react'; import ReactDOMServer from 'react-dom/server'; -import { render } from '@testing-library/react'; import { mount } from 'enzyme'; +import { render } from '../../../tests/utils'; import { Col, Row } from '..'; // eslint-disable-next-line no-unused-vars import * as styleChecker from '../../_util/styleChecker'; diff --git a/components/input/__tests__/focus.test.tsx b/components/input/__tests__/focus.test.tsx index 5637cabe80e0..ed72286b0aa0 100644 --- a/components/input/__tests__/focus.test.tsx +++ b/components/input/__tests__/focus.test.tsx @@ -3,6 +3,7 @@ import { mount } from 'enzyme'; import { spyElementPrototypes } from 'rc-util/lib/test/domHook'; import { InputRef } from '../Input'; import Input from '..'; +import { render, fireEvent } from '../../../tests/utils'; const { TextArea } = Input; @@ -58,12 +59,11 @@ describe('Input.Focus', () => { }); it('disabled should reset focus', () => { - const wrapper = mount(); - wrapper.find('input').simulate('focus'); - expect(wrapper.exists('.ant-input-affix-wrapper-focused')).toBeTruthy(); + const { rerender, container } = render(); + fireEvent.focus(container.querySelector('input')!); + expect(container.querySelector('.ant-input-affix-wrapper-focused')).toBeTruthy(); - wrapper.setProps({ disabled: true }); - wrapper.update(); - expect(wrapper.exists('.ant-input-affix-wrapper-focused')).toBeFalsy(); + rerender(); + expect(container.querySelector('.ant-input-affix-wrapper-focused')).toBeFalsy(); }); }); diff --git a/components/input/__tests__/index.test.tsx b/components/input/__tests__/index.test.tsx index 33fe8f78f115..602f7fac0d98 100644 --- a/components/input/__tests__/index.test.tsx +++ b/components/input/__tests__/index.test.tsx @@ -1,6 +1,6 @@ import React, { useState } from 'react'; import { mount } from 'enzyme'; -import { render, fireEvent } from '@testing-library/react'; +import { render, fireEvent } from '../../../tests/utils'; // eslint-disable-next-line import/no-unresolved import Form from '../../form'; import Input, { InputProps, InputRef } from '..'; diff --git a/components/input/__tests__/textarea.test.js b/components/input/__tests__/textarea.test.js index 5650d4f48b9b..5d314c7eb9b8 100644 --- a/components/input/__tests__/textarea.test.js +++ b/components/input/__tests__/textarea.test.js @@ -1,10 +1,9 @@ import React, { useState } from 'react'; import { mount } from 'enzyme'; -import { render } from '@testing-library/react'; import RcTextArea from 'rc-textarea'; import Input from '..'; import focusTest from '../../../tests/shared/focusTest'; -import { sleep } from '../../../tests/utils'; +import { sleep, render } from '../../../tests/utils'; const { TextArea } = Input; diff --git a/components/layout/__tests__/__snapshots__/index.test.js.snap b/components/layout/__tests__/__snapshots__/index.test.js.snap index 80c2074bd169..d9d432a065f3 100644 --- a/components/layout/__tests__/__snapshots__/index.test.js.snap +++ b/components/layout/__tests__/__snapshots__/index.test.js.snap @@ -37,47 +37,27 @@ exports[`Layout rtl render component should be rendered correctly in RTL directi `; exports[`Layout should be controlled by collapsed 1`] = ` - - `; exports[`Layout should be controlled by collapsed 2`] = ` - - - + Sider + + `; diff --git a/components/layout/__tests__/index.test.js b/components/layout/__tests__/index.test.js index ba35bc63780f..ffa4ddacadf7 100644 --- a/components/layout/__tests__/index.test.js +++ b/components/layout/__tests__/index.test.js @@ -176,10 +176,10 @@ describe('Layout', () => { it('should be controlled by collapsed', () => { const wrapper = mount(Sider); - expect(wrapper).toMatchSnapshot(); + expect(wrapper.render()).toMatchSnapshot(); wrapper.setProps({ collapsed: true }); wrapper.update(); - expect(wrapper).toMatchSnapshot(); + expect(wrapper.render()).toMatchSnapshot(); }); it('should not add ant-layout-has-sider when `hasSider` is `false`', () => { diff --git a/components/list/__tests__/Item.test.js b/components/list/__tests__/Item.test.js index 44c5fa10520b..0140430b39d9 100644 --- a/components/list/__tests__/Item.test.js +++ b/components/list/__tests__/Item.test.js @@ -1,5 +1,5 @@ import React from 'react'; -import { render, mount } from 'enzyme'; +import { mount } from 'enzyme'; import List from '..'; import ConfigProvider from '../../config-provider'; @@ -126,7 +126,7 @@ describe('List Item Layout', () => { /> , ); - expect(render(wrapper)).toMatchSnapshot(); + expect(wrapper.render()).toMatchSnapshot(); }); it('rowKey could be string', () => { diff --git a/components/locale-provider/__tests__/index.test.js b/components/locale-provider/__tests__/index.test.js index 0636cc072c2b..46a9b0236beb 100644 --- a/components/locale-provider/__tests__/index.test.js +++ b/components/locale-provider/__tests__/index.test.js @@ -257,27 +257,19 @@ describe('Locale Provider', () => { }); it('set moment locale when locale changes', () => { - class Test extends React.Component { - state = { - locale: zhCN, - }; + const Test = ({ locale }) => ( + + + + + + ); - render() { - const { locale } = this.state; - return ( - - - - - - ); - } - } - const wrapper = mount(); + const wrapper = mount(); expect(wrapper.render()).toMatchSnapshot(); - wrapper.setState({ locale: frFR }); + wrapper.setProps({ locale: frFR }); expect(wrapper.render()).toMatchSnapshot(); - wrapper.setState({ locale: null }); + wrapper.setProps({ locale: null }); expect(wrapper.render()).toMatchSnapshot(); }); }); diff --git a/components/menu/__tests__/index.test.js b/components/menu/__tests__/index.test.js index 526b0e33a4bb..934c5de7577e 100644 --- a/components/menu/__tests__/index.test.js +++ b/components/menu/__tests__/index.test.js @@ -7,13 +7,13 @@ import { PieChartOutlined, UserOutlined, } from '@ant-design/icons'; -import { render, fireEvent } from '@testing-library/react'; import { act } from 'react-dom/test-utils'; import Menu from '..'; import Layout from '../../layout'; import Tooltip from '../../tooltip'; import mountTest from '../../../tests/shared/mountTest'; import rtlTest from '../../../tests/shared/rtlTest'; +import { render, fireEvent } from '../../../tests/utils'; import collapseMotion from '../../_util/motion'; globalThis.IS_REACT_ACT_ENVIRONMENT = true; @@ -792,13 +792,23 @@ describe('Menu', () => { const onOpen = jest.fn(); const onClose = jest.fn(); render( - - - Option 1 - Option 2 - - menu2 - , + , ); expect(errorSpy.mock.calls.length).toBe(1); diff --git a/components/page-header/__tests__/index.test.js b/components/page-header/__tests__/index.test.js index 89649720a5d8..2bd63e32953d 100644 --- a/components/page-header/__tests__/index.test.js +++ b/components/page-header/__tests__/index.test.js @@ -1,5 +1,5 @@ import React from 'react'; -import { mount, render } from 'enzyme'; +import { mount } from 'enzyme'; import PageHeader from '..'; import Breadcrumb from '../../breadcrumb'; import ConfigProvider from '../../config-provider'; @@ -109,15 +109,13 @@ describe('PageHeader', () => { }); it('pageHeader should support className', () => { - const wrapper = render( - , - ); - expect(wrapper).toMatchSnapshot(); + const wrapper = mount(); + expect(wrapper.render()).toMatchSnapshot(); }); it('pageHeader should not render blank dom', () => { - const wrapper = render(); - expect(wrapper).toMatchSnapshot(); + const wrapper = mount(); + expect(wrapper.render()).toMatchSnapshot(); }); it('breadcrumbs and back icon can coexist', () => { @@ -149,7 +147,7 @@ describe('PageHeader', () => { , ); - expect(render(wrapper)).toMatchSnapshot(); + expect(wrapper.render()).toMatchSnapshot(); }); it('change container width', async () => { diff --git a/components/popconfirm/__tests__/index.test.js b/components/popconfirm/__tests__/index.test.js index 88ab9f45cc05..fb4df5519c2b 100644 --- a/components/popconfirm/__tests__/index.test.js +++ b/components/popconfirm/__tests__/index.test.js @@ -1,10 +1,9 @@ import React from 'react'; import { mount } from 'enzyme'; import { spyElementPrototype } from 'rc-util/lib/test/domHook'; -import { render, fireEvent } from '@testing-library/react'; import Popconfirm from '..'; import mountTest from '../../../tests/shared/mountTest'; -import { sleep } from '../../../tests/utils'; +import { sleep, render, fireEvent } from '../../../tests/utils'; import rtlTest from '../../../tests/shared/rtlTest'; import Button from '../../button'; diff --git a/components/popover/__tests__/index.test.js b/components/popover/__tests__/index.test.js index 93b597d23105..062e23489f64 100644 --- a/components/popover/__tests__/index.test.js +++ b/components/popover/__tests__/index.test.js @@ -1,6 +1,6 @@ import React from 'react'; import { mount } from 'enzyme'; -import { render } from '@testing-library/react'; +import { render } from '../../../tests/utils'; import Popover from '..'; import mountTest from '../../../tests/shared/mountTest'; import ConfigProvider from '../../config-provider'; diff --git a/components/result/__tests__/index.test.js b/components/result/__tests__/index.test.js index c39020666924..9a9bb46aca55 100644 --- a/components/result/__tests__/index.test.js +++ b/components/result/__tests__/index.test.js @@ -1,6 +1,6 @@ import React from 'react'; import { mount } from 'enzyme'; -import { render } from '@testing-library/react'; +import { render } from '../../../tests/utils'; import Result from '..'; import Button from '../../button'; import mountTest from '../../../tests/shared/mountTest'; diff --git a/components/segmented/__tests__/index.test.tsx b/components/segmented/__tests__/index.test.tsx index e14165c1c332..c89659def304 100644 --- a/components/segmented/__tests__/index.test.tsx +++ b/components/segmented/__tests__/index.test.tsx @@ -1,11 +1,10 @@ import React from 'react'; import { mount } from 'enzyme'; - import mountTest from '../../../tests/shared/mountTest'; import rtlTest from '../../../tests/shared/rtlTest'; - import Segmented from '../index'; import type { SegmentedValue } from '../index'; +import { render } from '../../../tests/utils'; // Make CSSMotion working without transition jest.mock('rc-motion/lib/util/motion', () => ({ @@ -221,7 +220,7 @@ describe('Segmented', () => { }); it('render segmented with className and other html attributes', () => { - const wrapper = mount( + const { container } = render( { />, ); - expect(wrapper.hasClass('mock-cls')).toBeTruthy(); - expect(wrapper.prop('data-test-id')).toBe('hello'); + expect(container.querySelector('.mock-cls')).toBeTruthy(); + expect(container.querySelector('[data-test-id]')).toHaveAttribute('data-test-id', 'hello'); }); it('render segmented with ref', () => { @@ -266,10 +265,10 @@ describe('Segmented', () => { const wrapper = mount(); wrapper.find('Segmented').find(`.${prefixCls}-item-input`).at(0).simulate('change'); - expect(wrapper.state().value).toBe('Map'); + expect(wrapper.find(Demo).state().value).toBe('Map'); wrapper.find('Segmented').find(`.${prefixCls}-item-input`).at(1).simulate('change'); - expect(wrapper.state().value).toBe('Transit'); + expect(wrapper.find(Demo).state().value).toBe('Transit'); }); it('render segmented with options null/undefined', () => { diff --git a/components/slider/__tests__/__snapshots__/index.test.js.snap b/components/slider/__tests__/__snapshots__/index.test.js.snap index 8b7c1eb1e711..7d8b571f5425 100644 --- a/components/slider/__tests__/__snapshots__/index.test.js.snap +++ b/components/slider/__tests__/__snapshots__/index.test.js.snap @@ -36,7 +36,7 @@ exports[`Slider should render in RTL direction 1`] = ` /> +Array [ + aria-disabled="false" + aria-valuemax="100" + aria-valuemin="0" + aria-valuenow="30" + class="ant-slider-handle ant-tooltip-open" + role="slider" + style="bottom: 30%; transform: translateY(50%);" + tabindex="0" + />, + - + + + + + 30 + + + , +] +`; + +exports[`Slider should show correct placement tooltip when set tooltipPlacement 2`] = ` +Array [ + , + + - 30 + + + + + 30 + - - + , +] `; -exports[`Slider should show correct placement tooltip when set tooltipPlacement 2`] = ``; - exports[`Slider should show tooltip when hovering slider handler 1`] = ` - +Array [ + aria-disabled="false" + aria-valuemax="100" + aria-valuemin="0" + aria-valuenow="30" + class="ant-slider-handle ant-tooltip-open" + role="slider" + style="left: 30%; transform: translateX(-50%);" + tabindex="0" + />, + - + + + + + 30 + + + , +] +`; + +exports[`Slider should show tooltip when hovering slider handler 2`] = ` +Array [ + , + + - 30 + + + + + 30 + - - + , +] `; - -exports[`Slider should show tooltip when hovering slider handler 2`] = ``; diff --git a/components/slider/__tests__/index.test.js b/components/slider/__tests__/index.test.js index 050d006aec1c..22c722c4d26f 100644 --- a/components/slider/__tests__/index.test.js +++ b/components/slider/__tests__/index.test.js @@ -1,5 +1,5 @@ import React from 'react'; -import { render, mount } from 'enzyme'; +import { mount } from 'enzyme'; import Slider from '..'; import ConfigProvider from '../../config-provider'; import mountTest from '../../../tests/shared/mountTest'; @@ -16,17 +16,17 @@ describe('Slider', () => { it('should show tooltip when hovering slider handler', () => { const wrapper = mount(); wrapper.find('.ant-slider-handle').at(0).simulate('mouseEnter'); - expect(render(wrapper.find('Trigger').instance().getComponent())).toMatchSnapshot(); + expect(wrapper.find('Trigger').render()).toMatchSnapshot(); wrapper.find('.ant-slider-handle').at(0).simulate('mouseLeave'); - expect(render(wrapper.find('Trigger').instance().getComponent())).toMatchSnapshot(); + expect(wrapper.find('Trigger').render()).toMatchSnapshot(); }); it('should show correct placement tooltip when set tooltipPlacement', () => { const wrapper = mount(); wrapper.find('.ant-slider-handle').at(0).simulate('mouseEnter'); - expect(render(wrapper.find('Trigger').instance().getComponent())).toMatchSnapshot(); + expect(wrapper.find('Trigger').render()).toMatchSnapshot(); wrapper.find('.ant-slider-handle').at(0).simulate('mouseLeave'); - expect(render(wrapper.find('Trigger').instance().getComponent())).toMatchSnapshot(); + expect(wrapper.find('Trigger').render()).toMatchSnapshot(); }); it('when tooltipVisible is true, tooltip should show always, or should never show', () => { @@ -84,7 +84,7 @@ describe('Slider', () => { , ); - expect(render(wrapper)).toMatchSnapshot(); + expect(wrapper.render()).toMatchSnapshot(); }); it('should keepAlign by calling forcePopupAlign', async () => { diff --git a/components/space/__tests__/__snapshots__/index.test.js.snap b/components/space/__tests__/__snapshots__/index.test.js.snap index 3ced7dfdd7c5..97918ea1eb74 100644 --- a/components/space/__tests__/__snapshots__/index.test.js.snap +++ b/components/space/__tests__/__snapshots__/index.test.js.snap @@ -8,13 +8,13 @@ exports[`Space should render correct with children 1`] = ` > text1 text1 @@ -35,7 +35,7 @@ Array [ > 1 @@ -54,7 +54,7 @@ Array [ > 1 @@ -73,7 +73,7 @@ Array [ > 1 @@ -97,7 +97,7 @@ Array [ > 1 @@ -116,7 +116,7 @@ Array [ > 1 @@ -135,7 +135,7 @@ Array [ > 1 @@ -158,19 +158,19 @@ exports[`Space split 1`] = ` > text1 - text1 @@ -178,7 +178,7 @@ exports[`Space split 1`] = ` - diff --git a/components/space/__tests__/index.test.js b/components/space/__tests__/index.test.js index 4214d4044ada..ecb19ff0bb83 100644 --- a/components/space/__tests__/index.test.js +++ b/components/space/__tests__/index.test.js @@ -1,5 +1,5 @@ import React, { useState } from 'react'; -import { render, mount } from 'enzyme'; +import { mount } from 'enzyme'; import { act } from 'react-dom/test-utils'; import Space from '..'; import ConfigProvider from '../../config-provider'; @@ -34,7 +34,7 @@ describe('Space', () => { , ); - expect(render(wrapper)).toMatchSnapshot(); + expect(wrapper.render()).toMatchSnapshot(); }); it('should render width rtl', () => { @@ -55,7 +55,7 @@ describe('Space', () => { , ); - expect(render(wrapper)).toMatchSnapshot(); + expect(wrapper.render()).toMatchSnapshot(); }); it('should render width customize size', () => { @@ -102,7 +102,7 @@ describe('Space', () => { , ); - expect(render(wrapper)).toMatchSnapshot(); + expect(wrapper.render()).toMatchSnapshot(); }); it('should render with invalidElement', () => { @@ -170,6 +170,6 @@ describe('Space', () => { , ); - expect(render(wrapper)).toMatchSnapshot(); + expect(wrapper.render()).toMatchSnapshot(); }); }); diff --git a/components/spin/__tests__/delay.test.js b/components/spin/__tests__/delay.test.js index fbee446e7c18..beeb347534c1 100644 --- a/components/spin/__tests__/delay.test.js +++ b/components/spin/__tests__/delay.test.js @@ -24,8 +24,8 @@ describe('delay spinning', () => { it('should cancel debounce function when unmount', async () => { const wrapper = mount(); - const spy = jest.spyOn(wrapper.instance().updateSpinning, 'cancel'); - expect(wrapper.instance().updateSpinning.cancel).toEqual(expect.any(Function)); + const spy = jest.spyOn(wrapper.find(Spin).instance().updateSpinning, 'cancel'); + expect(wrapper.find(Spin).instance().updateSpinning.cancel).toEqual(expect.any(Function)); expect(spy).not.toHaveBeenCalled(); wrapper.unmount(); expect(spy).toHaveBeenCalled(); diff --git a/components/spin/__tests__/index.test.js b/components/spin/__tests__/index.test.js index 3cb6b8b99b71..64ca76d7a7c0 100644 --- a/components/spin/__tests__/index.test.js +++ b/components/spin/__tests__/index.test.js @@ -1,8 +1,9 @@ import React from 'react'; -import { render, mount } from 'enzyme'; +import { mount } from 'enzyme'; import Spin from '..'; import mountTest from '../../../tests/shared/mountTest'; import rtlTest from '../../../tests/shared/rtlTest'; +import { render } from '../../../tests/utils'; describe('Spin', () => { mountTest(Spin); @@ -20,15 +21,15 @@ describe('Spin', () => { it("should render custom indicator when it's set", () => { const customIndicator = ; - const wrapper = render(); - expect(wrapper).toMatchSnapshot(); + const wrapper = mount(); + expect(wrapper.render()).toMatchSnapshot(); }); it('should be controlled by spinning', () => { - const wrapper = mount(); - expect(wrapper.instance().state.spinning).toBe(false); - wrapper.setProps({ spinning: true }); - expect(wrapper.instance().state.spinning).toBe(true); + const { container, rerender } = render(); + expect(container.querySelector('.ant-spin')).not.toHaveClass('ant-spin-spinning'); + rerender(); + expect(container.querySelector('.ant-spin')).toHaveClass('ant-spin-spinning'); }); it('if indicator set null should not be render default indicator', () => { diff --git a/components/statistic/__tests__/index.test.js b/components/statistic/__tests__/index.test.js index ecf2691ad269..109df17ab2f8 100644 --- a/components/statistic/__tests__/index.test.js +++ b/components/statistic/__tests__/index.test.js @@ -85,7 +85,7 @@ describe('Statistic', () => { wrapper.update(); // setInterval should work - const instance = wrapper.instance(); + const instance = wrapper.find('Countdown').instance(); expect(instance.countdownId).not.toBe(undefined); await sleep(10); @@ -142,8 +142,7 @@ describe('Statistic', () => { const wrapper = mount(); wrapper.update(); - const instance = wrapper.instance(); - expect(instance.countdownId).toBe(undefined); + expect(wrapper.find('Countdown').instance().countdownId).toBe(undefined); expect(onFinish).not.toHaveBeenCalled(); }); diff --git a/components/table/__tests__/Table.filter.test.js b/components/table/__tests__/Table.filter.test.js index 78dcebd8d666..23fc1f97cee3 100644 --- a/components/table/__tests__/Table.filter.test.js +++ b/components/table/__tests__/Table.filter.test.js @@ -2,7 +2,7 @@ import React from 'react'; import { mount } from 'enzyme'; import { act } from 'react-dom/test-utils'; -import { render, fireEvent } from '@testing-library/react'; +import { render, fireEvent } from '../../../tests/utils'; import Table from '..'; import Input from '../../input'; import Tooltip from '../../tooltip'; diff --git a/components/table/__tests__/Table.rowSelection.test.js b/components/table/__tests__/Table.rowSelection.test.js index efbf14b1eef4..3d90c0d14635 100644 --- a/components/table/__tests__/Table.rowSelection.test.js +++ b/components/table/__tests__/Table.rowSelection.test.js @@ -1,10 +1,11 @@ import React from 'react'; import { act } from 'react-dom/test-utils'; -import { mount, render } from 'enzyme'; +import { mount } from 'enzyme'; import Table from '..'; import Checkbox from '../../checkbox'; import { resetWarned } from '../../_util/devWarning'; import ConfigProvider from '../../config-provider'; +import { render } from '../../../tests/utils'; describe('Table.rowSelection', () => { window.requestAnimationFrame = callback => window.setTimeout(callback, 16); @@ -334,8 +335,8 @@ describe('Table.rowSelection', () => { selections: true, }; const wrapper = mount(createTable({ rowSelection })); - const dropdownWrapper = render(wrapper.find('Trigger').instance().getComponent()); - expect(dropdownWrapper).toMatchSnapshot(); + const dropdownWrapper = mount(wrapper.find('Trigger').instance().getComponent()); + expect(dropdownWrapper.render()).toMatchSnapshot(); }); it('fires selectInvert event', () => { @@ -569,32 +570,32 @@ describe('Table.rowSelection', () => { // https://github.com/ant-design/ant-design/issues/4245 it('should allow dynamic getCheckboxProps', () => { - class App extends React.Component { - state = { - disableName: 'Jack', - }; + const { container, rerender } = render( + ({ disabled: record.name === 'Jack' }), + }} + />, + ); - render() { - const { disableName } = this.state; - return ( - ({ disabled: record.name === disableName }), - }} - /> - ); - } - } - const wrapper = mount(); - let checkboxs = wrapper.find('input'); - expect(checkboxs.at(1).props().disabled).toBe(true); - expect(checkboxs.at(2).props().disabled).toBe(false); - wrapper.setState({ disableName: 'Lucy' }); - checkboxs = wrapper.find('input'); - expect(checkboxs.at(1).props().disabled).toBe(false); - expect(checkboxs.at(2).props().disabled).toBe(true); + let checkboxList = container.querySelectorAll('input'); + expect(checkboxList[1]).toHaveAttribute('disabled'); + expect(checkboxList[2]).not.toHaveAttribute('disabled'); + + rerender( + ({ disabled: record.name === 'Lucy' }), + }} + />, + ); + checkboxList = container.querySelectorAll('input'); + expect(checkboxList[1]).not.toHaveAttribute('disabled'); + expect(checkboxList[2]).toHaveAttribute('disabled'); }); // https://github.com/ant-design/ant-design/issues/4779 @@ -643,18 +644,18 @@ describe('Table.rowSelection', () => { }); it('fix selection column on the left', () => { - const wrapper = render( + const wrapper = mount( createTable({ rowSelection: { fixed: true }, scroll: { x: 903 }, }), ); - expect(wrapper).toMatchSnapshot(); + expect(wrapper.render()).toMatchSnapshot(); }); it('fix expand on th left when selection column fixed on the left', () => { - const wrapper = render( + const wrapper = mount( createTable({ expandable: { expandedRowRender() { @@ -666,11 +667,11 @@ describe('Table.rowSelection', () => { }), ); - expect(wrapper).toMatchSnapshot(); + expect(wrapper.render()).toMatchSnapshot(); }); it('fix selection column on the left when any other column is fixed', () => { - const wrapper = render( + const wrapper = mount( createTable({ rowSelection: {}, columns: [ @@ -684,11 +685,11 @@ describe('Table.rowSelection', () => { }), ); - expect(wrapper).toMatchSnapshot(); + expect(wrapper.render()).toMatchSnapshot(); }); it('use column as selection column when key is `selection-column`', () => { - const wrapper = render( + const wrapper = mount( createTable({ rowSelection: {}, columns: [ @@ -701,7 +702,7 @@ describe('Table.rowSelection', () => { }), ); - expect(wrapper).toMatchSnapshot(); + expect(wrapper.render()).toMatchSnapshot(); }); // https://github.com/ant-design/ant-design/issues/10629 diff --git a/components/table/__tests__/Table.test.js b/components/table/__tests__/Table.test.js index 951e1d57ef9a..789fd99210e9 100644 --- a/components/table/__tests__/Table.test.js +++ b/components/table/__tests__/Table.test.js @@ -1,10 +1,9 @@ import React from 'react'; import { mount } from 'enzyme'; -import { render } from '@testing-library/react'; import Table from '..'; import mountTest from '../../../tests/shared/mountTest'; import rtlTest from '../../../tests/shared/rtlTest'; -import { sleep } from '../../../tests/utils'; +import { sleep, render } from '../../../tests/utils'; const { Column, ColumnGroup } = Table; diff --git a/components/table/__tests__/__snapshots__/Table.rowSelection.test.js.snap b/components/table/__tests__/__snapshots__/Table.rowSelection.test.js.snap index 3f2d0f85c9c9..c301ce4063ba 100644 --- a/components/table/__tests__/__snapshots__/Table.rowSelection.test.js.snap +++ b/components/table/__tests__/__snapshots__/Table.rowSelection.test.js.snap @@ -18,10 +18,10 @@ exports[`Table.rowSelection fix expand on th left when selection column fixed on > @@ -112,7 +113,7 @@ exports[`Table.rowSelection fix expand on th left when selection column fixed on > @@ -452,7 +458,7 @@ exports[`Table.rowSelection fix selection column on the left 1`] = ` > Name @@ -726,22 +737,22 @@ exports[`Table.rowSelection fix selection column on the left when any other colu @@ -753,7 +764,7 @@ exports[`Table.rowSelection fix selection column on the left when any other colu > Jack @@ -784,7 +796,7 @@ exports[`Table.rowSelection fix selection column on the left when any other colu > Lucy @@ -815,7 +828,7 @@ exports[`Table.rowSelection fix selection column on the left when any other colu > Tom @@ -846,7 +860,7 @@ exports[`Table.rowSelection fix selection column on the left when any other colu > Jerry @@ -1701,7 +1716,7 @@ exports[`Table.rowSelection use column as selection column when key is \`selecti class="ant-table-content" > { diff --git a/components/transfer/__tests__/list.test.js b/components/transfer/__tests__/list.test.js index 367806fed3e2..a3433d2ea5cb 100644 --- a/components/transfer/__tests__/list.test.js +++ b/components/transfer/__tests__/list.test.js @@ -38,7 +38,7 @@ describe('Transfer.List', () => { it('when component has been unmounted, componentWillUnmount should be called', () => { const wrapper = mount(); - const willUnmount = jest.spyOn(wrapper.instance(), 'componentWillUnmount'); + const willUnmount = jest.spyOn(wrapper.find(List).instance(), 'componentWillUnmount'); wrapper.unmount(); expect(willUnmount).toHaveBeenCalled(); }); @@ -46,7 +46,7 @@ describe('Transfer.List', () => { it('when value is not exists, handleFilter should return', () => { const handleFilter = jest.fn(); const wrapper = mount(); - expect(wrapper.instance().handleFilter({ target: 'test' })).toBe(undefined); + expect(wrapper.find(List).instance().handleFilter({ target: 'test' })).toBe(undefined); expect(handleFilter).toHaveBeenCalled(); }); }); diff --git a/components/transfer/__tests__/search.test.js b/components/transfer/__tests__/search.test.js index 70a858e539e7..128502cd8e3f 100644 --- a/components/transfer/__tests__/search.test.js +++ b/components/transfer/__tests__/search.test.js @@ -1,6 +1,7 @@ import React from 'react'; import { mount } from 'enzyme'; -import { render, fireEvent } from '@testing-library/react'; +import { render as testLibRender } from '@testing-library/react'; +import { render, fireEvent } from '../../../tests/utils'; import Search from '../search'; import Transfer from '../index'; @@ -81,13 +82,18 @@ describe('Transfer.Search', () => { // https://github.com/ant-design/ant-design/issues/26208 it('typing space should trigger filterOption', () => { const filterOption = jest.fn(); - const wrapper = mount( + + // We use origin testing lib here since StrictMode will render multiple times + const { container } = testLibRender( , ); - wrapper - .find('.ant-input') - .at(0) - .simulate('change', { target: { value: ' ' } }); + + fireEvent.change(container.querySelector('.ant-input'), { + target: { + value: ' ', + }, + }); + expect(filterOption).toHaveBeenCalledTimes(dataSource.length); }); }); diff --git a/components/tree/__tests__/dropIndicator.test.tsx b/components/tree/__tests__/dropIndicator.test.tsx index 9aba04eb2926..6d7fdaac9365 100644 --- a/components/tree/__tests__/dropIndicator.test.tsx +++ b/components/tree/__tests__/dropIndicator.test.tsx @@ -11,7 +11,7 @@ describe('dropIndicatorRender', () => { direction: 'ltr', }); const wrapper = mount(indicator); - expect(wrapper.props().style.bottom).toEqual(-3); + expect(wrapper.find('div').props().style!.bottom).toEqual(-3); }); it('work with dropPosition inner (-0)', () => { const indicator = dropIndicatorRender({ @@ -22,8 +22,8 @@ describe('dropIndicatorRender', () => { direction: 'ltr', }); const wrapper = mount(indicator); - expect(wrapper.props().style.bottom).toEqual(-3); - expect(wrapper.props().style.left).toEqual(24 + offset); + expect(wrapper.find('div').props().style!.bottom).toEqual(-3); + expect(wrapper.find('div').props().style!.left).toEqual(24 + offset); }); it('work with dropPosition after (-1)', () => { const indicator = dropIndicatorRender({ @@ -34,7 +34,7 @@ describe('dropIndicatorRender', () => { direction: 'ltr', }); const wrapper = mount(indicator); - expect(wrapper.props().style.top).toEqual(-3); + expect(wrapper.find('div').props().style!.top).toEqual(-3); }); it('work with drop level', () => { const indicator = dropIndicatorRender({ @@ -45,7 +45,7 @@ describe('dropIndicatorRender', () => { direction: 'ltr', }); const wrapper = mount(indicator); - expect(wrapper.props().style.left).toEqual(-2 * 24 + offset); + expect(wrapper.find('div').props().style!.left).toEqual(-2 * 24 + offset); }); it('work with drop level (rtl)', () => { const indicator = dropIndicatorRender({ @@ -56,6 +56,6 @@ describe('dropIndicatorRender', () => { direction: 'rtl', }); const wrapper = mount(indicator); - expect(wrapper.props().style.right).toEqual(-2 * 24 + offset); + expect(wrapper.find('div').props().style!.right).toEqual(-2 * 24 + offset); }); }); diff --git a/components/typography/__tests__/index.test.js b/components/typography/__tests__/index.test.js index 83cf09584f5d..78cffbfd702f 100644 --- a/components/typography/__tests__/index.test.js +++ b/components/typography/__tests__/index.test.js @@ -1,6 +1,5 @@ import React from 'react'; import { mount } from 'enzyme'; -import { render } from '@testing-library/react'; import { SmileOutlined, LikeOutlined, HighlightOutlined, CheckOutlined } from '@ant-design/icons'; import KeyCode from 'rc-util/lib/KeyCode'; import { resetWarned } from 'rc-util/lib/warning'; @@ -14,7 +13,7 @@ import Base from '../Base'; import mountTest from '../../../tests/shared/mountTest'; import rtlTest from '../../../tests/shared/rtlTest'; import Typography from '../Typography'; -import { sleep } from '../../../tests/utils'; +import { sleep, render } from '../../../tests/utils'; jest.mock('copy-to-clipboard'); diff --git a/components/upload/__tests__/upload.test.js b/components/upload/__tests__/upload.test.js index cecfc2cc4461..8fc8526a6aa4 100644 --- a/components/upload/__tests__/upload.test.js +++ b/components/upload/__tests__/upload.test.js @@ -1,7 +1,6 @@ /* eslint-disable react/no-string-refs, react/prefer-es6-class */ import React from 'react'; -import { mount } from 'enzyme'; -import { render, fireEvent } from '@testing-library/react'; +import { mount, originMount } from 'enzyme'; import { act } from 'react-dom/test-utils'; import produce from 'immer'; import { cloneDeep } from 'lodash'; @@ -12,7 +11,7 @@ import { setup, teardown } from './mock'; import { resetWarned } from '../../_util/devWarning'; import mountTest from '../../../tests/shared/mountTest'; import rtlTest from '../../../tests/shared/rtlTest'; -import { sleep } from '../../../tests/utils'; +import { sleep, render, fireEvent } from '../../../tests/utils'; globalThis.IS_REACT_ACT_ENVIRONMENT = true; @@ -203,15 +202,16 @@ describe('Upload', () => { // https://github.com/ant-design/ant-design/issues/14779 it('should contain input file control if upload button is hidden', () => { - const wrapper = mount( + const { container, rerender } = render( upload , ); - expect(wrapper.find('input[type="file"]').length).toBe(1); - wrapper.setProps({ children: null }); - expect(wrapper.find('input[type="file"]').length).toBe(1); + expect(container.querySelectorAll('input[type="file"]')).toHaveLength(1); + + rerender(); + expect(container.querySelectorAll('input[type="file"]')).toHaveLength(1); }); // https://github.com/ant-design/ant-design/issues/14298 @@ -224,15 +224,15 @@ describe('Upload', () => { ); - const wrapper = mount( + const { container, rerender } = render( upload , ); - expect(wrapper.find('input#upload').length).toBe(1); - wrapper.setProps({ children: null }); - expect(wrapper.find('input#upload').length).toBe(0); + expect(container.querySelector('input#upload')).toBeTruthy(); + rerender(); + expect(container.querySelector('input#upload')).toBeFalsy(); }); // https://github.com/ant-design/ant-design/issues/16478 @@ -874,9 +874,10 @@ describe('Upload', () => { expect(onChange.mock.calls[0][0].fileList).toHaveLength(1); }); + // FIXME: @zombieJ React 18 StrictMode // https://github.com/ant-design/ant-design/issues/33819 it('should show the animation of the upload children leaving when the upload children becomes null', async () => { - const wrapper = mount( + const wrapper = originMount( upload , diff --git a/components/upload/__tests__/uploadlist.test.js b/components/upload/__tests__/uploadlist.test.js index f823ffcfcc2c..1e9957fd9eb2 100644 --- a/components/upload/__tests__/uploadlist.test.js +++ b/components/upload/__tests__/uploadlist.test.js @@ -752,7 +752,7 @@ describe('Upload List', () => { const wrapper = mount( , ); - expect(wrapper.props().previewFile(file)).toBeTruthy(); + expect(wrapper.find(UploadList).props().previewFile(file)).toBeTruthy(); wrapper.unmount(); }); @@ -771,7 +771,7 @@ describe('Upload List', () => { ); // Not throw - wrapper.props().onDownload(file); + wrapper.find(UploadList).props().onDownload(file); wrapper.unmount(); }); @@ -845,6 +845,7 @@ describe('Upload List', () => { , ); await wrapper + .find(UploadList) .props() .previewFile(mockFile) .then(dataUrl => { @@ -863,6 +864,7 @@ describe('Upload List', () => { , ); await wrapper + .find(UploadList) .props() .previewFile(mockFile) .then(dataUrl => { diff --git a/docs/spec/overview.zh-CN.md b/docs/spec/overview.zh-CN.md index 45a8f761f608..475c29886790 100644 --- a/docs/spec/overview.zh-CN.md +++ b/docs/spec/overview.zh-CN.md @@ -21,8 +21,8 @@ title: 概览 - 功能示例:由多个模板组成,以启发用户如何使用和构建一个通用功能。 - 模板:一个页面级示例,启发用户如何在系统中构建典型页面,例如详细信息页面。 - 组件 - - 基本组件:系统的最基本元素,例如按钮和分页器。 - - 业务组件/模块:块级示例,通常由多个组件组成,例如 PageHeader 通用标题。 + - 基本组件:系统的最基本元素,例如按钮和分页器。 + - 业务组件/模块:块级示例,通常由多个组件组成,例如 PageHeader 通用标题。 - 一般概念:保证 ETC 系统化的一些约定,例如排版、字体和文案。 ## 资源 diff --git a/tests/setup.js b/tests/setup.js index 0e5240350694..28c0ac9e0cdb 100644 --- a/tests/setup.js +++ b/tests/setup.js @@ -32,8 +32,8 @@ if (typeof window !== 'undefined') { // Fix css-animation or rc-motion deps on these // https://github.com/react-component/motion/blob/9c04ef1a210a4f3246c9becba6e33ea945e00669/src/util/motion.ts#L27-L35 // https://github.com/yiminghe/css-animation/blob/a5986d73fd7dfce75665337f39b91483d63a4c8c/src/Event.js#L44 - window.AnimationEvent = window.AnimationEvent || (() => {}); - window.TransitionEvent = window.TransitionEvent || (() => {}); + window.AnimationEvent = window.AnimationEvent || window.Event; + window.TransitionEvent = window.TransitionEvent || window.Event; } const Enzyme = require('enzyme'); @@ -60,3 +60,28 @@ Object.assign(Enzyme.ReactWrapper.prototype, { target.getBoundingClientRect = originGetBoundingClientRect; }, }); + +// React.StrictMode wrapper +jest.mock('enzyme', () => { + const enzyme = jest.requireActual('enzyme'); + const { StrictMode, cloneElement } = jest.requireActual('react'); + const { mount, render } = enzyme; + + function EnzymeWrapper({ strictMode, children, ...props }) { + // Not wrap StrictMode for some test case need count render times + if (strictMode === false) { + return cloneElement(children, props); + } + + return {cloneElement(children, props)}; + } + + return { + ...enzyme, + mount: (ui, { strictMode, ...config } = {}, ...args) => + mount({ui}, config, ...args), + render: (ui, { strictMode, ...config } = {}, ...args) => + render({ui}, config, ...args), + originMount: mount, + }; +}); diff --git a/tests/shared/focusTest.tsx b/tests/shared/focusTest.tsx index 0cd9be14d712..12d963273e41 100644 --- a/tests/shared/focusTest.tsx +++ b/tests/shared/focusTest.tsx @@ -1,7 +1,6 @@ import React from 'react'; -import { render } from '@testing-library/react'; import { mount, ReactWrapper } from 'enzyme'; -import { sleep } from '../utils'; +import { sleep, render } from '../utils'; // eslint-disable-next-line jest/no-export export default function focusTest( diff --git a/tests/utils.ts b/tests/utils.ts index 339c48fc3bd6..f556ba2145f3 100644 --- a/tests/utils.ts +++ b/tests/utils.ts @@ -1,5 +1,7 @@ import MockDate from 'mockdate'; +import { StrictMode, ReactElement } from 'react'; import { act } from 'react-dom/test-utils'; +import { render, RenderOptions } from '@testing-library/react'; export function setMockDate(dateString = '2017-09-18T03:30:07.795') { MockDate.set(dateString); @@ -18,3 +20,10 @@ export const sleep = async (timeout = 0) => { }); }); }; + +const customRender = (ui: ReactElement, options?: Omit) => + render(ui, { wrapper: StrictMode, ...options }); + +export { customRender as render }; + +export * from '@testing-library/react';
Card content