aboutsummaryrefslogtreecommitdiff
path: root/site
diff options
context:
space:
mode:
authorJoachim Filip Ignacy Bartosik <jbartosik@gmail.com>2011-05-10 10:37:18 +0200
committerJoachim Filip Ignacy Bartosik <jbartosik@gmail.com>2011-05-13 13:23:06 +0200
commit5c2d4c06c186d605e8ae0df958bcf287db77909c (patch)
tree86e46ae04367b64fe37b3c2b3888b332e82c30a9 /site
parentA working rspec test (diff)
downloadcouncil-webapp-5c2d4c06c186d605e8ae0df958bcf287db77909c.tar.gz
council-webapp-5c2d4c06c186d605e8ae0df958bcf287db77909c.tar.bz2
council-webapp-5c2d4c06c186d605e8ae0df958bcf287db77909c.zip
Cucumber with a login feature demonstrating cookies work
Diffstat (limited to 'site')
-rw-r--r--site/Gemfile5
-rw-r--r--site/Gemfile.lock48
-rw-r--r--site/config/cucumber.yml8
-rw-r--r--site/features/login.feature20
-rw-r--r--site/features/step_definitions/login_steps.rb15
-rw-r--r--site/features/step_definitions/web_steps.rb190
-rw-r--r--site/features/support/env.rb5
-rw-r--r--site/features/support/paths.rb36
-rw-r--r--site/features/support/selectors.rb39
-rw-r--r--site/lib/tasks/cucumber.rake50
-rwxr-xr-xsite/script/cucumber10
11 files changed, 426 insertions, 0 deletions
diff --git a/site/Gemfile b/site/Gemfile
index 7bac170..33fb3f8 100644
--- a/site/Gemfile
+++ b/site/Gemfile
@@ -6,6 +6,11 @@ group :development, :test do
gem 'ruby-debug'
gem 'rspec-rails'
gem 'shoulda'
+
+ gem 'cucumber-rails'
+ gem 'capybara'
+ gem 'database_cleaner'
+ gem 'launchy'
end
gem "hobo", ">= 1.3.0.pre28"
diff --git a/site/Gemfile.lock b/site/Gemfile.lock
index 94fd74f..e80cd7d 100644
--- a/site/Gemfile.lock
+++ b/site/Gemfile.lock
@@ -30,13 +30,42 @@ GEM
activesupport (3.0.3)
arel (2.0.9)
builder (3.0.0)
+ capybara (0.4.1.2)
+ celerity (>= 0.7.9)
+ culerity (>= 0.2.4)
+ mime-types (>= 1.16)
+ nokogiri (>= 1.3.3)
+ rack (>= 1.0.0)
+ rack-test (>= 0.5.4)
+ selenium-webdriver (>= 0.0.27)
+ xpath (~> 0.1.3)
+ celerity (0.8.8)
+ childprocess (0.1.8)
+ ffi (~> 1.0.6)
columnize (0.3.2)
+ configuration (1.2.0)
+ cucumber (0.10.2)
+ builder (>= 2.1.2)
+ diff-lcs (>= 1.1.2)
+ gherkin (>= 2.3.5)
+ json (>= 1.4.6)
+ term-ansicolor (>= 1.0.5)
+ cucumber-rails (0.4.0)
+ cucumber (>= 0.10.1)
+ nokogiri (>= 1.4.4)
+ rack-test (>= 0.5.7)
+ culerity (0.2.15)
+ database_cleaner (0.6.6)
diff-lcs (1.1.2)
dryml (1.3.0.pre28)
actionpack (>= 3.0.0)
hobo_support (= 1.3.0.pre28)
erubis (2.6.6)
abstract (>= 1.0.0)
+ ffi (1.0.7)
+ rake (>= 0.8.7)
+ gherkin (2.3.5)
+ json (>= 1.4.6)
hobo (1.3.0.pre28)
dryml (= 1.3.0.pre28)
hobo_fields (= 1.3.0.pre28)
@@ -49,6 +78,11 @@ GEM
hobo_support (1.3.0.pre28)
rails (>= 3.0.0)
i18n (0.5.0)
+ json (1.4.6)
+ json_pure (1.5.1)
+ launchy (0.4.0)
+ configuration (>= 0.0.5)
+ rake (>= 0.8.1)
linecache (0.43)
mail (2.2.15)
activesupport (>= 2.3.6)
@@ -56,6 +90,7 @@ GEM
mime-types (~> 1.16)
treetop (~> 1.4.8)
mime-types (1.16)
+ nokogiri (1.4.4)
polyglot (0.3.1)
rack (1.2.2)
rack-mount (0.6.14)
@@ -94,21 +129,34 @@ GEM
ruby-debug-base (~> 0.10.4.0)
ruby-debug-base (0.10.4)
linecache (>= 0.3)
+ rubyzip (0.9.4)
+ selenium-webdriver (0.1.4)
+ childprocess (>= 0.1.7)
+ ffi (>= 1.0.7)
+ json_pure
+ rubyzip
shoulda (2.11.3)
sqlite3 (1.3.3)
sqlite3-ruby (1.3.3)
sqlite3 (>= 1.3.3)
+ term-ansicolor (1.0.5)
thor (0.14.6)
treetop (1.4.9)
polyglot (>= 0.3.1)
tzinfo (0.3.25)
will_paginate (3.0.pre2)
+ xpath (0.1.3)
+ nokogiri (~> 1.3)
PLATFORMS
ruby
DEPENDENCIES
+ capybara
+ cucumber-rails
+ database_cleaner
hobo (>= 1.3.0.pre28)
+ launchy
rails (= 3.0.3)
rspec-rails
ruby-debug
diff --git a/site/config/cucumber.yml b/site/config/cucumber.yml
new file mode 100644
index 0000000..19b288d
--- /dev/null
+++ b/site/config/cucumber.yml
@@ -0,0 +1,8 @@
+<%
+rerun = File.file?('rerun.txt') ? IO.read('rerun.txt') : ""
+rerun_opts = rerun.to_s.strip.empty? ? "--format #{ENV['CUCUMBER_FORMAT'] || 'progress'} features" : "--format #{ENV['CUCUMBER_FORMAT'] || 'pretty'} #{rerun}"
+std_opts = "--format #{ENV['CUCUMBER_FORMAT'] || 'pretty'} --strict --tags ~@wip"
+%>
+default: <%= std_opts %> features
+wip: --tags @wip:3 --wip features
+rerun: <%= rerun_opts %> --format rerun --out rerun.txt --strict --tags ~@wip
diff --git a/site/features/login.feature b/site/features/login.feature
new file mode 100644
index 0000000..8ba5be3
--- /dev/null
+++ b/site/features/login.feature
@@ -0,0 +1,20 @@
+Feature: Login
+ In order to use site
+ I want to be able to login
+
+ Scenario: Email + password login
+ Given example user
+ When I am on the homepage
+ When I follow "Login"
+ Then I should be on the login page
+
+ When I login as example user
+ Then I should see "You have logged in."
+
+ Scenario: Login, then look around and see you're still logged in
+ Given example user
+ When I am on the login page
+ And I login as example user
+
+ When I follow "Logged in as Example"
+ Then I should see "Log out"
diff --git a/site/features/step_definitions/login_steps.rb b/site/features/step_definitions/login_steps.rb
new file mode 100644
index 0000000..52fbcd3
--- /dev/null
+++ b/site/features/step_definitions/login_steps.rb
@@ -0,0 +1,15 @@
+Given /^example user$/ do
+ user = User.new :name => "Example", :email_address => "example@example.com",
+ :password => "Example"
+ user.save!
+end
+
+When /^I login as "([^"]*)" with password "([^"]*)"$/ do |email, password|
+ When "I fill in \"login\" with \"#{email}\""
+ When "I fill in \"password\" with \"#{password}\""
+ When 'I press "Login"'
+end
+
+When /^I login as example user$/ do
+ When 'I login as "example@example.com" with password "Example"'
+end
diff --git a/site/features/step_definitions/web_steps.rb b/site/features/step_definitions/web_steps.rb
new file mode 100644
index 0000000..d615b65
--- /dev/null
+++ b/site/features/step_definitions/web_steps.rb
@@ -0,0 +1,190 @@
+require 'uri'
+require 'cgi'
+require File.expand_path(File.join(File.dirname(__FILE__), "..", "support", "paths"))
+require File.expand_path(File.join(File.dirname(__FILE__), "..", "support", "selectors"))
+
+module WithinHelpers
+ def with_scope(locator)
+ locator ? within(*selector_for(locator)) { yield } : yield
+ end
+end
+World(WithinHelpers)
+
+# Single-line step scoper
+When /^(.*) within ([^:]+)$/ do |step, parent|
+ with_scope(parent) { When step }
+end
+
+# Multi-line step scoper
+When /^(.*) within ([^:]+):$/ do |step, parent, table_or_string|
+ with_scope(parent) { When "#{step}:", table_or_string }
+end
+
+Given /^(?:|I )am on (.+)$/ do |page_name|
+ visit path_to(page_name)
+end
+
+When /^(?:|I )go to (.+)$/ do |page_name|
+ visit path_to(page_name)
+end
+
+When /^(?:|I )press "([^"]*)"$/ do |button|
+ click_button(button)
+end
+
+When /^(?:|I )follow "([^"]*)"$/ do |link|
+ click_link(link)
+end
+
+When /^(?:|I )fill in "([^"]*)" with "([^"]*)"$/ do |field, value|
+ fill_in(field, :with => value)
+end
+
+When /^(?:|I )fill in "([^"]*)" for "([^"]*)"$/ do |value, field|
+ fill_in(field, :with => value)
+end
+
+# Use this to fill in an entire form with data from a table. Example:
+#
+# When I fill in the following:
+# | Account Number | 5002 |
+# | Expiry date | 2009-11-01 |
+# | Note | Nice guy |
+# | Wants Email? | |
+#
+# TODO: Add support for checkbox, select og option
+# based on naming conventions.
+#
+When /^(?:|I )fill in the following:$/ do |fields|
+ fields.rows_hash.each do |name, value|
+ When %{I fill in "#{name}" with "#{value}"}
+ end
+end
+
+When /^(?:|I )select "([^"]*)" from "([^"]*)"$/ do |value, field|
+ select(value, :from => field)
+end
+
+When /^(?:|I )check "([^"]*)"$/ do |field|
+ check(field)
+end
+
+When /^(?:|I )uncheck "([^"]*)"$/ do |field|
+ uncheck(field)
+end
+
+When /^(?:|I )choose "([^"]*)"$/ do |field|
+ choose(field)
+end
+
+When /^(?:|I )attach the file "([^"]*)" to "([^"]*)"$/ do |path, field|
+ attach_file(field, File.expand_path(path))
+end
+
+Then /^(?:|I )should see "([^"]*)"$/ do |text|
+ if page.respond_to? :should
+ page.should have_content(text)
+ else
+ assert page.has_content?(text)
+ end
+end
+
+Then /^(?:|I )should see \/([^\/]*)\/$/ do |regexp|
+ regexp = Regexp.new(regexp)
+
+ if page.respond_to? :should
+ page.should have_xpath('//*', :text => regexp)
+ else
+ assert page.has_xpath?('//*', :text => regexp)
+ end
+end
+
+Then /^(?:|I )should not see "([^"]*)"$/ do |text|
+ if page.respond_to? :should
+ page.should have_no_content(text)
+ else
+ assert page.has_no_content?(text)
+ end
+end
+
+Then /^(?:|I )should not see \/([^\/]*)\/$/ do |regexp|
+ regexp = Regexp.new(regexp)
+
+ if page.respond_to? :should
+ page.should have_no_xpath('//*', :text => regexp)
+ else
+ assert page.has_no_xpath?('//*', :text => regexp)
+ end
+end
+
+Then /^the "([^"]*)" field(?: within (.*))? should contain "([^"]*)"$/ do |field, parent, value|
+ with_scope(parent) do
+ field = find_field(field)
+ field_value = (field.tag_name == 'textarea') ? field.text : field.value
+ if field_value.respond_to? :should
+ field_value.should =~ /#{value}/
+ else
+ assert_match(/#{value}/, field_value)
+ end
+ end
+end
+
+Then /^the "([^"]*)" field(?: within (.*))? should not contain "([^"]*)"$/ do |field, parent, value|
+ with_scope(parent) do
+ field = find_field(field)
+ field_value = (field.tag_name == 'textarea') ? field.text : field.value
+ if field_value.respond_to? :should_not
+ field_value.should_not =~ /#{value}/
+ else
+ assert_no_match(/#{value}/, field_value)
+ end
+ end
+end
+
+Then /^the "([^"]*)" checkbox(?: within (.*))? should be checked$/ do |label, parent|
+ with_scope(parent) do
+ field_checked = find_field(label)['checked']
+ if field_checked.respond_to? :should
+ field_checked.should be_true
+ else
+ assert field_checked
+ end
+ end
+end
+
+Then /^the "([^"]*)" checkbox(?: within (.*))? should not be checked$/ do |label, parent|
+ with_scope(parent) do
+ field_checked = find_field(label)['checked']
+ if field_checked.respond_to? :should
+ field_checked.should be_false
+ else
+ assert !field_checked
+ end
+ end
+end
+
+Then /^(?:|I )should be on (.+)$/ do |page_name|
+ current_path = URI.parse(current_url).path
+ if current_path.respond_to? :should
+ current_path.should == path_to(page_name)
+ else
+ assert_equal path_to(page_name), current_path
+ end
+end
+
+Then /^(?:|I )should have the following query string:$/ do |expected_pairs|
+ query = URI.parse(current_url).query
+ actual_params = query ? CGI.parse(query) : {}
+ expected_params = {}
+ expected_pairs.rows_hash.each_pair{|k,v| expected_params[k] = v.split(',')}
+
+ if actual_params.respond_to? :should
+ actual_params.should == expected_params
+ else
+ assert_equal expected_params, actual_params
+ end
+end
+
+Then /^show me the page$/ do
+ save_and_open_page
+end
diff --git a/site/features/support/env.rb b/site/features/support/env.rb
new file mode 100644
index 0000000..a7389e9
--- /dev/null
+++ b/site/features/support/env.rb
@@ -0,0 +1,5 @@
+require 'cucumber/rails'
+Capybara.default_selector = :css
+Capybara.default_driver = :selenium
+ActionController::Base.allow_rescue = false
+DatabaseCleaner.strategy = :transaction
diff --git a/site/features/support/paths.rb b/site/features/support/paths.rb
new file mode 100644
index 0000000..6ea5ce1
--- /dev/null
+++ b/site/features/support/paths.rb
@@ -0,0 +1,36 @@
+module NavigationHelpers
+ # Maps a name to a path. Used by the
+ #
+ # When /^I go to (.+)$/ do |page_name|
+ #
+ # step definition in web_steps.rb
+ #
+ def path_to(page_name)
+ case page_name
+
+ when /the home\s?page/
+ '/'
+
+ when /the login page/
+ user_login_path
+
+ # Add more mappings here.
+ # Here is an example that pulls values out of the Regexp:
+ #
+ # when /^(.*)'s profile page$/i
+ # user_profile_path(User.find_by_login($1))
+
+ else
+ begin
+ page_name =~ /the (.*) page/
+ path_components = $1.split(/\s+/)
+ self.send(path_components.push('path').join('_').to_sym)
+ rescue Object => e
+ raise "Can't find mapping from \"#{page_name}\" to a path.\n" +
+ "Now, go and add a mapping in #{__FILE__}"
+ end
+ end
+ end
+end
+
+World(NavigationHelpers)
diff --git a/site/features/support/selectors.rb b/site/features/support/selectors.rb
new file mode 100644
index 0000000..0856127
--- /dev/null
+++ b/site/features/support/selectors.rb
@@ -0,0 +1,39 @@
+module HtmlSelectorsHelpers
+ # Maps a name to a selector. Used primarily by the
+ #
+ # When /^(.+) within (.+)$/ do |step, scope|
+ #
+ # step definitions in web_steps.rb
+ #
+ def selector_for(locator)
+ case locator
+
+ when /the page/
+ "html > body"
+
+ # Add more mappings here.
+ # Here is an example that pulls values out of the Regexp:
+ #
+ # when /the (notice|error|info) flash/
+ # ".flash.#{$1}"
+
+ # You can also return an array to use a different selector
+ # type, like:
+ #
+ # when /the header/
+ # [:xpath, "//header"]
+
+ # This allows you to provide a quoted selector as the scope
+ # for "within" steps as was previously the default for the
+ # web steps:
+ when /"(.+)"/
+ $1
+
+ else
+ raise "Can't find mapping from \"#{locator}\" to a selector.\n" +
+ "Now, go and add a mapping in #{__FILE__}"
+ end
+ end
+end
+
+World(HtmlSelectorsHelpers) \ No newline at end of file
diff --git a/site/lib/tasks/cucumber.rake b/site/lib/tasks/cucumber.rake
new file mode 100644
index 0000000..ce49e1c
--- /dev/null
+++ b/site/lib/tasks/cucumber.rake
@@ -0,0 +1,50 @@
+unless ARGV.any? {|a| a =~ /^gems/} # Don't load anything when running the gems:* tasks
+
+vendored_cucumber_bin = Dir["#{Rails.root}/vendor/{gems,plugins}/cucumber*/bin/cucumber"].first
+$LOAD_PATH.unshift(File.dirname(vendored_cucumber_bin) + '/../lib') unless vendored_cucumber_bin.nil?
+
+begin
+ require 'cucumber/rake/task'
+
+ namespace :cucumber do
+ Cucumber::Rake::Task.new({:ok => 'db:test:prepare'}, 'Run features that should pass') do |t|
+ t.binary = vendored_cucumber_bin # If nil, the gem's binary is used.
+ t.fork = true # You may get faster startup if you set this to false
+ t.profile = 'default'
+ end
+
+ Cucumber::Rake::Task.new({:wip => 'db:test:prepare'}, 'Run features that are being worked on') do |t|
+ t.binary = vendored_cucumber_bin
+ t.fork = true # You may get faster startup if you set this to false
+ t.profile = 'wip'
+ end
+
+ Cucumber::Rake::Task.new({:rerun => 'db:test:prepare'}, 'Record failing features and run only them if any exist') do |t|
+ t.binary = vendored_cucumber_bin
+ t.fork = true # You may get faster startup if you set this to false
+ t.profile = 'rerun'
+ end
+
+ desc 'Run all features'
+ task :all => [:ok, :wip]
+ end
+ desc 'Alias for cucumber:ok'
+ task :cucumber => 'cucumber:ok'
+
+ task :default => :cucumber
+
+ task :features => :cucumber do
+ STDERR.puts "*** The 'features' task is deprecated. See rake -T cucumber ***"
+ end
+
+ # In case we don't have ActiveRecord, append a no-op task that we can depend upon.
+ task 'db:test:prepare' do
+ end
+rescue LoadError
+ desc 'cucumber rake task not available (cucumber not installed)'
+ task :cucumber do
+ abort 'Cucumber rake task is not available. Be sure to install cucumber as a gem or plugin'
+ end
+end
+
+end
diff --git a/site/script/cucumber b/site/script/cucumber
new file mode 100755
index 0000000..7fa5c92
--- /dev/null
+++ b/site/script/cucumber
@@ -0,0 +1,10 @@
+#!/usr/bin/env ruby
+
+vendored_cucumber_bin = Dir["#{File.dirname(__FILE__)}/../vendor/{gems,plugins}/cucumber*/bin/cucumber"].first
+if vendored_cucumber_bin
+ load File.expand_path(vendored_cucumber_bin)
+else
+ require 'rubygems' unless ENV['NO_RUBYGEMS']
+ require 'cucumber'
+ load Cucumber::BINARY
+end