featureTourModal.spec.jsx 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. import {Fragment} from 'react';
  2. import {render, screen, userEvent} from 'sentry-test/reactTestingLibrary';
  3. import GlobalModal from 'sentry/components/globalModal';
  4. import FeatureTourModal from 'sentry/components/modals/featureTourModal';
  5. const steps = [
  6. {
  7. title: 'First',
  8. body: 'First step',
  9. image: <em data-test-id="step-image">Image</em>,
  10. actions: (
  11. <a href="#" data-test-id="step-action">
  12. additional action
  13. </a>
  14. ),
  15. },
  16. {title: 'Second', body: 'Second step'},
  17. ];
  18. describe('FeatureTourModal', function () {
  19. let onAdvance, onCloseModal;
  20. const createWrapper = (props = {}) =>
  21. render(
  22. <Fragment>
  23. <GlobalModal />
  24. <FeatureTourModal
  25. steps={steps}
  26. onAdvance={onAdvance}
  27. onCloseModal={onCloseModal}
  28. {...props}
  29. >
  30. {({showModal}) => (
  31. <a href="#" onClick={showModal} data-test-id="reveal">
  32. Open
  33. </a>
  34. )}
  35. </FeatureTourModal>
  36. </Fragment>
  37. );
  38. const showModal = () => {
  39. userEvent.click(screen.getByTestId('reveal'));
  40. };
  41. beforeEach(function () {
  42. onAdvance = jest.fn();
  43. onCloseModal = jest.fn();
  44. });
  45. it('shows the modal on click', function () {
  46. createWrapper();
  47. // No modal showing
  48. expect(screen.queryByTestId('feature-tour')).not.toBeInTheDocument();
  49. showModal();
  50. // Modal is now showing
  51. expect(screen.getByTestId('feature-tour')).toBeInTheDocument();
  52. });
  53. it('advances on click', function () {
  54. createWrapper();
  55. showModal();
  56. // Should start on the first step.
  57. expect(screen.getByRole('heading')).toHaveTextContent(steps[0].title);
  58. // Advance to the next step.
  59. userEvent.click(screen.getByRole('button', {name: 'Next'}));
  60. // Should move to next step.
  61. expect(screen.getByRole('heading')).toHaveTextContent(steps[1].title);
  62. expect(onAdvance).toHaveBeenCalled();
  63. });
  64. it('shows step content', function () {
  65. createWrapper();
  66. showModal();
  67. // Should show title, image and actions
  68. expect(screen.getByRole('heading')).toHaveTextContent(steps[0].title);
  69. expect(screen.getByTestId('step-image')).toBeInTheDocument();
  70. expect(screen.getByTestId('step-action')).toBeInTheDocument();
  71. expect(screen.getByText('1 of 2')).toBeInTheDocument();
  72. });
  73. it('last step shows done', function () {
  74. createWrapper();
  75. showModal();
  76. // Advance to the the last step.
  77. userEvent.click(screen.getByRole('button', {name: 'Next'}));
  78. // Click the done
  79. userEvent.click(screen.getByRole('button', {name: 'Complete tour'}));
  80. // Wait for the ModalStore action to propagate.
  81. expect(onAdvance).toHaveBeenCalledTimes(1);
  82. expect(onCloseModal).toHaveBeenCalledTimes(1);
  83. });
  84. it('last step shows doneText and uses doneUrl', function () {
  85. const props = {doneText: 'Finished', doneUrl: 'http://example.org'};
  86. createWrapper(props);
  87. showModal();
  88. // Advance to the the last step.
  89. userEvent.click(screen.getByRole('button', {name: 'Next'}));
  90. // Ensure button looks right
  91. const button = screen.getByRole('button', {name: 'Complete tour'});
  92. expect(button).toHaveTextContent(props.doneText);
  93. expect(button).toHaveAttribute('href', props.doneUrl);
  94. // Click the done
  95. userEvent.click(button);
  96. // Wait for the ModalStore action to propagate.
  97. expect(onCloseModal).toHaveBeenCalledTimes(1);
  98. });
  99. it('close button dismisses modal', function () {
  100. createWrapper();
  101. showModal();
  102. userEvent.click(screen.getByRole('button', {name: 'Close tour'}));
  103. // Wait for the ModalStore action to propagate.
  104. expect(onCloseModal).toHaveBeenCalled();
  105. });
  106. });