index.spec.tsx 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. import {act, render, screen, userEvent} from 'sentry-test/reactTestingLibrary';
  2. import {Slider} from 'sentry/components/slider';
  3. describe('Slider', function () {
  4. it('renders', function () {
  5. render(<Slider label="Test" min={0} max={10} step={1} defaultValue={5} />);
  6. expect(screen.getByRole('group', {name: 'Test'})).toBeInTheDocument();
  7. expect(screen.getByRole('status')).toHaveTextContent('5'); // <output /> element
  8. const slider = screen.getByRole('slider', {name: 'Test'});
  9. expect(slider).toBeInTheDocument();
  10. expect(slider).toHaveValue('5');
  11. expect(slider).toHaveAttribute('min', '0');
  12. expect(slider).toHaveAttribute('max', '10');
  13. });
  14. it('renders without label/output', function () {
  15. render(<Slider aria-label="Test" min={0} max={10} step={1} defaultValue={5} />);
  16. expect(screen.queryByRole('status')).not.toBeInTheDocument();
  17. });
  18. it('calls onChange/onChangeEnd', async function () {
  19. const onChangeMock = jest.fn();
  20. const onChangeEndMock = jest.fn();
  21. render(
  22. <Slider
  23. label="Test"
  24. min={5}
  25. max={10}
  26. defaultValue={5}
  27. onChange={onChangeMock}
  28. onChangeEnd={onChangeEndMock}
  29. />
  30. );
  31. // To focus on the slider, we should call the focus() method. The slider input element
  32. // is visually hidden and only rendered for screen-reader & keyboard accessibility —
  33. // users can't actually click on it.
  34. act(() => {
  35. screen.getByRole('slider', {name: 'Test'}).focus();
  36. });
  37. await userEvent.keyboard('{ArrowRight}');
  38. expect(onChangeMock).toHaveBeenCalledWith(6);
  39. // onChangeEnd is called after the user stops dragging, but we can't simulate mouse
  40. // drags with RTL. Here we're just checking that it's called after a key press.
  41. expect(onChangeEndMock).toHaveBeenCalledWith(6);
  42. });
  43. it('works with larger step size', async function () {
  44. const onChangeEndMock = jest.fn();
  45. render(
  46. <Slider
  47. label="Test"
  48. min={0}
  49. max={10}
  50. step={5}
  51. defaultValue={5}
  52. onChangeEnd={onChangeEndMock}
  53. />
  54. );
  55. // To focus on the slider, we should call the focus() method. The slider input element
  56. // is visually hidden and only rendered for screen-reader & keyboard accessibility —
  57. // users can't actually click on it.
  58. act(() => {
  59. screen.getByRole('slider', {name: 'Test'}).focus();
  60. });
  61. await userEvent.keyboard('{ArrowRight}');
  62. expect(onChangeEndMock).toHaveBeenCalledWith(10);
  63. });
  64. it('supports advanced keyboard navigation', async function () {
  65. const onChangeEndMock = jest.fn();
  66. render(
  67. <Slider
  68. label="Test"
  69. min={5}
  70. max={100}
  71. defaultValue={5}
  72. onChangeEnd={onChangeEndMock}
  73. />
  74. );
  75. // To focus on the slider, we should call the focus() method. The slider input element
  76. // is visually hidden and only rendered for screen-reader & keyboard accessibility —
  77. // users can't actually click on it.
  78. act(() => {
  79. screen.getByRole('slider', {name: 'Test'}).focus();
  80. });
  81. // Pressing Arrow Right/Left increases/decreases value by 1
  82. await userEvent.keyboard('{ArrowRight}');
  83. expect(onChangeEndMock).toHaveBeenCalledWith(6);
  84. await userEvent.keyboard('{ArrowLeft}');
  85. expect(onChangeEndMock).toHaveBeenCalledWith(5);
  86. // Pressing Arrow Right/Left while holding Shift increases/decreases value by 10
  87. await userEvent.keyboard('{Shift>}{ArrowRight}{/Shift}');
  88. expect(onChangeEndMock).toHaveBeenCalledWith(15);
  89. await userEvent.keyboard('{Shift>}{ArrowLeft}{/Shift}');
  90. expect(onChangeEndMock).toHaveBeenCalledWith(5);
  91. // Pressing Page Up/Down increases/decreases value by 10
  92. await userEvent.keyboard('{PageUp}');
  93. expect(onChangeEndMock).toHaveBeenCalledWith(6);
  94. await userEvent.keyboard('{PageDown}');
  95. expect(onChangeEndMock).toHaveBeenCalledWith(5);
  96. // Pressing Home/End moves value to the min/max position
  97. await userEvent.keyboard('{Home}');
  98. expect(onChangeEndMock).toHaveBeenCalledWith(5);
  99. await userEvent.keyboard('{End}');
  100. expect(onChangeEndMock).toHaveBeenCalledWith(100);
  101. });
  102. it('works with two thumbs', async function () {
  103. const onChangeEndMock = jest.fn();
  104. render(
  105. <Slider
  106. label="Test"
  107. min={5}
  108. max={10}
  109. defaultValue={[6, 8]}
  110. onChangeEnd={onChangeEndMock}
  111. />
  112. );
  113. const sliders = screen.getAllByRole('slider', {name: 'Test'});
  114. // First slider
  115. await userEvent.tab();
  116. expect(sliders[0]).toHaveFocus();
  117. expect(sliders[0]).toHaveValue('6');
  118. expect(sliders[0]).toHaveAttribute('min', '5');
  119. expect(sliders[0]).toHaveAttribute('max', '8'); // can't go above second slider's value
  120. await userEvent.keyboard('{ArrowRight}');
  121. expect(onChangeEndMock).toHaveBeenCalledWith([7, 8]);
  122. // Second slider
  123. await userEvent.tab();
  124. expect(sliders[1]).toHaveFocus();
  125. expect(sliders[1]).toHaveValue('8');
  126. expect(sliders[1]).toHaveAttribute('min', '7'); // can't go below first slider's value
  127. expect(sliders[1]).toHaveAttribute('max', '10');
  128. await userEvent.keyboard('{ArrowRight}');
  129. expect(onChangeEndMock).toHaveBeenCalledWith([7, 9]);
  130. });
  131. });