Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: increase test coverage for ToggleTip #17661

Merged
merged 4 commits into from
Oct 9, 2024
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
240 changes: 240 additions & 0 deletions packages/react/src/components/Toggletip/__tests__/Toggletip-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -202,5 +202,245 @@ describe('Toggletip', () => {
);
});
});

describe('ToggletipLabel', () => {
it('should render with custom element using as prop', () => {
const CustomElement = forwardRef((props, ref) => (
<div data-testid="custom-label" ref={ref} {...props} />
));

render(<Toggletip as={CustomElement}>Label</Toggletip>);
expect(screen.getByTestId('custom-label')).toBeInTheDocument();
});
});

describe('ToggletipButton', () => {
const CustomButton = forwardRef((props, ref) => (
<div data-testid="custom-button" ref={ref} {...props} />
));

it('should render custom component with onClick handler', () => {
render(
<Toggletip>
<ToggletipButton as={CustomButton}>Click me</ToggletipButton>
</Toggletip>
);

const button = screen.getByTestId('custom-button');
expect(button).toBeInTheDocument();
fireEvent.click(button);
2nikhiltom marked this conversation as resolved.
Show resolved Hide resolved
});

it('should use default label when not provided', () => {
render(
<Toggletip>
<ToggletipButton>
<span>Icon</span>
</ToggletipButton>
</Toggletip>
);

expect(screen.getByRole('button')).toHaveAttribute(
'aria-label',
'Show information'
);
});
});

describe('ToggletipContent', () => {
it('should render with custom className', () => {
render(
<Toggletip defaultOpen>
<ToggletipContent className="custom-content">
Content
</ToggletipContent>
</Toggletip>
);

expect(screen.getByText('Content').parentElement).toHaveClass(
'custom-content'
);
});

it('should have correct aria attributes', async () => {
render(
<Toggletip>
<ToggletipButton>Toggle</ToggletipButton>
<ToggletipContent>Content</ToggletipContent>
</Toggletip>
);

expect(screen.getByText('Toggle')).toHaveAttribute(
'aria-expanded',
'false'
);
await userEvent.click(screen.getByText('Toggle'));
expect(screen.getByText('Toggle')).toHaveAttribute(
'aria-expanded',
'true'
);
});
});

describe('ToggletipActions', () => {
it('should render with custom className', () => {
render(
<ToggletipActions className="custom-actions">
<button>Action</button>
</ToggletipActions>
);

expect(screen.getByRole('button').parentElement).toHaveClass(
'custom-actions'
);
});
});

describe('Toggletip Keyboard Navigation', () => {
it('should handle Tab navigation correctly', async () => {
render(
<Toggletip defaultOpen>
<ToggletipButton>Toggle</ToggletipButton>
<ToggletipContent>
<button>Action 1</button>
<button>Action 2</button>
</ToggletipContent>
</Toggletip>
);

const toggleButton = screen.getByText('Toggle');
await userEvent.tab();
expect(toggleButton).toHaveFocus();
});

it('should close on blur when focus moves outside', async () => {
render(
<>
<button>Outside</button>
<Toggletip defaultOpen>
<ToggletipButton>Toggle</ToggletipButton>
<ToggletipContent>Content</ToggletipContent>
</Toggletip>
</>
);

const outsideButton = screen.getByText('Outside');
await userEvent.click(outsideButton);
expect(screen.getByText('Toggle')).toHaveAttribute(
'aria-expanded',
'false'
);
});
});

describe('Toggletip Focus Management', () => {
it('should return focus to trigger button when closing with Escape', async () => {
render(
<Toggletip defaultOpen>
<ToggletipButton>Toggle</ToggletipButton>
<ToggletipContent>
<button>Action</button>
</ToggletipContent>
</Toggletip>
);

const actionButton = screen.getByText('Action');
actionButton.focus();
await userEvent.keyboard('{Escape}');

expect(screen.getByText('Toggle')).toHaveFocus();
});
});

describe('Toggletip Alignment', () => {
it.each([
'left-start',
'left-end',
'right-start',
'right-end',
'top-start',
'top-end',
'bottom-start',
'bottom-end',
])('should handle %s alignment correctly', (alignment) => {
const { container } = render(
<Toggletip align={alignment} defaultOpen>
<ToggletipButton>Toggle</ToggletipButton>
<ToggletipContent>Content</ToggletipContent>
</Toggletip>
);

expect(container.firstChild).toHaveClass(`cds--popover--${alignment}`);
});
});

describe('Toggletip Closing Behavior', () => {
it('should not close when clicking inside the toggletip during auto-alignment', async () => {
render(
<Toggletip autoAlign defaultOpen>
<ToggletipButton>Toggle</ToggletipButton>
<ToggletipContent>
<div data-testid="content">Content</div>
</ToggletipContent>
</Toggletip>
);

await userEvent.click(screen.getByTestId('content'));
expect(screen.getByText('Toggle')).toHaveAttribute(
'aria-expanded',
'true'
);
});

it('should close when focus moves outside the toggletip', () => {
const { container } = render(
<>
<button data-testid="external-button">External</button>
<Toggletip defaultOpen>
<ToggletipButton>Toggle</ToggletipButton>
<ToggletipContent>Content</ToggletipContent>
</Toggletip>
</>
);

const toggleButton = screen.getByText('Toggle');
const externalButton = screen.getByTestId('external-button');

fireEvent.blur(toggleButton, {
2nikhiltom marked this conversation as resolved.
Show resolved Hide resolved
relatedTarget: externalButton,
});

expect(container.lastChild).not.toHaveClass(
`${prefix}--toggletip--open`
);
expect(container.lastChild).not.toHaveClass(`${prefix}--popover--open`);
});

it('should not close when open and relatedTarget is null', () => {
const { container } = render(
<Toggletip defaultOpen>
<ToggletipButton>Toggle</ToggletipButton>
<ToggletipContent>
<button>Action</button>
</ToggletipContent>
</Toggletip>
);

expect(container.firstChild).toHaveClass(`${prefix}--toggletip--open`);
const toggletipWrapper = container.firstChild;

fireEvent.blur(toggletipWrapper, {
2nikhiltom marked this conversation as resolved.
Show resolved Hide resolved
currentTarget: toggletipWrapper,
relatedTarget: null,
});

expect(container.firstChild).toHaveClass(`${prefix}--toggletip--open`);
expect(container.firstChild).toHaveClass(`${prefix}--popover--open`);
expect(screen.getByText('Toggle')).toHaveAttribute(
'aria-expanded',
'true'
);
});
});
});
});
Loading