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?
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]);
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With