import React from 'react';
import styled, { css } from 'styled-components';
import 'jest-styled-components';
import 'jest-axe/extend-expect';
import 'regenerator-runtime/runtime';
import { axe } from 'jest-axe';
import { render, fireEvent, screen } from '@testing-library/react';
import { Grommet, Tab, Tabs } from '../..';
import { ThemeType } from '../../../themes';
describe('Tabs', () => {
test('should have no accessibility violations', async () => {
const { container } = render(
,
);
const results = await axe(container);
expect(results).toHaveNoViolations();
expect(container).toMatchSnapshot();
});
test('no Tab', () => {
const { container } = render(
,
);
expect(container.firstChild).toMatchSnapshot();
});
test('no Tabs', () => {
const { container } = render(
,
);
expect(container.firstChild).toMatchSnapshot();
});
test('Tab', () => {
const { container } = render(
Tab body 1
{undefined}
Tab body 2
,
);
expect(container.firstChild).toMatchSnapshot();
});
test('complex title', () => {
const { container } = render(
Tab 1}>Tab body 1
{undefined}
Tab 2}>Tab body 2
,
);
expect(container.firstChild).toMatchSnapshot();
});
test('with icon + reverse', () => {
const { container } = render(
}>
Tab body 1
} reverse>
Tab body 2
,
);
expect(container.firstChild).toMatchSnapshot();
});
test('alignControls', () => {
const { container } = render(
Tab body 1
Tab body 2
,
);
expect(container.firstChild).toMatchSnapshot();
});
test('Custom Tab component', () => {
const CustomTab = () => Tab body 1;
const { container } = render(
Tab body 2
,
);
expect(container.firstChild).toMatchSnapshot();
});
test('change to second tab', () => {
const onActive = jest.fn();
const { getByText, container } = render(
Tab body 1
Tab body 2
,
);
expect(container.firstChild).toMatchSnapshot();
fireEvent.click(getByText('Tab 2'));
expect(onActive).toBeCalledWith(1);
expect(container.firstChild).toMatchSnapshot();
});
test('set on hover', () => {
const { getByText, container } = render(
{/* eslint-disable-next-line jsx-a11y/mouse-events-have-key-events */}
{}} onMouseOut={() => {}}>
Tab body 1
Tab body 2
,
);
expect(container.firstChild).toMatchSnapshot();
fireEvent.mouseOver(getByText('Tab 1'));
expect(container.firstChild).toMatchSnapshot();
fireEvent.mouseOver(getByText('Tab 2'));
expect(container.firstChild).toMatchSnapshot();
fireEvent.mouseOut(getByText('Tab 1'));
expect(container.firstChild).toMatchSnapshot();
fireEvent.mouseOut(getByText('Tab 2'));
expect(container.firstChild).toMatchSnapshot();
});
test('should style as disabled', () => {
const { container } = render(
This tab is enabled
This tab is disabled
,
);
expect(container.firstChild).toMatchSnapshot();
});
test('should apply custom theme disabled style', () => {
const disabledTextColor = 'blue';
const disabledBorderBottomColor = 'green';
const customTheme = {
tab: {
border: {
disabled: {
color: disabledBorderBottomColor,
},
},
disabled: {
color: disabledTextColor,
},
},
};
const { container, getByText } = render(
This tab is enabled
This tab is disabled
,
);
expect(container.firstChild).toMatchSnapshot();
const disabledTab = getByText('Disabled Tab').parentElement!;
const disabledTabStyle = window.getComputedStyle(disabledTab);
expect(disabledTabStyle.color).toBe(disabledTextColor);
expect(disabledTabStyle.borderBottomColor).toBe(disabledBorderBottomColor);
});
test(`should apply custom theme disabled style when theme.button.default is
defined`, () => {
const disabledTextColor = 'blue';
const disabledBorderBottomColor = 'green';
const customTheme = {
button: {
default: {},
},
tab: {
border: {
disabled: {
color: disabledBorderBottomColor,
},
},
disabled: {
color: disabledTextColor,
},
},
};
const { container, getByText } = render(
This tab is enabled
This tab is disabled
,
);
expect(container.firstChild).toMatchSnapshot();
const disabledTab = getByText('Disabled Tab').parentElement!;
const disabledTabStyle = window.getComputedStyle(disabledTab);
expect(disabledTabStyle.color).toBe(disabledTextColor);
expect(disabledTabStyle.borderBottomColor).toBe(disabledBorderBottomColor);
});
test('styled component should change tab color when active', () => {
// @ts-ignore
const ButtonTab = styled(Tab)<{ active?: boolean }>`
${(props) => css`
background: ${props.active ? 'blue' : 'green'};
`}
`;
const { container, getByText } = render(
,
);
fireEvent.click(getByText('Activity'));
expect(container.firstChild).toMatchSnapshot();
});
test('should have no default styles with plain prop', () => {
const { container, getByText } = render(
,
);
expect(container.firstChild).toMatchSnapshot();
const plainTab = getByText('Title 1').parentElement!;
const plainTabStyle = window.getComputedStyle(plainTab);
expect(plainTabStyle.borderBottom).toBe('');
});
test('should allow to extend tab styles', () => {
const customTheme: ThemeType = {
tab: {
extend: `color: red;
padding: 20px;
box-shadow: rgba(0, 0, 0, 0.25) 0px 54px 55px, rgba(0, 0, 0, 0.12) 0px -12px 30px, rgba(0, 0, 0, 0.12) 0px 4px 6px, rgba(0, 0, 0, 0.17) 0px 12px 13px, rgba(0, 0, 0, 0.09) 0px -3px 5px;
margin: 30px;`,
},
};
const { container, getByText } = render(
Some content
Some content 2
,
);
expect(container.firstChild).toMatchSnapshot();
const extendedPlainTab = getByText('Title 1')!;
const extendedPlainTabStyle = window.getComputedStyle(extendedPlainTab);
// color can be changed only when plain prop used
expect(extendedPlainTabStyle.color).toBe('red');
const extendedTab = getByText('Title 2')!;
const extendedTabStyle = window.getComputedStyle(extendedTab);
expect(extendedTabStyle.color).not.toBe('red');
const extendedTabParent = extendedTab.parentElement!;
const extendedTabParentStyle = window.getComputedStyle(extendedTabParent);
expect(extendedTabParentStyle.padding).toBe('20px');
});
test('onClick', () => {
const onClick = jest.fn();
const { getByText, container } = render(
Tab body 1
Tab body 2
,
);
expect(container.firstChild).toMatchSnapshot();
fireEvent.click(getByText('Tab 2'));
expect(onClick).toBeCalled();
});
test('should apply theme alignSelf to tab controls', () => {
const customTheme = {
tabs: {
header: {
alignSelf: 'start',
},
},
};
const { asFragment } = render(
This tab is first
This tab is second
,
);
expect(asFragment()).toMatchSnapshot();
const tabsHeader = screen.getByRole('tablist')!;
const tabsHeaderStyle = window.getComputedStyle(tabsHeader);
expect(tabsHeaderStyle.alignSelf).toBe('flex-start');
});
});