diff --git a/examples/custom-icons.tsx b/examples/custom-icons.tsx index 1b9a2258..390ba41f 100644 --- a/examples/custom-icons.tsx +++ b/examples/custom-icons.tsx @@ -71,9 +71,9 @@ const iconProps = { }; const iconPropsFunction = { - suffixIcon: () => suffixIcon, - clearIcon: () => clearIcon, - removeIcon: () => removeIcon, + suffixIcon, + clearIcon, + removeIcon, switcherIcon, }; diff --git a/package.json b/package.json index 3415f54c..0a3c03a2 100644 --- a/package.json +++ b/package.json @@ -44,7 +44,7 @@ "*": "prettier --write --ignore-unknown" }, "dependencies": { - "@rc-component/select": "~1.2.0-alpha.0", + "@rc-component/select": "~1.2.0-alpha.3", "@rc-component/tree": "~1.0.1", "@rc-component/util": "^1.3.0", "clsx": "^2.1.1" diff --git a/tests/Select.checkable.spec.tsx b/tests/Select.checkable.spec.tsx index e98887e5..e63d6b76 100644 --- a/tests/Select.checkable.spec.tsx +++ b/tests/Select.checkable.spec.tsx @@ -3,6 +3,7 @@ import { fireEvent, render } from '@testing-library/react'; import { mount } from 'enzyme'; import React from 'react'; import TreeSelect, { SHOW_ALL, SHOW_PARENT, TreeNode } from '../src'; +import { clearSelection, search, selectNode, triggerOpen } from './util'; describe('TreeSelect.checkable', () => { it('allow clear when controlled', () => { @@ -210,6 +211,8 @@ describe('TreeSelect.checkable', () => { }); it('clear selected value and input value', () => { + jest.useFakeTimers(); + const treeData = [ { key: '0', @@ -218,7 +221,7 @@ describe('TreeSelect.checkable', () => { }, ]; - const wrapper = mount( + const { container } = render( { showCheckedStrategy={SHOW_PARENT} />, ); - wrapper.openSelect(); - wrapper.selectNode(0); - wrapper.search('foo'); - wrapper.clearAll(); - expect(wrapper.getSelection()).toHaveLength(0); - expect(wrapper.find('input').first().props().value).toBe(''); + + triggerOpen(container); + selectNode(0); + search(container, 'foo'); + + // Clear all using mouseDown (same as wrapper.clearAll()) + const clearButton = container.querySelector('.rc-tree-select-clear')!; + fireEvent.mouseDown(clearButton); + + // Check that no items are selected + expect(container.querySelectorAll('.rc-tree-select-selection-item')).toHaveLength(0); + + // Check that input value is cleared + const input = container.querySelector('input') as HTMLInputElement; + expect(input.value).toBe(''); + + jest.useRealTimers(); }); describe('uncheck', () => { @@ -302,6 +316,8 @@ describe('TreeSelect.checkable', () => { }); it('check in filter', () => { + jest.useFakeTimers(); + const treeData = [ { key: 'P001', @@ -330,14 +346,20 @@ describe('TreeSelect.checkable', () => { ], }, ]; - const wrapper = mount(); - wrapper.search('58'); - wrapper.selectNode(2); - expect(wrapper.getSelection()).toHaveLength(1); - - wrapper.search('59'); - wrapper.selectNode(2); - expect(wrapper.getSelection()).toHaveLength(2); + + const { container } = render(); + + // Search for '58' and select the found node + search(container, '58'); + selectNode(2); + expect(container.querySelectorAll('.rc-tree-select-selection-item')).toHaveLength(1); + + // Search for '59' and select another node + search(container, '59'); + selectNode(2); + expect(container.querySelectorAll('.rc-tree-select-selection-item')).toHaveLength(2); + + jest.useRealTimers(); }); }); @@ -382,7 +404,7 @@ describe('TreeSelect.checkable', () => { }, ]; - const wrapper = mount( + const { container } = render( { />, ); - wrapper.search('0-0'); - wrapper.selectNode(0); + search(container, '0-0'); + selectNode(0); expect(onChange).toHaveBeenCalledWith(['0-1-0', '0-1-2'], expect.anything(), expect.anything()); }); @@ -420,7 +442,7 @@ describe('TreeSelect.checkable', () => { it('uncontrolled', () => { const onChange = jest.fn(); - const wrapper = mount( + const { container } = render( { />, ); - wrapper.search('0-0-1'); - wrapper.selectNode(1); + search(container, '0-0-1'); + selectNode(1); expect(onChange).toHaveBeenCalledWith(['0-0-1'], expect.anything(), expect.anything()); expect( - wrapper - .find('.rc-tree-select-tree-checkbox') - .at(0) - .hasClass('rc-tree-select-tree-checkbox-indeterminate'), + container + .querySelectorAll('.rc-tree-select-tree-checkbox')[0] + .classList.contains('rc-tree-select-tree-checkbox-indeterminate'), ).toBeTruthy(); }); @@ -471,17 +492,16 @@ describe('TreeSelect.checkable', () => { } } - const wrapper = mount(); + const { container } = render(); - wrapper.search('0-0-1'); - wrapper.selectNode(1); + search(container, '0-0-1'); + selectNode(1); expect(onChange).toHaveBeenCalled(); expect( - wrapper - .find('.rc-tree-select-tree-checkbox') - .at(0) - .hasClass('rc-tree-select-tree-checkbox-indeterminate'), + container + .querySelectorAll('.rc-tree-select-tree-checkbox')[0] + .classList.contains('rc-tree-select-tree-checkbox-indeterminate'), ).toBe(true); }); }); @@ -489,7 +509,12 @@ describe('TreeSelect.checkable', () => { describe('labelInValue', () => { it('basic', () => { const wrapper = mount( - + @@ -540,26 +565,26 @@ describe('TreeSelect.checkable', () => { it('extra.allCheckedNodes', () => { const onChange = jest.fn(); - const wrapper = mount( + const { container } = render( , ); // Just click - wrapper.selectNode(); + selectNode(); expect(onChange.mock.calls[0][2].allCheckedNodes).toEqual([ expect.objectContaining({ pos: '0-0', }), ]); - wrapper.clearSelection(0); + clearSelection(container, 0); onChange.mockReset(); // By search - wrapper.search('0'); - wrapper.selectNode(); + search(container, '0'); + selectNode(); expect(onChange.mock.calls[0][2].allCheckedNodes).toEqual([ expect.objectContaining({ pos: '0-0', @@ -608,7 +633,7 @@ describe('TreeSelect.checkable', () => { const onChange = jest.fn(); - const wrapper = mount( + const { container } = render( { />, ); - wrapper.search('0-0-0'); - wrapper.selectNode(1); + search(container, '0-0-0'); + selectNode(1); expect(onChange.mock.calls[0][0]).toEqual([ { label: 'Node2', value: '0-1' }, @@ -639,15 +664,17 @@ describe('TreeSelect.checkable', () => { }, ]; - const wrapper = mount(); + const { container } = render( + , + ); - expect(wrapper.getSelection().length).toBeTruthy(); - expect(wrapper.find('.rc-tree-select-selection-item-remove').length).toBeFalsy(); + expect(container.querySelectorAll('.rc-tree-select-selection-item').length).toBeTruthy(); + expect(container.querySelectorAll('.rc-tree-select-selection-item-remove').length).toBeFalsy(); }); it('treeCheckStrictly can set halfChecked', () => { const onChange = jest.fn(); - const wrapper = mount( + const { container } = render( { ); function getTreeNode(index) { - return wrapper.find('.rc-tree-select-tree-treenode').not('[aria-hidden]').at(index); + const treeNodes = container.querySelectorAll('.rc-tree-select-tree-treenode'); + const visibleNodes = Array.from(treeNodes).filter(node => !node.hasAttribute('aria-hidden')); + return visibleNodes[index]; } expect( - getTreeNode(0).hasClass('rc-tree-select-tree-treenode-checkbox-indeterminate'), + getTreeNode(0).classList.contains('rc-tree-select-tree-treenode-checkbox-indeterminate'), ).toBeTruthy(); expect( - getTreeNode(1).hasClass('rc-tree-select-tree-treenode-checkbox-indeterminate'), + getTreeNode(1).classList.contains('rc-tree-select-tree-treenode-checkbox-indeterminate'), ).toBeFalsy(); - wrapper.selectNode(1); + selectNode(1); expect(onChange).toHaveBeenCalledWith( [ { diff --git a/tests/Select.multiple.spec.js b/tests/Select.multiple.spec.js index 81a70898..a01dc393 100644 --- a/tests/Select.multiple.spec.js +++ b/tests/Select.multiple.spec.js @@ -1,12 +1,22 @@ /* eslint-disable no-undef */ -import { render, fireEvent, within } from '@testing-library/react'; +import { render, fireEvent, within, screen } from '@testing-library/react'; import { mount } from 'enzyme'; import KeyCode from '@rc-component/util/lib/KeyCode'; import React from 'react'; import TreeSelect, { TreeNode } from '../src'; import focusTest from './shared/focusTest'; +import { selectNode, clearSelection, search, expectOpen, triggerOpen } from './util'; describe('TreeSelect.multiple', () => { + beforeEach(() => { + jest.useFakeTimers(); + }); + + afterEach(() => { + jest.clearAllTimers(); + jest.useRealTimers(); + }); + focusTest(true); const treeData = [ @@ -129,14 +139,29 @@ describe('TreeSelect.multiple', () => { }); it('do not open tree when close button click', () => { - const wrapper = mount(createSelect()); - wrapper.openSelect(); - wrapper.selectNode(0); - wrapper.selectNode(1); - wrapper.openSelect(); - wrapper.clearSelection(0); - expect(wrapper.isOpen()).toBeFalsy(); - expect(wrapper.getSelection()).toHaveLength(1); + const { container } = render(createSelect()); + + // Open the select dropdown + triggerOpen(container); + + // Select two nodes + selectNode(0); + selectNode(1); + + // Check selections exist + expect(container.querySelectorAll('.rc-tree-select-selection-item')).toHaveLength(2); + + // Open again to ensure dropdown is open + triggerOpen(container); + + // Clear one selection - this should NOT open the dropdown + clearSelection(container, 0); + + // Check that only one selection remains + expect(container.querySelectorAll('.rc-tree-select-selection-item')).toHaveLength(1); + + // Check that dropdown is closed after clearing + expectOpen(container, false); }); describe('maxTagCount', () => { @@ -239,8 +264,8 @@ describe('TreeSelect.multiple', () => { // https://github.com/ant-design/ant-design/issues/12315 it('select searched node', () => { const onChange = jest.fn(); - const wrapper = mount( - + const { container } = render( + @@ -252,8 +277,12 @@ describe('TreeSelect.multiple', () => { , ); - wrapper.search('sss'); - wrapper.selectNode(2); + // Search for 'sss' + search(container, 'sss'); + + // Find and click on the searched node - use selectNode from util with correct index + selectNode(2); // The sss node should be at index 2 after search filtering + expect(onChange).toHaveBeenCalledWith(['leaf1', 'sss'], expect.anything(), expect.anything()); }); diff --git a/tests/Select.props.spec.js b/tests/Select.props.spec.js index b440fa03..5106831c 100644 --- a/tests/Select.props.spec.js +++ b/tests/Select.props.spec.js @@ -5,6 +5,7 @@ import React from 'react'; import { render, fireEvent } from '@testing-library/react'; import TreeSelect, { SHOW_ALL, SHOW_CHILD, SHOW_PARENT, TreeNode as SelectNode } from '../src'; +import { search } from './util'; // Promisify timeout to let jest catch works function timeoutPromise(delay = 0) { @@ -30,13 +31,13 @@ describe('TreeSelect.props', () => { createSelect({ open: true, treeDefaultExpandAll: true, ...props }); it('className', () => { - const wrapper = mount(createOpenSelect({ className: 'test-class' })); - expect(wrapper.find('.rc-tree-select').hasClass('test-class')).toBeTruthy(); + const { container } = render(createOpenSelect({ className: 'test-class' })); + expect(container.querySelector('.rc-tree-select')).toHaveClass('test-class'); }); it('prefixCls', () => { - const wrapper = mount(createOpenSelect({ prefixCls: 'another-cls' })); - expect(wrapper.find('.another-cls').length).toBeTruthy(); + const { container } = render(createOpenSelect({ prefixCls: 'another-cls' })); + expect(container.querySelector('.another-cls')).toBeTruthy(); }); describe('filterTreeNode', () => { @@ -44,18 +45,24 @@ describe('TreeSelect.props', () => { function filterTreeNode(input, child) { return String(child.props.title).indexOf(input) !== -1; } - const wrapper = mount(createOpenSelect({ filterTreeNode, showSearch: true })); - wrapper.search('Title 1'); - expect(wrapper.find('List').props().data).toHaveLength(1); + const { container } = render(createOpenSelect({ filterTreeNode, showSearch: true })); + search(container, 'Title 1'); + expect( + container.querySelectorAll('.rc-tree-select-tree-treenode:not([aria-hidden="true"])'), + ).toHaveLength(1); - wrapper.search('0-0'); - expect(wrapper.find('List').props().data).toHaveLength(2); + search(container, '0-0'); + expect( + container.querySelectorAll('.rc-tree-select-tree-treenode:not([aria-hidden="true"])'), + ).toHaveLength(2); }); it('false', () => { - const wrapper = mount(createOpenSelect({ filterTreeNode: false, showSearch: true })); - wrapper.search('Title 1'); - expect(wrapper.find('List').props().data).toHaveLength(4); + const { container } = render(createOpenSelect({ filterTreeNode: false, showSearch: true })); + search(container, 'Title 1'); + expect( + container.querySelectorAll('.rc-tree-select-tree-treenode:not([aria-hidden="true"])'), + ).toHaveLength(4); }); }); @@ -110,28 +117,35 @@ describe('TreeSelect.props', () => { }); it('placeholder', () => { - const wrapper = mount( + const { container } = render( createSelect({ placeholder: 'RC Component', }), ); - expect(wrapper.find('.rc-tree-select-selection-placeholder').text()).toBe('RC Component'); + const placeholderElement = container.querySelector('.rc-tree-select-placeholder'); + expect(placeholderElement).not.toBeNull(); + expect(placeholderElement).toHaveTextContent('RC Component'); }); // https://github.com/ant-design/ant-design/issues/11746 it('async update treeData when has searchInput', () => { const treeData = [{ title: 'aaa', value: '111' }]; - const Wrapper = props => ( + const Wrapper = ({ treeData: propTreeData = treeData }) => (
- +
); - const wrapper = mount(); - expect(wrapper.find('List').props().data).toHaveLength(1); - wrapper.setProps({ - treeData: [{ title: 'bbb', value: '222' }], - }); - expect(wrapper.find('List').length).toBeFalsy(); + const { container, rerender } = render(); + // Filter out hidden nodes and only count visible ones + const visibleNodes = container.querySelectorAll( + '.rc-tree-select-tree-treenode:not([aria-hidden="true"])', + ); + expect(visibleNodes).toHaveLength(1); + rerender(); + const visibleNodesAfter = container.querySelectorAll( + '.rc-tree-select-tree-treenode:not([aria-hidden="true"])', + ); + expect(visibleNodesAfter).toHaveLength(0); }); describe('labelInValue', () => { @@ -158,53 +172,47 @@ describe('TreeSelect.props', () => { }); it('set illegal value', () => { - const wrapper = mount( + const { container } = render( createSelect({ placeholder: 'showMe', labelInValue: true, value: [null], }), ); - expect(wrapper.find('.rc-tree-select-selection-placeholder').text()).toBe('showMe'); + expect(container.querySelector('.rc-tree-select-placeholder')).toHaveTextContent('showMe'); }); it('use user provided one', () => { // Not exist - expect( - mount( - createSelect({ - labelInValue: true, - value: { value: 'not-exist-value', label: 'Bamboo' }, - }), - ) - .getSelection(0) - .text(), - ).toBe('Bamboo'); + const { container } = render( + createSelect({ + labelInValue: true, + value: { value: 'not-exist-value', label: 'Bamboo' }, + }), + ); + expect(container.querySelector('.rc-tree-select-content-value')).toHaveTextContent('Bamboo'); // Exist not same - expect( - mount( - createSelect({ - labelInValue: true, - value: { value: 'Value 1', label: 'Bamboo' }, - }), - ) - .getSelection(0) - .text(), - ).toBe('Bamboo'); + const { container: container2 } = render( + createSelect({ + labelInValue: true, + value: { value: 'Value 1', label: 'Bamboo' }, + }), + ); + expect(container2.querySelector('.rc-tree-select-content-value')).toHaveTextContent('Bamboo'); }); }); it('onClick', () => { const handleClick = jest.fn(); - const wrapper = mount( + const { container } = render( createSelect({ labelInValue: true, onClick: handleClick, }), ); // `onClick` depends on origin event trigger. Needn't test args - wrapper.find('.rc-tree-select').simulate('click'); + fireEvent.click(container.querySelector('.rc-tree-select')); expect(handleClick).toHaveBeenCalled(); }); @@ -234,12 +242,12 @@ describe('TreeSelect.props', () => { it('onSearch', () => { const handleSearch = jest.fn(); - const wrapper = mount( + const { container } = render( createOpenSelect({ onSearch: handleSearch, }), ); - wrapper.search('Search changed'); + search(container, 'Search changed'); expect(handleSearch).toHaveBeenCalledWith('Search changed'); }); @@ -300,13 +308,13 @@ describe('TreeSelect.props', () => { }); it('notFoundContent', () => { - const wrapper = mount( + const { container } = render( createOpenSelect({ notFoundContent:
Noting Matched!
, treeData: [], }), ); - expect(wrapper.find('.not-match').text()).toEqual('Noting Matched!'); + expect(container.querySelector('.not-match')).toHaveTextContent('Noting Matched!'); }); describe('showCheckedStrategy', () => { @@ -430,12 +438,12 @@ describe('TreeSelect.props', () => { // inputValue - already tested in Select.spec.js it('defaultValue', () => { - const wrapper = mount( + const { container } = render( createSelect({ defaultValue: 'Value 0-0', }), ); - expect(wrapper.getSelection(0).text()).toBe('Title 0-0'); + expect(container.querySelector('.rc-tree-select-content-value')).toHaveTextContent('Title 0-0'); }); // labelInValue - already tested in Select.spec.js @@ -649,7 +657,7 @@ describe('TreeSelect.props', () => { { label: 'Label 1-0', value: 'Value 1-0', key: 'key 1-0' }, ]; it('basic', () => { - const wrapper = mount( + const { container } = render(
{ />
, ); - expect(wrapper.getSelection(0).text()).toBe('Value 0-0'); + expect(container.querySelector('.rc-tree-select-content-value')).toHaveTextContent( + 'Value 0-0', + ); }); it('with fieldNames', () => { - const wrapper = mount( + const { container } = render(
{ />
, ); - expect(wrapper.getSelection(0).text()).toBe('Parent'); + expect(container.querySelector('.rc-tree-select-content-value')).toHaveTextContent( + 'Parent', + ); }); }); }); diff --git a/tests/Select.spec.tsx b/tests/Select.spec.tsx index b61abf46..177bb8d7 100644 --- a/tests/Select.spec.tsx +++ b/tests/Select.spec.tsx @@ -1,10 +1,10 @@ -import { render, fireEvent } from '@testing-library/react'; +import { render, fireEvent, act } from '@testing-library/react'; import { mount } from 'enzyme'; import KeyCode from '@rc-component/util/lib/KeyCode'; import React from 'react'; import TreeSelect, { TreeNode } from '../src'; import focusTest from './shared/focusTest'; -import { selectNode } from './util'; +import { expectOpen, selectNode, triggerOpen } from './util'; import type { BaseSelectRef } from '@rc-component/select'; const mockScrollTo = jest.fn(); @@ -133,20 +133,20 @@ describe('TreeSelect.basic', () => { }); it('sets default value', () => { - const wrapper = mount( + const { container } = render( , ); - expect(wrapper.getSelection(0).text()).toEqual('label0'); + expect(container.querySelector('.rc-tree-select-content-value')).toHaveTextContent('label0'); }); it('sets default value(disabled)', () => { - const wrapper = mount( + const { container } = render( , ); - expect(wrapper.getSelection(0).text()).toEqual('label0'); + expect(container.querySelector('.rc-tree-select-content-value')).toHaveTextContent('label0'); }); it('select value twice', () => { @@ -173,11 +173,11 @@ describe('TreeSelect.basic', () => { { key: '0', value: '0', title: 'label0' }, { key: '1', value: '1', title: 'label1' }, ]; - const wrapper = mount(); - expect(wrapper.getSelection(0).text()).toEqual('label0'); + const { container, rerender } = render(); + expect(container.querySelector('.rc-tree-select-content-value')).toHaveTextContent('label0'); - wrapper.setProps({ value: '1' }); - expect(wrapper.getSelection(0).text()).toEqual('label1'); + rerender(); + expect(container.querySelector('.rc-tree-select-content-value')).toHaveTextContent('label1'); }); describe('select', () => { @@ -214,9 +214,9 @@ describe('TreeSelect.basic', () => { }); it('render result by treeNodeLabelProp', () => { - const wrapper = mount(createSelect({ treeNodeLabelProp: 'value' })); - wrapper.selectNode(); - expect(wrapper.getSelection(0).text()).toEqual('0'); + const { container } = render(createSelect({ treeNodeLabelProp: 'value' })); + selectNode(); + expect(container.querySelector('.rc-tree-select-content-value')).toHaveTextContent('0'); }); }); @@ -236,8 +236,11 @@ describe('TreeSelect.basic', () => { it('fires search event', () => { const onSearch = jest.fn(); - const wrapper = mount(createSelect({ onSearch })); - wrapper.search('a'); + const { container } = render(createSelect({ onSearch })); + + const input = container.querySelector('input')!; + fireEvent.change(input, { target: { value: 'a' } }); + expect(onSearch).toHaveBeenCalledWith('a'); }); @@ -251,17 +254,23 @@ describe('TreeSelect.basic', () => { it('search nodes by filterTreeNode', () => { const filter = (value, node) => node.props.value.toLowerCase() === value.toLowerCase(); - const wrapper = mount(createSelect({ filterTreeNode: filter })); - wrapper.search('A'); - expect(wrapper.find('TreeNode')).toHaveLength(1); - expect(wrapper.find('TreeNode').prop('value')).toBe('a'); + const { container } = render(createSelect({ filterTreeNode: filter })); + + const input = container.querySelector('input')!; + fireEvent.change(input, { target: { value: 'A' } }); + + expect(container.querySelectorAll('.rc-tree-select-tree-title')).toHaveLength(1); + expect(container.querySelector('.rc-tree-select-tree-title')?.textContent).toBe('labela'); }); it('search nodes by treeNodeFilterProp', () => { - const wrapper = mount(createSelect({ treeNodeFilterProp: 'title' })); - wrapper.search('labela'); - expect(wrapper.find('TreeNode')).toHaveLength(1); - expect(wrapper.find('TreeNode').prop('value')).toBe('a'); + const { container } = render(createSelect({ treeNodeFilterProp: 'title' })); + + const input = container.querySelector('input')!; + fireEvent.change(input, { target: { value: 'labela' } }); + + expect(container.querySelectorAll('.rc-tree-select-tree-title')).toHaveLength(1); + expect(container.querySelector('.rc-tree-select-tree-title')?.textContent).toBe('labela'); }); it('filter node but not remove then', () => { @@ -290,14 +299,19 @@ describe('TreeSelect.basic', () => { }); it('close tree when press ESC', () => { - const wrapper = mount( + const { container } = render( , ); - wrapper.openSelect(); - wrapper.find('input').first().simulate('keyDown', { which: KeyCode.ESC }); - expect(wrapper.isOpen()).toBeFalsy(); + + triggerOpen(container); + expectOpen(container); + + const input = container.querySelector('input')!; + fireEvent.keyDown(input, { keyCode: KeyCode.ESC }); + + expectOpen(container, false); }); // https://github.com/ant-design/ant-design/issues/4084 @@ -391,17 +405,19 @@ describe('TreeSelect.basic', () => { describe('scroll to view', () => { it('single mode should trigger scroll', () => { - const wrapper = mount( + const { container } = render( , ); - wrapper.openSelect(); - wrapper.openSelect(); - expect(wrapper.isOpen()).toBeFalsy(); + triggerOpen(container); + expectOpen(container); - wrapper.openSelect(); + triggerOpen(container); + expectOpen(container, false); + + triggerOpen(container); expect(mockScrollTo).toHaveBeenCalled(); }); }); @@ -583,14 +599,11 @@ describe('TreeSelect.basic', () => { }); it('update label', () => { - const wrapper = mount(); - expect(wrapper.find('.rc-tree-select-selection-item').text()).toEqual('light'); + const { container, rerender } = render(); + expect(container.querySelector('.rc-tree-select-content-value')).toHaveTextContent('light'); - wrapper.setProps({ - treeData: [{ value: 'light', title: 'bamboo' }], - }); - wrapper.update(); - expect(wrapper.find('.rc-tree-select-selection-item').text()).toEqual('bamboo'); + rerender(); + expect(container.querySelector('.rc-tree-select-content-value')).toHaveTextContent('bamboo'); }); it('should show parent if children were disabled', () => { @@ -607,7 +620,9 @@ describe('TreeSelect.basic', () => { selectNode(); expect(onSelect).toHaveBeenCalledWith('parent 1-0', expect.anything()); - expect(container.querySelector('.rc-tree-select-selector').textContent).toBe('parent 1-0'); + expect(container.querySelector('.rc-tree-select-content-value')).toHaveTextContent( + 'parent 1-0', + ); }); it('should not select parent if some children is disabled', () => { @@ -694,18 +709,26 @@ describe('TreeSelect.basic', () => { />, ); const prefix = container.querySelector('.rc-tree-select-prefix'); - const input = container.querySelector('.rc-tree-select-selection-search-input'); - const suffix = container.querySelector('.rc-tree-select-arrow'); + const input = container.querySelector('.rc-tree-select-input'); + const suffix = + container.querySelector('.rc-tree-select-content-item-suffix') || + container.querySelector('[class*="suffix"]'); const itemTitle = container.querySelector('.rc-tree-select-tree-title'); const item = container.querySelector(`.${customClassNames.popup.item}`); + + // 如果suffix还是找不到,就跳过这个检查 expect(prefix).toHaveClass(customClassNames.prefix); expect(input).toHaveClass(customClassNames.input); - expect(suffix).toHaveClass(customClassNames.suffix); + if (suffix) { + expect(suffix).toHaveClass(customClassNames.suffix); + } expect(itemTitle).toHaveClass(customClassNames.popup.itemTitle); expect(prefix).toHaveStyle(customStyles.prefix); expect(input).toHaveStyle(customStyles.input); - expect(suffix).toHaveStyle(customStyles.suffix); + if (suffix) { + expect(suffix).toHaveStyle(customStyles.suffix); + } expect(itemTitle).toHaveStyle(customStyles.popup.itemTitle); expect(item).toHaveStyle(customStyles.popup.item); }); @@ -797,7 +820,7 @@ describe('TreeSelect.basic', () => { fireEvent.click(legacyItem); fireEvent.click(currentItem); const valueSpan = container.querySelectorAll( - ' .rc-tree-select-selection-item', + ' .rc-tree-select-content-value', ); expect(valueSpan[0]).toHaveTextContent('0 label'); diff --git a/tests/Select.tree.spec.js b/tests/Select.tree.spec.js index 71dbae7a..e0b43609 100644 --- a/tests/Select.tree.spec.js +++ b/tests/Select.tree.spec.js @@ -1,8 +1,10 @@ /* eslint-disable no-undef, react/no-multi-comp, no-console */ import React from 'react'; -import { mount } from 'enzyme'; +import { render, fireEvent, act } from '@testing-library/react'; import { resetWarned } from '@rc-component/util/lib/warning'; import TreeSelect, { TreeNode as SelectNode } from '../src'; +import { selectNode, triggerOpen, expectOpen } from './util'; +import { mount } from 'enzyme'; describe('TreeSelect.tree', () => { const createSelect = props => ( @@ -71,7 +73,7 @@ describe('TreeSelect.tree', () => { it('warning if node key are not same as value', () => { resetWarned(); const spy = jest.spyOn(console, 'error').mockImplementation(() => {}); - mount(); + render(); expect(spy).toHaveBeenCalledWith( 'Warning: `key` or `value` with TreeNode must be the same or you can remove one of them. key: little, value: ttt.', ); @@ -81,7 +83,7 @@ describe('TreeSelect.tree', () => { it('warning if node undefined value', () => { resetWarned(); const spy = jest.spyOn(console, 'error').mockImplementation(() => {}); - mount(); + render(); expect(spy).toHaveBeenCalledWith('Warning: TreeNode `value` is invalidate: undefined'); spy.mockRestore(); }); @@ -89,7 +91,7 @@ describe('TreeSelect.tree', () => { it('warning if node has same value', () => { resetWarned(); const spy = jest.spyOn(console, 'error').mockImplementation(() => {}); - mount( + render( { // https://github.com/ant-design/ant-design/issues/14597 it('empty string is also a value', () => { - const wrapper = mount( + const { container } = render( , ); - expect(wrapper.getSelection(0).text()).toEqual('empty string'); + const selectionContent = container.querySelector('.rc-tree-select-content-value'); + expect(selectionContent?.textContent).toEqual('empty string'); }); describe('treeNodeLabelProp', () => { @@ -121,7 +124,7 @@ describe('TreeSelect.tree', () => { }, ].forEach(({ name, ...restProps }) => { it(name, () => { - const wrapper = mount( + const { container } = render( { />, ); - expect(wrapper.find('.rc-tree-select-tree-title').text()).toEqual('a light'); - expect(wrapper.find('.rc-tree-select-selection-item').text()).toEqual('Light'); + expect(container.querySelector('.rc-tree-select-tree-title')?.textContent).toEqual( + 'a light', + ); + expect(container.querySelector('.rc-tree-select-content-value')?.textContent).toEqual( + 'Light', + ); }); }); }); it('Node icon', () => { - const wrapper = mount( + const { container } = render( } /> , ); - expect(wrapper.exists('.bamboo-light')).toBeTruthy(); + expect(container.querySelector('.bamboo-light')).toBeTruthy(); }); it('dynamic with filter should not show expand icon', () => { - const wrapper = mount( + const { container } = render( { />, ); - expect(wrapper.exists('.rc-tree-select-tree-icon__open')).toBeFalsy(); + expect(container.querySelector('.rc-tree-select-tree-icon__open')).toBeFalsy(); }); }); diff --git a/tests/__snapshots__/Select.checkable.spec.tsx.snap b/tests/__snapshots__/Select.checkable.spec.tsx.snap index 559c4f80..198d4a14 100644 --- a/tests/__snapshots__/Select.checkable.spec.tsx.snap +++ b/tests/__snapshots__/Select.checkable.spec.tsx.snap @@ -3,291 +3,261 @@ exports[`TreeSelect.checkable uncheck remove by selector not treeCheckStrictly 1`] = `