2. Modern applications
use Javascript
• Rich user interfaces
• Faster, more responsive interfaces
• Easier to build reusable interface
components
3. You need to test your
Javascript
• No excuses
• Broken Javascript means a broken page
• In Javascript-heavy applications, it’s difficult
to write capybara tests without running
Javascript
4. Limits of rack-test
• “Dumb” web browser
• Follows redirects
• Rendering engine is Nokogiri
• Fill out forms, click links
• Handles 90% of the web
• (but the other 10% is the shiny part)
5. Simple Test
Feature: sign up for an account
Scenario: sign up
When I go to the home page
And I fill in the following:
| Email | jferris@thoughtbot.com |
| Password | taters |
And I press "Sign up"
Then I should have an email of "jferris@thoughtbot.com"
1 scenario (1 passed)
4 steps (4 passed)
0m0.446s
6. Simple Change
Feature: sign up for an account
Scenario: sign up
When I go to the home page
And I fill in the following:
| Email | jferris@thoughtbot.com |
| Password | taters |
And I press "Sign up"
Then I should have an email of "jferris@thoughtbot.com"
And I should have an account name of "jferris"
7. Add some Javascript
<script type="text/javascript">
$("#email").keyup(function () {
var email = $(this).val();
var name = email.replace(/@.*$/, "");
$("#accountName").val(name);
});
</script>
8. Feature: sign up for an account
Scenario: sign up and get the default account name
When I go to the home page
And I fill in the following:
| Email | jferris@thoughtbot.com |
| Password | taters |
And I press "Sign up"
Then I should have an email of "jferris@thoughtbot.com"
And I should have an account name of "jferris"
expected: "jferris"
got: "" (using ==) (RSpec::Expectations::ExpectationNotMetError)
./features/step_definitions/web_steps.rb:218:in `/^I should have an account
name of "([^"]*)"$/'
features/sign_up_javascript.feature:10:in `And I should have an account name of
"jferris"'
Failing Scenarios:
cucumber features/sign_up_javascript.feature:3
1 scenario (1 failed)
5 steps (1 failed, 4 passed)
0m0.398s
10. Selenium
• Runs tests in a real browser (usually
Firefox, but supports Chrome, Safari, and
Internet Explorer)
• Supports any Javascript your browser
supports, just like real users
• Easy to set up with capybara
11. Limits of Selenium
• Slow, slow, slow
• GUI browser adds a lot of cruft you don’t
want that gets in the way
• Browsers were designed to be clicked on
and looked at, not controlled and queried
12. Slow
• Boot up Firefox with fresh profile
• Set up Firefox with extension
• Communicates over JSON REST API
19. But you need Qt
• Download installer on OS X
• Most Linux distros have a package
20. Caveats
• capybara-webkit’s engine is still designed to
build browsers, so there are some
interactions we can’t get between
• All tests are asynchronous (like with
Selenium), so you still need Capybara’s
retrying methods
• capybara-webkit is still young, so things are
flakier than with Selenium
21. WebKits: how do they work?
• capybara-webkit is built around QtWebKit
• Headless browser listens for commands
using a lightweight socket layer
• Ruby driver implements the capybara API
and communicates with the server
22. WebKit
• Based on KHTML
• Open source
• Powers Safari, Chrome, and other browsers
• Cross-platform, fast, standards-compliant
23. WebKit
• WebKit is not a browser, or really even a
browser engine
• WebKit is a set of libraries for building
browsers
• WebKit is not packaged as a standalone
library
• There is no one WebKit
24. Qt
• Powers the KDE desktop
• Tools, extensions, and libraries for building
GUI applications in C++
• Provides a packaged wrapper around
WebKit called QtWebKit
25. QtWebKit
• Qt implementation of WebKit with nice API
and documentation
• Lots of injection points for building your
own browser
• We built a test harness instead
26. • capybara makes acceptance tests easy to write
• capybara-webkit is fast and easy to set up
• There is no excuse (anymore) for not testing
Javascript