carousel.spec.tsx 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. import {act, render, screen, userEvent} from 'sentry-test/reactTestingLibrary';
  2. import Carousel from 'sentry/components/carousel';
  3. describe('Carousel', function () {
  4. let intersectionOnbserverCb: (entries: Partial<IntersectionObserverEntry>[]) => void =
  5. jest.fn();
  6. window.IntersectionObserver = class IntersectionObserver {
  7. root = null;
  8. rootMargin = '';
  9. thresholds = [];
  10. takeRecords = jest.fn();
  11. constructor(cb: IntersectionObserverCallback) {
  12. // @ts-expect-error The callback wants just way too much stuff for our simple mock
  13. intersectionOnbserverCb = cb;
  14. }
  15. observe() {}
  16. unobserve() {}
  17. disconnect() {}
  18. };
  19. it('hides arrows if content does not overflow in x', function () {
  20. render(
  21. <Carousel>
  22. <div data-test-id="child-1" />
  23. </Carousel>
  24. );
  25. // Child is visible
  26. act(() =>
  27. intersectionOnbserverCb([
  28. {target: screen.getByTestId('child-1'), intersectionRatio: 1},
  29. ])
  30. );
  31. expect(screen.queryByRole('button', {name: 'Scroll left'})).not.toBeInTheDocument();
  32. expect(screen.queryByRole('button', {name: 'Scroll right'})).not.toBeInTheDocument();
  33. });
  34. it('shows right arrow when elements exist to the right', async function () {
  35. render(
  36. <Carousel>
  37. <div data-test-id="child-1" />
  38. <div data-test-id="child-2" />
  39. <div data-test-id="child-3" />
  40. </Carousel>
  41. );
  42. const elements = [
  43. screen.getByTestId('child-1'),
  44. screen.getByTestId('child-2'),
  45. screen.getByTestId('child-3'),
  46. ];
  47. // Element on the right is not visible
  48. act(() =>
  49. intersectionOnbserverCb([
  50. {target: elements[0], intersectionRatio: 1},
  51. {target: elements[1], intersectionRatio: 0.5},
  52. {target: elements[2], intersectionRatio: 0},
  53. ])
  54. );
  55. const rightButton = screen.getByRole('button', {name: 'Scroll right'});
  56. expect(screen.queryByRole('button', {name: 'Scroll left'})).not.toBeInTheDocument();
  57. // Test scroll into view, the 2nd element should have it's 'scrollIntoView' called
  58. elements[1].scrollIntoView = jest.fn();
  59. await userEvent.click(rightButton);
  60. expect(elements[1].scrollIntoView).toHaveBeenCalled();
  61. });
  62. it('shows left arrow when elements exist to the left', async function () {
  63. render(
  64. <Carousel>
  65. <div data-test-id="child-1" />
  66. <div data-test-id="child-2" />
  67. <div data-test-id="child-3" />
  68. </Carousel>
  69. );
  70. const elements = [
  71. screen.getByTestId('child-1'),
  72. screen.getByTestId('child-2'),
  73. screen.getByTestId('child-3'),
  74. ];
  75. // Element on the left is not visible
  76. act(() =>
  77. intersectionOnbserverCb([
  78. {target: elements[0], intersectionRatio: 0},
  79. {target: elements[1], intersectionRatio: 1},
  80. {target: elements[2], intersectionRatio: 1},
  81. ])
  82. );
  83. const leftButton = screen.getByRole('button', {name: 'Scroll left'});
  84. expect(screen.queryByRole('button', {name: 'Scroll right'})).not.toBeInTheDocument();
  85. // Test scroll into view, the 1st element should have it's 'scrollIntoView' called
  86. elements[0].scrollIntoView = jest.fn();
  87. await userEvent.click(leftButton);
  88. expect(elements[0].scrollIntoView).toHaveBeenCalled();
  89. });
  90. it('skips an element when it is past the visibleRatio', async function () {
  91. render(
  92. <Carousel visibleRatio={0.9}>
  93. <div data-test-id="child-1" />
  94. <div data-test-id="child-2" />
  95. <div data-test-id="child-3" />
  96. </Carousel>
  97. );
  98. const elements = [
  99. screen.getByTestId('child-1'),
  100. screen.getByTestId('child-2'),
  101. screen.getByTestId('child-3'),
  102. ];
  103. // Second element is MOSTLY visibile, past the
  104. act(() =>
  105. intersectionOnbserverCb([
  106. {target: elements[0], intersectionRatio: 1},
  107. {target: elements[1], intersectionRatio: 0.95},
  108. {target: elements[2], intersectionRatio: 0},
  109. ])
  110. );
  111. const rightButton = screen.getByRole('button', {name: 'Scroll right'});
  112. expect(screen.queryByRole('button', {name: 'Scroll left'})).not.toBeInTheDocument();
  113. // Test scroll into view, the 2nd element should have it's 'scrollIntoView' called
  114. elements[2].scrollIntoView = jest.fn();
  115. await userEvent.click(rightButton);
  116. expect(elements[2].scrollIntoView).toHaveBeenCalled();
  117. });
  118. });