import { userEvent, fireEvent, render, screen, mockMatchMedia } from '../test-utils'; import Display from '../display'; import Title from '../title'; import Carousel, { type CarouselCard } from './Carousel'; mockMatchMedia(); jest.mock('@wise/components-theming', () => ({ ...jest.requireActual>('@wise/components-theming'), useTheme: jest.fn().mockReturnValue({ theme: 'personal' }), })); const yourInvoiceOnClick = jest.fn(); const carouselCards: CarouselCard[] = [ { id: 'YOUR_INVOICE', type: 'anchor', href: 'https://wise.com', onClick: yourInvoiceOnClick, content:
Add a link in accounting software like Xero or QuickBooks.
, }, { id: 'YOUR_WEBSITE', type: 'button', onClick: () => {}, content: Wise., }, { id: 'SHOP_OR_STALL', type: 'anchor', href: 'https://wise.com', onClick: () => {}, content: Get Quick Pay, }, ]; const onClick = jest.fn(); const renderCarousel = () => { render(); }; describe('Carousel', () => { const focusSpy = jest.fn(); const scrollBy = jest.fn(); beforeEach(() => { window.HTMLElement.prototype.scrollIntoView = focusSpy; window.HTMLElement.prototype.scrollBy = scrollBy; }); afterEach(() => { focusSpy.mockClear(); }); it('shows expected content on page', async () => { renderCarousel(); expect( screen.getByText('Add a link in accounting software like Xero or QuickBooks.'), ).toBeInTheDocument(); expect(screen.getByText('Wise.')).toBeInTheDocument(); expect(screen.getByText('Get Quick Pay')).toBeInTheDocument(); }); it('allows user to scroll carousel to the right when at start', async () => { mockPositions(948, 903); renderCarousel(); const scrollLeftButton = screen.getByTestId('scroll-carousel-left'); const scrollRightButton = screen.getByTestId('scroll-carousel-right'); expect(scrollLeftButton).toBeDisabled(); expect(scrollRightButton).toBeEnabled(); await userEvent.click(scrollRightButton); expect(scrollBy).toHaveBeenCalledWith({ left: 300, behavior: 'smooth' }); }); it('allows user to scroll carousel to the left or right when in middle', async () => { mockPositions(948, 903); renderCarousel(); const carousel = screen.getByRole('list'); fireEvent.scroll(carousel, { target: { scrollLeft: 10 } }); const scrollLeftButton = screen.getByTestId('scroll-carousel-left'); const scrollRightButton = screen.getByTestId('scroll-carousel-right'); expect(scrollLeftButton).toBeEnabled(); expect(scrollRightButton).toBeEnabled(); await userEvent.click(scrollLeftButton); expect(scrollBy).toHaveBeenCalledWith({ left: -300, behavior: 'smooth' }); await userEvent.click(scrollRightButton); expect(scrollBy).toHaveBeenCalledWith({ left: 300, behavior: 'smooth' }); }); it('allows user to scroll carousel to the left when at end', async () => { mockPositions(948, 903); renderCarousel(); const carousel = screen.getByRole('list'); fireEvent.scroll(carousel, { target: { scrollLeft: 50 } }); const scrollLeftButton = screen.getByTestId('scroll-carousel-left'); const scrollRightButton = screen.getByTestId('scroll-carousel-right'); expect(scrollLeftButton).toBeEnabled(); expect(scrollRightButton).toBeDisabled(); await userEvent.click(scrollLeftButton); expect(scrollBy).toHaveBeenCalledWith({ left: -300, behavior: 'smooth' }); }); it('allows user to go through carousel by indicator', async () => { mockPositions(948, 903); renderCarousel(); const yourInvoiceIndicator = screen.getByTestId('YOUR_INVOICE-indicator'); const yourWebsiteIndicator = screen.getByTestId('YOUR_WEBSITE-indicator'); const shopOrStallIndicator = screen.getByTestId('SHOP_OR_STALL-indicator'); const firstCard = getFirstCard(); const secondCard = getSecondCard(); const thirdCard = getThirdCard(); expect(focusSpy).toHaveBeenCalledTimes(0); expect(firstCard).toHaveClass('carousel__card--focused'); await userEvent.click(yourWebsiteIndicator); expect(focusSpy).toHaveBeenCalledTimes(1); expect(secondCard).toHaveClass('carousel__card--focused'); await userEvent.click(shopOrStallIndicator); expect(focusSpy).toHaveBeenCalledTimes(2); expect(thirdCard).toHaveClass('carousel__card--focused'); await userEvent.click(yourInvoiceIndicator); expect(focusSpy).toHaveBeenCalledTimes(3); expect(firstCard).toHaveClass('carousel__card--focused'); }); it('is focused on the first element and lets user navigate through them', async () => { renderCarousel(); const firstCard = getFirstCard(); const secondCard = getSecondCard(); const thirdCard = getThirdCard(); expect(firstCard).toBeInTheDocument(); firstCard.focus(); expect(firstCard).toHaveFocus(); await userEvent.keyboard('{arrowright}'); expect(secondCard).toHaveFocus(); await userEvent.keyboard('{arrowright}'); expect(thirdCard).toHaveFocus(); await userEvent.keyboard('{arrowleft}'); expect(secondCard).toHaveFocus(); await userEvent.keyboard('{arrowleft}'); expect(firstCard).toHaveFocus(); }); it('calls onClick when a card is clicked', async () => { renderCarousel(); await userEvent.click(getFirstCard()); expect(onClick).toHaveBeenCalledTimes(1); expect(yourInvoiceOnClick).toHaveBeenCalledTimes(1); }); }); const mockPositions = (scrollWidth: number, offsetWidth: number) => { Object.defineProperty(HTMLElement.prototype, 'scrollWidth', { configurable: true, value: scrollWidth, }); Object.defineProperty(HTMLElement.prototype, 'offsetWidth', { configurable: true, value: offsetWidth, }); }; const getFirstCard = () => screen.getByRole('link', { name: /Add a link in accounting software like Xero or QuickBooks\./, }); const getSecondCard = () => screen.getByRole('button', { name: /Wise\./ }); const getThirdCard = () => screen.getByRole('link', { name: /Get Quick Pay/ });