diff --git a/packages/react/src/components/Slider/Slider-test.js b/packages/react/src/components/Slider/Slider-test.js index 0dd69acf8e60..27560530c9c9 100644 --- a/packages/react/src/components/Slider/Slider-test.js +++ b/packages/react/src/components/Slider/Slider-test.js @@ -1,5 +1,5 @@ /** - * Copyright IBM Corp. 2016, 2018 + * Copyright IBM Corp. 2016, 2022 * * This source code is licensed under the Apache-2.0 license found in the * LICENSE file in the root directory of this source tree. @@ -7,435 +7,484 @@ import React from 'react'; import Slider from './Slider'; -import { mount } from 'enzyme'; -import 'requestanimationframe'; -import throttle from 'lodash.throttle'; - -jest.mock('lodash.throttle'); - -throttle.mockImplementation((fn) => Object.assign(fn, { throttled: true })); +import userEvent from '@testing-library/user-event'; +import { fireEvent, render, screen } from '@testing-library/react'; const prefix = 'cds'; +const inputAriaValue = 'slider-input-aria-label-value'; +const initialValue = 50; +const defaultSliderValue = 1; +const onBlur = jest.fn(); +const onChange = jest.fn(); +const onClick = jest.fn(); +const onRelease = jest.fn(); +const onKeyDown = jest.fn(); + +const renderSlider = ({ + value = defaultSliderValue, + min = 1, + max = 3, + step = 1, + ...rest +} = {}) => + render(); describe('Slider', () => { - const id = 'slider'; - let wrapper; beforeEach(() => { - wrapper = mount( - - ); + jest.clearAllMocks(); + jest.resetAllMocks(); }); - describe('Renders as expected', () => { - it('renders children as expected', () => { - expect(wrapper.find(`.${prefix}--text-input`).length).toBe(1); + describe('behaves as expected - Component API', () => { + it('should render children as expected', () => { + renderSlider({ ariaLabelInput: inputAriaValue }); + expect(screen.getByLabelText(inputAriaValue)).toBeInTheDocument(); }); - it('has the expected classes', () => { - expect(wrapper.find(`.${prefix}--slider`).length).toBe(1); + it('should apply the expected classes', () => { + const labelTextValue = 'slider label text'; + const { container } = renderSlider({ labelText: labelTextValue }); + expect(screen.getByRole('slider')).toHaveClass( + `${prefix}--slider__thumb` + ); + expect(container.firstChild).toHaveClass(`${prefix}--form-item`); + expect(screen.getByLabelText(labelTextValue)).toBeInTheDocument(); }); - it('renders extra classes passed in via className', () => { - expect( - wrapper.find(`.${prefix}--slider`).hasClass('extra-class') - ).toEqual(true); + it('should render extra classes passed in via className', () => { + const customSliderClass = 'slider-custom-class'; + renderSlider({ className: customSliderClass }); + expect(screen.getByRole('presentation')).toHaveClass(customSliderClass); }); - it('can be disabled', () => { - wrapper.setProps({ disabled: true }); - expect(wrapper.props().disabled).toEqual(true); + it('should be able to apply a disabled state', () => { + renderSlider({ disabled: true, ariaLabelInput: inputAriaValue }); + expect(screen.getByLabelText(inputAriaValue)).toHaveAttribute('disabled'); + expect(screen.getByRole('presentation')).toHaveClass( + `${prefix}--slider--disabled` + ); }); - it('can set value via props', () => { - wrapper.setProps({ value: 55 }); - expect(wrapper.props().value).toEqual(55); + it('should be able to set value via props', () => { + renderSlider({ + ariaLabelInput: inputAriaValue, + value: initialValue, + max: 100, + }); + const inputElement = screen.getByLabelText(inputAriaValue); + const wrapperElement = screen.getByRole('presentation'); + expect(parseInt(inputElement.getAttribute('value'))).toEqual( + initialValue + ); + expect(parseInt(wrapperElement.getAttribute('value'))).toEqual( + initialValue + ); }); - it('should change the value upon change in props', () => { - wrapper.setProps({ value: 1 }); - wrapper.setState({ value: 1 }); - wrapper.update(); - wrapper.setProps({ value: 2 }); - expect(wrapper.state().value).toEqual(2); + it('should change the value upon interacting with the slider', () => { + const { type, click } = userEvent; + renderSlider({ + onClick, + onChange, + }); + // Click events should fire + const theSlider = screen.getByRole('slider'); + click(theSlider); + expect(onClick).toHaveBeenCalledTimes(1); + type(theSlider, '{arrowright}'); + expect(onChange).toHaveBeenCalledTimes(1); + expect(onChange).toHaveBeenLastCalledWith({ value: 2 }); }); it('should accurately position slider on mount', () => { - expect(wrapper.state().left).toEqual(0); + renderSlider({ value: 50, max: 100, min: 0 }); + expect(screen.getByRole('slider').style.left).toEqual('50%'); }); it('marks input field as hidden if hidden via props', () => { - wrapper.setProps({ hideTextInput: true }); - expect(wrapper.find(`#${id}-input-for-slider`).props().type).toEqual( - 'hidden' - ); - }); - - it('sets style to display:none on input field if hidden via props', () => { - wrapper.setProps({ hideTextInput: true }); - expect(wrapper.find(`#${id}-input-for-slider`).props().style).toEqual({ - display: 'none', + const { container } = renderSlider({ + ariaLabelInput: inputAriaValue, + hideTextInput: true, }); - }); - }); - - describe('Supporting label', () => { - it('concatenates the value and the label by default', () => { - const wrapper = mount( - - ); - expect( - wrapper.find(`.${prefix}--slider__range-label`).first().text() - ).toBe('0min'); - expect( - wrapper.find(`.${prefix}--slider__range-label`).last().text() - ).toBe('100max'); - }); - - it('supports custom formatting of the label', () => { - const wrapper = mount( - `${value}-${label}`} - value={0} - /> + const inputElement = container.querySelector( + `.${prefix}--text-input.${prefix}--slider-text-input` ); - expect( - wrapper.find(`.${prefix}--slider__range-label`).first().text() - ).toBe('0-min'); - expect( - wrapper.find(`.${prefix}--slider__range-label`).last().text() - ).toBe('100-max'); + expect(inputElement.style.display).toEqual('none'); + expect(inputElement.getAttribute('type')).toEqual('hidden'); }); - }); - describe('key/mouse event processing', () => { - const handleChange = jest.fn(); - const handleRelease = jest.fn(); - const handleBlur = jest.fn(); - - const wrapper = mount( - - ); - - it('sets correct state from event with a right/up keydown', () => { - const evt = { - type: 'keydown', - which: '38', - }; - wrapper.instance().onKeyDown(evt); - expect(wrapper.state().value).toEqual(51); - expect(handleChange).toHaveBeenLastCalledWith({ value: 51 }); - }); + it('allows user to set invalid value when typing in input field', () => { + const { type, tab } = userEvent; + renderSlider({ + ariaLabelInput: inputAriaValue, + value: initialValue, + max: 100, + onChange, + }); + const inputElement = screen.getByLabelText(inputAriaValue); + const slider = screen.getByRole('slider'); - it('sets correct state from event with a left/down keydown', () => { - const evt = { - type: 'keydown', - which: '40', - }; - wrapper.instance().onKeyDown(evt); - expect(wrapper.state().value).toEqual(50); - expect(handleChange).toHaveBeenLastCalledWith({ value: 50 }); + tab(); // Brings focus to slider + tab(); // Brings focus to input + type(inputElement, '{selectall}999'); + expect(parseInt(slider.getAttribute('aria-valuenow'))).toEqual(999); + expect(onChange).toHaveBeenLastCalledWith({ value: 999 }); }); - it('correctly uses setMultiplier with a right/up keydown', () => { - const evt = { - type: 'keydown', - which: '38', - shiftKey: true, - }; - wrapper.instance().onKeyDown(evt); - expect(wrapper.state().value).toEqual(55); - expect(handleChange).toHaveBeenLastCalledWith({ value: 55 }); + it('sets correct state when typing a valid value in input field', () => { + const { type, tab } = userEvent; + renderSlider({ + ariaLabelInput: inputAriaValue, + value: initialValue, + max: 100, + onChange, + }); + const inputElement = screen.getByLabelText(inputAriaValue); + tab(); // Brings focus to slider + tab(); // Brings focus to input + type(inputElement, '{selectall}12'); + expect(onChange).toHaveBeenLastCalledWith({ value: 12 }); + }); + + it('should check for the invalid class on the input', () => { + const { type, tab } = userEvent; + renderSlider({ + ariaLabelInput: inputAriaValue, + value: initialValue, + max: 100, + }); + const inputElement = screen.getByLabelText(inputAriaValue); + tab(); // Brings focus to slider + tab(); // Brings focus to input + type(inputElement, '{selectall}101'); + tab(); // Need to tab away from input for invalid class to be applied + expect(inputElement).toHaveClass(`${prefix}--text-input--invalid`); }); - it('sets correct state from event with a clientX in a mousemove', () => { - const evt = { - type: 'mousemove', - clientX: '1000', - }; - wrapper.instance()._onDrag(evt); - expect(handleChange).toHaveBeenLastCalledWith({ value: 100 }); - expect(wrapper.state().value).toEqual(100); + it('should apply the given id to the element with role of slider', () => { + const testId = 'slider-test-custom-id'; + renderSlider({ id: testId }); + expect(screen.getByRole('slider').id).toEqual(testId); }); - it('sets correct state from event with a clientX in a touchmove', () => { - const evt = { - type: 'touchmove', - touches: [{ clientX: '0' }], - }; - wrapper.instance()._onDrag(evt); - expect(handleChange).toHaveBeenLastCalledWith({ value: 0 }); - expect(wrapper.state().value).toEqual(0); + it('should apply a custom input type', () => { + const customInputType = 'text'; + renderSlider({ + ariaLabelInput: inputAriaValue, + inputType: customInputType, + }); + expect(screen.getByLabelText(inputAriaValue).type).toEqual( + customInputType + ); }); - it('throttles mousemove events', () => { - expect(wrapper.instance().onDrag.throttled).toBe(true); + it('should apply a custom input name', () => { + const customInputName = 'Custom input name value'; + renderSlider({ ariaLabelInput: inputAriaValue, name: customInputName }); + expect(screen.getByLabelText(inputAriaValue).name).toEqual( + customInputName + ); }); - describe('user is holding the handle', () => { - it('does not call onRelease', () => { - const evt = { - type: 'mousemove', - clientX: '1000', - }; - handleRelease.mockClear(); - expect(handleRelease).not.toHaveBeenCalled(); - - wrapper.instance().onDragStart(evt); - wrapper.instance().onDrag(evt); - expect(handleRelease).not.toHaveBeenCalled(); + it('should mark an empty input as invalid when using the required prop', () => { + const customInputName = 'Custom input name value'; + const { tab, type } = userEvent; + renderSlider({ + ariaLabelInput: inputAriaValue, + name: customInputName, + required: true, + }); + const inputElement = screen.getByLabelText(inputAriaValue); + tab(); // Brings focus to slider + tab(); // Brings focus to input + type(inputElement, '{selectall}{backspace}'); + tab(); + expect(inputElement).toHaveClass(`${prefix}--text-input--invalid`); + }); + + it('should respect readOnly prop', () => { + const { click, type } = userEvent; + renderSlider({ + ariaLabelInput: inputAriaValue, + onClick, + onChange, + readOnly: true, }); - }); - describe('user releases the handle', () => { - it('calls onRelease', () => { - handleRelease.mockClear(); - expect(handleRelease).not.toHaveBeenCalled(); - wrapper.setState({ - needsOnRelease: true, + // Click events should fire + const theSlider = screen.getByRole('slider'); + click(theSlider); + expect(onClick).toHaveBeenCalledTimes(1); + type(theSlider, '{arrowright}'); + const theInput = screen.getByRole('spinbutton'); + type(theInput, '{selectall}3'); + expect(onChange).toHaveBeenCalledTimes(0); + }); + + describe('Error handling, expected behavior from event handlers', () => { + it('handles non-number typed into input field', () => { + const { type, tab } = userEvent; + renderSlider({ + ariaLabelInput: inputAriaValue, + value: initialValue, + max: 100, + onChange, }); - wrapper.instance().onDragStop(); - expect(handleRelease).toHaveBeenCalled(); + const inputElement = screen.getByLabelText(inputAriaValue); + tab(); // Brings focus to slider + tab(); // Brings focus to input + type(inputElement, '{space}'); + tab(); // Brings focus out of input + expect(onChange).not.toHaveBeenCalled(); }); - }); - it('allows user to set invalid value when typing in input field', () => { - const evt = { - target: { - value: '999', - }, - }; - - wrapper.instance().onChange(evt); - expect(wrapper.state().value).toEqual(999); - expect(handleChange).toHaveBeenLastCalledWith({ value: 999 }); - }); - - it('checks for validity onBlur', () => { - const checkValidity = jest.fn(); - - const evt = { - target: { - value: '', - checkValidity: checkValidity, - }, - }; + it('gracefully tolerates empty event passed to _onDrag', () => { + const { mouseDown, mouseUp, mouseMove } = fireEvent; + const { container } = renderSlider({ + ariaLabelInput: inputAriaValue, + value: 1, + max: 100, + onChange, + }); + const theSlider = screen.getByRole('slider'); + mouseDown(theSlider, { clientX: 0 }); + mouseMove(container.firstChild, { clientX: 0 }); + mouseUp(theSlider); + expect(onChange).not.toHaveBeenCalled(); + }); - wrapper.instance().onBlur(evt); - expect(checkValidity).toHaveBeenCalled(); - }); + it('gracefully tolerates empty event passed to onChange', () => { + const { type, tab } = userEvent; + renderSlider({ + ariaLabelInput: inputAriaValue, + value: initialValue, + max: 100, + onChange, + }); + const inputElement = screen.getByLabelText(inputAriaValue); + tab(); // Brings focus to slider + tab(); // Brings focus to input + type(inputElement, '{space}'); + tab(); // Brings focus out of input + expect(onChange).not.toHaveBeenCalled(); + }); - it('sets correct state when typing a valid value in input field', () => { - const evt = { - target: { - value: '12', - }, - }; - - wrapper.instance().onChange(evt); - expect(wrapper.state().value).toEqual(12); - expect(handleChange).toHaveBeenLastCalledWith({ value: 12 }); - }); - }); + it('should call onBlur as expected', () => { + const { type, tab } = userEvent; + renderSlider({ + ariaLabelInput: inputAriaValue, + value: 10, + max: 100, + onBlur, + }); + const inputElement = screen.getByLabelText(inputAriaValue); + tab(); // Brings focus to slider + tab(); // Brings focus to input + type(inputElement, '{space}'); + tab(); // Brings focus out of input + expect(onBlur).toHaveBeenCalledTimes(2); + }); - describe('syncs invalid state and props', () => { - const handleChange = jest.fn(); - const handleRelease = jest.fn(); - const handleBlur = jest.fn(); - - const wrapper = mount( - - ); - - it('overrides invalid state for invalid prop', () => { - const changeEvt = { - target: { - value: '200', - }, - }; - - const blurEvt = { - target: { - checkValidity: () => false, - }, - }; - - wrapper.instance().onChange(changeEvt); - wrapper.instance().onBlur(blurEvt); - expect(wrapper.state().value).toEqual(200); - expect(wrapper.state().isValid).toEqual(true); - expect( - wrapper - .find(`.${prefix}--slider-text-input`) - .hasClass(`${prefix}--text-input--invalid`) - ).toEqual(false); - }); - }); + it('should call onKeyDown as expected', () => { + const { type, click } = userEvent; + renderSlider({ + ariaLabelInput: inputAriaValue, + onKeyDown, + }); + const theSlider = screen.getByRole('slider'); + click(theSlider); + type(theSlider, '{arrowright}'); + type(theSlider, '{arrowright}'); + expect(onKeyDown).toHaveBeenCalledTimes(2); + }); - describe('error handling', () => { - const handleChange = jest.fn(); - const handleRelease = jest.fn(); - const wrapper = mount( - - ); - - it('handles non-number typed into input field', () => { - const evt = { - target: { - value: '', - }, - }; - wrapper.instance().onChange(evt); - expect(wrapper.state().value).toEqual(''); - expect(handleChange).not.toHaveBeenCalled(); - }); + it('should call onKeyDown and properly handle the stepMultiplier prop', () => { + const { keyboard, click } = userEvent; + renderSlider({ + ariaLabelInput: inputAriaValue, + max: 100, + onChange, + stepMultiplier: 10, + }); + const theSlider = screen.getByRole('slider'); + click(theSlider); + keyboard('{shift}{arrowright}{/shift}{/arrowright}'); + expect(onChange).toHaveBeenLastCalledWith({ + value: 11, + }); + }); - it('gracefully tolerates empty event passed to _onDrag', () => { - const evt = {}; - wrapper.instance()._onDrag(evt); - expect(wrapper.state().value).toEqual(''); // from last test - expect(handleChange).not.toHaveBeenCalled(); + it('should gracefully handle non-numeric keys', () => { + const { tab, type } = userEvent; + renderSlider({ + ariaLabelInput: inputAriaValue, + max: 100, + onChange, + stepMultiplier: 10, + }); + const inputElement = screen.getByLabelText(inputAriaValue); + tab(); // Brings focus to slider + tab(); // Brings focus to input + type(inputElement, '{selectall}a'); + expect(onChange).not.toHaveBeenCalled(); + }); }); - it('gracefully tolerates empty event passed to onChange', () => { - const evt = {}; - wrapper.instance().onChange(evt); - expect(wrapper.state().value).toEqual(''); // from last test - expect(handleChange).not.toHaveBeenCalled(); - }); + describe('Disabled state', () => { + it('should do nothing when trying to type in the input', () => { + const { tab, type } = userEvent; + renderSlider({ + ariaLabelInput: inputAriaValue, + max: 100, + onChange: onChange, + disabled: true, + }); + const inputElement = screen.getByLabelText(inputAriaValue); + tab(); // Brings focus to slider + tab(); // Brings focus to input + type(inputElement, '1'); + expect(onChange).not.toHaveBeenCalled(); + }); - it('gracefully tolerates empty event passed to onBlur', () => { - const evt = {}; - wrapper.instance().onBlur(evt); - expect(wrapper.state().value).toEqual(''); // from last test - expect(handleChange).not.toHaveBeenCalled(); - }); + it('should do nothing when trying to drag', () => { + const { mouseDown, mouseMove, mouseUp } = fireEvent; + const { container } = renderSlider({ + onChange, + ariaLabelInput: inputAriaValue, + max: 100, + disabled: true, + }); + const theSlider = screen.getByRole('slider'); + mouseDown(theSlider, { clientX: 0 }); + expect(onChange).not.toHaveBeenCalled(); + mouseMove(container.firstChild, { clientX: 0 }); + expect(onChange).not.toHaveBeenCalled(); + mouseUp(theSlider); + expect(onChange).not.toHaveBeenCalled(); + }); - it('gracefully tolerates empty event passed to onKeyDown', () => { - const evt = {}; - wrapper.instance().onKeyDown(evt); - expect(wrapper.state().value).toEqual(''); // from last test - expect(handleChange).not.toHaveBeenCalled(); + it('should not change slider value when using arrow key', () => { + const { click, type } = userEvent; + renderSlider({ disabled: true }); + const slider = screen.getByRole('slider'); + click(slider); + type(slider, '{arrowright}'); + expect(parseInt(slider.getAttribute('aria-valuenow'))).toEqual( + defaultSliderValue + ); + }); }); - it('gracefully tolerates bad key code passed to onKeyDown', () => { - const evt = { - which: '123', - }; - wrapper.instance().onKeyDown(evt); - expect(wrapper.state().value).toEqual(''); // from last test - expect(handleChange).not.toHaveBeenCalled(); - }); - }); + describe('Supporting label', () => { + it('concatenates the value and the label by default', () => { + const { container } = renderSlider({ + min: 0, + minLabel: 'min', + max: 100, + maxLabel: 'max', + value: 50, + }); + const rangeLabels = container.querySelectorAll( + `.${prefix}--slider__range-label` + ); + expect(rangeLabels[0].textContent).toEqual('0min'); + expect(rangeLabels[1].textContent).toEqual('100max'); + }); - describe('slider is disabled', () => { - const handleChange = jest.fn(); - const handleRelease = jest.fn(); - const wrapper = mount( - - ); - - it('does nothing when trying to type in the input', () => { - const evt = { - target: { - value: '', - }, - }; - wrapper.instance().onChange(evt); - expect(wrapper.state().value).toEqual(50); - expect(handleChange).not.toHaveBeenCalled(); + it('supports custom formatting of the label', () => { + const { container } = renderSlider({ + min: 0, + minLabel: 'min', + max: 100, + maxLabel: 'max', + value: 50, + formatLabel: (value, label) => `${value}-${label}`, + }); + const rangeLabels = container.querySelectorAll( + `.${prefix}--slider__range-label` + ); + expect(rangeLabels[0].textContent).toEqual('0-min'); + expect(rangeLabels[1].textContent).toEqual('100-max'); + }); }); - it('does nothing when trying to start a drag', () => { - const evt = { - type: 'mousedown', - clientX: '1001', - }; - wrapper.instance().onDragStart(evt); - expect(wrapper.state().value).toEqual(50); - expect(handleChange).not.toHaveBeenCalled(); - }); + describe('Key/mouse event processing', () => { + it('sets correct state from event with arrow keys', () => { + const { type, click } = userEvent; + renderSlider({ + onClick, + onChange, + min: 0, + max: 100, + }); + // Click events should fire + const theSlider = screen.getByRole('slider'); + click(theSlider); + expect(onClick).toHaveBeenCalledTimes(1); + type(theSlider, '{arrowright}'); + expect(onChange).toHaveBeenCalledTimes(2); + expect(onChange).toHaveBeenLastCalledWith({ + value: 1, + }); + type(theSlider, '{arrowleft}'); + expect(onChange).toHaveBeenCalledTimes(3); + expect(onChange).toHaveBeenLastCalledWith({ + value: 0, + }); + type(theSlider, '{arrowup}'); + expect(onChange).toHaveBeenCalledTimes(4); + expect(onChange).toHaveBeenLastCalledWith({ + value: 1, + }); + type(theSlider, '{arrowdown}'); + expect(onChange).toHaveBeenCalledTimes(5); + expect(onChange).toHaveBeenLastCalledWith({ + value: 0, + }); + }); - it('does nothing when trying to drag', () => { - const evt = { - type: 'mousemove', - clientX: '1000', - }; - wrapper.instance()._onDrag(evt); - expect(wrapper.state().value).toEqual(50); - expect(handleChange).not.toHaveBeenCalled(); - }); + it('sets correct state from event with a clientX in a mousemove', () => { + const { mouseDown, mouseUp, mouseMove } = fireEvent; + const { container } = renderSlider({ + onChange, + min: 0, + max: 100, + }); + const theSlider = screen.getByRole('slider'); + mouseDown(theSlider, { clientX: 10 }); + mouseMove(container.firstChild, { clientX: 1000 }); + mouseUp(theSlider); + expect(onChange).toHaveBeenLastCalledWith({ + value: 100, + }); + }); - it('does nothing when trying to stop a drag', () => { - const evt = { - type: 'mouseup', - clientX: '1001', - }; - wrapper.instance().onDragStop(evt); - expect(wrapper.state().needsOnRelease).toEqual(false); - expect(handleChange).not.toHaveBeenCalled(); - expect(handleRelease).not.toHaveBeenCalled(); - }); + it('should call release', () => { + const { mouseDown, mouseUp, mouseMove } = fireEvent; + const { container } = renderSlider({ + onRelease, + min: 0, + max: 100, + }); + const theSlider = screen.getByRole('slider'); + mouseDown(theSlider, { clientX: 10 }); + mouseMove(container.firstChild, { clientX: 1000 }); + mouseUp(theSlider); + expect(onRelease).toHaveBeenCalled(); + }); - it('does nothing when using arrow key', () => { - const evt = { - type: 'keydown', - which: '40', - }; - wrapper.instance().onKeyDown(evt); - expect(wrapper.state().value).toEqual(50); - expect(handleChange).not.toHaveBeenCalled(); + it('should not call onRelease', () => { + const { mouseDown, mouseMove } = fireEvent; + const { container } = renderSlider({ + onRelease, + min: 0, + max: 100, + }); + const theSlider = screen.getByRole('slider'); + mouseDown(theSlider, { clientX: 10 }); + mouseMove(container.firstChild, { clientX: 1000 }); + expect(onRelease).not.toHaveBeenCalled(); + }); }); }); }); diff --git a/packages/react/src/components/Slider/__tests__/Slider-test.js b/packages/react/src/components/Slider/__tests__/Slider-test.js deleted file mode 100644 index aad87d3e2256..000000000000 --- a/packages/react/src/components/Slider/__tests__/Slider-test.js +++ /dev/null @@ -1,89 +0,0 @@ -/** - * Copyright IBM Corp. 2016, 2018 - * - * This source code is licensed under the Apache-2.0 license found in the - * LICENSE file in the root directory of this source tree. - */ - -import React from 'react'; -import Slider from '../Slider'; -import userEvent from '@testing-library/user-event'; -import { render, screen } from '@testing-library/react'; - -describe('Slider', () => { - describe('behaves as expected - Component API', () => { - it('should respect work normally when not readonly prop', () => { - const onChange = jest.fn(); - const onClick = jest.fn(); - - render( - - ); - - // Click events should fire - const theSlider = screen.getByRole('slider'); - userEvent.click(theSlider); - expect(onClick).toHaveBeenCalledTimes(1); - - userEvent.type(theSlider, '{arrowright}'); - - expect(onChange).toHaveBeenCalledTimes(1); - expect(onChange).toHaveBeenCalledWith( - expect.objectContaining({ - value: 2, - }) - ); - - const theInput = screen.getByRole('spinbutton'); - userEvent.type(theInput, '{selectall}3'); - expect(onChange).toHaveBeenCalledTimes(2); - expect(onChange).toHaveBeenCalledWith( - expect.objectContaining({ - value: 3, - }) - ); - }); - - it('should respect readOnly prop', () => { - const onChange = jest.fn(); - const onClick = jest.fn(); - - render( - - ); - - // Click events should fire - const theSlider = screen.getByRole('slider'); - userEvent.click(theSlider); - expect(onClick).toHaveBeenCalledTimes(1); - - userEvent.type(theSlider, '{arrowright}'); - - const theInput = screen.getByRole('spinbutton'); - userEvent.type(theInput, '{selectall}3'); - - expect(onChange).toHaveBeenCalledTimes(0); - }); - }); -});