Skip to content

Commit 9d225cf

Browse files
author
Jon Yurek
committed
Use Capybara to drive a generated Rails app through integration tests.
1 parent eb30f10 commit 9d225cf

File tree

7 files changed

+355
-0
lines changed

7 files changed

+355
-0
lines changed

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,4 @@ tmp
44
test/s3.yml
55
public
66
paperclip*.gem
7+
capybara*.html

features/rails.feature

+33
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
Feature: Running paperclip in a Rails app
2+
3+
Scenario: Basic utilization
4+
Given I generate a rails application
5+
And I have a "users" resource with "name:string"
6+
And I run "script/generate paperclip user avatar"
7+
And I save the following as "app/models/user.rb"
8+
"""
9+
class User < ActiveRecord::Base
10+
has_attached_file :avatar
11+
end
12+
"""
13+
And I save the following as "app/views/users/new.html.erb"
14+
"""
15+
<% form_for @user, :html => { :multipart => true } do |f| %>
16+
<%= f.text_field :name %>
17+
<%= f.file_field :avatar %>
18+
<%= submit_tag "Submit" %>
19+
<% end %>
20+
"""
21+
And I save the following as "app/views/users/show.html.erb"
22+
"""
23+
<p>Name: <%= @user.name %></p>
24+
<p>Avatar: <%= image_tag @user.avatar.url %></p>
25+
"""
26+
And this plugin is available
27+
And the rails application is prepped and running
28+
When I visit /users/new
29+
And I fill in "user_name" with "something"
30+
And I attach the file "test/fixtures/5k.png" to "user_avatar"
31+
And I press "Submit"
32+
Then I should see "Name: something"
33+
And I save and open the page
+46
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
Given %r{I generate a rails application} do
2+
FileUtils.rm_rf TEMP_ROOT
3+
FileUtils.mkdir_p TEMP_ROOT
4+
Dir.chdir(TEMP_ROOT) do
5+
`rails _2.3.8_ #{APP_NAME}`
6+
end
7+
ENV['RAILS_ENV'] = 'test'
8+
end
9+
10+
When %r{I save the following as "([^"]*)"} do |path, string|
11+
FileUtils.mkdir_p(File.join(CUC_RAILS_ROOT, File.dirname(path)))
12+
File.open(File.join(CUC_RAILS_ROOT, path), 'w') { |file| file.write(string) }
13+
end
14+
15+
When %r{the rails application is prepped and running$} do
16+
When "the rails application is prepped"
17+
When "the rails application is running"
18+
end
19+
20+
When %r{the rails application is prepped$} do
21+
When %{I run "rake db:create db:migrate"}
22+
end
23+
24+
When %r{the rails application is running} do
25+
Dir.chdir(CUC_RAILS_ROOT) do
26+
require "config/environment"
27+
Capybara.app = ActionController::Dispatcher.new
28+
end
29+
end
30+
31+
When %r{this plugin is available} do
32+
$LOAD_PATH << "#{PROJECT_ROOT}/lib"
33+
require 'paperclip'
34+
When %{I save the following as "vendor/plugins/paperclip/rails/init.rb"},
35+
IO.read("#{PROJECT_ROOT}/rails/init.rb")
36+
end
37+
38+
When %r{I run "([^"]*)"} do |command|
39+
Dir.chdir(CUC_RAILS_ROOT) do
40+
`#{command}`
41+
end
42+
end
43+
44+
When %r{I have a "([^"]*)" resource with "([^"]*)"} do |resource, fields|
45+
When %{I run "script/generate scaffold #{resource} #{fields}"}
46+
end
+227
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,227 @@
1+
# IMPORTANT: This file is generated by cucumber-rails - edit at your own peril.
2+
# It is recommended to regenerate this file in the future when you upgrade to a
3+
# newer version of cucumber-rails. Consider adding your own code to a new file
4+
# instead of editing this one. Cucumber will automatically load all features/**/*.rb
5+
# files.
6+
7+
8+
require 'uri'
9+
require 'cgi'
10+
require File.expand_path(File.join(File.dirname(__FILE__), "..", "support", "paths"))
11+
12+
module WithinHelpers
13+
def with_scope(locator)
14+
locator ? within(locator) { yield } : yield
15+
end
16+
end
17+
World(WithinHelpers)
18+
19+
Given /^(?:|I )am on (.+)$/ do |page_name|
20+
visit path_to(page_name)
21+
end
22+
23+
When /^(?:|I )go to (.+)$/ do |page_name|
24+
visit path_to(page_name)
25+
end
26+
27+
When /^(?:|I )visit (\/.+)$/ do |page_path|
28+
visit page_path
29+
end
30+
31+
When /^(?:|I )press "([^"]*)"(?: within "([^"]*)")?$/ do |button, selector|
32+
with_scope(selector) do
33+
click_button(button)
34+
end
35+
end
36+
37+
When /^(?:|I )follow "([^"]*)"(?: within "([^"]*)")?$/ do |link, selector|
38+
with_scope(selector) do
39+
click_link(link)
40+
end
41+
end
42+
43+
When /^(?:|I )fill in "([^"]*)" with "([^"]*)"(?: within "([^"]*)")?$/ do |field, value, selector|
44+
with_scope(selector) do
45+
fill_in(field, :with => value)
46+
end
47+
end
48+
49+
When /^(?:|I )fill in "([^"]*)" for "([^"]*)"(?: within "([^"]*)")?$/ do |value, field, selector|
50+
with_scope(selector) do
51+
fill_in(field, :with => value)
52+
end
53+
end
54+
55+
# Use this to fill in an entire form with data from a table. Example:
56+
#
57+
# When I fill in the following:
58+
# | Account Number | 5002 |
59+
# | Expiry date | 2009-11-01 |
60+
# | Note | Nice guy |
61+
# | Wants Email? | |
62+
#
63+
# TODO: Add support for checkbox, select og option
64+
# based on naming conventions.
65+
#
66+
When /^(?:|I )fill in the following(?: within "([^"]*)")?:$/ do |selector, fields|
67+
with_scope(selector) do
68+
fields.rows_hash.each do |name, value|
69+
When %{I fill in "#{name}" with "#{value}"}
70+
end
71+
end
72+
end
73+
74+
When /^(?:|I )select "([^"]*)" from "([^"]*)"(?: within "([^"]*)")?$/ do |value, field, selector|
75+
with_scope(selector) do
76+
select(value, :from => field)
77+
end
78+
end
79+
80+
When /^(?:|I )check "([^"]*)"(?: within "([^"]*)")?$/ do |field, selector|
81+
with_scope(selector) do
82+
check(field)
83+
end
84+
end
85+
86+
When /^(?:|I )uncheck "([^"]*)"(?: within "([^"]*)")?$/ do |field, selector|
87+
with_scope(selector) do
88+
uncheck(field)
89+
end
90+
end
91+
92+
When /^(?:|I )choose "([^"]*)"(?: within "([^"]*)")?$/ do |field, selector|
93+
with_scope(selector) do
94+
choose(field)
95+
end
96+
end
97+
98+
When /^(?:|I )attach the file "([^"]*)" to "([^"]*)"(?: within "([^"]*)")?$/ do |path, field, selector|
99+
with_scope(selector) do
100+
attach_file(field, path)
101+
end
102+
end
103+
104+
Then /^(?:|I )should see JSON:$/ do |expected_json|
105+
require 'json'
106+
expected = JSON.pretty_generate(JSON.parse(expected_json))
107+
actual = JSON.pretty_generate(JSON.parse(response.body))
108+
expected.should == actual
109+
end
110+
111+
Then /^(?:|I )should see "([^"]*)"(?: within "([^"]*)")?$/ do |text, selector|
112+
with_scope(selector) do
113+
if page.respond_to? :should
114+
page.should have_content(text)
115+
else
116+
assert page.has_content?(text)
117+
end
118+
end
119+
end
120+
121+
Then /^(?:|I )should see \/([^\/]*)\/(?: within "([^"]*)")?$/ do |regexp, selector|
122+
regexp = Regexp.new(regexp)
123+
with_scope(selector) do
124+
if page.respond_to? :should
125+
page.should have_xpath('//*', :text => regexp)
126+
else
127+
assert page.has_xpath?('//*', :text => regexp)
128+
end
129+
end
130+
end
131+
132+
Then /^(?:|I )should not see "([^"]*)"(?: within "([^"]*)")?$/ do |text, selector|
133+
with_scope(selector) do
134+
if page.respond_to? :should
135+
page.should have_no_content(text)
136+
else
137+
assert page.has_no_content?(text)
138+
end
139+
end
140+
end
141+
142+
Then /^(?:|I )should not see \/([^\/]*)\/(?: within "([^"]*)")?$/ do |regexp, selector|
143+
regexp = Regexp.new(regexp)
144+
with_scope(selector) do
145+
if page.respond_to? :should
146+
page.should have_no_xpath('//*', :text => regexp)
147+
else
148+
assert page.has_no_xpath?('//*', :text => regexp)
149+
end
150+
end
151+
end
152+
153+
Then /^the "([^"]*)" field(?: within "([^"]*)")? should contain "([^"]*)"$/ do |field, selector, value|
154+
with_scope(selector) do
155+
field = find_field(field)
156+
field_value = (field.tag_name == 'textarea') ? field.text : field.value
157+
if field_value.respond_to? :should
158+
field_value.should =~ /#{value}/
159+
else
160+
assert_match(/#{value}/, field_value)
161+
end
162+
end
163+
end
164+
165+
Then /^the "([^"]*)" field(?: within "([^"]*)")? should not contain "([^"]*)"$/ do |field, selector, value|
166+
with_scope(selector) do
167+
field = find_field(field)
168+
field_value = (field.tag_name == 'textarea') ? field.text : field.value
169+
if field_value.respond_to? :should_not
170+
field_value.should_not =~ /#{value}/
171+
else
172+
assert_no_match(/#{value}/, field_value)
173+
end
174+
end
175+
end
176+
177+
Then /^the "([^"]*)" checkbox(?: within "([^"]*)")? should be checked$/ do |label, selector|
178+
with_scope(selector) do
179+
field_checked = find_field(label)['checked']
180+
if field_checked.respond_to? :should
181+
field_checked.should be_true
182+
else
183+
assert field_checked
184+
end
185+
end
186+
end
187+
188+
Then /^the "([^"]*)" checkbox(?: within "([^"]*)")? should not be checked$/ do |label, selector|
189+
with_scope(selector) do
190+
field_checked = find_field(label)['checked']
191+
if field_checked.respond_to? :should
192+
field_checked.should be_false
193+
else
194+
assert !field_checked
195+
end
196+
end
197+
end
198+
199+
Then /^(?:|I )should be on (.+)$/ do |page_name|
200+
current_path = URI.parse(current_url).path
201+
if current_path.respond_to? :should
202+
current_path.should == path_to(page_name)
203+
else
204+
assert_equal path_to(page_name), current_path
205+
end
206+
end
207+
208+
Then /^(?:|I )should have the following query string:$/ do |expected_pairs|
209+
query = URI.parse(current_url).query
210+
actual_params = query ? CGI.parse(query) : {}
211+
expected_params = {}
212+
expected_pairs.rows_hash.each_pair{|k,v| expected_params[k] = v.split(',')}
213+
214+
if actual_params.respond_to? :should
215+
actual_params.should == expected_params
216+
else
217+
assert_equal expected_params, actual_params
218+
end
219+
end
220+
221+
Then /^I save and open the page$/ do
222+
save_and_open_page
223+
end
224+
225+
Then /^show me the page$/ do
226+
save_and_open_page
227+
end

features/support/env.rb

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
require 'capybara/cucumber'
2+
require 'test/unit/assertions'
3+
World(Test::Unit::Assertions)

features/support/paths.rb

+35
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
module NavigationHelpers
2+
# Maps a name to a path. Used by the
3+
#
4+
# When /^I go to (.+)$/ do |page_name|
5+
#
6+
# step definition in web_steps.rb
7+
#
8+
def path_to(page_name)
9+
case page_name
10+
11+
when /the new user page/
12+
'/users/new'
13+
when /the home\s?page/
14+
'/'
15+
16+
# Add more mappings here.
17+
# Here is an example that pulls values out of the Regexp:
18+
#
19+
# when /^(.*)'s profile page$/i
20+
# user_profile_path(User.find_by_login($1))
21+
22+
else
23+
begin
24+
page_name =~ /the (.*) page/
25+
path_components = $1.split(/\s+/)
26+
self.send(path_components.push('path').join('_').to_sym)
27+
rescue Object => e
28+
raise "Can't find mapping from \"#{page_name}\" to a path.\n" +
29+
"Now, go and add a mapping in #{__FILE__}"
30+
end
31+
end
32+
end
33+
end
34+
35+
World(NavigationHelpers)

features/support/rails.rb

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
PROJECT_ROOT = File.expand_path(File.join(File.dirname(__FILE__), '..', '..')).freeze
2+
TEMP_ROOT = File.join(PROJECT_ROOT, 'tmp').freeze
3+
APP_NAME = 'testapp'.freeze
4+
CUC_RAILS_ROOT = File.join(TEMP_ROOT, APP_NAME).freeze
5+
6+
Before do
7+
FileUtils.rm_rf(TEMP_ROOT)
8+
FileUtils.mkdir_p(CUC_RAILS_ROOT)
9+
Dir.chdir(PROJECT_ROOT)
10+
end

0 commit comments

Comments
 (0)