Skip to content

Test suite: Clicking on track does not set the slider to the new valueΒ #265

Open
@elotgamu

Description

@elotgamu

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 but onChange 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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions