diff --git a/components/avatar/__tests__/Avatar.test.js b/components/avatar/__tests__/Avatar.test.js index 1826e2e980..6526db952d 100644 --- a/components/avatar/__tests__/Avatar.test.js +++ b/components/avatar/__tests__/Avatar.test.js @@ -3,7 +3,6 @@ import ReactDOM from 'react-dom'; import { act } from 'react-dom/test-utils'; import { mount } from 'enzyme'; import { render } from '@testing-library/react'; -import '@testing-library/jest-dom'; import Avatar from '..'; import mountTest from '../../../tests/shared/mountTest'; import rtlTest from '../../../tests/shared/rtlTest'; diff --git a/components/breadcrumb/__tests__/Breadcrumb.test.js b/components/breadcrumb/__tests__/Breadcrumb.test.js index bae5f3bfd7..d9988d2489 100644 --- a/components/breadcrumb/__tests__/Breadcrumb.test.js +++ b/components/breadcrumb/__tests__/Breadcrumb.test.js @@ -1,7 +1,6 @@ import React from 'react'; import { mount } from 'enzyme'; import { render } from '@testing-library/react'; -import '@testing-library/jest-dom'; import Breadcrumb from '../index'; import mountTest from '../../../tests/shared/mountTest'; import rtlTest from '../../../tests/shared/rtlTest'; diff --git a/components/button/__tests__/index.test.tsx b/components/button/__tests__/index.test.tsx index f34dcaf2f3..19d53bcb13 100644 --- a/components/button/__tests__/index.test.tsx +++ b/components/button/__tests__/index.test.tsx @@ -1,7 +1,6 @@ import React, { Component } from 'react'; import { mount } from 'enzyme'; import { render } from '@testing-library/react'; -import '@testing-library/jest-dom'; import { act } from 'react-dom/test-utils'; import { SearchOutlined } from '@ant-design/icons'; import { resetWarned } from 'rc-util/lib/warning'; diff --git a/components/config-provider/__tests__/form.test.js b/components/config-provider/__tests__/form.test.js index f48333ba8d..d890e6a552 100644 --- a/components/config-provider/__tests__/form.test.js +++ b/components/config-provider/__tests__/form.test.js @@ -1,7 +1,6 @@ import React from 'react'; import { mount } from 'enzyme'; import { render } from '@testing-library/react'; -import '@testing-library/jest-dom'; import { act } from 'react-dom/test-utils'; import ConfigProvider from '..'; import zhCN from '../../locale/zh_CN'; diff --git a/components/drawer/__tests__/Drawer.test.js b/components/drawer/__tests__/Drawer.test.js index f17a8fe42d..8d23fe6dbc 100644 --- a/components/drawer/__tests__/Drawer.test.js +++ b/components/drawer/__tests__/Drawer.test.js @@ -1,7 +1,6 @@ import React from 'react'; import { mount } from 'enzyme'; import { render } from '@testing-library/react'; -import '@testing-library/jest-dom'; import Drawer from '..'; import ConfigProvider from '../../config-provider'; import mountTest from '../../../tests/shared/mountTest'; diff --git a/components/form/__tests__/index.test.js b/components/form/__tests__/index.test.js index 1aaa52097e..c5342131d4 100644 --- a/components/form/__tests__/index.test.js +++ b/components/form/__tests__/index.test.js @@ -1,7 +1,6 @@ import React, { Component, useState } from 'react'; import { mount } from 'enzyme'; import { render, fireEvent } from '@testing-library/react'; -import '@testing-library/jest-dom'; import { act } from 'react-dom/test-utils'; import scrollIntoView from 'scroll-into-view-if-needed'; import Form from '..'; diff --git a/components/form/__tests__/list.test.js b/components/form/__tests__/list.test.js index b7b1881c86..00a1fc408f 100644 --- a/components/form/__tests__/list.test.js +++ b/components/form/__tests__/list.test.js @@ -2,7 +2,6 @@ import React from 'react'; import { mount } from 'enzyme'; import { act } from 'react-dom/test-utils'; import { render, fireEvent } from '@testing-library/react'; -import '@testing-library/jest-dom'; import Form from '..'; import Input from '../../input'; import Button from '../../button'; diff --git a/components/grid/__tests__/gap.test.js b/components/grid/__tests__/gap.test.js index cb955d9b4f..a61e3be747 100644 --- a/components/grid/__tests__/gap.test.js +++ b/components/grid/__tests__/gap.test.js @@ -1,7 +1,6 @@ import React from 'react'; import ReactDOMServer from 'react-dom/server'; import { render } from '@testing-library/react'; -import '@testing-library/jest-dom'; import { mount } from 'enzyme'; import { Col, Row } from '..'; // eslint-disable-next-line no-unused-vars diff --git a/components/input/__tests__/index.test.tsx b/components/input/__tests__/index.test.tsx index 164c711eba..844f807f9c 100644 --- a/components/input/__tests__/index.test.tsx +++ b/components/input/__tests__/index.test.tsx @@ -1,7 +1,6 @@ import React, { useState } from 'react'; import { mount } from 'enzyme'; import { render, fireEvent } from '@testing-library/react'; -import '@testing-library/jest-dom'; // 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 2b8701ff94..7d36cea02a 100644 --- a/components/input/__tests__/textarea.test.js +++ b/components/input/__tests__/textarea.test.js @@ -1,7 +1,6 @@ import React, { useState } from 'react'; import { mount } from 'enzyme'; import { render } from '@testing-library/react'; -import '@testing-library/jest-dom'; import RcTextArea from 'rc-textarea'; import Input from '..'; import focusTest from '../../../tests/shared/focusTest'; diff --git a/components/menu/__tests__/index.test.js b/components/menu/__tests__/index.test.js index ca49d1f5cc..526b0e33a4 100644 --- a/components/menu/__tests__/index.test.js +++ b/components/menu/__tests__/index.test.js @@ -8,7 +8,6 @@ import { UserOutlined, } from '@ant-design/icons'; import { render, fireEvent } from '@testing-library/react'; -import '@testing-library/jest-dom'; import { act } from 'react-dom/test-utils'; import Menu from '..'; import Layout from '../../layout'; diff --git a/components/message/__tests__/config.test.js b/components/message/__tests__/config.test.js index a3e4c0c401..2e7815f534 100644 --- a/components/message/__tests__/config.test.js +++ b/components/message/__tests__/config.test.js @@ -1,3 +1,4 @@ +import { act } from 'react-dom/test-utils'; import { sleep } from '../../../tests/utils'; import message, { getInstance } from '..'; import ConfigProvider from '../../config-provider'; @@ -11,18 +12,26 @@ describe('message.config', () => { beforeEach(() => { jest.useFakeTimers(); + jest.clearAllTimers(); }); afterEach(() => { - message.destroy(); jest.useRealTimers(); + + act(() => { + message.destroy(); + }); }); it('should be able to config top', () => { message.config({ top: 100, }); - message.info('whatever'); + + act(() => { + message.info('whatever'); + }); + expect(document.querySelectorAll('.ant-message')[0].style.top).toBe('100px'); }); @@ -30,7 +39,11 @@ describe('message.config', () => { message.config({ rtl: true, }); - message.info('whatever'); + + act(() => { + message.info('whatever'); + }); + expect(document.querySelectorAll('.ant-message-rtl').length).toBe(1); }); @@ -43,7 +56,10 @@ describe('message.config', () => { return div; }, }); - message.info('whatever'); + + act(() => { + message.info('whatever'); + }); expect(document.querySelectorAll('.custom-container').length).toBe(1); }); @@ -52,13 +68,21 @@ describe('message.config', () => { maxCount: 5, }); for (let i = 0; i < 10; i += 1) { - message.info('test'); + act(() => { + message.info('test'); + }); } - message.info('last'); + act(() => { + message.info('last'); + }); + expect(document.querySelectorAll('.ant-message-notice').length).toBe(5); expect(document.querySelectorAll('.ant-message-notice')[4].textContent).toBe('last'); - jest.runAllTimers(); + + act(() => { + jest.runAllTimers(); + }); expect(getInstance().component.state.notices).toHaveLength(0); }); @@ -67,7 +91,10 @@ describe('message.config', () => { message.config({ duration: 0.5, }); - message.info('last'); + + act(() => { + message.info('last'); + }); expect(getInstance().component.state.notices).toHaveLength(1); await sleep(1000); @@ -82,7 +109,9 @@ describe('message.config', () => { prefixCls: 'light-message', }); - message.info('bamboo'); + act(() => { + message.info('bamboo'); + }); expect(getInstance().config).toEqual( expect.objectContaining({ @@ -97,7 +126,11 @@ describe('message.config', () => { it('should be able to global config rootPrefixCls', () => { ConfigProvider.config({ prefixCls: 'prefix-test', iconPrefixCls: 'bamboo' }); - message.info('last'); + + act(() => { + message.info('last'); + }); + expect(document.querySelectorAll('.ant-message-notice')).toHaveLength(0); expect(document.querySelectorAll('.prefix-test-message-notice')).toHaveLength(1); expect(document.querySelectorAll('.bamboo-info-circle')).toHaveLength(1); @@ -107,7 +140,11 @@ describe('message.config', () => { message.config({ prefixCls: 'prefix-test', }); - message.info('last'); + + act(() => { + message.info('last'); + }); + expect(document.querySelectorAll('.ant-message-notice')).toHaveLength(0); expect(document.querySelectorAll('.prefix-test-notice')).toHaveLength(1); message.config({ @@ -119,7 +156,11 @@ describe('message.config', () => { message.config({ transitionName: '', }); - message.info('last'); + + act(() => { + message.info('last'); + }); + expect(document.querySelectorAll('.ant-move-up-enter')).toHaveLength(0); message.config({ transitionName: 'ant-move-up', @@ -145,13 +186,20 @@ describe('message.config', () => { getContainer: () => container1, }); const messageText1 = 'mounted in container1'; - message.info(messageText1); + + act(() => { + message.info(messageText1); + }); + expect(container1.querySelector('.ant-message-notice').textContent).toEqual(messageText1); message.config({ getContainer: () => container2, }); const messageText2 = 'mounted in container2'; - message.info(messageText2); + + act(() => { + message.info(messageText2); + }); expect(container2.querySelector('.ant-message-notice').textContent).toEqual(messageText2); removeContainer1(); removeContainer2(); diff --git a/components/message/__tests__/hooks.test.js b/components/message/__tests__/hooks.test.js index 3b656ec6eb..8fd11a6862 100644 --- a/components/message/__tests__/hooks.test.js +++ b/components/message/__tests__/hooks.test.js @@ -1,6 +1,7 @@ /* eslint-disable jsx-a11y/control-has-associated-label */ import React from 'react'; import { mount } from 'enzyme'; +import { act } from 'react-dom/test-utils'; import message, { getInstance } from '..'; import ConfigProvider from '../../config-provider'; @@ -167,10 +168,16 @@ describe('message.hooks', () => { const wrapper = mount(); wrapper.find('button').simulate('click'); - jest.runAllTimers(); + + act(() => { + jest.runAllTimers(); + }); expect(document.querySelectorAll('.my-test-message-notice').length).toBe(1); - hide(); - jest.runAllTimers(); + + act(() => { + hide(); + jest.runAllTimers(); + }); expect(getInstance().component.state.notices).toHaveLength(0); }); diff --git a/components/message/__tests__/index.test.js b/components/message/__tests__/index.test.js index 0f68684be0..2efc4840cf 100644 --- a/components/message/__tests__/index.test.js +++ b/components/message/__tests__/index.test.js @@ -1,50 +1,91 @@ import React from 'react'; import { mount } from 'enzyme'; +import { act } from 'react-dom/test-utils'; import { SmileOutlined } from '@ant-design/icons'; import message, { getInstance } from '..'; +globalThis.IS_REACT_ACT_ENVIRONMENT = true; + describe('message', () => { beforeEach(() => { jest.useFakeTimers(); }); afterEach(() => { - message.destroy(); jest.useRealTimers(); + + act(() => { + message.destroy(); + }); }); - it('should be able to hide manually', () => { - const hide1 = message.info('whatever', 0); - const hide2 = message.info('whatever', 0); + it('should be able to hide manually', async () => { + let hide1; + let hide2; + + act(() => { + hide1 = message.info('whatever', 0); + }); + act(() => { + hide2 = message.info('whatever', 0); + }); + expect(document.querySelectorAll('.ant-message-notice').length).toBe(2); + hide1(); - jest.runAllTimers(); + act(() => { + jest.runAllTimers(); + }); expect(getInstance().component.state.notices).toHaveLength(1); + hide2(); - jest.runAllTimers(); + act(() => { + jest.runAllTimers(); + }); expect(getInstance().component.state.notices).toHaveLength(0); }); it('should be able to remove manually with a unique key', () => { const key1 = 'key1'; const key2 = 'key2'; - message.info({ content: 'Message1', key: 'key1', duration: 0 }); - message.info({ content: 'Message2', key: 'key2', duration: 0 }); + + act(() => { + message.info({ content: 'Message1', key: 'key1', duration: 0 }); + }); + act(() => { + message.info({ content: 'Message2', key: 'key2', duration: 0 }); + }); + expect(document.querySelectorAll('.ant-message-notice').length).toBe(2); - message.destroy(key1); - jest.runAllTimers(); + + act(() => { + message.destroy(key1); + jest.runAllTimers(); + }); expect(getInstance().component.state.notices).toHaveLength(1); - message.destroy(key2); - jest.runAllTimers(); + + act(() => { + message.destroy(key2); + jest.runAllTimers(); + }); expect(getInstance().component.state.notices).toHaveLength(0); }); it('should be able to destroy globally', () => { - message.info('whatever', 0); - message.info('whatever', 0); + act(() => { + message.info('whatever', 0); + }); + act(() => { + message.info('whatever', 0); + }); + expect(document.querySelectorAll('.ant-message').length).toBe(1); expect(document.querySelectorAll('.ant-message-notice').length).toBe(2); - message.destroy(); + + act(() => { + message.destroy(); + jest.runAllTimers(); + }); expect(document.querySelectorAll('.ant-message').length).toBe(0); expect(document.querySelectorAll('.ant-message-notice').length).toBe(0); }); @@ -103,7 +144,9 @@ describe('message', () => { let hide; class Test extends React.Component { componentDidMount() { - hide = message.loading('Action in progress..', 0); + act(() => { + hide = message.loading('Action in progress..', 0); + }); } render() { @@ -112,13 +155,18 @@ describe('message', () => { } mount(); expect(document.querySelectorAll('.ant-message-notice').length).toBe(1); - hide(); - jest.runAllTimers(); + + act(() => { + hide(); + jest.runAllTimers(); + }); expect(getInstance().component.state.notices).toHaveLength(0); }); it('should allow custom icon', () => { - message.open({ content: 'Message', icon: }); + act(() => { + message.open({ content: 'Message', icon: }); + }); expect(document.querySelectorAll('.anticon-smile').length).toBe(1); }); @@ -177,9 +225,16 @@ describe('message', () => { const key = 'updatable'; class Test extends React.Component { componentDidMount() { - const hideLoading = message.loading({ content: 'Loading...', key, duration: 0 }); + let hideLoading; + act(() => { + hideLoading = message.loading({ content: 'Loading...', key, duration: 0 }); + }); // Testing that content of the message should be cancel manually. - setTimeout(hideLoading, 1000); + setTimeout(() => { + act(() => { + hideLoading(); + }); + }, 1000); } render() { @@ -189,6 +244,7 @@ describe('message', () => { mount(); expect(document.querySelectorAll('.ant-message-notice').length).toBe(1); + jest.advanceTimersByTime(1500); expect(getInstance().component.state.notices).toHaveLength(0); }); diff --git a/components/notification/__tests__/config.test.js b/components/notification/__tests__/config.test.js index 40d23a24c4..33b14509e8 100644 --- a/components/notification/__tests__/config.test.js +++ b/components/notification/__tests__/config.test.js @@ -1,3 +1,4 @@ +import { act } from 'react-dom/test-utils'; import notification, { getInstance } from '..'; import { sleep } from '../../../tests/utils'; @@ -17,26 +18,37 @@ describe('notification.config', () => { }); for (let i = 0; i < 10; i += 1) { - notification.open({ - message: 'Notification message', - key: i, + act(() => { + notification.open({ + message: 'Notification message', + key: i, + }); }); } - notification.open({ - message: 'Notification last', - key: '11', + act(() => { + notification.open({ + message: 'Notification last', + key: '11', + }); }); - await Promise.resolve(); + await act(async () => { + await Promise.resolve(); + }); expect(document.querySelectorAll('.ant-notification-notice').length).toBe(5); expect(document.querySelectorAll('.ant-notification-notice')[4].textContent).toBe( 'Notification last', ); - jest.runAllTimers(); - await sleep(500); + act(() => { + jest.runAllTimers(); + }); + + await act(async () => { + await sleep(500); + }); expect((await getInstance('ant-notification-topRight')).component.state.notices).toHaveLength( 0, ); diff --git a/components/notification/__tests__/index.test.js b/components/notification/__tests__/index.test.js index 5391f8985b..6f7446e6ca 100644 --- a/components/notification/__tests__/index.test.js +++ b/components/notification/__tests__/index.test.js @@ -1,109 +1,171 @@ import React from 'react'; -import ReactDOM from 'react-dom'; +import { act } from 'react-dom/test-utils'; import { UserOutlined } from '@ant-design/icons'; import notification, { getInstance } from '..'; import ConfigProvider from '../../config-provider'; +import { sleep } from '../../../tests/utils'; + +globalThis.IS_REACT_ACT_ENVIRONMENT = true; describe('notification', () => { beforeEach(() => { jest.useFakeTimers(); + jest.clearAllTimers(); }); afterEach(() => { + jest.runAllTimers(); jest.useRealTimers(); - notification.destroy(); + + act(() => { + notification.destroy(); + }); }); - it('not duplicate create holder', () => { - const originRender = ReactDOM.render; - const argsList = []; - const spyRender = jest.spyOn(ReactDOM, 'render').mockImplementation((...args) => { - argsList.push(args); - }); + it('not duplicate create holder', async () => { for (let i = 0; i < 5; i += 1) { - notification.open({ - message: 'Notification Title', - duration: 0, - prefixCls: 'additional-holder', + act(() => { + notification.open({ + message: 'Notification Title', + duration: 0, + prefixCls: 'additional-holder', + }); }); } - argsList.forEach(args => { - originRender(...args); - }); + await sleep(); const count = document.querySelectorAll('.additional-holder').length; expect(count).toEqual(1); - - spyRender.mockRestore(); }); it('should be able to hide manually', async () => { - notification.open({ - message: 'Notification Title', - duration: 0, - key: '1', - }); - notification.open({ - message: 'Notification Title', - duration: 0, - key: '2', + act(() => { + notification.open({ + message: 'Notification Title 1', + duration: 0, + key: '1', + }); + jest.runAllTimers(); }); - await Promise.resolve(); + act(() => { + jest.runAllTimers(); + }); + + act(() => { + notification.open({ + message: 'Notification Title 2', + duration: 0, + key: '2', + }); + jest.runAllTimers(); + }); + + act(() => { + jest.runAllTimers(); + }); + + await act(async () => { + await Promise.resolve(); + }); expect(document.querySelectorAll('.ant-notification-notice').length).toBe(2); - notification.close('1'); - jest.runAllTimers(); + act(() => { + notification.close('1'); + jest.runAllTimers(); + }); + + await act(async () => { + await Promise.resolve(); + }); expect((await getInstance('ant-notification-topRight')).component.state.notices).toHaveLength( 1, ); - notification.close('2'); - jest.runAllTimers(); + act(() => { + notification.close('2'); + jest.runAllTimers(); + }); + + await act(async () => { + await Promise.resolve(); + }); + expect((await getInstance('ant-notification-topRight')).component.state.notices).toHaveLength( 0, ); }); it('should be able to destroy globally', async () => { - notification.open({ - message: 'Notification Title', - duration: 0, + act(() => { + notification.open({ + message: 'Notification Title', + duration: 0, + }); }); - notification.open({ - message: 'Notification Title', - duration: 0, + + act(() => { + notification.open({ + message: 'Notification Title', + duration: 0, + }); }); - await Promise.resolve(); + + await act(async () => { + await Promise.resolve(); + }); + expect(document.querySelectorAll('.ant-notification').length).toBe(1); expect(document.querySelectorAll('.ant-notification-notice').length).toBe(2); - notification.destroy(); - await Promise.resolve(); + + act(() => { + notification.destroy(); + }); + + await act(async () => { + await Promise.resolve(); + }); + expect(document.querySelectorAll('.ant-notification').length).toBe(0); expect(document.querySelectorAll('.ant-notification-notice').length).toBe(0); }); it('should be able to destroy after config', () => { - notification.config({ - bottom: 100, + act(() => { + notification.config({ + bottom: 100, + }); + }); + + act(() => { + notification.destroy(); }); - notification.destroy(); }); it('should be able to config rtl', () => { - notification.config({ - rtl: true, + act(() => { + notification.config({ + rtl: true, + }); }); - notification.open({ - message: 'whatever', + + act(() => { + notification.open({ + message: 'whatever', + }); }); + expect(document.querySelectorAll('.ant-notification-rtl').length).toBe(1); }); it('should be able to global config rootPrefixCls', () => { ConfigProvider.config({ prefixCls: 'prefix-test', iconPrefixCls: 'bamboo' }); - notification.success({ message: 'Notification Title', duration: 0 }); + + act(() => { + notification.success({ message: 'Notification Title', duration: 0 }); + }); + expect(document.querySelectorAll('.ant-notification-notice')).toHaveLength(0); expect(document.querySelectorAll('.prefix-test-notification-notice')).toHaveLength(1); expect(document.querySelectorAll('.bamboo-check-circle')).toHaveLength(1); @@ -114,68 +176,93 @@ describe('notification', () => { notification.config({ prefixCls: 'prefix-test', }); - notification.open({ - message: 'Notification Title', - duration: 0, + + act(() => { + notification.open({ + message: 'Notification Title', + duration: 0, + }); }); + expect(document.querySelectorAll('.ant-notification-notice')).toHaveLength(0); expect(document.querySelectorAll('.prefix-test-notice')).toHaveLength(1); + notification.config({ prefixCls: '', }); }); it('should be able to open with icon', async () => { + const iconPrefix = '.ant-notification-notice-icon'; + const openNotificationWithIcon = async type => { - const iconPrefix = '.ant-notification-notice-icon'; - notification[type]({ - message: 'Notification Title', - duration: 0, - description: 'This is the content of the notification.', + act(() => { + notification[type]({ + message: 'Notification Title', + duration: 0, + description: 'This is the content of the notification.', + }); + jest.runAllTimers(); }); - await Promise.resolve(); - expect(document.querySelectorAll(`${iconPrefix}-${type}`).length).toBe(1); }; - const promises = ['success', 'info', 'warning', 'error'].map(type => - openNotificationWithIcon(type), - ); + const list = ['success', 'info', 'warning', 'error']; - await Promise.all(promises); + const promises = list.map(type => openNotificationWithIcon(type)); + + await act(async () => { + await Promise.all(promises); + }); + + list.forEach(type => { + expect(document.querySelectorAll(`${iconPrefix}-${type}`).length).toBe(1); + }); }); it('should be able to add parent class for different notification types', async () => { const openNotificationWithIcon = async type => { - notification[type]({ - message: 'Notification Title', - duration: 0, - description: 'This is the content of the notification.', + act(() => { + notification[type]({ + message: 'Notification Title', + duration: 0, + description: 'This is the content of the notification.', + }); + jest.runAllTimers(); }); - await Promise.resolve(); - expect(document.querySelectorAll(`.ant-notification-notice-${type}`).length).toBe(1); }; - const promises = ['success', 'info', 'warning', 'error'].map(type => - openNotificationWithIcon(type), - ); + const list = ['success', 'info', 'warning', 'error']; + const promises = list.map(type => openNotificationWithIcon(type)); - await Promise.all(promises); + await act(async () => { + await Promise.all(promises); + }); + + list.forEach(type => { + expect(document.querySelectorAll(`.ant-notification-notice-${type}`).length).toBe(1); + }); }); it('trigger onClick', () => { - notification.open({ - message: 'Notification Title', - duration: 0, + act(() => { + notification.open({ + message: 'Notification Title', + duration: 0, + }); }); + expect(document.querySelectorAll('.ant-notification').length).toBe(1); }); it('support closeIcon', () => { - notification.open({ - message: 'Notification Title', - duration: 0, - closeIcon: , + act(() => { + notification.open({ + message: 'Notification Title', + duration: 0, + closeIcon: , + }); }); + expect(document.querySelectorAll('.test-customize-icon').length).toBe(1); }); @@ -183,45 +270,64 @@ describe('notification', () => { notification.config({ closeIcon: , }); - notification.open({ - message: 'Notification Title', - duration: 0, - closeIcon: , + + act(() => { + notification.open({ + message: 'Notification Title', + duration: 0, + closeIcon: , + }); }); + expect(document.querySelectorAll('.test-customize-icon').length).toBe(1); }); it('closeIcon should be update', async () => { const openNotificationWithCloseIcon = async type => { - notification.open({ - message: 'Notification Title', - closeIcon: , + act(() => { + notification.open({ + message: 'Notification Title', + closeIcon: , + }); + jest.runAllTimers(); }); - await Promise.resolve(); - expect(document.querySelectorAll(`.test-customize-icon-${type}`).length).toBe(1); }; - const promises = ['1', '2'].map(type => openNotificationWithCloseIcon(type)); + const list = ['1', '2']; + const promises = list.map(type => openNotificationWithCloseIcon(type)); - await Promise.all(promises); + await act(async () => { + await Promise.all(promises); + }); + + list.forEach(type => { + expect(document.querySelectorAll(`.test-customize-icon-${type}`).length).toBe(1); + }); }); it('support config duration', () => { notification.config({ duration: 0, }); - notification.open({ - message: 'whatever', + + act(() => { + notification.open({ + message: 'whatever', + }); }); + expect(document.querySelectorAll('.ant-notification').length).toBe(1); }); it('support icon', () => { - notification.open({ - message: 'Notification Title', - duration: 0, - icon: , + act(() => { + notification.open({ + message: 'Notification Title', + duration: 0, + icon: , + }); }); + expect(document.querySelectorAll('.anticon-user').length).toBe(1); }); }); diff --git a/components/notification/__tests__/placement.test.js b/components/notification/__tests__/placement.test.js index 054b109e80..bc79559a4c 100644 --- a/components/notification/__tests__/placement.test.js +++ b/components/notification/__tests__/placement.test.js @@ -1,3 +1,4 @@ +import { act } from 'react-dom/test-utils'; import notification from '..'; describe('Notification.placement', () => { @@ -25,7 +26,10 @@ describe('Notification.placement', () => { notification.config({ ...args, }); - open(); + + act(() => { + open(); + }); } describe('placement', () => { @@ -35,10 +39,13 @@ describe('Notification.placement', () => { let style; // top - open({ - placement: 'top', - top: 50, + act(() => { + open({ + placement: 'top', + top: 50, + }); }); + style = getStyle($$('.ant-notification-top')[0]); expect(style.top).toBe('50px'); expect(style.left).toBe('50%'); @@ -46,44 +53,56 @@ describe('Notification.placement', () => { expect(style.right).toBe(''); expect(style.bottom).toBe(''); - open({ - placement: 'top', + act(() => { + open({ + placement: 'top', + }); }); expect($$('.ant-notification-top').length).toBe(1); // topLeft - open({ - placement: 'topLeft', - top: 50, + act(() => { + open({ + placement: 'topLeft', + top: 50, + }); }); style = getStyle($$('.ant-notification-topLeft')[0]); expect(style.top).toBe('50px'); expect(style.left).toBe('0px'); expect(style.bottom).toBe(''); - open({ - placement: 'topLeft', + act(() => { + open({ + placement: 'topLeft', + }); }); expect($$('.ant-notification-topLeft').length).toBe(1); // topRight - open({ - placement: 'topRight', + act(() => { + open({ + placement: 'topRight', + }); }); style = getStyle($$('.ant-notification-topRight')[0]); expect(style.top).toBe(defaultTop); expect(style.right).toBe('0px'); expect(style.bottom).toBe(''); - open({ - placement: 'topRight', + act(() => { + open({ + placement: 'topRight', + }); }); expect($$('.ant-notification-topRight').length).toBe(1); // bottom - open({ - placement: 'bottom', - bottom: 100, + act(() => { + open({ + placement: 'bottom', + bottom: 100, + }); }); style = getStyle($$('.ant-notification-bottom')[0]); expect(style.top).toBe(''); @@ -92,37 +111,47 @@ describe('Notification.placement', () => { expect(style.right).toBe(''); expect(style.bottom).toBe('100px'); - open({ - placement: 'bottom', + act(() => { + open({ + placement: 'bottom', + }); }); expect($$('.ant-notification-bottom').length).toBe(1); // bottomRight - open({ - placement: 'bottomRight', - bottom: 100, + act(() => { + open({ + placement: 'bottomRight', + bottom: 100, + }); }); style = getStyle($$('.ant-notification-bottomRight')[0]); expect(style.top).toBe(''); expect(style.right).toBe('0px'); expect(style.bottom).toBe('100px'); - open({ - placement: 'bottomRight', + act(() => { + open({ + placement: 'bottomRight', + }); }); expect($$('.ant-notification-bottomRight').length).toBe(1); // bottomLeft - open({ - placement: 'bottomLeft', + act(() => { + open({ + placement: 'bottomLeft', + }); }); style = getStyle($$('.ant-notification-bottomLeft')[0]); expect(style.top).toBe(''); expect(style.left).toBe('0px'); expect(style.bottom).toBe(defaultBottom); - open({ - placement: 'bottomLeft', + act(() => { + open({ + placement: 'bottomLeft', + }); }); expect($$('.ant-notification-bottomLeft').length).toBe(1); }); @@ -186,16 +215,19 @@ describe('Notification.placement', () => { }); it('can be configured per notification using the `open` method', () => { - open({ - getContainer: () => $container, + act(() => { + open({ + getContainer: () => $container, + }); }); + expect($container.querySelector('.ant-notification')).not.toBe(null); - notification.destroy(); - setTimeout(() => { // Upcoming notifications still use their default mountNode and not $container - open(); + act(() => { + open(); + }); expect($container.querySelector('.ant-notification')).toBe(null); }); }); @@ -205,12 +237,12 @@ describe('Notification.placement', () => { getContainer: () => $container, }); expect($container.querySelector('.ant-notification')).not.toBe(null); - notification.destroy(); - setTimeout(() => { // Upcoming notifications are mounted in $container - open(); + act(() => { + open(); + }); expect($container.querySelector('.ant-notification')).not.toBe(null); }); }); diff --git a/components/notification/index.tsx b/components/notification/index.tsx index 15fb147454..fe743147f7 100755 --- a/components/notification/index.tsx +++ b/components/notification/index.tsx @@ -156,6 +156,7 @@ function getNotificationInstance( const cacheKey = `${prefixCls}-${placement}`; const cacheInstance = notificationInstance[cacheKey]; + if (cacheInstance) { Promise.resolve(cacheInstance).then(instance => { callback({ prefixCls: `${prefixCls}-notice`, iconPrefixCls, instance }); diff --git a/components/popconfirm/__tests__/index.test.js b/components/popconfirm/__tests__/index.test.js index 9d58b1dd35..88ab9f45cc 100644 --- a/components/popconfirm/__tests__/index.test.js +++ b/components/popconfirm/__tests__/index.test.js @@ -2,7 +2,6 @@ import React from 'react'; import { mount } from 'enzyme'; import { spyElementPrototype } from 'rc-util/lib/test/domHook'; import { render, fireEvent } from '@testing-library/react'; -import '@testing-library/jest-dom'; import Popconfirm from '..'; import mountTest from '../../../tests/shared/mountTest'; import { sleep } from '../../../tests/utils'; diff --git a/components/popover/__tests__/index.test.js b/components/popover/__tests__/index.test.js index fd9ac7bdd0..93b597d231 100644 --- a/components/popover/__tests__/index.test.js +++ b/components/popover/__tests__/index.test.js @@ -1,7 +1,6 @@ import React from 'react'; import { mount } from 'enzyme'; import { render } from '@testing-library/react'; -import '@testing-library/jest-dom'; 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 09b31f4f2d..c390206669 100644 --- a/components/result/__tests__/index.test.js +++ b/components/result/__tests__/index.test.js @@ -1,7 +1,6 @@ import React from 'react'; import { mount } from 'enzyme'; import { render } from '@testing-library/react'; -import '@testing-library/jest-dom'; import Result from '..'; import Button from '../../button'; import mountTest from '../../../tests/shared/mountTest'; diff --git a/components/table/__tests__/Table.filter.test.js b/components/table/__tests__/Table.filter.test.js index 1d4977d40b..78dcebd8d6 100644 --- a/components/table/__tests__/Table.filter.test.js +++ b/components/table/__tests__/Table.filter.test.js @@ -3,7 +3,6 @@ import React from 'react'; import { mount } from 'enzyme'; import { act } from 'react-dom/test-utils'; import { render, fireEvent } from '@testing-library/react'; -import '@testing-library/jest-dom'; import Table from '..'; import Input from '../../input'; import Tooltip from '../../tooltip'; diff --git a/components/table/__tests__/Table.test.js b/components/table/__tests__/Table.test.js index d3bbffcc7b..951e1d57ef 100644 --- a/components/table/__tests__/Table.test.js +++ b/components/table/__tests__/Table.test.js @@ -1,7 +1,6 @@ import React from 'react'; import { mount } from 'enzyme'; import { render } from '@testing-library/react'; -import '@testing-library/jest-dom'; import Table from '..'; import mountTest from '../../../tests/shared/mountTest'; import rtlTest from '../../../tests/shared/rtlTest'; diff --git a/components/transfer/__tests__/customize.test.js b/components/transfer/__tests__/customize.test.js index 9369d408b2..9e09dd0e0e 100644 --- a/components/transfer/__tests__/customize.test.js +++ b/components/transfer/__tests__/customize.test.js @@ -1,7 +1,6 @@ import React from 'react'; import { mount } from 'enzyme'; import { render } from '@testing-library/react'; -import '@testing-library/jest-dom'; import Transfer from '../index'; describe('Transfer.Customize', () => { diff --git a/components/transfer/__tests__/search.test.js b/components/transfer/__tests__/search.test.js index 25e04c6f28..70a858e539 100644 --- a/components/transfer/__tests__/search.test.js +++ b/components/transfer/__tests__/search.test.js @@ -1,7 +1,6 @@ import React from 'react'; import { mount } from 'enzyme'; import { render, fireEvent } from '@testing-library/react'; -import '@testing-library/jest-dom'; import Search from '../search'; import Transfer from '../index'; diff --git a/components/typography/__tests__/index.test.js b/components/typography/__tests__/index.test.js index 6d7fd19ee2..83cf09584f 100644 --- a/components/typography/__tests__/index.test.js +++ b/components/typography/__tests__/index.test.js @@ -1,7 +1,6 @@ import React from 'react'; import { mount } from 'enzyme'; import { render } from '@testing-library/react'; -import '@testing-library/jest-dom'; import { SmileOutlined, LikeOutlined, HighlightOutlined, CheckOutlined } from '@ant-design/icons'; import KeyCode from 'rc-util/lib/KeyCode'; import { resetWarned } from 'rc-util/lib/warning'; diff --git a/components/upload/__tests__/upload.test.js b/components/upload/__tests__/upload.test.js index 321c51fc85..d70616f0b7 100644 --- a/components/upload/__tests__/upload.test.js +++ b/components/upload/__tests__/upload.test.js @@ -2,7 +2,6 @@ import React from 'react'; import { mount } from 'enzyme'; import { render, fireEvent } from '@testing-library/react'; -import '@testing-library/jest-dom'; import { act } from 'react-dom/test-utils'; import produce from 'immer'; import { cloneDeep } from 'lodash'; diff --git a/package.json b/package.json index b755233d9e..b83a26b5e4 100644 --- a/package.json +++ b/package.json @@ -136,7 +136,7 @@ "rc-mentions": "~1.7.0", "rc-menu": "~9.5.1", "rc-motion": "^2.4.4", - "rc-notification": "~4.5.7", + "rc-notification": "~4.6.0", "rc-pagination": "~3.1.9", "rc-picker": "~2.6.4", "rc-progress": "~3.2.1", diff --git a/tests/setupAfterEnv.ts b/tests/setupAfterEnv.ts index b7587e7ccf..1bc9eb2caf 100644 --- a/tests/setupAfterEnv.ts +++ b/tests/setupAfterEnv.ts @@ -1,3 +1,4 @@ import { toHaveNoViolations } from 'jest-axe'; +import '@testing-library/jest-dom'; expect.extend(toHaveNoViolations); diff --git a/tests/shared/focusTest.tsx b/tests/shared/focusTest.tsx index badb1142d2..0cd9be14d7 100644 --- a/tests/shared/focusTest.tsx +++ b/tests/shared/focusTest.tsx @@ -1,6 +1,5 @@ import React from 'react'; import { render } from '@testing-library/react'; -import '@testing-library/jest-dom'; import { mount, ReactWrapper } from 'enzyme'; import { sleep } from '../utils';