Minimal cucumber stack for testing a rich javascript application

by on

These are instructions for setting up a very bare cucumber stack for testing a rich javascript application.

All code available here: https://github.com/ngauthier/cucumber-webapp-demo


The following stack is used:

  • Cucumber
  • Capybara
  • Selenium
  • WEBrick


First, we make our awesome javascript powered webapp:

<!DOCTYPE html>
<html>
<head>
<script type='text/javascript' src='jquery-1.4.3.min.js'></script>
<script type='text/javascript'>
$(function() {
$('#special-link').click(function(event) {
$('#results').html("This is totally awesome");
event.preventDefault();
});
});
</script>
</head>
<body>
<h1>My Webapp</h1>
<p>
<a href='#' id='special-link'>Click on this link to make cool stuff happen</a>
</p>
<div id="results"></div>
</body>
</html>


All we're doing here is showing some text when we click a link. But we're using jquery's events to do it.


Now here is our feature file:

Feature: My Awesome Link
Scenario: Clicking the awesome link shows awesome text
Given I am on the home page
Then I should see "My Webapp"
And I should see "Click on this link to make cool stuff happen"
And I should not see "This is totally awesome"
When I click "Click on this link to make cool stuff happen"
Then I should see "This is totally awesome"


And here are our simple step definitions:

Given /^I am on the home page$/ do
visit 'index.html'
end

Then /^I should see "([^"]*)"$/ do |content|
within('body') do
assert page.has_content?(content)
end
end

Then /^I should not see "([^"]*)"$/ do |content|
within('body') do
refute page.has_content?(content)
end
end

When /^I click "([^"]*)"$/ do |link_text|
click_link_or_button(link_text)
end


And here is the cucumber environment file where all the magic happens. See comments for description:

require 'rubygems'
require 'cucumber'
require 'capybara/cucumber'
require 'webrick'

# setup capybara on selenium
Capybara.default_driver = :selenium

# This maps to webrick below
Capybara.app_host = 'http://127.0.0.1:3000'
Capybara.default_selector = :css

# Extend Cucumber's World with minitest assertions
World(MiniTest::Assertions)

# Launch a webrick server in a thread
AfterConfiguration do
server_thread = Thread.new do
project_root = File.join(File.dirname(__FILE__), '..', '..')
WEBrick::HTTPServer.new(
:Port => 3000,
# TODO use the real application directory
# Using the prototype directory for now
:DocumentRoot => File.join(project_root, 'public'),
:Logger => WEBrick::Log.new(File.join(project_root, 'cucumber.log')),
:AccessLog => StringIO.new # to nowhere
).start
end
# Kill the server when cucumber is done
at_exit do
server_thread.exit
end
end

The idea here is to boot webrick in a thread to serve the public directory, then connect selenium up to it. Very simple and light.

All code available here: https://github.com/ngauthier/cucumber-webapp-demo

Comments

Sharad Jain
Nice, thanks!
blog comments powered by Disqus