I'd like to ask your opinion about using jQuery
in Capybara specs.
Is it really simulating the real user interaction, or is it faking it?
find("#my_checkbox[value='1']").set(true)
page.execute_script("$('#my_checkbox').prop('checked', true);")
?
find("#my_button").click
page.execute_script("$('#my_button').click();")
?I know that the spec result will be the same, but I'm really wondering:
jQuery
in the specs?jQuery
?Using execute_script
/evaluate_script
to interact with the page in your tests is NOT simulating real user interaction and in a lot of cases can make your tests pointless. The main reason for this is that it allows you to do things a user never could (changing the values of hidden/readonly/disabled fields, etc). It also doesn't generate the same events a user interacting with elements would generate, so the JS in your page may not be reacting the same way. execute_script
does have its place in writing tests but it's limited and usually to get values (as opposed to changing things) or to work around problems in browsers/drivers (once you fully understand the issue you're trying to work around and are sure it isn't a situation where the user couldn't actually do what you're trying to do).
As far as speed goes the execute_script
may be slightly faster in some cases but that's only because it's not verifying that a user could actually do what it's doing. Also a slightly faster but meaningless test isn't really saving you anything.
That covers using execute_script
with JS which I believe is what your question is really asking, although you specifically mention jQuery. There is also a reason not to use jQuery in any execute_script
calls you do have in your tests which is that if you ever refactor your app to remove jQuery and just go with plain JS your tests will break. ie - you could prefer document.getElementById('abc')
over $('#abc')
. This may not be a big concern to you since there really shouldn't be that many instances of execute_script
in your tests.
TLDR -
check('my_checkbox', option: 1) # best
find("#my_checkbox[value='1']").set(true) # valid but too verbose
page.execute_script("$('#my_checkbox').prop('checked', true);") # Don't use - not replicating a user
click_on('my_button') # best if element is a link or button
find("#my_button").click # valid
find("#my_button").trigger('click') # Only supported on some drivers - don't use in tests unless you REALLY understand why you're using it - basically the same as using `execute_script`
page.execute_script("$('#my_button').click()") # Don't use - not replicating a user