Skip to content

Commit

Permalink
test(tabs): include unit test for Tabs components
Browse files Browse the repository at this point in the history
  • Loading branch information
cafrias committed Nov 8, 2023
1 parent 628ba27 commit ffc39bd
Show file tree
Hide file tree
Showing 2 changed files with 76 additions and 164 deletions.
4 changes: 2 additions & 2 deletions packages/react/src/components/Tabs/index.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,9 @@ export default {

export const Uncontrolled = () => (
<div style={{ maxWidth: '960px' }}>
<Tabs defaultSelectedIndex={0}>
<Tabs>
<TabList>
<Tab>Cats</Tab>
<Tab disabled>Cats</Tab>
<Tab>Dogs</Tab>
<Tab disabled>Horses</Tab>
<Tab>Cows</Tab>
Expand Down
236 changes: 74 additions & 162 deletions packages/react/src/components/Tabs/index.test.tsx
Original file line number Diff line number Diff line change
@@ -1,162 +1,74 @@
// import test from 'ava';
// import React from 'react';
// import {
// cleanup, render, fireEvent, screen,
// } from '@testing-library/react';
// import {
// Tabs, Tab, TabList, TabPanels, TabPanel,
// } from '.';
// import { shortContent } from './modal.fixtures';

// test.afterEach(cleanup);

// test('the default modal contains focus when open', (t) => {
// render(<Tabs isOpen title={defaultTitle}>{shortContent}</Tabs>);
// t.true(screen.getByRole('dialog').contains(document.activeElement));
// });

// test('a modal without the default close button contains focus when open', (t) => {
// render(<Tabs isOpen title={defaultTitle} hideCloseButton>{shortContent}</Tabs>);
// t.true(screen.getByRole('dialog').contains(document.activeElement));
// });

// test('a modal with no focusable elements still contains focus when open', (t) => {
// render((
// <Tabs
// isOpen
// title={defaultTitle}
// hideTitle
// hideCloseButton
// >
// {shortContent}
// </Tabs>
// ));
// t.true(screen.getByRole('dialog').contains(document.activeElement));
// });

// test('the initially focused element can be chosen before render', (t) => {
// const testId = 'focused';
// const InitiallyFocused = () => {
// const [el, setEl] = React.useState<HTMLButtonElement | null>(null);
// return (
// <Tabs isOpen title={defaultTitle} focusOnOpen={el}>
// {shortContent}
// <button type="button" ref={setEl} data-testid={testId}>Focused button</button>
// </Tabs>
// );
// };

// render(<InitiallyFocused />);
// t.is(document.activeElement, screen.getByTestId(testId));
// });

// // fixture for inner focus tests
// const InnerFocus = () => (
// <Tabs
// isOpen
// title={defaultTitle}
// hideCloseButton
// actions={(
// <>
// <button type="button" data-testid="second">Second</button>
// <button type="button" data-testid="last">Last</button>
// </>
// )}
// >
// <button type="button" data-testid="first">First</button>
// {shortContent}
// </Tabs>
// );

// test('`Shift + Tab` wraps focus when on the first focusable element', (t) => {
// render(<InnerFocus />);
// fireEvent.keyDown(document.activeElement, { key: 'Tab', shiftKey: true });
// t.is(document.activeElement, screen.getByTestId('last'));
// });

// test('`Tab` wraps focus when on the last focusable element', (t) => {
// render(<InnerFocus />);
// const lastEl = screen.getByTestId('last');
// lastEl.focus();
// fireEvent.keyDown(document.activeElement, { key: 'Tab', shiftKey: false });
// t.is(document.activeElement, screen.getByTestId('first'));
// });

// // fixture for controlled open tests
// // eslint-disable-next-line react/require-default-props
// const Controlled = ({ isOpen: openProp = false }: { isOpen?: boolean }) => {
// const [isOpen, setOpen] = React.useState(openProp);
// const toggle = () => setOpen(!isOpen);
// return (
// <>
// <button
// type="button"
// onClick={() => setOpen(true)}
// data-testid="trigger"
// >
// Open modal
// </button>
// <Tabs
// isOpen={isOpen}
// onRequestClose={toggle}
// title={defaultTitle}
// >
// {shortContent}
// </Tabs>
// </>
// );
// };

// test('the modal can be closed by clicking the internal close button', (t) => {
// render(<Controlled isOpen />);
// fireEvent.click(document.activeElement);
// t.falsy(screen.queryByRole('dialog'));
// });

// test('the modal can be closed by clicking the backdrop', (t) => {
// render(<Controlled isOpen />);
// fireEvent.click(screen.getByRole('dialog').parentElement);
// t.falsy(screen.queryByRole('dialog'));
// });

// test('the modal can be closed with the `Escape` key', (t) => {
// render(<Controlled isOpen />);
// fireEvent.keyDown(document.activeElement, { key: 'Escape' });
// t.falsy(screen.queryByRole('dialog'));
// });

// test('the modal cannot be closed by releasing the click from inside the dialog
// to outside', (t) => {
// render(<Controlled isOpen />);
// fireEvent.pointerDown(screen.getByRole('dialog'));
// fireEvent.pointerUp(screen.getByRole('dialog').parentElement);
// t.truthy(screen.queryByRole('dialog'));
// });

// test('on close, focus returns to the element that opened the modal', (t) => {
// render(<Controlled />);
// const trigger = screen.getByTestId('trigger');
// // force focus on the trigger since fireEvent.click doesn't simulate it
// trigger.focus();
// // open the modal
// fireEvent.click(trigger);
// // close the modal
// fireEvent.keyDown(document.activeElement, { key: 'Escape' });

// t.is(document.activeElement, trigger);
// });

// test('existing body styles are preserved when the modal closes', (t) => {
// document.body.style.overflow = 'visible';
// const bodyCSSText = document.body.style.cssText;

// render(<Controlled isOpen />);

// // body styles should be overwritten on open
// t.not(document.body.style.cssText, bodyCSSText);

// fireEvent.click(document.activeElement);

// // and restored on close
// t.is(document.body.style.cssText, bodyCSSText);
// });
import test from 'ava';
import React from 'react';
import {
cleanup, render, fireEvent, screen,
} from '@testing-library/react';
import {
Tabs, Tab, TabList, TabPanels, TabPanel,
} from '.';

test.beforeEach(() => {
global.ResizeObserver = function ResizeObserver() {
return {
observe: () => {},
disconnect: () => {},
};
} as any;

Check warning on line 16 in packages/react/src/components/Tabs/index.test.tsx

View workflow job for this annotation

GitHub Actions / ESLint

Unexpected any. Specify a different type
});

test.afterEach(cleanup);

test('clicking on tabs, switches panels', (t) => {
render(
<Tabs>
<TabList>
<Tab>Cats</Tab>
<Tab>Dogs</Tab>
</TabList>
<TabPanels>
<TabPanel>Cats content</TabPanel>
<TabPanel>Dogs content</TabPanel>
</TabPanels>
</Tabs>,
);

// Cats is selected by default
const catsTab = screen.getByRole('tab', { name: 'Cats' });
t.true(catsTab.getAttribute('aria-selected') === 'true');
const catsPanel = screen.queryByRole('tabpanel', { name: 'Cats' });
t.true(catsPanel !== null);

// TabPanel changes when click on Dogs Tab
const dogsTab = screen.getByRole('tab', { name: 'Dogs' });
fireEvent.click(dogsTab);

const dogsPanel = screen.queryByRole('tabpanel', { name: 'Dogs' });
t.true(dogsPanel !== null);
});

test('clicking on disabled tab, will not switch panel', (t) => {
render(
<Tabs>
<TabList>
<Tab>Cats</Tab>
<Tab disabled>Dogs</Tab>
</TabList>
<TabPanels>
<TabPanel>Cats content</TabPanel>
<TabPanel>Dogs content</TabPanel>
</TabPanels>
</Tabs>,
);

// TabPanel changes when click on Dogs Tab
const dogsTab = screen.getByRole('tab', { name: 'Dogs' });
t.true((dogsTab as HTMLButtonElement).disabled === true);
fireEvent.click(dogsTab);

const catsPanel = screen.queryByRole('tabpanel', { name: 'Cats' });
t.true(catsPanel !== null);
});

test.skip('when first tab disabled, default panel must be valid', () => {
// TBD
});

0 comments on commit ffc39bd

Please sign in to comment.