dougui_users 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/MIT-LICENSE +20 -0
- data/README.rdoc +3 -0
- data/Rakefile +39 -0
- data/app/assets/javascripts/dougui_users/application.js +9 -0
- data/app/assets/stylesheets/dougui_users/application.css +7 -0
- data/app/assets/stylesheets/scaffold.css +56 -0
- data/app/controllers/dougui_users/application_controller.rb +27 -0
- data/app/controllers/dougui_users/user_activates_controller.rb +13 -0
- data/app/controllers/dougui_users/user_reset_passwords_controller.rb +41 -0
- data/app/controllers/dougui_users/user_sessions_controller.rb +34 -0
- data/app/controllers/dougui_users/users_controller.rb +51 -0
- data/app/helpers/dougui_users/user_mailer_helper.rb +13 -0
- data/app/mailers/dougui_users/user_mailer.rb +15 -0
- data/app/models/dougui_users/user.rb +16 -0
- data/app/models/dougui_users/user_session.rb +11 -0
- data/app/models/user_session.rb +2 -0
- data/app/views/dougui_users/user_mailer/activation.html.erb +1 -0
- data/app/views/dougui_users/user_mailer/reset_password.html.erb +1 -0
- data/app/views/dougui_users/user_reset_passwords/edit.html.erb +16 -0
- data/app/views/dougui_users/user_reset_passwords/new.html.erb +11 -0
- data/app/views/dougui_users/user_sessions/new.html.erb +22 -0
- data/app/views/dougui_users/users/edit.html.erb +16 -0
- data/app/views/dougui_users/users/new.html.erb +25 -0
- data/app/views/layouts/dougui_users/application.html.erb +12 -0
- data/config/cucumber.yml +8 -0
- data/config/locales/en.yml +5 -0
- data/config/locales/fr.yml +50 -0
- data/config/routes.rb +13 -0
- data/db/migrate/20110916144049_create_dougui_users_users.rb +20 -0
- data/features/step_definitions/custom_web_steps.rb +3 -0
- data/features/step_definitions/email_steps.rb +206 -0
- data/features/step_definitions/user_steps.rb +90 -0
- data/features/step_definitions/web_steps.rb +211 -0
- data/features/support/env.rb +88 -0
- data/features/support/paths.rb +49 -0
- data/features/support/selectors.rb +39 -0
- data/features/user.feature +86 -0
- data/features/user_activates.feature +13 -0
- data/features/user_reset_passwords.feature +56 -0
- data/features/user_session.feature +35 -0
- data/lib/dougui_users/engine.rb +5 -0
- data/lib/dougui_users/version.rb +3 -0
- data/lib/dougui_users.rb +7 -0
- data/lib/tasks/cucumber.rake +65 -0
- data/lib/tasks/dougui_users_tasks.rake +4 -0
- data/spec/controllers/dougui_users/user_activates_controller_spec.rb +32 -0
- data/spec/controllers/dougui_users/user_reset_passwords_controller_spec.rb +59 -0
- data/spec/controllers/dougui_users/user_sessions_controller_spec.rb +57 -0
- data/spec/controllers/dougui_users/users_controller_spec.rb +98 -0
- data/spec/dummy/Rakefile +7 -0
- data/spec/dummy/app/assets/javascripts/application.js +9 -0
- data/spec/dummy/app/assets/stylesheets/application.css +7 -0
- data/spec/dummy/app/controllers/application_controller.rb +3 -0
- data/spec/dummy/app/helpers/application_helper.rb +2 -0
- data/spec/dummy/app/views/layouts/application.html.erb +14 -0
- data/spec/dummy/config/application.rb +45 -0
- data/spec/dummy/config/boot.rb +10 -0
- data/spec/dummy/config/database.yml +25 -0
- data/spec/dummy/config/environment.rb +5 -0
- data/spec/dummy/config/environments/development.rb +30 -0
- data/spec/dummy/config/environments/production.rb +60 -0
- data/spec/dummy/config/environments/test.rb +42 -0
- data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/spec/dummy/config/initializers/inflections.rb +10 -0
- data/spec/dummy/config/initializers/mime_types.rb +5 -0
- data/spec/dummy/config/initializers/secret_token.rb +7 -0
- data/spec/dummy/config/initializers/session_store.rb +8 -0
- data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
- data/spec/dummy/config/locales/en.yml +5 -0
- data/spec/dummy/config/locales/fr.yml +269 -0
- data/spec/dummy/config/routes.rb +4 -0
- data/spec/dummy/config.ru +4 -0
- data/spec/dummy/db/development.sqlite3 +0 -0
- data/spec/dummy/db/schema.rb +28 -0
- data/spec/dummy/db/test.sqlite3 +0 -0
- data/spec/dummy/log/development.log +1340 -0
- data/spec/dummy/log/test.log +15056 -0
- data/spec/dummy/public/404.html +26 -0
- data/spec/dummy/public/422.html +26 -0
- data/spec/dummy/public/500.html +26 -0
- data/spec/dummy/public/favicon.ico +0 -0
- data/spec/dummy/script/rails +6 -0
- data/spec/dummy/tmp/cache/assets/D0B/620/sprockets%2F5fe8057c4691686098ead34f79e79e8f +0 -0
- data/spec/factories/dougui_users/user_factory.rb +9 -0
- data/spec/models/dougui_users/user_spec.rb +30 -0
- data/spec/spec_helper.rb +65 -0
- metadata +326 -0
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
# Commonly used email steps
|
|
2
|
+
#
|
|
3
|
+
# To add your own steps make a custom_email_steps.rb
|
|
4
|
+
# The provided methods are:
|
|
5
|
+
#
|
|
6
|
+
# last_email_address
|
|
7
|
+
# reset_mailer
|
|
8
|
+
# open_last_email
|
|
9
|
+
# visit_in_email
|
|
10
|
+
# unread_emails_for
|
|
11
|
+
# mailbox_for
|
|
12
|
+
# current_email
|
|
13
|
+
# open_email
|
|
14
|
+
# read_emails_for
|
|
15
|
+
# find_email
|
|
16
|
+
#
|
|
17
|
+
# General form for email scenarios are:
|
|
18
|
+
# - clear the email queue (done automatically by email_spec)
|
|
19
|
+
# - execute steps that sends an email
|
|
20
|
+
# - check the user received an/no/[0-9] emails
|
|
21
|
+
# - open the email
|
|
22
|
+
# - inspect the email contents
|
|
23
|
+
# - interact with the email (e.g. click links)
|
|
24
|
+
#
|
|
25
|
+
# The Cucumber steps below are setup in this order.
|
|
26
|
+
|
|
27
|
+
module EmailHelpers
|
|
28
|
+
def current_email_address
|
|
29
|
+
# Replace with your a way to find your current email. e.g @current_user.email
|
|
30
|
+
# last_email_address will return the last email address used by email spec to find an email.
|
|
31
|
+
# Note that last_email_address will be reset after each Scenario.
|
|
32
|
+
last_email_address || "guirec.corbel@gmail.com"
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
World(EmailHelpers)
|
|
37
|
+
|
|
38
|
+
#
|
|
39
|
+
# Reset the e-mail queue within a scenario.
|
|
40
|
+
# This is done automatically before each scenario.
|
|
41
|
+
#
|
|
42
|
+
|
|
43
|
+
Given /^(?:a clear email queue|no emails have been sent)$/ do
|
|
44
|
+
reset_mailer
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
#
|
|
48
|
+
# Check how many emails have been sent/received
|
|
49
|
+
#
|
|
50
|
+
|
|
51
|
+
Then /^(?:I|they|"([^"]*?)") should receive (an|no|\d+) emails?$/ do |address, amount|
|
|
52
|
+
unread_emails_for(address).size.should == parse_email_count(amount)
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
Then /^(?:I|they|"([^"]*?)") should have (an|no|\d+) emails?$/ do |address, amount|
|
|
56
|
+
mailbox_for(address).size.should == parse_email_count(amount)
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
Then /^(?:I|they|"([^"]*?)") should receive (an|no|\d+) emails? with subject "([^"]*?)"$/ do |address, amount, subject|
|
|
60
|
+
unread_emails_for(address).select { |m| m.subject =~ Regexp.new(Regexp.escape(subject)) }.size.should == parse_email_count(amount)
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
Then /^(?:I|they|"([^"]*?)") should receive (an|no|\d+) emails? with subject \/([^"]*?)\/$/ do |address, amount, subject|
|
|
64
|
+
unread_emails_for(address).select { |m| m.subject =~ Regexp.new(subject) }.size.should == parse_email_count(amount)
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
Then /^(?:I|they|"([^"]*?)") should receive an email with the following body:$/ do |address, expected_body|
|
|
68
|
+
open_email(address, :with_text => expected_body)
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
#
|
|
72
|
+
# Accessing emails
|
|
73
|
+
#
|
|
74
|
+
|
|
75
|
+
# Opens the most recently received email
|
|
76
|
+
When /^(?:I|they|"([^"]*?)") opens? the email$/ do |address|
|
|
77
|
+
open_email(address)
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
When /^(?:I|they|"([^"]*?)") opens? the email with subject "([^"]*?)"$/ do |address, subject|
|
|
81
|
+
open_email(address, :with_subject => subject)
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
When /^(?:I|they|"([^"]*?)") opens? the email with subject \/([^"]*?)\/$/ do |address, subject|
|
|
85
|
+
open_email(address, :with_subject => Regexp.new(subject))
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
When /^(?:I|they|"([^"]*?)") opens? the email with text "([^"]*?)"$/ do |address, text|
|
|
89
|
+
open_email(address, :with_text => text)
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
When /^(?:I|they|"([^"]*?)") opens? the email with text \/([^"]*?)\/$/ do |address, text|
|
|
93
|
+
open_email(address, :with_text => Regexp.new(text))
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
#
|
|
97
|
+
# Inspect the Email Contents
|
|
98
|
+
#
|
|
99
|
+
|
|
100
|
+
Then /^(?:I|they) should see "([^"]*?)" in the email subject$/ do |text|
|
|
101
|
+
current_email.should have_subject(text)
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
Then /^(?:I|they) should see \/([^"]*?)\/ in the email subject$/ do |text|
|
|
105
|
+
current_email.should have_subject(Regexp.new(text))
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
Then /^(?:I|they) should see "([^"]*?)" in the email body$/ do |text|
|
|
109
|
+
current_email.default_part_body.to_s.should include(text)
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
Then /^(?:I|they) should see \/([^"]*?)\/ in the email body$/ do |text|
|
|
113
|
+
current_email.default_part_body.to_s.should =~ Regexp.new(text)
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
Then /^(?:I|they) should see the email delivered from "([^"]*?)"$/ do |text|
|
|
117
|
+
current_email.should be_delivered_from(text)
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
Then /^(?:I|they) should see "([^\"]*)" in the email "([^"]*?)" header$/ do |text, name|
|
|
121
|
+
current_email.should have_header(name, text)
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
Then /^(?:I|they) should see \/([^\"]*)\/ in the email "([^"]*?)" header$/ do |text, name|
|
|
125
|
+
current_email.should have_header(name, Regexp.new(text))
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
Then /^I should see it is a multi\-part email$/ do
|
|
129
|
+
current_email.should be_multipart
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
Then /^(?:I|they) should see "([^"]*?)" in the email html part body$/ do |text|
|
|
133
|
+
current_email.html_part.body.to_s.should include(text)
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
Then /^(?:I|they) should see "([^"]*?)" in the email text part body$/ do |text|
|
|
137
|
+
current_email.text_part.body.to_s.should include(text)
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
#
|
|
141
|
+
# Inspect the Email Attachments
|
|
142
|
+
#
|
|
143
|
+
|
|
144
|
+
Then /^(?:I|they) should see (an|no|\d+) attachments? with the email$/ do |amount|
|
|
145
|
+
current_email_attachments.size.should == parse_email_count(amount)
|
|
146
|
+
end
|
|
147
|
+
|
|
148
|
+
Then /^there should be (an|no|\d+) attachments? named "([^"]*?)"$/ do |amount, filename|
|
|
149
|
+
current_email_attachments.select { |a| a.filename == filename }.size.should == parse_email_count(amount)
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
Then /^attachment (\d+) should be named "([^"]*?)"$/ do |index, filename|
|
|
153
|
+
current_email_attachments[(index.to_i - 1)].filename.should == filename
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
Then /^there should be (an|no|\d+) attachments? of type "([^"]*?)"$/ do |amount, content_type|
|
|
157
|
+
current_email_attachments.select { |a| a.content_type.include?(content_type) }.size.should == parse_email_count(amount)
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
Then /^attachment (\d+) should be of type "([^"]*?)"$/ do |index, content_type|
|
|
161
|
+
current_email_attachments[(index.to_i - 1)].content_type.should include(content_type)
|
|
162
|
+
end
|
|
163
|
+
|
|
164
|
+
Then /^all attachments should not be blank$/ do
|
|
165
|
+
current_email_attachments.each do |attachment|
|
|
166
|
+
attachment.read.size.should_not == 0
|
|
167
|
+
end
|
|
168
|
+
end
|
|
169
|
+
|
|
170
|
+
Then /^show me a list of email attachments$/ do
|
|
171
|
+
EmailSpec::EmailViewer::save_and_open_email_attachments_list(current_email)
|
|
172
|
+
end
|
|
173
|
+
|
|
174
|
+
#
|
|
175
|
+
# Interact with Email Contents
|
|
176
|
+
#
|
|
177
|
+
|
|
178
|
+
When /^(?:I|they) follow "([^"]*?)" in the email$/ do |link|
|
|
179
|
+
visit_in_email(link)
|
|
180
|
+
end
|
|
181
|
+
|
|
182
|
+
When /^(?:I|they) click the first link in the email$/ do
|
|
183
|
+
click_first_link_in_email
|
|
184
|
+
end
|
|
185
|
+
|
|
186
|
+
#
|
|
187
|
+
# Debugging
|
|
188
|
+
# These only work with Rails and OSx ATM since EmailViewer uses RAILS_ROOT and OSx's 'open' command.
|
|
189
|
+
# Patches accepted. ;)
|
|
190
|
+
#
|
|
191
|
+
|
|
192
|
+
Then /^save and open current email$/ do
|
|
193
|
+
EmailSpec::EmailViewer::save_and_open_email(current_email)
|
|
194
|
+
end
|
|
195
|
+
|
|
196
|
+
Then /^save and open all text emails$/ do
|
|
197
|
+
EmailSpec::EmailViewer::save_and_open_all_text_emails
|
|
198
|
+
end
|
|
199
|
+
|
|
200
|
+
Then /^save and open all html emails$/ do
|
|
201
|
+
EmailSpec::EmailViewer::save_and_open_all_html_emails
|
|
202
|
+
end
|
|
203
|
+
|
|
204
|
+
Then /^save and open all raw emails$/ do
|
|
205
|
+
EmailSpec::EmailViewer::save_and_open_all_raw_emails
|
|
206
|
+
end
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
#encoding=utf-8
|
|
2
|
+
World(DouguiUsers::Engine.routes.url_helpers)
|
|
3
|
+
World(Rails.application.routes.url_helpers)
|
|
4
|
+
module UserHelpers
|
|
5
|
+
def log_a_user(user)
|
|
6
|
+
visit dougui_users_login_path
|
|
7
|
+
fill_in 'dougui_users_user_session_username', :with => user.username
|
|
8
|
+
fill_in 'dougui_users_user_session_password', :with => user.password
|
|
9
|
+
click_button "Se connecter"
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def create_a_user_from_fields(fields)
|
|
13
|
+
user = Factory.build(:user)
|
|
14
|
+
fields.rows_hash.each do |field, value|
|
|
15
|
+
user.attributes = { field => value }
|
|
16
|
+
end
|
|
17
|
+
user.save
|
|
18
|
+
user
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
World(UserHelpers)
|
|
22
|
+
|
|
23
|
+
Given /^I have no users$/ do
|
|
24
|
+
DouguiUsers::User.destroy_all
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
Given /^I have a user with ([^"]*) "([^"]*)"$/ do |field, value|
|
|
28
|
+
Factory.create(:user, field.to_sym => value)
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
Given /^I am a logged user$/ do
|
|
32
|
+
user = Factory.create(:user, :active => true)
|
|
33
|
+
log_a_user(user)
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
Given /^I am a logged user with ([^"]*) "([^"]*)"$/ do |field, value|
|
|
37
|
+
user = Factory.create(:user, :active => true, field.to_sym => value)
|
|
38
|
+
log_a_user(user)
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
Given /^I am a logged user with this following:$/ do |fields|
|
|
42
|
+
user = create_a_user_from_fields(fields)
|
|
43
|
+
log_a_user(user)
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
When /^I create a user$/ do
|
|
48
|
+
When "I fill in \"user_username\" with \"dougui\""
|
|
49
|
+
When "I fill in \"user_email\" with \"guirec.corbel@gmail.com\""
|
|
50
|
+
When "I fill in \"user_password\" with \"test1234\""
|
|
51
|
+
When "I fill in \"user_password_confirmation\" with \"test1234\""
|
|
52
|
+
When "I press \"S'inscrire\""
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
When /^(?:|I )have a user with this following:$/ do |fields|
|
|
56
|
+
create_a_user_from_fields(fields)
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
Then /^I should have (\d+|no) users?$/ do |count|
|
|
61
|
+
count = 0 if count == "no"
|
|
62
|
+
DouguiUsers::User.all.count.should == count.to_i
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
Then /^I should see a link for ([^"]*) in the email body$/ do |page_name|
|
|
66
|
+
open_email(current_email_address)
|
|
67
|
+
current_email.default_part_body.to_s.should include(path_to(page_name))
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
Then /^I should have (\d+|no|a) users? with this following:$/ do |count, fields|
|
|
71
|
+
count = 0 if count == "no"
|
|
72
|
+
count = 1 if count == "a"
|
|
73
|
+
|
|
74
|
+
users = DouguiUsers::User
|
|
75
|
+
|
|
76
|
+
fields.rows_hash.each do |field, value|
|
|
77
|
+
|
|
78
|
+
case DouguiUsers::User.columns_hash[field].sql_type
|
|
79
|
+
when "boolean"
|
|
80
|
+
if value.downcase == "true"
|
|
81
|
+
users = users.where(field.to_sym => true)
|
|
82
|
+
else
|
|
83
|
+
users = users.where(field.to_sym => false)
|
|
84
|
+
end
|
|
85
|
+
else
|
|
86
|
+
users = users.where(field.to_sym => value)
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
users.count.should == count.to_i
|
|
90
|
+
end
|
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
# TL;DR: YOU SHOULD DELETE THIS FILE
|
|
2
|
+
#
|
|
3
|
+
# This file was generated by Cucumber-Rails and is only here to get you a head start
|
|
4
|
+
# These step definitions are thin wrappers around the Capybara/Webrat API that lets you
|
|
5
|
+
# visit pages, interact with widgets and make assertions about page content.
|
|
6
|
+
#
|
|
7
|
+
# If you use these step definitions as basis for your features you will quickly end up
|
|
8
|
+
# with features that are:
|
|
9
|
+
#
|
|
10
|
+
# * Hard to maintain
|
|
11
|
+
# * Verbose to read
|
|
12
|
+
#
|
|
13
|
+
# A much better approach is to write your own higher level step definitions, following
|
|
14
|
+
# the advice in the following blog posts:
|
|
15
|
+
#
|
|
16
|
+
# * http://benmabey.com/2008/05/19/imperative-vs-declarative-scenarios-in-user-stories.html
|
|
17
|
+
# * http://dannorth.net/2011/01/31/whose-domain-is-it-anyway/
|
|
18
|
+
# * http://elabs.se/blog/15-you-re-cuking-it-wrong
|
|
19
|
+
#
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
require 'uri'
|
|
23
|
+
require 'cgi'
|
|
24
|
+
require File.expand_path(File.join(File.dirname(__FILE__), "..", "support", "paths"))
|
|
25
|
+
require File.expand_path(File.join(File.dirname(__FILE__), "..", "support", "selectors"))
|
|
26
|
+
|
|
27
|
+
module WithinHelpers
|
|
28
|
+
def with_scope(locator)
|
|
29
|
+
locator ? within(*selector_for(locator)) { yield } : yield
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
World(WithinHelpers)
|
|
33
|
+
|
|
34
|
+
# Single-line step scoper
|
|
35
|
+
When /^(.*) within (.*[^:])$/ do |step, parent|
|
|
36
|
+
with_scope(parent) { When step }
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
# Multi-line step scoper
|
|
40
|
+
When /^(.*) within (.*[^:]):$/ do |step, parent, table_or_string|
|
|
41
|
+
with_scope(parent) { When "#{step}:", table_or_string }
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
Given /^(?:|I )am on (.+)$/ do |page_name|
|
|
45
|
+
visit path_to(page_name)
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
When /^(?:|I )go to (.+)$/ do |page_name|
|
|
49
|
+
visit path_to(page_name)
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
When /^(?:|I )press "([^"]*)"$/ do |button|
|
|
53
|
+
click_button(button)
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
When /^(?:|I )follow "([^"]*)"$/ do |link|
|
|
57
|
+
click_link(link)
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
When /^(?:|I )fill in "([^"]*)" with "([^"]*)"$/ do |field, value|
|
|
61
|
+
fill_in(field, :with => value)
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
When /^(?:|I )fill in "([^"]*)" for "([^"]*)"$/ do |value, field|
|
|
65
|
+
fill_in(field, :with => value)
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
# Use this to fill in an entire form with data from a table. Example:
|
|
69
|
+
#
|
|
70
|
+
# When I fill in the following:
|
|
71
|
+
# | Account Number | 5002 |
|
|
72
|
+
# | Expiry date | 2009-11-01 |
|
|
73
|
+
# | Note | Nice guy |
|
|
74
|
+
# | Wants Email? | |
|
|
75
|
+
#
|
|
76
|
+
# TODO: Add support for checkbox, select og option
|
|
77
|
+
# based on naming conventions.
|
|
78
|
+
#
|
|
79
|
+
When /^(?:|I )fill in the following:$/ do |fields|
|
|
80
|
+
fields.rows_hash.each do |name, value|
|
|
81
|
+
When %{I fill in "#{name}" with "#{value}"}
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
When /^(?:|I )select "([^"]*)" from "([^"]*)"$/ do |value, field|
|
|
86
|
+
select(value, :from => field)
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
When /^(?:|I )check "([^"]*)"$/ do |field|
|
|
90
|
+
check(field)
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
When /^(?:|I )uncheck "([^"]*)"$/ do |field|
|
|
94
|
+
uncheck(field)
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
When /^(?:|I )choose "([^"]*)"$/ do |field|
|
|
98
|
+
choose(field)
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
When /^(?:|I )attach the file "([^"]*)" to "([^"]*)"$/ do |path, field|
|
|
102
|
+
attach_file(field, File.expand_path(path))
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
Then /^(?:|I )should see "([^"]*)"$/ do |text|
|
|
106
|
+
if page.respond_to? :should
|
|
107
|
+
page.should have_content(text)
|
|
108
|
+
else
|
|
109
|
+
assert page.has_content?(text)
|
|
110
|
+
end
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
Then /^(?:|I )should see \/([^\/]*)\/$/ do |regexp|
|
|
114
|
+
regexp = Regexp.new(regexp)
|
|
115
|
+
|
|
116
|
+
if page.respond_to? :should
|
|
117
|
+
page.should have_xpath('//*', :text => regexp)
|
|
118
|
+
else
|
|
119
|
+
assert page.has_xpath?('//*', :text => regexp)
|
|
120
|
+
end
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
Then /^(?:|I )should not see "([^"]*)"$/ do |text|
|
|
124
|
+
if page.respond_to? :should
|
|
125
|
+
page.should have_no_content(text)
|
|
126
|
+
else
|
|
127
|
+
assert page.has_no_content?(text)
|
|
128
|
+
end
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
Then /^(?:|I )should not see \/([^\/]*)\/$/ do |regexp|
|
|
132
|
+
regexp = Regexp.new(regexp)
|
|
133
|
+
|
|
134
|
+
if page.respond_to? :should
|
|
135
|
+
page.should have_no_xpath('//*', :text => regexp)
|
|
136
|
+
else
|
|
137
|
+
assert page.has_no_xpath?('//*', :text => regexp)
|
|
138
|
+
end
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
Then /^the "([^"]*)" field(?: within (.*))? should contain "([^"]*)"$/ do |field, parent, value|
|
|
142
|
+
with_scope(parent) do
|
|
143
|
+
field = find_field(field)
|
|
144
|
+
field_value = (field.tag_name == 'textarea') ? field.text : field.value
|
|
145
|
+
if field_value.respond_to? :should
|
|
146
|
+
field_value.should =~ /#{value}/
|
|
147
|
+
else
|
|
148
|
+
assert_match(/#{value}/, field_value)
|
|
149
|
+
end
|
|
150
|
+
end
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
Then /^the "([^"]*)" field(?: within (.*))? should not contain "([^"]*)"$/ do |field, parent, value|
|
|
154
|
+
with_scope(parent) do
|
|
155
|
+
field = find_field(field)
|
|
156
|
+
field_value = (field.tag_name == 'textarea') ? field.text : field.value
|
|
157
|
+
if field_value.respond_to? :should_not
|
|
158
|
+
field_value.should_not =~ /#{value}/
|
|
159
|
+
else
|
|
160
|
+
assert_no_match(/#{value}/, field_value)
|
|
161
|
+
end
|
|
162
|
+
end
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
Then /^the "([^"]*)" checkbox(?: within (.*))? should be checked$/ do |label, parent|
|
|
166
|
+
with_scope(parent) do
|
|
167
|
+
field_checked = find_field(label)['checked']
|
|
168
|
+
if field_checked.respond_to? :should
|
|
169
|
+
field_checked.should be_true
|
|
170
|
+
else
|
|
171
|
+
assert field_checked
|
|
172
|
+
end
|
|
173
|
+
end
|
|
174
|
+
end
|
|
175
|
+
|
|
176
|
+
Then /^the "([^"]*)" checkbox(?: within (.*))? should not be checked$/ do |label, parent|
|
|
177
|
+
with_scope(parent) do
|
|
178
|
+
field_checked = find_field(label)['checked']
|
|
179
|
+
if field_checked.respond_to? :should
|
|
180
|
+
field_checked.should be_false
|
|
181
|
+
else
|
|
182
|
+
assert !field_checked
|
|
183
|
+
end
|
|
184
|
+
end
|
|
185
|
+
end
|
|
186
|
+
|
|
187
|
+
Then /^(?:|I )should be on (.+)$/ do |page_name|
|
|
188
|
+
current_path = URI.parse(current_url).path
|
|
189
|
+
if current_path.respond_to? :should
|
|
190
|
+
current_path.should == path_to(page_name)
|
|
191
|
+
else
|
|
192
|
+
assert_equal path_to(page_name), current_path
|
|
193
|
+
end
|
|
194
|
+
end
|
|
195
|
+
|
|
196
|
+
Then /^(?:|I )should have the following query string:$/ do |expected_pairs|
|
|
197
|
+
query = URI.parse(current_url).query
|
|
198
|
+
actual_params = query ? CGI.parse(query) : {}
|
|
199
|
+
expected_params = {}
|
|
200
|
+
expected_pairs.rows_hash.each_pair{|k,v| expected_params[k] = v.split(',')}
|
|
201
|
+
|
|
202
|
+
if actual_params.respond_to? :should
|
|
203
|
+
actual_params.should == expected_params
|
|
204
|
+
else
|
|
205
|
+
assert_equal expected_params, actual_params
|
|
206
|
+
end
|
|
207
|
+
end
|
|
208
|
+
|
|
209
|
+
Then /^show me the page$/ do
|
|
210
|
+
save_and_open_page
|
|
211
|
+
end
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
#encoding=utf-8
|
|
2
|
+
require 'spork'
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
Spork.prefork do
|
|
6
|
+
require 'rails'
|
|
7
|
+
|
|
8
|
+
#require 'cucumber/rails3/application'
|
|
9
|
+
ENV["RAILS_ENV"] ||= "test"
|
|
10
|
+
|
|
11
|
+
ENV["RAILS_ROOT"] ||= File.dirname(__FILE__) + "../../../spec/dummy"
|
|
12
|
+
require 'cucumber/rails'
|
|
13
|
+
|
|
14
|
+
require File.expand_path(File.dirname(__FILE__) + '/../../spec/dummy/config/environment')
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
#require 'cucumber/rails3/action_controller'
|
|
18
|
+
|
|
19
|
+
if defined?(ActiveRecord::Base)
|
|
20
|
+
require 'rails/test_help'
|
|
21
|
+
else
|
|
22
|
+
require 'action_dispatch/testing/test_process'
|
|
23
|
+
require 'action_dispatch/testing/integration'
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
if !Rails.application.config.cache_classes
|
|
27
|
+
warn "WARNING: You have set Rails' config.cache_classes to false (most likely in config/environments/cucumber.rb). This setting is known to cause problems with database transactions. Set config.cache_classes to true if you want to use transactions. For more information see https://rspec.lighthouseapp.com/projects/16211/tickets/165."
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
require 'cucumber/rails/world'
|
|
32
|
+
require 'cucumber/rails/hooks'
|
|
33
|
+
require 'cucumber/rails/capybara'
|
|
34
|
+
|
|
35
|
+
require 'cucumber/web/tableish'
|
|
36
|
+
|
|
37
|
+
require 'capybara/rails'
|
|
38
|
+
require 'capybara/cucumber'
|
|
39
|
+
require 'capybara/session'
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
# Capybara defaults to XPath selectors rather than Webrat's default of CSS3. In
|
|
44
|
+
# order to ease the transition to Capybara we set the default here. If you'd
|
|
45
|
+
# prefer to use XPath just remove this line and adjust any selectors in your
|
|
46
|
+
# steps to use the XPath syntax.
|
|
47
|
+
Capybara.default_selector = :css
|
|
48
|
+
|
|
49
|
+
# By default, any exception happening in your Rails application will bubble up
|
|
50
|
+
# to Cucumber so that your scenario will fail. This is a different from how
|
|
51
|
+
# your application behaves in the production environment, where an error page will
|
|
52
|
+
# be rendered instead.
|
|
53
|
+
#
|
|
54
|
+
# Sometimes we want to override this default behaviour and allow Rails to rescue
|
|
55
|
+
# exceptions and display an error page (just like when the app is running in production).
|
|
56
|
+
# Typical scenarios where you want to do this is when you test your error pages.
|
|
57
|
+
# There are two ways to allow Rails to rescue exceptions:
|
|
58
|
+
#
|
|
59
|
+
# 1) Tag your scenario (or feature) with @allow-rescue
|
|
60
|
+
#
|
|
61
|
+
# 2) Set the value below to true. Beware that doing this globally is not
|
|
62
|
+
# recommended as it will mask a lot of errors for you!
|
|
63
|
+
#
|
|
64
|
+
|
|
65
|
+
#ActionController::Base.allow_rescue = false
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
require 'factory_girl'
|
|
69
|
+
Dir.glob(File.join(File.dirname(__FILE__), '../../spec/factories/dougui_users/*.rb')).each {|f| require f }
|
|
70
|
+
|
|
71
|
+
require 'email_spec'
|
|
72
|
+
require 'email_spec/cucumber'
|
|
73
|
+
|
|
74
|
+
# Remove/comment out the lines below if your app doesn't have a database.
|
|
75
|
+
# For some databases (like MongoDB and CouchDB) you may need to use :truncation instead.
|
|
76
|
+
begin
|
|
77
|
+
DatabaseCleaner.strategy = :transaction
|
|
78
|
+
rescue NameError
|
|
79
|
+
raise "You need to add database_cleaner to your Gemfile (in the :test group) if you wish to use it."
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
Spork.each_run do
|
|
84
|
+
load "#{Rails.root}/config/routes.rb"
|
|
85
|
+
Dir["#{Rails.root}/app/**/*.rb"].each { |f| load f }
|
|
86
|
+
I18n.backend.load_translations
|
|
87
|
+
end
|
|
88
|
+
|
|
@@ -0,0 +1,49 @@
|
|
|
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 home\s?page$/
|
|
12
|
+
'/'
|
|
13
|
+
|
|
14
|
+
when /the login page/
|
|
15
|
+
'/login'
|
|
16
|
+
|
|
17
|
+
when /^(.*)'s edit page$/i
|
|
18
|
+
user = User.find_by_username($1)
|
|
19
|
+
url_for(:controller => :users, :action => :edit, :id => user.id, :only_path => true)
|
|
20
|
+
|
|
21
|
+
when /^(.*)'s reset password page$/i
|
|
22
|
+
user = User.find_by_username($1)
|
|
23
|
+
url_for(:controller => :user_reset_passwords, :action => :edit, :id => user.perishable_token, :only_path => true)
|
|
24
|
+
|
|
25
|
+
when /^(.*)'s activate page$/i
|
|
26
|
+
user = User.find_by_username($1)
|
|
27
|
+
url_for(:controller => :user_activates, :action => :new, :id => user.perishable_token, :only_path => true)
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
# Add more mappings here.
|
|
31
|
+
# Here is an example that pulls values out of the Regexp:
|
|
32
|
+
#
|
|
33
|
+
# when /^(.*)'s profile page$/i
|
|
34
|
+
# user_profile_path(User.find_by_login($1))
|
|
35
|
+
|
|
36
|
+
else
|
|
37
|
+
begin
|
|
38
|
+
page_name =~ /^the (.*) page$/
|
|
39
|
+
path_components = $1.split(/\s+/)
|
|
40
|
+
self.send(path_components.push('path').join('_').to_sym)
|
|
41
|
+
rescue NoMethodError, ArgumentError
|
|
42
|
+
raise "Can't find mapping from \"#{page_name}\" to a path.\n" +
|
|
43
|
+
"Now, go and add a mapping in #{__FILE__}"
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
World(NavigationHelpers)
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
module HtmlSelectorsHelpers
|
|
2
|
+
# Maps a name to a selector. Used primarily by the
|
|
3
|
+
#
|
|
4
|
+
# When /^(.+) within (.+)$/ do |step, scope|
|
|
5
|
+
#
|
|
6
|
+
# step definitions in web_steps.rb
|
|
7
|
+
#
|
|
8
|
+
def selector_for(locator)
|
|
9
|
+
case locator
|
|
10
|
+
|
|
11
|
+
when "the page"
|
|
12
|
+
"html > body"
|
|
13
|
+
|
|
14
|
+
# Add more mappings here.
|
|
15
|
+
# Here is an example that pulls values out of the Regexp:
|
|
16
|
+
#
|
|
17
|
+
# when /^the (notice|error|info) flash$/
|
|
18
|
+
# ".flash.#{$1}"
|
|
19
|
+
|
|
20
|
+
# You can also return an array to use a different selector
|
|
21
|
+
# type, like:
|
|
22
|
+
#
|
|
23
|
+
# when /the header/
|
|
24
|
+
# [:xpath, "//header"]
|
|
25
|
+
|
|
26
|
+
# This allows you to provide a quoted selector as the scope
|
|
27
|
+
# for "within" steps as was previously the default for the
|
|
28
|
+
# web steps:
|
|
29
|
+
when /^"(.+)"$/
|
|
30
|
+
$1
|
|
31
|
+
|
|
32
|
+
else
|
|
33
|
+
raise "Can't find mapping from \"#{locator}\" to a selector.\n" +
|
|
34
|
+
"Now, go and add a mapping in #{__FILE__}"
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
World(HtmlSelectorsHelpers)
|