import React from 'react';
import { screen, render, waitFor } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { ModalTrigger } from './ModalTrigger';
describe('Modal', () => {
it('Modal is closed by default', async () => {
render(
{(onClose, titleProps) => (
)}
,
);
expect(screen.queryByTestId('modal')).toBeFalsy();
expect(screen.queryAllByLabelText('Open testing modal')).toHaveLength(0);
});
it('Modal should render label', async () => {
render(
{(onClose, titleProps) => (
)}
,
);
expect(screen.getByLabelText('Open testing modal')).toBeTruthy();
});
it('Modal opens when triggered', async () => {
render(
{(onClose, titleProps) => (
)}
,
);
const user = userEvent.setup();
user.click(screen.getByText('Open testing modal'));
await waitFor(() => {
expect(screen.queryByTestId('modal')).toBeTruthy();
});
});
it('Clicking outside the modal closes it', async () => {
render(
{(onClose, titleProps) => (
)}
,
);
const user = userEvent.setup();
user.click(screen.getByText('Open testing modal'));
await waitFor(() => {
expect(screen.queryByTestId('modal')).toBeTruthy();
});
user.click(screen.getByTestId('outside'));
await waitFor(() => {
expect(screen.queryByTestId('modal')).toBeFalsy();
});
});
it('ESC closes modal', async () => {
render(
{(onClose, titleProps) => (
)}
,
);
const user = userEvent.setup();
user.click(screen.getByText('Open testing modal'));
await waitFor(() => {
expect(screen.queryByTestId('modal')).toBeTruthy();
});
user.type(screen.getByTestId('modal'), '{escape}');
await waitFor(() => {
expect(screen.queryByTestId('modal')).toBeFalsy();
});
});
it('Invoking onClose function closes modal', async () => {
render(
{(onClose, titleProps) => (
)}
,
);
const user = userEvent.setup();
user.click(screen.getByText('Open testing modal'));
await waitFor(() => {
expect(screen.queryByTestId('modal')).toBeTruthy();
});
user.click(screen.getByTestId('closeButton'));
await waitFor(() => {
expect(screen.queryByTestId('modal')).toBeFalsy();
});
});
it('Modal does not open if modal trigger button is disabled', async () => {
render(
{(onClose, titleProps) => (
)}
,
);
const user = userEvent.setup();
user.click(screen.getByText('Open testing modal'));
await waitFor(() => {
expect(screen.queryByTestId('modal')).not.toBeTruthy();
});
});
it('Focus is trapped within modal', async () => {
render(
{(onClose, titleProps) => (
)}
,
);
const user = userEvent.setup();
user.click(screen.getByText('Open testing modal'));
await waitFor(() => {
expect(screen.queryByTestId('modal')).toBeTruthy();
});
user.type(screen.getByTestId('modal'), '{tab}');
user.type(screen.getByTestId('modal'), '{tab}');
await waitFor(() => {
expect(screen.queryByTestId('closeButton')).toHaveFocus();
});
});
it('Focus should start on the dialog', async () => {
render(
{(onClose, titleProps) => (
)}
,
);
const user = userEvent.setup();
user.click(screen.getByText('Open testing modal'));
await waitFor(() => {
expect(screen.queryByTestId('modal')).toBeTruthy();
expect(screen.queryByRole('dialog')).toHaveFocus();
});
});
it('Title props provides id for dialog link', async () => {
let titleId: string | undefined = '';
render(
{(onClose, titleProps) => {
titleId = titleProps.id;
return (
);
}}
,
);
const user = userEvent.setup();
user.click(screen.getByText('Open testing modal'));
await waitFor(() => {
expect(screen.queryByTestId('modal')).toBeTruthy();
expect(screen.queryByTestId('title')).toHaveAttribute('id'); // Title was provided an id by 'titleProps'
expect(screen.queryByRole('dialog')).toHaveAttribute('aria-labelledby', titleId); // 'titleProps' id is added to the dialog label
});
});
});