import { render, screen, act } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import { Tabs, TabsProps } from '../Tabs'; import styles from '@patternfly/react-styles/css/components/Tabs/tabs'; import { Tab } from '../Tab'; import { TabTitleText } from '../TabTitleText'; import { TabTitleIcon } from '../TabTitleIcon'; import { TabContent } from '../TabContent'; import { TabContentBody } from '../TabContentBody'; import { createRef } from 'react'; jest.mock('../../../helpers/GenerateId/GenerateId'); const renderSeparateTabs = (props?: Pick) => { const contentRef1 = createRef(); const contentRef2 = createRef(); const contentRef3 = createRef(); let calculatedActiveKey; if (props?.defaultActiveKey) { calculatedActiveKey = props?.defaultActiveKey; } else { calculatedActiveKey = props?.activeKey; } return ( <> Tab item 1} tabContentId="refTab1Section" tabContentRef={contentRef1} /> Tab item 2} tabContentId="refTab2Section" tabContentRef={contentRef2} /> Tab item 3} tabContentId="refTab3Section" tabContentRef={contentRef3} />
); }; test(`Renders with classes ${styles.tabs} and ${styles.modifiers.animateCurrent} by default`, () => { render( Tab Content ); expect(screen.getByRole('region')).toHaveClass(`${styles.tabs} ${styles.modifiers.animateCurrent}`); }); test(`Renders with class ${styles.modifiers.initializingAccent} when component initially mounts`, () => { render( Tab Content ); expect(screen.getByRole('region')).toHaveClass(styles.modifiers.initializingAccent); }); test(`Does not render with class ${styles.modifiers.initializingAccent} when component is finished mounting`, () => { jest.useFakeTimers(); render( Tab Content ); act(() => { jest.advanceTimersByTime(500); }); expect(screen.getByRole('region')).not.toHaveClass(styles.modifiers.initializingAccent); jest.useRealTimers(); }); test(`Renders with class ${styles.modifiers.initializingAccent} when uncontrolled expandable component initially mounts`, async () => { const user = userEvent.setup({ advanceTimers: jest.advanceTimersByTime }); render( Tab Content ); jest.useFakeTimers(); await user.click(screen.getByRole('button', { name: 'Jump to section' })); act(() => { jest.advanceTimersByTime(100); }); expect(screen.getByRole('region')).toHaveClass(styles.modifiers.initializingAccent); jest.useRealTimers(); }); test(`Does not render with class ${styles.modifiers.initializingAccent} when uncontrolled expandable component is finished mounting`, async () => { const user = userEvent.setup(); render( Tab Content ); await user.click(screen.getByRole('button', { name: 'Jump to section' })); expect(screen.getByRole('region')).not.toHaveClass(styles.modifiers.initializingAccent); }); test(`Renders with class ${styles.modifiers.nav} when isNav is true`, () => { render( Tab Content ); expect(screen.getByRole('region')).toHaveClass(styles.modifiers.nav); }); test(`Renders with div wrapper by default`, () => { render( Tab Content ); expect(screen.queryByRole('navigation')).not.toBeInTheDocument(); }); test(`Renders with nav wrapper when component="nav"`, () => { render( Tab Content ); expect(screen.getByRole('navigation')).toBeInTheDocument(); }); test(`Renders with nav wrapper when isNav is true`, () => { render( Tab Content ); expect(screen.getByRole('navigation')).toBeInTheDocument(); }); test(`Overrides isNav nav wrapper when component="div" is passed`, () => { render( Tab Content ); expect(screen.queryByRole('navigation')).not.toBeInTheDocument(); }); test('should render simple tabs', () => { const { asFragment } = render( "Tab item 1"}> Tab 1 section "Tab item 2"}> Tab 2 section "Tab item 3"}> Tab 3 section 4 {' '} Users{' '} } > Tab 4 section ); expect(asFragment()).toMatchSnapshot(); }); test('should render closeable tabs', () => { render( "Tab item 1"} closeButtonAriaLabel="close-label"> Tab 1 section ); expect(screen.getByLabelText('close-label')).toBeTruthy(); }); test('should render add button', () => { render( "Tab item 1"} closeButtonAriaLabel="close-label"> Tab 1 section ); expect(screen.getByLabelText('add-label')).toBeTruthy(); }); test('should render uncontrolled tabs', () => { const { asFragment } = render( "Tab item 1"}> Tab 1 section "Tab item 2"}> Tab 2 section "Tab item 3"}> Tab 3 section 4 {' '} Users{' '} } > Tab 4 section ); expect(asFragment()).toMatchSnapshot(); }); test('should render vertical tabs', () => { const { asFragment } = render( "Tab item 1"}> Tab 1 section "Tab item 2"}> Tab 2 section "Tab item 3"}> Tab 3 section 4 {' '} Users{' '} } > Tab 4 section ); expect(asFragment()).toMatchSnapshot(); }); test('should render expandable vertical tabs', () => { const { asFragment } = render( "Tab item 1"}> Tab 1 section "Tab item 2"}> Tab 2 section "Tab item 3"}> Tab 3 section 4 {' '} Users{' '} } > Tab 4 section ); expect(asFragment()).toMatchSnapshot(); }); test('should log error when there is no aria-label or toggleText for expandable vertical tabs', () => { const consoleErrorMock = jest.fn(); global.console = { error: consoleErrorMock } as any; render( "Tab item 1"}> Tab 1 section "Tab item 2"}> Tab 2 section "Tab item 3"}> Tab 3 section 4 {' '} Users{' '} } > Tab 4 section ); expect(consoleErrorMock).toHaveBeenCalled(); }); test('should render box tabs', () => { const { asFragment } = render( "Tab item 1"}> Tab 1 section "Tab item 2"}> Tab 2 section "Tab item 3"}> Tab 3 section 4 {' '} Users{' '} } > Tab 4 section ); expect(asFragment()).toMatchSnapshot(); }); test('should render accessible tabs', () => { const { asFragment } = render( "Tab item 1"} href="#/items/1"> Tab 1 section "Tab item 2"} href="#/items/2"> Tab 2 section "Tab item 3"} href="#/items/3"> Tab 3 section ); expect(asFragment()).toMatchSnapshot(); }); test('should render filled tabs', () => { const { asFragment } = render( "Tab item 1"}> Tab 1 section "Tab item 2"}> Tab 2 section "Tab item 3"}> Tab 3 section ); expect(asFragment()).toMatchSnapshot(); }); test('should render subtabs', () => { const { asFragment } = render( "Tab item 1"}> "Subtab item 1"}> Subtab 1 section "Subtab item 2"}> Subtab 2 section "Subtab item 3"}> Subtab 3 section "Tab item 2"}> Tab 2 section "Tab item 3"}> Tab 3 section ); expect(asFragment()).toMatchSnapshot(); }); test('should render tabs with eventKey Strings', () => { const { asFragment } = render( "Secondary Tab item 1"}> Tab 1 section "Secondary Tab item 2"}> Tab 2 section "Secondary Tab item 3"}> Tab 3 section ); expect(asFragment()).toMatchSnapshot(); }); test('should render tabs with separate content', () => { const contentRef1: React.RefObject = null; const contentRef2: React.RefObject = null; const contentRef3: React.RefObject = null; const { asFragment } = render( <> Tab item 1} tabContentId="refTab1Section" tabContentRef={contentRef1} /> Tab item 2} tabContentId="refTab2Section" tabContentRef={contentRef2} /> Tab item 3} tabContentId="refTab3Section" tabContentRef={contentRef3} />
Tab 1 section
); expect(asFragment()).toMatchSnapshot(); }); test('should render correct tab content for uncontrolled tabs with separate content', () => { render(renderSeparateTabs({ defaultActiveKey: 1 })); expect(screen.getByText(/Tab 1 section/i)).not.toBeVisible(); expect(screen.getByText(/Tab 2 section/i)).toBeVisible(); expect(screen.getByText(/Tab 3 section with padding/i)).not.toBeVisible(); }); test('should correctly advance tab content for uncontrolled tabs with separate content', async () => { render(renderSeparateTabs({ defaultActiveKey: 1 })); userEvent.setup(); expect(screen.getByText(/Tab 1 section/i)).not.toBeVisible(); expect(screen.getByText(/Tab 2 section/i)).toBeVisible(); expect(screen.getByText(/Tab 3 section with padding/i)).not.toBeVisible(); await userEvent.click(screen.getByRole('tab', { name: /Tab item 1/i })); expect(screen.getByText(/Tab 1 section/i)).toBeVisible(); expect(screen.getByText(/Tab 2 section/i)).not.toBeVisible(); }); test('should render correct tab content for controlled tabs with separate content', () => { render(renderSeparateTabs({ activeKey: 1 })); expect(screen.getByText(/Tab 1 section/i)).not.toBeVisible(); expect(screen.getByText(/Tab 2 section/i)).toBeVisible(); expect(screen.getByText(/Tab 3 section with padding/i)).not.toBeVisible(); }); test('should correctly advance tab content for controlled tabs with separate content', async () => { render(renderSeparateTabs({ activeKey: 1 })); userEvent.setup(); expect(screen.getByText(/Tab 1 section/i)).not.toBeVisible(); expect(screen.getByText(/Tab 2 section/i)).toBeVisible(); expect(screen.getByText(/Tab 3 section with padding/i)).not.toBeVisible(); await userEvent.click(screen.getByRole('tab', { name: /Tab item 1/i })); expect(screen.getByText(/Tab 1 section/i)).toBeVisible(); expect(screen.getByText(/Tab 2 section/i)).not.toBeVisible(); }); test('should render box tabs of secondary variant', () => { const { asFragment } = render( "Tab item 1"}> Tab 1 section "Tab item 2"}> Tab 2 section "Tab item 3"}> Tab 3 section ); expect(asFragment()).toMatchSnapshot(); }); test('should render tabs with no bottom border', () => { const { asFragment } = render( "Tab item 1"}> Tab 1 section "Tab item 2"}> Tab 2 section "Tab item 3"}> Tab 3 section ); expect(asFragment()).toMatchSnapshot(); }); test('should render subtabs with no bottom border when passed hasNoBorderBottom', () => { render( "Tab item 1"}> Tab 1 section "Tab item 2"}> Tab 2 section "Tab item 3"}> Tab 3 section ); const tabsContainer = screen.queryByLabelText('Subtab bottom border'); expect(tabsContainer).toHaveClass('pf-m-no-border-bottom'); }); test('should render subtabs with border bottom', () => { render( "Tab item 1"}> Tab 1 section "Tab item 2"}> Tab 2 section "Tab item 3"}> Tab 3 section ); const tabsContainer = screen.queryByLabelText('Subtab bottom border'); expect(tabsContainer).not.toHaveClass('pf-m-no-border-bottom'); }); test('should not render scroll buttons by default', () => { render( "Tab item 1"}> Tab 1 section "Tab item 2"}> Tab 2 section "Tab item 3"}> Tab 3 section ); expect(screen.queryByLabelText('Scroll left')).not.toBeInTheDocument(); expect(screen.queryByLabelText('Scroll right')).not.toBeInTheDocument(); }); test('should not render scroll buttons when isVertical is true', () => { render( "Tab item 1"}> Tab 1 section "Tab item 2"}> Tab 2 section "Tab item 3"}> Tab 3 section ); expect(screen.queryByLabelText('Scroll left')).not.toBeInTheDocument(); expect(screen.queryByLabelText('Scroll right')).not.toBeInTheDocument(); }); test('should render a disabled add button', () => { render(
Tab content
); const addButton = screen.getByLabelText('add-label'); expect(addButton).toBeDisabled(); }); test('should render an enabled add button', () => { render(
Tab content
); const addButton = screen.getByLabelText('add-label'); expect(addButton).not.toBeDisabled(); }); test(`should render with custom inline style and accent position inline style`, () => { render( Tab Content ); expect(screen.getByRole('region')).toHaveStyle(`background-color: #12345;--pf-v6-c-tabs--link-accent--start: 0px;`); }); test('should render tablist aria-label when provided', () => { const { asFragment } = render( "Tab item 1"}> Tab 1 section "Tab item 2"}> Tab 2 section ); expect(asFragment()).toMatchSnapshot(); }); test('should render tablist aria-labelledby when provided', () => { const { asFragment } = render( <>

My tabs heading

"Tab item 1"}> Tab 1 section "Tab item 2"}> Tab 2 section ); expect(asFragment()).toMatchSnapshot(); }); test('should not render tablist aria-label or aria-labelledby when neither is provided', () => { const { asFragment } = render( "Tab item 1"}> Tab 1 section "Tab item 2"}> Tab 2 section ); expect(asFragment()).toMatchSnapshot(); });