@cpytel As you requested, here is an example of a JavaScript bug I’m having difficulty testing.
Here’s the bug:
Clicking the Time Limit checkbox label on the New Question page does weird things. The time limit boxes will slide up, then down, and the checkbox gets out of sync with the hide/display status of the time limit boxes.
Here’s the code:
$(document).ready(function(){
$('#time_limit_enabled').click(timeLimitToggle);
...
}
function timeLimitToggle() {
$('#time_limit_parts_box').slideToggle();
...
}
The main problem is - how do I write a failing test case for this?
A few other thoughts:
This is legacy Javascript and I should probably convert this to CoffeeScript, although I’m not sure it’s worth the effort.
I’m not great with JavaScript / jQuery and perhaps there is a better way to write this code. Of course, I’d like to have a failing test case first.
There’s not enough here for me to help much, I’m afraid. From the description, it sounds like slideToggle is actually being called a couple of times (you describe a couple of slides).
What is it your trying to do? Is this an exercise in one of the courses (I’m not familiar with the course material). Would it be possible for you to post a reproduction on something like jsfiddle.net?
Without seeing the code or being familiar with what it’s trying to do, it’s hard to say how you should test it.
The point of the code there is that the second line (the asterisks) should only appear when the checkbox is checked, and should disappear when the checkbox is unchecked. However, click around a bit and you will see the synchronization is off.
Quickly you will see that there are a combination of HTML errors here that cause the problem:
I am wrapping the input inside the label tag
The label tag has an ‘id’ attribute identical to the input tag
The label tag is missing the ‘for’ attribute
One solution would be to write unit tests verifying the HTML is valid and proper. But at the integration-test level, how would I test that clicking on the label doesn’t screw up the show/hide synchornization?
@dsilver829, part of the issue you have is because the jQuery click() method’s argument needs to be a function. Also, slideToggle() simply toggles display: none; on and off. Because of this you need to start with the asterisks hidden. An updated JSFiddle that works as desired can be found here: Edit fiddle - JSFiddle - Code Playground
To test this behavior I would use the be_visible matcher (auto-generated by RSpec from Capybara’s visible? method)
scenario 'user shows/hides asterisks by clicking checkbox' do
# Asterisks are hidden on initial page view
visit 'some/url'
expect(find('#asterisks').to_not be_visible
# Asterisks are visible after checking the box
check('#show-asterisks')
expect(find('#asterisks').to be_visible
# Asterisks are hidden again after unchecking the box
uncheck('#show-asterisks')
expect(find('#asterisks').to_not be_visible
end
Typically you would use Capybara with one of the following webdrivers:
####Selenium
Probably the easiest to set up
Pops up an actual browser window and you can see things happen on the page ast the suite runs
You need to have Firefox installed
I much slower than alternatives
Tightly coupled with Firefox (e.g. upgrading FF may cause your tests to fail until you also upgrade selenium)
####Capybara-webkit
is a headless browser (it doesn’t actually open a window) which makes it much faster
depends on Qt which can sometimes be a pain to install
is based on an implementation of webkit (the engine behind Chrome and Safari)
####PhantomJS
is also a headless browser
is also based on webkit
I tend to stay away from Selenium since it is slow and tightly coupled the the version of Firefox installed on my machine. However, I do sometimes temporarily switch to Selenium when visually seing what is happening during a test would help with debugging.