Files
2024-02-15 17:01:50 +00:00

141 lines
3.8 KiB
TypeScript

import {Fragment} from 'react';
import {render, screen, userEvent} from 'sentry-test/reactTestingLibrary';
import GlobalModal from 'sentry/components/globalModal';
import FeatureTourModal from 'sentry/components/modals/featureTourModal';
import ModalStore from 'sentry/stores/modalStore';
const steps = [
{
title: 'First',
body: 'First step',
image: <em data-test-id="step-image">Image</em>,
actions: (
<a href="#" data-test-id="step-action">
additional action
</a>
),
},
{title: 'Second', body: 'Second step'},
];
describe('FeatureTourModal', function () {
let onAdvance, onCloseModal;
const createWrapper = (props = {}) =>
render(
<Fragment>
<GlobalModal />
<FeatureTourModal
steps={steps}
onAdvance={onAdvance}
onCloseModal={onCloseModal}
{...props}
>
{({showModal}) => (
<a href="#" onClick={showModal} data-test-id="reveal">
Open
</a>
)}
</FeatureTourModal>
</Fragment>
);
async function clickModal() {
await userEvent.click(screen.getByTestId('reveal'));
}
beforeEach(function () {
ModalStore.reset();
onAdvance = jest.fn();
onCloseModal = jest.fn();
});
it('shows the modal on click', async function () {
createWrapper();
// No modal showing
expect(screen.queryByTestId('feature-tour')).not.toBeInTheDocument();
await clickModal();
// Modal is now showing
expect(screen.getByTestId('feature-tour')).toBeInTheDocument();
});
it('advances on click', async function () {
createWrapper();
await clickModal();
// Should start on the first step.
expect(screen.getByRole('heading')).toHaveTextContent(steps[0].title);
// Advance to the next step.
await userEvent.click(screen.getByRole('button', {name: 'Next'}));
// Should move to next step.
expect(screen.getByRole('heading')).toHaveTextContent(steps[1].title);
expect(onAdvance).toHaveBeenCalled();
});
it('shows step content', async function () {
createWrapper();
await clickModal();
// Should show title, image and actions
expect(screen.getByRole('heading')).toHaveTextContent(steps[0].title);
expect(screen.getByTestId('step-image')).toBeInTheDocument();
expect(screen.getByTestId('step-action')).toBeInTheDocument();
expect(screen.getByText('1 of 2')).toBeInTheDocument();
});
it('last step shows done', async function () {
createWrapper();
await clickModal();
// Advance to the the last step.
await userEvent.click(screen.getByRole('button', {name: 'Next'}));
// Click the done
await userEvent.click(screen.getByRole('button', {name: 'Complete tour'}));
// Wait for the ModalStore action to propagate.
expect(onAdvance).toHaveBeenCalledTimes(1);
expect(onCloseModal).toHaveBeenCalledTimes(1);
});
it('last step shows doneText and uses doneUrl', async function () {
const props = {doneText: 'Finished', doneUrl: 'http://example.org'};
createWrapper(props);
await clickModal();
// Advance to the the last step.
await userEvent.click(screen.getByRole('button', {name: 'Next'}));
// Ensure button looks right
const button = screen.getByRole('button', {name: 'Complete tour'});
expect(button).toHaveTextContent(props.doneText);
expect(button).toHaveAttribute('href', props.doneUrl);
// Click the done
await userEvent.click(button);
// Wait for the ModalStore action to propagate.
expect(onCloseModal).toHaveBeenCalledTimes(1);
});
it('close button dismisses modal', async function () {
createWrapper();
await clickModal();
await userEvent.click(screen.getByRole('button', {name: 'Close tour'}));
// Wait for the ModalStore action to propagate.
expect(onCloseModal).toHaveBeenCalled();
});
});