Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to test ant design date picker using @testing-library/react?

I have two ant design date pickers in a component. I am trying to change and test the value of date picker but not able to find the calendar input in the test environment dom.

Date Pickers Component

import { DatePicker, Form } from "antd";
import React, { Component } from "react";

import moment from "moment";

class DatePickers extends Component {
  constructor(props) {
    super(props);
    this.state = {
      startDate: moment().subtract(1, "month"),
      startDateError: "",
      endDate: moment(),
      endDateError: "",
    };
  }

  onStartDateChange = (date) => {
    this.setState({
      startDate: date,
      startDateError: date ? "" : "Please select start date",
    });
  };

  onEndDateChange = (date) => {
    this.setState({
      endDate: date,
      endDateError: date ? "" : "Please select end date",
    });
  };

  render() {
    const { endDate, endDateError, startDate, startDateError } = this.state;

    return (
      <React.Fragment>
        <Form.Item
          validateStatus={startDateError ? "error" : ""}
          help={startDateError}
          htmlFor="startDate"
          label="Date From"
        >
          <DatePicker
            id="startDate"
            placeholder="Select Start Date"
            allowClear={false}
            onChange={this.onStartDateChange}
            defaultPickerValue={startDate}
            defaultValue={startDate}
            format="DD-MM-YYYY"
          />
        </Form.Item>
        <Form.Item
          validateStatus={endDateError ? "error" : ""}
          help={endDateError}
          htmlFor="endDate"
          label="To"
        >
          <DatePicker
            id="endDate"
            placeholder="Select End Date"
            allowClear={false}
            onChange={this.onEndDateChange}
            defaultPickerValue={endDate}
            defaultValue={endDate}
            format="DD-MM-YYYY"
          />
        </Form.Item>
      </React.Fragment>
    );
  }
}


export default DatePickers;

Test case using @testing-library/react

import { render, screen, waitFor } from "@testing-library/react";
import userEvent from "@testing-library/user-event";

test("date input value validation", async () => {
  const { container } = render(<DatePickers />);

  const startDateNode = screen.getByPlaceholderText(/select start date/i);
  const endDateNode = screen.getByPlaceholderText(/select end date/i);

  userEvent.click(startDateNode);

  const calendarInput = container.querySelector("ant-calendar-input");
  await userEvent.type(calendarInput, "");

  // assert
  expect(screen.getByText("Please select by start date")).toBeInTheDocument();
});

The test case fails and throws an error

console.error node_modules/jest-environment-jsdom-fourteen/node_modules/jsdom/lib/jsdom/virtual-console.js:29
      Error: Not implemented: navigation (except hash changes)

Versions:

"react" : "16.10.1",
"antd": "3.25.1",
"@testing-library/jest-dom": "5.7.0",
"@testing-library/react": "10.0.4",
"@testing-library/user-event": "10.1.2"

Is there any solution to assert this?

like image 862
Rahul Avatar asked Dec 10 '22 00:12

Rahul


2 Answers

I had the exact same issue with antd v4. The above solution is apt and its working. I had a bit of trouble with multiple date pickers in Form.Item and if we have a custom validation to Datepicker make sure date formats are set properly.

    const startDate = screen.getByTestId("start-date");
    fireEvent.mouseDown(startDate);
    fireEvent.change(startDate, { target: { value: "10-12-2020" } });
    fireEvent.click(document.querySelectorAll(".ant-picker-cell-selected")[0]);

When the date is set make sure the value is correct format, according to your validation and also make sure if not using moment all the date strings are set to whatever library you are using. I was using dayjs and had a moment object messing with one of the date. Which literally took several hours for me to figure out. Hope it helps.

    const endDate = screen.getByTestId("end-date");
    fireEvent.mouseDown(endDate);
    fireEvent.change(endDate, { target: { value: "10-25-2020" } });
    fireEvent.click(document.querySelectorAll(".ant-picker-cell-selected")[1]);

like image 71
Akshay Monish Avatar answered Jan 01 '23 13:01

Akshay Monish


This error seems to be unrelated to a date picker test problem : https://github.com/jsdom/jsdom/issues/2112

Anyway, this is how I test Ant Design date pickers with RTL :

Code below works with antd v4

Component

<Form.Item colon={false} label={t('searchFields.creationDate.label')} name="creationDateRange">
  <RangePicker data-testid="creationDate" />
</Form.Item>

Test

[...]
rtl = render(...);
[...]

// grab the input
const creationDateFromInput = rtl.getByTestId('creationDate').querySelectorAll('input')[0];
// mouseDown opens the calendar popup, set focus on the input
fireEvent.mouseDown(creationDateFromInput);
// type date in input
fireEvent.change(creationDateFromInput, { target: { value: '2020-01-15' } });
// now calendar popup is opened and 2020-01-15 cell is selected, just click on it
fireEvent.click(document.querySelector('.ant-picker-cell-selected'));

// now form field is correclty set

I tried to make this more readable and avoid the document.querySelector part which I'm not a big fan of, but I could not find another solution. This could certainly be improved.

Good luck

like image 40
Florian Motteau Avatar answered Jan 01 '23 12:01

Florian Motteau