Permalink
Browse files

Use Capybara to drive a generated Rails app through integration tests.

  • Loading branch information...
jyurek committed Jul 9, 2010
1 parent eb30f10 commit 9d225cf6d0b26cb31ea84b152a7b844a83008f5d
View
@@ -4,3 +4,4 @@ tmp
test/s3.yml
public
paperclip*.gem
+capybara*.html
View
@@ -0,0 +1,33 @@
+Feature: Running paperclip in a Rails app
+
+ Scenario: Basic utilization
+ Given I generate a rails application
+ And I have a "users" resource with "name:string"
+ And I run "script/generate paperclip user avatar"
+ And I save the following as "app/models/user.rb"
+ """
+ class User < ActiveRecord::Base
+ has_attached_file :avatar
+ end
+ """
+ And I save the following as "app/views/users/new.html.erb"
+ """
+ <% form_for @user, :html => { :multipart => true } do |f| %>
+ <%= f.text_field :name %>
+ <%= f.file_field :avatar %>
+ <%= submit_tag "Submit" %>
+ <% end %>
+ """
+ And I save the following as "app/views/users/show.html.erb"
+ """
+ <p>Name: <%= @user.name %></p>
+ <p>Avatar: <%= image_tag @user.avatar.url %></p>
+ """
+ And this plugin is available
+ And the rails application is prepped and running
+ When I visit /users/new
+ And I fill in "user_name" with "something"
+ And I attach the file "test/fixtures/5k.png" to "user_avatar"
+ And I press "Submit"
+ Then I should see "Name: something"
+ And I save and open the page
@@ -0,0 +1,46 @@
+Given %r{I generate a rails application} do
+ FileUtils.rm_rf TEMP_ROOT
+ FileUtils.mkdir_p TEMP_ROOT
+ Dir.chdir(TEMP_ROOT) do
+ `rails _2.3.8_ #{APP_NAME}`
+ end
+ ENV['RAILS_ENV'] = 'test'
+end
+
+When %r{I save the following as "([^"]*)"} do |path, string|
+ FileUtils.mkdir_p(File.join(CUC_RAILS_ROOT, File.dirname(path)))
+ File.open(File.join(CUC_RAILS_ROOT, path), 'w') { |file| file.write(string) }
+end
+
+When %r{the rails application is prepped and running$} do
+ When "the rails application is prepped"
+ When "the rails application is running"
+end
+
+When %r{the rails application is prepped$} do
+ When %{I run "rake db:create db:migrate"}
+end
+
+When %r{the rails application is running} do
+ Dir.chdir(CUC_RAILS_ROOT) do
+ require "config/environment"
+ Capybara.app = ActionController::Dispatcher.new
+ end
+end
+
+When %r{this plugin is available} do
+ $LOAD_PATH << "#{PROJECT_ROOT}/lib"
+ require 'paperclip'
+ When %{I save the following as "vendor/plugins/paperclip/rails/init.rb"},
+ IO.read("#{PROJECT_ROOT}/rails/init.rb")
+end
+
+When %r{I run "([^"]*)"} do |command|
+ Dir.chdir(CUC_RAILS_ROOT) do
+ `#{command}`
+ end
+end
+
+When %r{I have a "([^"]*)" resource with "([^"]*)"} do |resource, fields|
+ When %{I run "script/generate scaffold #{resource} #{fields}"}
+end
@@ -0,0 +1,227 @@
+# IMPORTANT: This file is generated by cucumber-rails - edit at your own peril.
+# It is recommended to regenerate this file in the future when you upgrade to a
+# newer version of cucumber-rails. Consider adding your own code to a new file
+# instead of editing this one. Cucumber will automatically load all features/**/*.rb
+# files.
+
+
+require 'uri'
+require 'cgi'
+require File.expand_path(File.join(File.dirname(__FILE__), "..", "support", "paths"))
+
+module WithinHelpers
+ def with_scope(locator)
+ locator ? within(locator) { yield } : yield
+ end
+end
+World(WithinHelpers)
+
+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 )visit (\/.+)$/ do |page_path|
+ visit page_path
+end
+
+When /^(?:|I )press "([^"]*)"(?: within "([^"]*)")?$/ do |button, selector|
+ with_scope(selector) do
+ click_button(button)
+ end
+end
+
+When /^(?:|I )follow "([^"]*)"(?: within "([^"]*)")?$/ do |link, selector|
+ with_scope(selector) do
+ click_link(link)
+ end
+end
+
+When /^(?:|I )fill in "([^"]*)" with "([^"]*)"(?: within "([^"]*)")?$/ do |field, value, selector|
+ with_scope(selector) do
+ fill_in(field, :with => value)
+ end
+end
+
+When /^(?:|I )fill in "([^"]*)" for "([^"]*)"(?: within "([^"]*)")?$/ do |value, field, selector|
+ with_scope(selector) do
+ fill_in(field, :with => value)
+ end
+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(?: within "([^"]*)")?:$/ do |selector, fields|
+ with_scope(selector) do
+ fields.rows_hash.each do |name, value|
+ When %{I fill in "#{name}" with "#{value}"}
+ end
+ end
+end
+
+When /^(?:|I )select "([^"]*)" from "([^"]*)"(?: within "([^"]*)")?$/ do |value, field, selector|
+ with_scope(selector) do
+ select(value, :from => field)
+ end
+end
+
+When /^(?:|I )check "([^"]*)"(?: within "([^"]*)")?$/ do |field, selector|
+ with_scope(selector) do
+ check(field)
+ end
+end
+
+When /^(?:|I )uncheck "([^"]*)"(?: within "([^"]*)")?$/ do |field, selector|
+ with_scope(selector) do
+ uncheck(field)
+ end
+end
+
+When /^(?:|I )choose "([^"]*)"(?: within "([^"]*)")?$/ do |field, selector|
+ with_scope(selector) do
+ choose(field)
+ end
+end
+
+When /^(?:|I )attach the file "([^"]*)" to "([^"]*)"(?: within "([^"]*)")?$/ do |path, field, selector|
+ with_scope(selector) do
+ attach_file(field, path)
+ end
+end
+
+Then /^(?:|I )should see JSON:$/ do |expected_json|
+ require 'json'
+ expected = JSON.pretty_generate(JSON.parse(expected_json))
+ actual = JSON.pretty_generate(JSON.parse(response.body))
+ expected.should == actual
+end
+
+Then /^(?:|I )should see "([^"]*)"(?: within "([^"]*)")?$/ do |text, selector|
+ with_scope(selector) do
+ if page.respond_to? :should
+ page.should have_content(text)
+ else
+ assert page.has_content?(text)
+ end
+ end
+end
+
+Then /^(?:|I )should see \/([^\/]*)\/(?: within "([^"]*)")?$/ do |regexp, selector|
+ regexp = Regexp.new(regexp)
+ with_scope(selector) do
+ if page.respond_to? :should
+ page.should have_xpath('//*', :text => regexp)
+ else
+ assert page.has_xpath?('//*', :text => regexp)
+ end
+ end
+end
+
+Then /^(?:|I )should not see "([^"]*)"(?: within "([^"]*)")?$/ do |text, selector|
+ with_scope(selector) do
+ if page.respond_to? :should
+ page.should have_no_content(text)
+ else
+ assert page.has_no_content?(text)
+ end
+ end
+end
+
+Then /^(?:|I )should not see \/([^\/]*)\/(?: within "([^"]*)")?$/ do |regexp, selector|
+ regexp = Regexp.new(regexp)
+ with_scope(selector) do
+ if page.respond_to? :should
+ page.should have_no_xpath('//*', :text => regexp)
+ else
+ assert page.has_no_xpath?('//*', :text => regexp)
+ end
+ end
+end
+
+Then /^the "([^"]*)" field(?: within "([^"]*)")? should contain "([^"]*)"$/ do |field, selector, value|
+ with_scope(selector) 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, selector, value|
+ with_scope(selector) 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, selector|
+ with_scope(selector) 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, selector|
+ with_scope(selector) 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 /^I save and open the page$/ do
+ save_and_open_page
+end
+
+Then /^show me the page$/ do
+ save_and_open_page
+end
View
@@ -0,0 +1,3 @@
+require 'capybara/cucumber'
+require 'test/unit/assertions'
+World(Test::Unit::Assertions)
View
@@ -0,0 +1,35 @@
+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 new user page/
+ '/users/new'
+ when /the home\s?page/
+ '/'
+
+ # 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)
View
@@ -0,0 +1,10 @@
+PROJECT_ROOT = File.expand_path(File.join(File.dirname(__FILE__), '..', '..')).freeze
+TEMP_ROOT = File.join(PROJECT_ROOT, 'tmp').freeze
+APP_NAME = 'testapp'.freeze
+CUC_RAILS_ROOT = File.join(TEMP_ROOT, APP_NAME).freeze
+
+Before do
+ FileUtils.rm_rf(TEMP_ROOT)
+ FileUtils.mkdir_p(CUC_RAILS_ROOT)
+ Dir.chdir(PROJECT_ROOT)
+end

0 comments on commit 9d225cf

Please sign in to comment.