enzyme: Simulating click does not honor the disabled attribute
There seems to be a difference in behaviour between shallow/mount and react-addons-test-utils when it comes to simulating a click on an element with the disabled
attribute. React and react-addons-test-utils does not call the onClick handler when the disabled attribute is present but shallow/mount does.
Component under test:
export const DisabledButton = React.createClass({
getInitialState (){
return {
clicks: 0
}
},
handleClick () {
console.log(`the click was registered`)
this.setState({
clicks: ++this.state.clicks
})
},
render () {
return (
<section>
<p>Clicks: {this.state.clicks}</p>
<button onClick={this.handleClick} disabled={true}>Click Me!</button>
</section>
)
}
})
All tests pass using react-addons-test-utils
:
import TestUtils from 'react-addons-test-utils'
import ReactDOM from 'react-dom'
describe('<DisabledButton /> TestUtils', function () {
it('should start with zero clicks', () => {
const component = TestUtils.renderIntoDocument(
<DisabledButton />
)
const p = ReactDOM.findDOMNode(TestUtils.findRenderedDOMComponentWithTag(component, 'p'))
expect(p.textContent).toContain('0')
})
it('should not do anything when clicked because the button is disabled', () => {
const component = TestUtils.renderIntoDocument(
<DisabledButton />
)
TestUtils.Simulate.click(TestUtils.findRenderedDOMComponentWithTag(component, 'button'))
const p = ReactDOM.findDOMNode(TestUtils.findRenderedDOMComponentWithTag(component, 'p'))
expect(p.textContent).toContain('0')
})
})
Using shallow
the second test will fail:
import { shallow } from 'enzyme'
describe('<DisabledButton /> shallow', function () {
it('should start with zero clicks', () => {
const wrapper = shallow(
<DisabledButton />
)
expect(wrapper.find('p').text()).toContain('0')
})
it('should not do anything when clicked because the button is disabled', () => {
const wrapper = shallow(
<DisabledButton />
)
wrapper.find('button').simulate('click')
expect(wrapper.find('p').text()).toContain('0')
})
})
Using mount
the second test will fail:
import { mount } from 'enzyme'
describe('<DisabledButton /> mount', function () {
it('should start with zero clicks', () => {
const wrapper = mount(
<DisabledButton />
)
expect(wrapper.find('p').text()).toContain('0')
})
it('should not do anything when clicked because the button is disabled', () => {
const wrapper = shallow(
<DisabledButton />
)
wrapper.find('button').simulate('click')
expect(wrapper.find('p').text()).toContain('0')
})
})
About this issue
- Original URL
- State: open
- Created 8 years ago
- Reactions: 14
- Comments: 20 (5 by maintainers)
@zachfejes react 15 only goes up to 15.6; there’s no 15.9?
simulate
should be avoided; it doesn’t faithfully simulate anything. If you want to invoke theonClick
function, extract it from props and invoke it.I can confirm this.
@djskinner your second test uses
shallow
in the failing test case when it should usemount
. Can you verify it actually fails withmount
? I wouldn’t expect it to, assimulate
is a thin wrapper aroundReactTestUtils.Simulate
.shallow
on the other hand doesn’t have any guard against this AFAIK right now.Hi! Any updates on this issue?
My bad.
mount
does indeed work as expected.@mattvalli the plan is in v4, to remove simulate entirely. It’s a bad API, and it doesn’t faithfully simulate anything.
Nobody should be using
simulate
in their tests.@ljharb thanks for the response - I’ve corrected the version number in my comment to clarify, react 15.5.4.
I’m noticing this bug with react 15.5.4 + enzyme 3.1.0, specifically with a shallow component. For reference, the component has 3 buttons in it, I’m finding them with wrapper.find(‘button’) with has a length 3, and then attempting to simulate a click with:
And the test fails, because fooMock was called once - despite the button being disabled. Is there any way around this?