/* eslint-disable react/no-unstable-nested-components */ import React, { useEffect, useRef } from 'react'; import Tour from '..'; import mountTest from '../../../tests/shared/mountTest'; import rtlTest from '../../../tests/shared/rtlTest'; import { fireEvent, render, screen } from '../../../tests/utils'; import type { TourProps } from '../interface'; describe('Tour', () => { mountTest(Tour); rtlTest(Tour); it('single', () => { const App: React.FC = () => { const coverBtnRef = useRef(null); return ( <> coverBtnRef.current!, }, ]} /> ); }; const { getByText, baseElement } = render(); expect(getByText('cover title')).toBeTruthy(); expect(getByText('cover description.')).toBeTruthy(); expect(baseElement).toMatchSnapshot(); }); it('steps is empty', () => { const App: React.FC = () => { const coverBtnRef = useRef(null); return ( <> ); }; const { baseElement } = render(); expect(baseElement).toMatchSnapshot(); }); it('steps props indicatorsRender', () => { const onClickMock = jest.fn(); const indicatorsRenderMock = jest.fn(); const App: React.FC = () => { const coverBtnRef = useRef(null); return ( <> ); }; const { baseElement } = render(); fireEvent.click(screen.getByRole('button', { name: 'Next' })); fireEvent.click(screen.getByRole('button', { name: 'Previous' })); fireEvent.click(screen.getByRole('button', { name: 'Next' })); fireEvent.click(screen.getByRole('button', { name: 'Next' })); fireEvent.click(screen.getByRole('button', { name: 'Finish' })); expect(onClickMock).toHaveBeenCalledTimes(5); expect(baseElement).toMatchSnapshot(); }); it('button props onClick', () => { const App: React.FC = () => { const coverBtnRef = useRef(null); const [btnName, steBtnName] = React.useState('defaultBtn'); return ( <> {btnName} coverBtnRef.current!, nextButtonProps: { onClick: () => steBtnName('nextButton'), }, }, { title: '', target: () => coverBtnRef.current!, prevButtonProps: { onClick: () => steBtnName('prevButton'), }, nextButtonProps: { onClick: () => steBtnName('finishButton'), }, }, ]} /> ); }; const { baseElement } = render(); expect(baseElement.querySelector('#btnName')).toHaveTextContent('defaultBtn'); fireEvent.click(screen.getByRole('button', { name: 'Next' })); expect(baseElement.querySelector('#btnName')).toHaveTextContent('nextButton'); fireEvent.click(screen.getByRole('button', { name: 'Previous' })); expect(baseElement.querySelector('#btnName')).toHaveTextContent('prevButton'); fireEvent.click(screen.getByRole('button', { name: 'Next' })); fireEvent.click(screen.getByRole('button', { name: 'Finish' })); expect(baseElement.querySelector('#btnName')).toHaveTextContent('finishButton'); expect(baseElement).toMatchSnapshot(); }); it('Primary', () => { const App: React.FC = () => { const coverBtnRef = useRef(null); return ( <> coverBtnRef.current!, }, ]} /> ); }; const { getByText, baseElement } = render(); expect(getByText('primary description.')).toBeTruthy(); expect(baseElement.querySelector('.ant-tour-content')?.parentElement).toHaveClass( 'ant-tour-primary', ); expect(baseElement).toMatchSnapshot(); }); it('step support Primary', () => { const App: React.FC = () => { const coverBtnRef = useRef(null); return ( <> coverBtnRef.current!, }, { title: 'primary title', description: 'primary description.', target: () => coverBtnRef.current!, type: 'primary', }, ]} /> ); }; const { getByText, container, baseElement } = render(); expect(getByText('cover description.')).toBeTruthy(); expect(container.querySelector('.ant-tour-primary .ant-tour-content')).toBeFalsy(); fireEvent.click(screen.getByRole('button', { name: 'Next' })); expect(getByText('primary description.')).toBeTruthy(); expect(container.querySelector('.ant-tour-primary .ant-tour-content')).toBeTruthy(); expect(baseElement).toMatchSnapshot(); }); it('basic', () => { const App: React.FC = () => { const coverBtnRef = useRef(null); const placementBtnRef = useRef(null); const [show, setShow] = React.useState(); useEffect(() => { if (show === false) { setShow(true); } }, [show]); return ( <>
{show && ( coverBtnRef.current!, cover: ( tour.png ), }, { title: 'Adjust Placement', description: 'Here is the content of Tour which show on the right.', placement: 'right', target: () => placementBtnRef.current!, }, ]} /> )} ); }; const { getByText, container, baseElement } = render(); fireEvent.click(screen.getByRole('button', { name: 'Show' })); expect(getByText('Show in Center')).toBeTruthy(); fireEvent.click(screen.getByRole('button', { name: 'Next' })); expect(getByText('Here is the content of Tour.')).toBeTruthy(); fireEvent.click(screen.getByRole('button', { name: 'Next' })); expect(getByText('Adjust Placement')).toBeTruthy(); fireEvent.click(screen.getByRole('button', { name: 'Finish' })); expect(container.querySelector('.ant-tour')).toBeFalsy(); expect(baseElement).toMatchSnapshot(); }); it('panelRender should correct render when total is undefined or null', () => { [undefined, null].forEach((total: undefined) => { const { container } = render(test, total }]} />); expect( container.querySelector('.ant-tour-content .ant-tour-indicators'), ).toBeFalsy(); }); }); it('panelRender should correct render when title is undefined or null', () => { [undefined, null].forEach((title) => { const { container } = render(); expect( container.querySelector('.ant-tour-content .ant-tour-header'), ).toBeFalsy(); }); }); it('custom step pre btn & next btn className & style', () => { const App: React.FC = () => ( ), }, ]} /> ); const { container } = render(); // className expect(screen.getByRole('button', { name: 'Next' }).className.includes('customClassName')).toBe( true, ); // style expect(screen.getByRole('button', { name: 'Next' }).style.backgroundColor).toEqual( 'rgb(69, 69, 255)', ); expect(container.firstChild).toMatchSnapshot(); }); it('custom indicator', () => { const steps: TourProps['steps'] = [ { title: 'Upload File', description: 'Put your files here.', }, { title: 'Save', description: 'Save your changes.', }, { title: 'Other Actions', description: 'Click to see other actions.', }, ]; const App: React.FC = () => ( ( {current + 1} / {total} )} /> ); const { container } = render(); expect(container.querySelector('.custom-indicator')).toBeTruthy(); }); it('controlled current', () => { const App: React.FC = () => { const [current, setCurrent] = React.useState(0); return ( <>
); }; const { getByText, container, baseElement } = render(); fireEvent.click(screen.getByRole('button', { name: 'SetCurrent' })); expect(getByText('Primary description.')).toBeTruthy(); expect(container.querySelector('.ant-tour-primary .ant-tour-content')).toBeTruthy(); expect(baseElement).toMatchSnapshot(); }); it('support closeIcon', () => { const Demo = ({ closeIcon = false }: { closeIcon?: React.ReactNode }) => { const createBtnRef = useRef(null); const updateBtnRef = useRef(null); const deleteBtnRef = useRef(null); return (
createBtnRef.current!, mask: true, }, { title: '更新', closeIcon: !closeIcon, description: (
更新一条数据
), target: () => updateBtnRef.current!, }, { title: '删除', closeIcon: Close, description: (
危险操作:删除一条数据
), target: () => deleteBtnRef.current!, }, ]} />
); }; const { baseElement, rerender } = render(); const resetIndex = () => { // reset fireEvent.click(baseElement.querySelector('.ant-tour-prev-btn')!); fireEvent.click(baseElement.querySelector('.ant-tour-prev-btn')!); }; expect(baseElement.querySelector('.ant-tour-close')).toBeFalsy(); fireEvent.click(baseElement.querySelector('.ant-tour-next-btn')!); expect(baseElement.querySelector('.ant-tour-close')).toBeTruthy(); expect(baseElement.querySelector('.ant-tour-close-icon')).toBeTruthy(); fireEvent.click(baseElement.querySelector('.ant-tour-next-btn')!); expect(baseElement.querySelector('.ant-tour-close')).toBeTruthy(); expect(baseElement.querySelector('.ant-tour-close-icon')).toBeFalsy(); expect(baseElement.querySelector('.custom-del-close-icon')).toBeTruthy(); resetIndex(); rerender(); expect(baseElement.querySelector('.ant-tour-close')).toBeTruthy(); expect(baseElement.querySelector('.ant-tour-close-icon')).toBeTruthy(); fireEvent.click(baseElement.querySelector('.ant-tour-next-btn')!); expect(baseElement.querySelector('.ant-tour-close')).toBeFalsy(); expect(baseElement.querySelector('.ant-tour-close-icon')).toBeFalsy(); fireEvent.click(baseElement.querySelector('.ant-tour-next-btn')!); expect(baseElement.querySelector('.ant-tour-close')).toBeTruthy(); expect(baseElement.querySelector('.ant-tour-close-icon')).toBeFalsy(); expect(baseElement.querySelector('.custom-del-close-icon')).toBeTruthy(); resetIndex(); rerender(X} />); expect(baseElement.querySelector('.ant-tour-close')).toBeTruthy(); expect(baseElement.querySelector('.custom-global-close-icon')).toBeTruthy(); fireEvent.click(baseElement.querySelector('.ant-tour-next-btn')!); expect(baseElement.querySelector('.ant-tour-close')).toBeFalsy(); expect(baseElement.querySelector('.ant-tour-close-icon')).toBeFalsy(); expect(baseElement.querySelector('.custom-global-close-icon')).toBeFalsy(); fireEvent.click(baseElement.querySelector('.ant-tour-next-btn')!); expect(baseElement.querySelector('.ant-tour-close')).toBeTruthy(); expect(baseElement.querySelector('.ant-tour-close-icon')).toBeFalsy(); expect(baseElement.querySelector('.custom-del-close-icon')).toBeTruthy(); resetIndex(); }); it('first step should be primary', () => { const App: React.FC = () => { const coverBtnRef = useRef(null); return ( <> coverBtnRef.current!, type: 'primary', className: 'should-be-primary', }, { title: '', target: () => coverBtnRef.current!, }, ]} /> ); }; render(); fireEvent.click(screen.getByRole('button', { name: 'target' })); expect(document.querySelector('.should-be-primary')).toBeTruthy(); expect(document.querySelector('.should-be-primary')).toHaveClass('ant-tour-primary'); }); });