Hi, I'm using Jest and Enzyme to test my component.
import React, { Component, Fragment } from "react";
import equal from "fast-deep-equal";
import { TextField, Tooltip, Zoom, withStyles } from "@material-ui/core";
import { checkValue, setValue } from "./PickersFunction";
import { customVariant } from "../../MuiTheme";
import {
valueVerificationPropType,
cellValPropType,
classesPropType,
typePropType
} from "../../../proptypes";
export class TextFieldWrapper extends Component {
constructor(props) {
super(props);
this.state = {
tooltipOpen: false,
message: "",
error: false
};
}
componentDidMount() {
const { valueVerification } = this.props;
if (valueVerification) {
const newState = checkValue({
...this.props,
mounting: true
});
if (!equal(this.state, newState)) {
this.setState(newState);
}
}
}
onValueChange = e => {
const { value } = e.target;
const newState = setValue({
...this.props,
value
});
if (!equal(this.state, newState)) {
this.setState(newState);
}
};
toggleCloseTooltip = open => {
const { error } = this.state;
if (error) {
this.setState({ tooltipOpen: open });
}
};
render() {
const { type, cellVal, classes } = this.props;
const { tooltipOpen, message, error } = this.state;
return (
<Tooltip
open={tooltipOpen}
classes={{
tooltip: classes.errorTooltip
}}
title={message}
TransitionComponent={Zoom}
interactive
>
<Fragment>
<TextField
value={cellVal}
error={error}
onFocus={() => this.toggleCloseTooltip(true)}
onBlur={() => this.setState({ tooltipOpen: false })}
onChange={this.onValueChange}
type={type}
fullWidth
/>
</Fragment>
</Tooltip>
);
}
}
TextFieldWrapper.propTypes = {
cellVal: cellValPropType.isRequired,
classes: classesPropType.isRequired,
type: typePropType.isRequired,
valueVerification: valueVerificationPropType
};
export default withStyles(customVariant)(TextFieldWrapper);
My test :
it("should render a Tootltip and Textfield", () => {
const wrapper = mount(
<TextFieldWrapperPureComponent
cellVal={10}
type="number"
columnId="age"
rowId={rowId}
valueVerification={valueVerification}
setRowEdited={setRowEdited}
classes={{ customVariant }}
/>
);
wrapper.instance().onValueChange({ target: { value: 105 } });
});
Result: ```
TypeError: document.createRange is not a function
41 | });
42 | if (!equal(this.state, newState)) {
> 43 | this.setState(newState);
| ^
44 | }
45 | };
46 |
...
console.error node_modules/react-dom/cjs/react-dom.development.js:17117
The above error occurred in the
in Portal (created by Popper)
in Popper (created by Tooltip)
in Tooltip (created by WithStyles(Tooltip))
in WithStyles(Tooltip) (created by TextFieldWrapper)
in TextFieldWrapper (created by WrapperComponent)
in WrapperComponent
```
Any ideas ?
Please create a minimal repro. It looks like your test setup is incomplete i.e. no DOM is available.
@MorganDbs See https://github.com/jsdom/jsdom/issues/317. We use the following patch for our tests:
global.document.createRange = () => ({
setStart: () => {},
setEnd: () => {},
commonAncestorContainer: {
nodeName: 'BODY',
ownerDocument: document,
},
});
Does it fix your problem?
Update, no longer required since Jest v26.0.0 and https://github.com/facebook/jest/pull/9606.
@oliviertassinari Thanks you it's working now !! If I'm understanding well, my test wasn't attached to the BODY, right ?
@oliviertassinari adding the mock for createRange seem to help, my test is passing, but I get the following console.error:
√ without consent, cannot go further (190ms)
console.error node_modules/react-dom/cjs/react-dom.development.js:506
Warning: An update to ForwardRef(Popper) inside a test was not wrapped in act(...).
When testing, code that causes React state updates should be wrapped into act(...):
act(() => {
/* fire events that update state */
});
/* assert on the output */
This ensures that you're testing the behavior the user would see in the browser. Learn more at https://fb.me/react-wrap-tests-with-act
in ForwardRef(Popper) (created by Tooltip)
in Tooltip (created by WithStyles(Tooltip))
....
My test (using @testing-library/react
):
it('without consent, cannot go further', () => {
const {getByText} = render(<Registration/>)
const loginButton = getByText(/Log in/)
act(() => {
fireEvent.mouseEnter(loginButton)
})
expect(getByText(/Please accept our terms and conditions/)).toBeInTheDocument()
})
@balazsorban44 There are timeouts started when hovering. You should either let all timers run out inside your act()
or set the timeouts to 0 via props.
@eps1lon Trying like this:
+ jest.useFakeTimers()
it('without consent, cannot go further', () => {
const {getByText} = render(<Registration/>)
const loginButton = getByText(/Log in/)
act(() => {
fireEvent.mouseEnter(loginButton)
+ jest.runAllTimers()
})
expect(getByText(/Please accept our terms and conditions/)).toBeInTheDocument()
})
Still the same. 🤔 What do I do wrong? I would prefer this solution.
Or if not that, what do you mean by
set timeouts to 0 via props
?
Yeah sorry this was just a quick guess. Could you ask the question on stackoverflow and link it from here? I'll take a look later.
@eps1lon
Yeah sorry this was just a quick guess. Could you ask the question on stackoverflow and link it from here? I'll take a look later.
UPDATE:
The warning goes away in [email protected]
, don't even need the timers!
Hey! I just found this thread. I am still reproducing this issue on [email protected]
, so I guess it did not go way?
The issue should have been solved in [email protected] now.
I stumbled on this thread as well. As @oliviertassinari suggested, using jest-environment-jsdom-sixteen solved the issue for me. Upgrading jest to v26 works as well as jest uses jsdom v16 as of v26 https://jestjs.io/blog/2020/05/05/jest-26
@tedwardmah Updating to jest-environment-jsdom-sixteen fixed the issue for me
@MorganDbs See jsdom/jsdom#317. We use the following patch for our tests:
global.document.createRange = () => ({ setStart: () => {}, setEnd: () => {}, commonAncestorContainer: { nodeName: 'BODY', ownerDocument: document, }, });
Does it fix your problem?
I tried this and fixed my problem, thanks
Update, since Jest v26.0.0 (https://github.com/facebook/jest/pull/9606), the workaround in https://github.com/mui-org/material-ui/issues/15726#issuecomment-493124813 is no longer required.
Most helpful comment
@MorganDbs See https://github.com/jsdom/jsdom/issues/317. We use the following patch for our tests:
Does it fix your problem?
Update, no longer required since Jest v26.0.0 and https://github.com/facebook/jest/pull/9606.