Trying to implement this method. But sporadically running into this error when the test is run.
TypeError: p.instance(...).dispatchEvent is not a function
And here is the test.
it('clicking outside of cell deselects cell', () => {
const callBack = jest.fn();
const thisWrapper = mount(
<ObjectItemEditableSelectCell
{...mockConnectProps}
handleClick={callBack}
/>,
);
const p = thisWrapper.find(Layout);
console.log('p.debug()', p.debug());
p.instance().dispatchEvent(new Event('click'), { bubbles: true } );
thisWrapper.update();
expect(thisWrapper.state('selectedCell')).toBe(true);
});
Here is the output of p.debug
p.debug() <Layout listen={true} onClick={[Function: bound handleClick]} el={[Function: el]} width="100%" className="table-editable-cell" node="div" listeners={{...}} tag={false} attr={{...}}>
<div onClick={[Function: bound handleClick]} id={[undefined]} style={{...}} className="layout table-editable-cell">
<Text listen={true} node="div" accent={false} bold={false} light={false} disabled={false} secondary={false}>
<div id={[undefined]} style={[undefined]} className="text text-primary" />
</Text>
</div>
</Layout>
and here is the entire ObjectItemEditableSelectCell
component.
import React, { Component } from 'react';
import { Layout, Text, Select } from 'agile-ui';
import cx from 'classnames';
import { ObjectSelect } from '../../../common/_object_dropdown/ObjectSelect.jsx';
import { objectItemEditableSelectCellConnectService } from '../../../../business_layer/connect_services/_object_item/_table/objectItemEditableSelectCellConnectService';
@objectItemEditableSelectCellConnectService
export default class ObjectItemEditableSelectCell extends Component {
static getDerivedStateFromProps({ displayValue }, { prevDisplayValue }) {
if (prevDisplayValue !== displayValue) {
return {
showField: displayValue,
prevDisplayValue: displayValue,
};
}
return null;
}
constructor(props) {
super(props);
this.handleClick = this.handleClick.bind(this);
this.state = {
selectedCell: false,
showDropdown: false,
showField: props.displayValue,
prevDisplayValue: props.displayValue,
highlightValue: {},
};
}
componentDidMount() {
this.setState({ highlightValue: this.props.value });
}
componentWillUnmount() {
const query = document.querySelector('.Grid');
query.removeEventListener('click', this.handleOnClickOnDocument, false);
}
handleOnClickOnDocument = (e) => {
if (this.node && (this.node.contains(e.target) || this.node === e.target)) {
return;
}
this.handleOnClickOutsideCell(e);
};
handleOnClickOutsideCell = (e) => {
const { selectedCell, showDropdown } = this.state;
this.setState({ selectedCell: false, showDropdown: false });
const query = document.querySelector('.Grid');
query.removeEventListener('click', this.handleOnClickOnDocument, false);
};
handleClickOnCell = () => {
const { selectedCell, showDropdown } = this.state;
if (selectedCell) {
this.setState({ showDropdown: true });
} else if (!selectedCell) {
this.setState({ selectedCell: true });
}
};
handleUnsetPriority = (ev, itemId, workspaceId, onBlur, displayValue) => {
this.setState({ showField: '' });
this.setState({
highlightValue: {
displayName: '',
id: null,
},
});
if (displayValue !== null) {
return onBlur({
name: ev.name,
value: null,
itemId,
workspaceId,
});
}
};
onBlur = (ev) => {
const { onBlur, itemId, workspaceId, displayValue } = this.props;
const { selectedCell, showDropdown } = this.state;
this.setState({ showDropdown: false, selectedCell: false });
if (ev.name === 'priority' && !ev.value) {
this.handleUnsetPriority(ev, itemId, workspaceId, onBlur, displayValue);
}
if (ev && ev.value) {
switch (ev.name) {
case 'priority': {
this.setState({ showField: ev.value.displayName });
this.setState({
highlightValue: {
displayName: ev.value.displayName,
id: ev.value.id,
},
});
if (displayValue !== ev.value.displayName) {
return onBlur({
value: ev.value,
name: ev.name,
itemId,
workspaceId,
});
}
return;
}
case 'myCost': {
this.setState({
showField: ev.value.get('label'),
});
if (displayValue !== ev.value.get('value')) {
return onBlur({
costSize: ev.value.get('label'),
value: ev.value.get('value'),
name: ev.name,
updateOboScores: true,
inTable: true,
itemId,
workspaceId,
});
}
return;
}
case 'myValidateCost': {
this.setState({
showField: ev.value.get('label'),
});
if (displayValue !== ev.value.get('value')) {
return onBlur({
costSize: ev.value.get('label'),
value: ev.value.get('value'),
name: ev.name,
updateOboScores: true,
inTable: true,
itemId,
workspaceId,
});
}
return;
}
case 'owner': {
const ownerName = `${ev.value.fname} ${ev.value.lname}`;
this.setState({ showField: ownerName });
this.setState({
highlightValue: {
fname: ev.value.fname,
id: ev.value.id,
lname: ev.value.lname,
},
});
if (this.props.value.id !== ev.value.id) {
return onBlur({
value: ev.value,
name: ev.name,
itemId,
workspaceId,
});
}
break;
}
case 'objectItemType': {
this.setState({ showField: ev.value.name });
if (displayValue !== ev.value.name) {
this.setState({
highlightValue: { name: ev.value.name, id: ev.value.id },
});
return onBlur({
value: ev.value,
name: ev.name,
inTable: true,
itemId,
workspaceId,
});
}
break;
}
case 'status': {
this.setState({ showField: ev.value.name });
if (displayValue !== ev.value.name) {
this.setState({
highlightValue: { name: ev.value.name, id: ev.value.id },
});
if (ev.value.name !== '') {
return onBlur({
value: ev.value,
name: ev.name,
inTable: true,
itemId,
workspaceId,
});
}
}
break;
}
default:
this.setState({ showField: ev.value.name });
if (displayValue !== ev.value.name) {
this.setState({
highlightValue: { name: ev.value.name, id: ev.value.id },
});
return onBlur({
value: ev.value,
name: ev.name,
itemId,
workspaceId,
});
}
}
}
};
handleClick() {
console.log('handleClick');
const { selectedCell, showDropdown } = this.state;
if (!selectedCell) {
this.setState({ selectedCell: true });
const query = document.querySelector('.Grid');
query.addEventListener('click', this.handleOnClickOnDocument, false);
} else if (selectedCell && !showDropdown) {
this.setState({ showDropdown: true });
}
}
render() {
const {
children,
onEdit,
className,
columnName,
onValueChange,
name,
domain,
record,
value,
itemId,
noExtendedFilters,
accessor,
displayValue,
onBlur,
filters,
placeholder,
narrowResizedWidth,
} = this.props;
const {
selectedCell,
showDropdown,
showField,
highlightValue,
} = this.state;
return (
<Layout
listen
onClick={this.handleClick}
el={(node) => {
this.node = node;
}}
width="100%"
className={cx(
className,
'table-editable-cell',
selectedCell && 'table-editable-cell--selected',
showDropdown && 'table-editable-cell--showDropdown',
)}
>
{showDropdown ? (
<Layout
className={cx(
className,
'dropdown-layout-container',
narrowResizedWidth &&
'dropdown-layout-container--narrowResizedWidth',
)}
>
<ObjectSelect
minWidth="6rem"
domain={domain}
onBlur={this.onBlur}
value={
name === 'status' || name === 'myCost' ? value : highlightValue
}
filters={filters}
noExtendedFilters={noExtendedFilters}
placeholder={placeholder}
Record={record}
name={name}
open
rounded
accessor={accessor}
/>
</Layout>
) : (
<Text listen>
{name === 'status' || name === 'myCost' ? displayValue : showField}
</Text>
)}
</Layout>
);
}
}
Would be grateful to anyone who can help.
I am trying to test that once I click anywhere in this component the selectedCell
state will get set to true. Sometimes the tests run but the selectedCell
state is still false.
Click event should be registered on component.
MacOS Mojave
| library | version
| ------------------- | -------
| enzyme | 3.3.0
| react | 16.8.6
| react-dom | 16.8.6
| react-test-renderer | 15.6.2
| adapter (below) |
As you can see from p.debug()
, p
is a Layout
component, which has an instance that is not a DOM element.
Since you're using mount, you can do p.getDOMNode()
to get the DOM node, on which dispatchEvent
should work.
Most helpful comment
As you can see from
p.debug()
,p
is aLayout
component, which has an instance that is not a DOM element.Since you're using mount, you can do
p.getDOMNode()
to get the DOM node, on whichdispatchEvent
should work.