Description
Description
I ran into issues when I created a test when user clicks on steps to update slider value. However, testing using keyboard Arrow Rigth
works as expected.
Also when testing with the preview the click on the steps works as expected.
Package versions:
react-slider 1.3.1
React 16.14.0
ReactDOM 16.14.0
react-scripts 4.0.3
testing-library/react 12.0.0
testing-library/user-event 13.0.16
testing-library/jest-dom 5.14.1
Relevant code
Component
import React from "react";
import ReactSlider from "react-slider";
import "../styles.css";
import "./slider.css";
const Slider = ({ onChange, currentIndex }) => {
return (
<div>
<label id="slider-label" className="slider-label">
Step Slider
</label>
<ReactSlider
ariaLabelledby={["slider-label"]}
className="vertical-slider"
markClassName="example-mark"
onChange={onChange}
trackClassName="example-track"
defaultValue={0}
value={currentIndex}
min={0}
max={5}
marks
ariaValuetext={(state) => `Thumb value ${state.valueNow}`}
renderMark={(props) => {
if (props.key < currentIndex) {
props.className = "example-mark example-mark-completed";
} else if (props.key === currentIndex) {
props.className = "example-mark example-mark-active";
}
return <span {...props} aria-label={`Set ${props.key}`} />;
}}
/>
</div>
);
};
export default Slider;
App
export default function App() {
const [currentIndex, setCurrentIndex] = useState(0);
const _handleIndexChange = (index) => {
console.log("does this get called? ", index);
setCurrentIndex(index);
};
return (
<div className="App">
<Slider onChange={_handleIndexChange} currentIndex={currentIndex} />
<div className="container">
<Step currentIndex={currentIndex} />
</div>
</div>
);
}
Tests
import * as React from "react";
import "@testing-library/jest-dom";
import userEvent from "@testing-library/user-event";
import { render, screen } from "@testing-library/react";
import App from "./App";
beforeEach(() => {
// `React Slider` package uses ResizeObserver api
// mock is needed
Object.defineProperty(global, "ResizeObserver", {
writable: true,
value: jest.fn().mockImplementation(() => ({
observe: jest.fn(() => "Mocking works"),
unobserve: jest.fn(),
disconnect: jest.fn()
}))
});
});
describe("update slider values", () => {
// this pass without issues π
it("should allow user to change value by keyboard input", () => {
render(<App />);
const slider = screen.getByLabelText("Step Slider");
screen.debug(slider);
expect(slider).toHaveAttribute("aria-valuenow", "0");
userEvent.type(slider, "{ArrowRight}");
expect(slider).toHaveAttribute("aria-valuenow", "1");
});
// this does not pass π
// on change handler receives old value
it("should allow user to change value by click on marks", () => {
render(<App />);
const slider = screen.getByLabelText("Step Slider");
screen.debug(slider);
expect(slider).toHaveAttribute("aria-valuenow", "0");
const step1 = screen.getByLabelText("Set 1");
screen.debug(step1);
userEvent.click(step1);
expect(slider).toHaveAttribute("aria-valuenow", "1");
});
});
Notes:
-
The span for each mark contains an aria-label useful with testing so we can query this mark with
getByLabelText
. Even though aria-label does not make much sense on span tags. We are able to query and click marks butonChange
get called with old value or not called at all. So slider value does not get updated. -
Tested this code with react-slider v2.0.1 with a local app however, sandbox throws some errors. So I set and older version. But same error on related to test suite happens when testing with either 1.3.1 or 2.0.1.
-
Maybe this old solved issues could be related: onChange returns old value if used with value propΒ #197 onAfterChange called with old valuesΒ #201 but didn't seems to provide a solution since this one is a weird behavior on test.
CodeSandbox
Please replicate on the below sandbox link
https://codesandbox.io/s/react-slider-prompt-level-iun34i?file=/src/App.test.js
Thank you so much for the library, it is an awesome one.