spreewald 2.99.3 → 4.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/test.yml +40 -0
- data/CHANGELOG.md +45 -4
- data/Gemfile +1 -1
- data/Gemfile.lock +2 -2
- data/Gemfile.ruby245 +3 -0
- data/Gemfile.ruby245.lock +10 -1
- data/Gemfile.ruby266 +3 -0
- data/Gemfile.ruby266.lock +12 -2
- data/README.md +40 -32
- data/Rakefile +34 -19
- data/features/binary.feature +2 -2
- data/features/support/step_definitions/custom_steps.rb +10 -0
- data/lib/spreewald.rb +1 -0
- data/lib/spreewald/development_steps.rb +1 -8
- data/lib/spreewald/email_steps.rb +3 -43
- data/lib/spreewald/frame_steps.rb +77 -0
- data/lib/spreewald/web_steps.rb +17 -61
- data/lib/spreewald_support/mail_finder.rb +12 -13
- data/lib/spreewald_support/mail_to_plaintext_converter.rb +42 -0
- data/lib/spreewald_support/unsupported_email_header.rb +22 -0
- data/lib/spreewald_support/version.rb +1 -1
- data/spec/spreewald_support/mail_to_plaintext_converter_spec.rb +60 -0
- data/tests/{rails-4_capybara-3 → rails-4_capybara-2}/Gemfile +1 -1
- data/tests/{rails-4_capybara-3 → rails-4_capybara-2}/Gemfile.lock +14 -16
- data/tests/{rails-4_capybara-3 → rails-4_capybara-2}/README.rdoc +0 -0
- data/tests/{rails-4_capybara-3 → rails-4_capybara-2}/Rakefile +0 -0
- data/tests/{rails-4_capybara-3 → rails-4_capybara-2}/app +0 -0
- data/tests/{rails-4_capybara-3 → rails-4_capybara-2}/bin/bundle +0 -0
- data/tests/{rails-4_capybara-3 → rails-4_capybara-2}/bin/rails +0 -0
- data/tests/{rails-4_capybara-3 → rails-4_capybara-2}/bin/rake +0 -0
- data/tests/{rails-4_capybara-3 → rails-4_capybara-2}/bin/setup +0 -0
- data/tests/{rails-4_capybara-3 → rails-4_capybara-2}/config.ru +0 -0
- data/tests/{rails-4_capybara-3 → rails-4_capybara-2}/config/application.rb +0 -0
- data/tests/{rails-4_capybara-3 → rails-4_capybara-2}/config/boot.rb +0 -0
- data/tests/{rails-4_capybara-3 → rails-4_capybara-2}/config/cucumber.yml +0 -0
- data/tests/{rails-4_capybara-3 → rails-4_capybara-2}/config/database.yml +0 -0
- data/tests/{rails-4_capybara-3 → rails-4_capybara-2}/config/environment.rb +0 -0
- data/tests/{rails-4_capybara-3 → rails-4_capybara-2}/config/environments/development.rb +0 -0
- data/tests/{rails-4_capybara-3 → rails-4_capybara-2}/config/environments/test.rb +0 -0
- data/tests/{rails-4_capybara-3 → rails-4_capybara-2}/config/initializers/backtrace_silencers.rb +0 -0
- data/tests/{rails-4_capybara-3 → rails-4_capybara-2}/config/initializers/cookies_serializer.rb +0 -0
- data/tests/{rails-4_capybara-3 → rails-4_capybara-2}/config/initializers/filter_parameter_logging.rb +0 -0
- data/tests/{rails-4_capybara-3 → rails-4_capybara-2}/config/initializers/inflections.rb +0 -0
- data/tests/{rails-4_capybara-3 → rails-4_capybara-2}/config/initializers/mime_types.rb +0 -0
- data/tests/{rails-4_capybara-3 → rails-4_capybara-2}/config/initializers/session_store.rb +0 -0
- data/tests/{rails-4_capybara-3 → rails-4_capybara-2}/config/initializers/silence_deprecation_warnings.rb +0 -0
- data/tests/{rails-4_capybara-3 → rails-4_capybara-2}/config/initializers/to_time_preserves_timezone.rb +0 -0
- data/tests/{rails-4_capybara-3 → rails-4_capybara-2}/config/initializers/wrap_parameters.rb +0 -0
- data/tests/{rails-4_capybara-3 → rails-4_capybara-2}/config/locales/en.yml +0 -0
- data/tests/{rails-3_capybara-1 → rails-4_capybara-2}/config/routes.rb +0 -0
- data/tests/{rails-4_capybara-3 → rails-4_capybara-2}/config/secrets.yml +0 -0
- data/tests/{rails-4_capybara-3 → rails-4_capybara-2}/db +0 -0
- data/tests/{rails-4_capybara-3 → rails-4_capybara-2}/features/browser_tab_steps.feature +0 -0
- data/tests/{rails-4_capybara-3 → rails-4_capybara-2}/features/development_steps.feature +0 -0
- data/tests/{rails-4_capybara-3 → rails-4_capybara-2}/features/email_steps.feature +0 -0
- data/tests/rails-4_capybara-2/features/iframe_steps.feature +1 -0
- data/tests/{rails-4_capybara-3 → rails-4_capybara-2}/features/overriding.feature +0 -0
- data/tests/{rails-4_capybara-3 → rails-4_capybara-2}/features/session_steps.feature +0 -0
- data/tests/{rails-4_capybara-3 → rails-4_capybara-2}/features/step_definitions/overriding_steps.rb +0 -0
- data/tests/{rails-4_capybara-3 → rails-4_capybara-2}/features/step_definitions/test_steps.rb +0 -0
- data/tests/{rails-4_capybara-3 → rails-4_capybara-2}/features/support/env.rb +0 -0
- data/tests/{rails-3_capybara-1 → rails-4_capybara-2}/features/support/paths.rb +0 -0
- data/tests/{rails-3_capybara-1 → rails-4_capybara-2}/features/support/selectors.rb +0 -0
- data/tests/rails-4_capybara-2/features/support/selenium.rb +1 -0
- data/tests/{rails-4_capybara-3 → rails-4_capybara-2}/features/table_steps.feature +0 -0
- data/tests/{rails-4_capybara-3 → rails-4_capybara-2}/features/time_steps.feature +0 -0
- data/tests/{rails-4_capybara-3 → rails-4_capybara-2}/features/web_steps.feature +0 -0
- data/tests/{rails-4_capybara-3 → rails-4_capybara-2}/lib/tasks/cucumber.rake +0 -0
- data/tests/{rails-4_capybara-3 → rails-4_capybara-2}/log/.keep +0 -0
- data/tests/{rails-4_capybara-3 → rails-4_capybara-2}/public/404.html +0 -0
- data/tests/{rails-4_capybara-3 → rails-4_capybara-2}/public/422.html +0 -0
- data/tests/{rails-4_capybara-3 → rails-4_capybara-2}/public/500.html +0 -0
- data/tests/{rails-4_capybara-3 → rails-4_capybara-2}/public/favicon.ico +0 -0
- data/tests/{rails-4_capybara-3 → rails-4_capybara-2}/public/fixture_files +0 -0
- data/tests/{rails-3_capybara-1 → rails-4_capybara-2}/script/cucumber +0 -0
- data/tests/rails-6_capybara-3/Gemfile.lock +2 -2
- data/tests/rails-6_capybara-3/app/mailers/spreewald_mailer.rb +16 -0
- data/tests/rails-6_capybara-3/features/iframe_steps.feature +1 -0
- data/tests/rails-6_capybara-3/features/support/selenium.rb +1 -0
- data/tests/shared/app/controllers/emails_controller.rb +20 -0
- data/tests/shared/app/controllers/iframes_controller.rb +11 -0
- data/tests/shared/app/controllers/static_pages_controller.rb +12 -8
- data/tests/shared/app/models/mailer.rb +32 -0
- data/tests/shared/app/views/forms/checkbox_form.html.haml +3 -0
- data/tests/shared/app/views/forms/disabled_elements.html.haml +1 -0
- data/tests/shared/app/views/forms/form1.html.haml +4 -1
- data/tests/shared/app/views/forms/invalid_form.html.haml +3 -0
- data/tests/shared/app/views/iframes/iframe_1_content.haml +12 -0
- data/tests/shared/app/views/iframes/iframe_2_content.haml +12 -0
- data/tests/shared/app/views/mailer/html_email_for_failed_test_without_header.haml +5 -0
- data/tests/shared/app/views/mailer/html_email_for_successful_test_without_header.haml +7 -0
- data/tests/shared/app/views/mailer/text_email_for_failed_test_without_header.text.erb +1 -0
- data/tests/shared/app/views/mailer/text_email_for_successful_test_without_header.text.erb +3 -0
- data/tests/shared/app/views/static_pages/iframe.haml +3 -0
- data/tests/shared/config/routes.rb +8 -0
- data/tests/shared/features/shared/email_steps.feature +172 -35
- data/tests/shared/features/shared/iframe_steps.feature +38 -0
- data/tests/shared/features/shared/step_definitions/test_steps.rb +5 -6
- data/tests/shared/features/shared/web_steps.feature +15 -10
- data/tests/shared/features/support/selenium.rb +10 -0
- metadata +137 -186
- data/.travis.yml +0 -29
- data/Gemfile.ruby218 +0 -7
- data/Gemfile.ruby218.lock +0 -58
- data/lib/spreewald/file_attachment_steps.rb +0 -22
- data/lib/spreewald/timecop_steps.rb +0 -9
- data/tests/rails-3_capybara-1/.ruby-version +0 -1
- data/tests/rails-3_capybara-1/Gemfile +0 -20
- data/tests/rails-3_capybara-1/Gemfile.lock +0 -182
- data/tests/rails-3_capybara-1/Rakefile +0 -18
- data/tests/rails-3_capybara-1/app +0 -1
- data/tests/rails-3_capybara-1/config.ru +0 -4
- data/tests/rails-3_capybara-1/config/application.rb +0 -29
- data/tests/rails-3_capybara-1/config/boot.rb +0 -15
- data/tests/rails-3_capybara-1/config/cucumber.yml +0 -1
- data/tests/rails-3_capybara-1/config/database.yml +0 -1
- data/tests/rails-3_capybara-1/config/environment.rb +0 -7
- data/tests/rails-3_capybara-1/config/initializers/backtrace_silencers.rb +0 -9
- data/tests/rails-3_capybara-1/config/initializers/inflections.rb +0 -12
- data/tests/rails-3_capybara-1/config/initializers/mime_types.rb +0 -7
- data/tests/rails-3_capybara-1/config/initializers/secret_token.rb +0 -9
- data/tests/rails-3_capybara-1/config/initializers/session_store.rb +0 -5
- data/tests/rails-3_capybara-1/db +0 -1
- data/tests/rails-3_capybara-1/features/shared +0 -1
- data/tests/rails-3_capybara-1/features/support/env.rb +0 -65
- data/tests/rails-3_capybara-1/features/support/selenium.rb +0 -3
- data/tests/rails-3_capybara-1/public +0 -1
- data/tests/rails-3_capybara-1/script/rails +0 -6
- data/tests/rails-3_capybara-2/.ruby-version +0 -1
- data/tests/rails-3_capybara-2/Gemfile +0 -21
- data/tests/rails-3_capybara-2/Gemfile.lock +0 -191
- data/tests/rails-3_capybara-2/Rakefile +0 -1
- data/tests/rails-3_capybara-2/app +0 -1
- data/tests/rails-3_capybara-2/config +0 -1
- data/tests/rails-3_capybara-2/config.ru +0 -1
- data/tests/rails-3_capybara-2/db +0 -1
- data/tests/rails-3_capybara-2/features +0 -1
- data/tests/rails-3_capybara-2/public +0 -1
- data/tests/rails-3_capybara-2/script +0 -1
- data/tests/rails-4_capybara-3/config/routes.rb +0 -1
- data/tests/rails-4_capybara-3/features/support/paths.rb +0 -1
- data/tests/rails-4_capybara-3/features/support/selectors.rb +0 -1
- data/tests/rails-4_capybara-3/features/support/selenium.rb +0 -3
- data/tests/rails-4_capybara-3/script/cucumber +0 -10
- data/tests/rails-6_capybara-3/features/support/selenium.rb +0 -3
@@ -0,0 +1,10 @@
|
|
1
|
+
Then /^the output should( not)? contain \/(.*)\/$/ do |negated, regexp|
|
2
|
+
output = all_commands.map { |c| c.output }.join("\n")
|
3
|
+
regexp = Regexp.new(regexp)
|
4
|
+
|
5
|
+
if negated
|
6
|
+
expect(output).not_to match(regexp)
|
7
|
+
else
|
8
|
+
expect(output).to match(regexp)
|
9
|
+
end
|
10
|
+
end
|
data/lib/spreewald.rb
CHANGED
@@ -5,15 +5,8 @@ Then /^it should work(.+?)?$/ do |message|
|
|
5
5
|
pending(message)
|
6
6
|
end.overridable
|
7
7
|
|
8
|
-
# nodoc
|
9
|
-
Then 'debugger' do
|
10
|
-
warn 'The step "Then debugger" will be removed in future versions of Spreewald. Please use "Then console" instead.'
|
11
|
-
step 'console' # Alias
|
12
|
-
end.overridable
|
13
|
-
|
14
8
|
# Pauses test execution and opens an IRB shell with current context. Does not halt the application-
|
15
|
-
# under-test.
|
16
|
-
# for its job)
|
9
|
+
# under-test.
|
17
10
|
Then 'console' do
|
18
11
|
require 'irb'
|
19
12
|
ARGV.clear # IRB takes ARGV as its own arguments
|
@@ -30,10 +30,9 @@ end.overridable
|
|
30
30
|
#
|
31
31
|
# """
|
32
32
|
#
|
33
|
-
#
|
34
|
-
#
|
35
|
-
#
|
36
|
-
# You may skip lines in the header, of course.
|
33
|
+
# You may skip lines in the header.
|
34
|
+
# Please note: In older versions of Spreewald, unmentioned body lines were skipped.
|
35
|
+
# Now you have to use the asterisk explicitly to omit lines in the body.
|
37
36
|
Then /^(an?|no)( HTML| plain-text|) e?mail should have been sent with:$/ do |mode, type, raw_data|
|
38
37
|
patiently do
|
39
38
|
results = MailFinder.find(raw_data, type.strip)
|
@@ -70,26 +69,6 @@ ERROR
|
|
70
69
|
end
|
71
70
|
end.overridable
|
72
71
|
|
73
|
-
# nodoc (deprecated)
|
74
|
-
Then /^(an|no) e?mail should have been sent((?: |and|with|from "[^"]+"|bcc "[^"]+"|cc "[^"]+"|to "[^"]+"|the subject "[^"]+"|the body "[^"]+"|the attachments "[^"]+")+)$/ do |mode, query|
|
75
|
-
warn "The step `an email should have been sent (from ...) (to ...) (cc ...) ...` has been deprecated in favor of `(an?|no)( HTML| plain-text|) e?mail should have been sent with:`"
|
76
|
-
patiently do
|
77
|
-
filename_method = Rails::VERSION::MAJOR < 3 ? 'original_filename' : 'filename'
|
78
|
-
@mail = ActionMailer::Base.deliveries.find do |mail|
|
79
|
-
[ query =~ /to "([^"]+)"/ && !mail.to.include?(MailFinder.resolve_email $1),
|
80
|
-
query =~ /cc "([^"]+)"/ && !mail.cc.include?(MailFinder.resolve_email $1),
|
81
|
-
query =~ /bcc "([^"]+)"/ && !mail.bcc.include?(MailFinder.resolve_email $1),
|
82
|
-
query =~ /from "([^"]+)"/ && !mail.from.include?(MailFinder.resolve_email $1),
|
83
|
-
query =~ /reply_to "([^"]+)"/ && !mail.reply_to.include?(MailFinder.resolve_email $1),
|
84
|
-
query =~ /subject "([^"]+)"/ && !mail.subject.include?($1),
|
85
|
-
query =~ /the attachments "([^"]+)"/ && $1.split(/\s*,\s*/).sort != Array(mail.attachments).collect(&:"#{filename_method}").sort
|
86
|
-
].none?
|
87
|
-
end
|
88
|
-
expectation = mode == 'no' ? 'not_to' : 'to'
|
89
|
-
expect(@mail).send(expectation, be_present)
|
90
|
-
end
|
91
|
-
end.overridable
|
92
|
-
|
93
72
|
# Please note that this step will only follow HTTP and HTTPS links.
|
94
73
|
# Other links (such as mailto: or ftp:// links) are ignored.
|
95
74
|
When /^I follow the (first|second|third)? ?link in the e?mail$/ do |index_in_words|
|
@@ -141,22 +120,3 @@ Then /^show me the e?mail( header)?s with:$/ do |only_header, raw_data|
|
|
141
120
|
|
142
121
|
print MailFinder.show_mails(results.mails, only_header)
|
143
122
|
end.overridable
|
144
|
-
|
145
|
-
# nodoc (deprecated)
|
146
|
-
Then /^that e?mail should( not)? have the following lines in the body:$/ do |negate, body|
|
147
|
-
warn "The step /^that e?mail should( not)? have the following lines in the body:$/ has been deprecated in favor of the updated step /^(an?|no)( HTML| plain-text|) e?mail should have been sent with:$/."
|
148
|
-
expectation = negate ? 'not_to' : 'to'
|
149
|
-
mail = @mail || ActionMailer::Base.deliveries.last
|
150
|
-
email_text_body = MailFinder.email_text_body(mail)
|
151
|
-
|
152
|
-
body.to_s.strip.split(/\n/).each do |line|
|
153
|
-
expect(email_text_body).send(expectation, include(line.strip))
|
154
|
-
end
|
155
|
-
end.overridable
|
156
|
-
|
157
|
-
# nodoc (deprecated)
|
158
|
-
Then /^that e?mail should have the following (?:|content in the )body:$/ do |body|
|
159
|
-
warn "The step /^that e?mail should have the following( content in the)? body:$/ has been deprecated in favor of the updated step /^(an?|no)( HTML| plain-text|) e?mail should have been sent with:$/."
|
160
|
-
mail = @mail || ActionMailer::Base.deliveries.last
|
161
|
-
expect(MailFinder.email_text_body(mail)).to include(body.strip)
|
162
|
-
end.overridable
|
@@ -0,0 +1,77 @@
|
|
1
|
+
# You can append `inside the [name or number] iframe` to any other step.
|
2
|
+
# Then the step will operate inside the given iframe.
|
3
|
+
# Examples:
|
4
|
+
#
|
5
|
+
# Then I should see "Kiwi" inside the 1st iframe
|
6
|
+
# Then I should see "Cherry" inside the fruits iframe
|
7
|
+
# When I press "Save" inside the 2nd iframe
|
8
|
+
#
|
9
|
+
When /^(.*?) inside the (.*?) iframe$/ do |nested_step, frame_identifier|
|
10
|
+
patiently do
|
11
|
+
frame = find_frame(frame_identifier)
|
12
|
+
page.within_frame(frame) do
|
13
|
+
step nested_step
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end.overridable
|
17
|
+
|
18
|
+
# nodoc
|
19
|
+
When /^(.*?) inside the (.*?) iframe:$/ do |nested_step, frame_identifier, table_or_string|
|
20
|
+
patiently do
|
21
|
+
frame = find_frame(frame_identifier)
|
22
|
+
page.within_frame(frame) do
|
23
|
+
step("#{nested_step}:", table_or_string)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end.overridable
|
27
|
+
|
28
|
+
if Gem::Version.new(Capybara::VERSION) >= Gem::Version.new('3')
|
29
|
+
|
30
|
+
# This step will switch to the iframe identified by its name or number.
|
31
|
+
# All further steps will operate inside the iframe.
|
32
|
+
# To switch to operating on the main page again, use the step
|
33
|
+
# "I switch back to the whole page".
|
34
|
+
# Examples:
|
35
|
+
#
|
36
|
+
# When I switch to the 1st iframe
|
37
|
+
# When I switch to the fruits iframe
|
38
|
+
#
|
39
|
+
# Please note: This step is only available for Capybara >= 3.
|
40
|
+
When /^I switch to the (.*?) iframe$/ do |frame_identifier|
|
41
|
+
frame = find_frame(frame_identifier)
|
42
|
+
page.driver.switch_to_frame(frame)
|
43
|
+
end.overridable
|
44
|
+
|
45
|
+
# This step can be used to switch back to the whole page if you switched
|
46
|
+
# to operating inside an iframe before (step `I switch to the ... iframe`).
|
47
|
+
#
|
48
|
+
# Please note: This step is only available for Capybara >= 3.
|
49
|
+
When /^I switch back to the whole page$/ do
|
50
|
+
handle = page.driver.current_window_handle
|
51
|
+
page.driver.switch_to_window(handle)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
module IframeStepsHelper
|
56
|
+
def find_frame(frame_identifier)
|
57
|
+
frame_id = convert_frame_identifier(frame_identifier)
|
58
|
+
case frame_id
|
59
|
+
when Integer
|
60
|
+
frames = page.find_all('iframe')
|
61
|
+
frames[frame_id]
|
62
|
+
when String
|
63
|
+
page.find("iframe[name='#{frame_id}']")
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
def convert_frame_identifier(frame_identifier)
|
68
|
+
number_regex = /\A(?<number>\d+)(st|nd|rd|th|\.)\z/
|
69
|
+
matches = frame_identifier.match(number_regex)
|
70
|
+
if matches && matches[:number]
|
71
|
+
matches[:number].to_i - 1 # selenium starts counting a 0
|
72
|
+
else
|
73
|
+
frame_identifier
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
World(IframeStepsHelper)
|
data/lib/spreewald/web_steps.rb
CHANGED
@@ -201,10 +201,10 @@ Then /^I should( not)? see a field "([^"]*)"$/ do |negate, name|
|
|
201
201
|
expectation = negate ? :not_to : :to
|
202
202
|
patiently do
|
203
203
|
begin
|
204
|
-
# In old Capybaras
|
205
|
-
field =
|
204
|
+
# In old Capybaras find returns nil, so we assign it to `field`
|
205
|
+
field = find_with_disabled(:field, name)
|
206
206
|
rescue Capybara::ElementNotFound
|
207
|
-
# In Capybara 0.4+ #
|
207
|
+
# In Capybara 0.4+ #find raises an error instead of returning nil
|
208
208
|
# We must explicitely reset the field variable from a previous patiently iteration
|
209
209
|
field = nil
|
210
210
|
end
|
@@ -327,7 +327,7 @@ end.overridable
|
|
327
327
|
# Checks that an input field contains some value (allowing * as wildcard character)
|
328
328
|
Then /^the "([^"]*)" field should (not )?contain "([^"]*)"$/ do |label, negate, expected_string|
|
329
329
|
patiently do
|
330
|
-
field =
|
330
|
+
field = find_with_disabled(:field, label)
|
331
331
|
field_value = case field.tag_name
|
332
332
|
when 'select'
|
333
333
|
options = field.all('option')
|
@@ -347,7 +347,7 @@ end.overridable
|
|
347
347
|
# Checks that a multiline textarea contains some value (allowing * as wildcard character)
|
348
348
|
Then(/^the "(.*?)" field should (not )?contain:$/) do |label, negate, expected_string|
|
349
349
|
patiently do
|
350
|
-
field =
|
350
|
+
field = find_with_disabled(:field, label)
|
351
351
|
expect(field.value.chomp).send(negate ? :not_to : :to, contain_with_wildcards(expected_string))
|
352
352
|
end
|
353
353
|
end.overridable
|
@@ -369,7 +369,7 @@ end.overridable
|
|
369
369
|
# Checks that an input field was wrapped with a validation error
|
370
370
|
Then /^the "([^"]*)" field should have the error "([^"]*)"$/ do |field, error_message|
|
371
371
|
patiently do
|
372
|
-
element =
|
372
|
+
element = find_with_disabled(:field, field)
|
373
373
|
classes = element.find(:xpath, '..')[:class].split(' ')
|
374
374
|
|
375
375
|
form_for_input = element.find(:xpath, 'ancestor::form[1]')
|
@@ -390,35 +390,17 @@ end.overridable
|
|
390
390
|
Then /^the "([^\"]*)" field should( not)? have an error$/ do |label, negate|
|
391
391
|
patiently do
|
392
392
|
expectation = negate ? :not_to : :to
|
393
|
-
field =
|
393
|
+
field = find_with_disabled(:field, label)
|
394
394
|
expect(field[:id]).to be_present # prevent bad CSS selector if field lacks id
|
395
395
|
expect(page).send(expectation, have_css(".field_with_errors ##{field[:id]}"))
|
396
396
|
end
|
397
397
|
end.overridable
|
398
398
|
|
399
|
-
Then /^the "([^"]*)"
|
400
|
-
warn 'The step /^the "([^"]*)" field should have no error$/ is deprecated and scheduled for removal. Use the step /^the "([^\"]*)" field should( not)? have an error$/ instead.'
|
401
|
-
patiently do
|
402
|
-
element = find_field(field)
|
403
|
-
classes = element.find(:xpath, '..')[:class].split(' ')
|
404
|
-
expect(classes).not_to include('field_with_errors')
|
405
|
-
expect(classes).not_to include('error')
|
406
|
-
end
|
407
|
-
end.overridable
|
408
|
-
|
409
|
-
Then /^the "([^"]*)" checkbox should( not)? be checked( and disabled)?$/ do |label, negate, disabled|
|
399
|
+
Then /^the "([^"]*)" checkbox should( not)? be checked?$/ do |label, negate|
|
410
400
|
expectation = negate ? :not_to : :to
|
411
401
|
|
412
|
-
if disabled
|
413
|
-
warn 'The step /^the "([^"]*)" checkbox should( not)? be checked( and disabled)?$/ will lose the `and disabled` modifier in Spreewald 3. In that version, the step will find a checkbox regardless of whether it is disabled.'
|
414
|
-
end
|
415
|
-
|
416
402
|
patiently do
|
417
|
-
field =
|
418
|
-
find_field(label)
|
419
|
-
else
|
420
|
-
find_field(label, :disabled => !!disabled)
|
421
|
-
end
|
403
|
+
field = find_with_disabled(:field, label)
|
422
404
|
expect(field).send expectation, be_checked
|
423
405
|
end
|
424
406
|
end.overridable
|
@@ -489,7 +471,7 @@ end.overridable
|
|
489
471
|
|
490
472
|
Then /^nothing should be selected for "([^"]*)"$/ do |field|
|
491
473
|
patiently do
|
492
|
-
select =
|
474
|
+
select = find_with_disabled(:field, field)
|
493
475
|
begin
|
494
476
|
selected_option = select.find(:xpath, ".//option[@selected = 'selected']") || select.all(:css, 'option').first
|
495
477
|
value = selected_option ? selected_option.value : nil
|
@@ -509,11 +491,11 @@ Then /^"([^"]*)" should( not)? be an option for "([^"]*)"$/ do |value, negate, f
|
|
509
491
|
patiently do
|
510
492
|
if negate
|
511
493
|
begin
|
512
|
-
expect(
|
494
|
+
expect(find_with_disabled(:field, field)).to have_no_css(*finder_arguments)
|
513
495
|
rescue Capybara::ElementNotFound
|
514
496
|
end
|
515
497
|
else
|
516
|
-
expect(
|
498
|
+
expect(find_with_disabled(:field, field)).to have_css(*finder_arguments)
|
517
499
|
end
|
518
500
|
end
|
519
501
|
end.overridable
|
@@ -542,18 +524,12 @@ end.overridable
|
|
542
524
|
# Within a selenium test, the browser is asked whether the element is really visible
|
543
525
|
# In a non-selenium test, we only check for `.hidden`, `.invisible` or `style: display:none`
|
544
526
|
#
|
545
|
-
# The step 'Then (the tag )?"..." should **not** be visible' is ambiguous. Please use 'Then (the tag )?"..." should be hidden' or 'Then I should not see "..."' instead. Note that the **not** option will be removed in future versions of Spreewald.
|
546
|
-
#
|
547
527
|
# More details [here](https://makandracards.com/makandra/1049-capybara-check-that-a-page-element-is-hidden-via-css)
|
548
|
-
Then /^(the tag )?"([^\"]+)" should
|
549
|
-
if hidden
|
550
|
-
warn "The step 'Then ... should not be visible' is prone to misunderstandings. Please use 'Then ... should be hidden' or 'Then I should not see ...' instead."
|
551
|
-
end
|
552
|
-
|
528
|
+
Then /^(the tag )?"([^\"]+)" should be visible$/ do |tag, selector_or_text|
|
553
529
|
options = {}
|
554
530
|
tag ? options.store(:selector, selector_or_text) : options.store(:text, selector_or_text)
|
555
531
|
|
556
|
-
|
532
|
+
assert_visible(options)
|
557
533
|
end.overridable
|
558
534
|
|
559
535
|
# Checks that an element is actually present and hidden, also considering styles.
|
@@ -621,12 +597,6 @@ Then /^"([^"]*)" should link to "([^"]*)"$/ do |link_label, target|
|
|
621
597
|
end
|
622
598
|
end.overridable
|
623
599
|
|
624
|
-
# Checks that the result has content type `text/plain`
|
625
|
-
Then /^I should get a text response$/ do
|
626
|
-
warn 'The step /^I should get a text response$/ is deprecated and scheduled for removal. Use `I should get a response with content-type "text/plain"` instead.'
|
627
|
-
step 'I should get a response with content-type "text/plain"'
|
628
|
-
end.overridable
|
629
|
-
|
630
600
|
# Click a link within an element matching the given selector. Will try to be clever
|
631
601
|
# and disregard elements that don't contain a matching link.
|
632
602
|
#
|
@@ -695,11 +665,11 @@ end.overridable
|
|
695
665
|
# Tests that a field with the given label is visible.
|
696
666
|
Then /^the "([^\"]*)" field should( not)? be visible$/ do |label, hidden|
|
697
667
|
if Spreewald::Comparison.compare_versions(Capybara::VERSION, :<, "2.1")
|
698
|
-
field =
|
668
|
+
field = find_with_disabled(:field, label)
|
699
669
|
else
|
700
670
|
# Capybara 2.1+ won't usually interact with hidden elements,
|
701
671
|
# but we can override this behavior by passing { visible: false }
|
702
|
-
field =
|
672
|
+
field = find_with_disabled(:field, label, :visible => false)
|
703
673
|
end
|
704
674
|
|
705
675
|
selector = "##{field['id']}"
|
@@ -711,20 +681,6 @@ Then /^the "([^\"]*)" field should( not)? be visible$/ do |label, hidden|
|
|
711
681
|
end
|
712
682
|
end.overridable
|
713
683
|
|
714
|
-
# Waits for the page to finish loading and AJAX requests to finish.
|
715
|
-
#
|
716
|
-
# More details [here](https://makandracards.com/makandra/12139-waiting-for-page-loads-and-ajax-requests-to-finish-with-capybara).
|
717
|
-
When /^I wait for the page to load$/ do
|
718
|
-
warn 'The step /^I wait for the page to load$/ is deprecated and scheduled for removal. Please see https://github.com/makandra/spreewald/issues/136'
|
719
|
-
if javascript_capable?
|
720
|
-
patiently do
|
721
|
-
# when no jQuery is loaded, we assume there are no pending AJAX requests
|
722
|
-
page.execute_script("return typeof jQuery === 'undefined' || $.active == 0;").should == true
|
723
|
-
end
|
724
|
-
end
|
725
|
-
page.has_content? ''
|
726
|
-
end.overridable
|
727
|
-
|
728
684
|
# Performs HTTP basic authentication with the given credentials and visits the given path.
|
729
685
|
#
|
730
686
|
# More details [here](https://makandracards.com/makandra/971-perform-http-basic-authentication-in-cucumber).
|
@@ -761,7 +717,7 @@ end.overridable
|
|
761
717
|
# Tests whether a select field is sorted. Uses Array#natural_sort, if defined;
|
762
718
|
# Array#sort else.
|
763
719
|
Then /^the "(.*?)" select should( not)? be sorted$/ do |label, negate|
|
764
|
-
select =
|
720
|
+
select = find_with_disabled(:field, label)
|
765
721
|
options = select.all('option').reject { |o| o.value.blank? }
|
766
722
|
option_texts = options.collect(&:text)
|
767
723
|
|
@@ -1,20 +1,29 @@
|
|
1
1
|
# coding: UTF-8
|
2
|
+
require "spreewald_support/mail_to_plaintext_converter"
|
3
|
+
require "forwardable"
|
2
4
|
|
3
5
|
class MailFinder
|
6
|
+
|
4
7
|
class << self
|
5
8
|
|
6
9
|
attr_accessor :user_identity
|
7
10
|
|
8
11
|
def find(raw_data, type = '')
|
9
|
-
header, body = raw_data.split(/\n\n/, 2) # 2: maximum number of fields
|
12
|
+
header, body = raw_data.split(/\n\n/, 2).map(&:strip_heredoc) # 2: maximum number of fields
|
10
13
|
conditions = {}
|
11
14
|
header.split("\n").each do |row|
|
12
15
|
if row.match(/^[A-Za-z\-]+: /i)
|
13
16
|
key, value = row.split(": ", 2)
|
17
|
+
raise Spreewald::UnsupportedEmailHeader.new(key, value) unless Spreewald::SUPPORTED_EMAIL_HEADERS.include? key.strip
|
14
18
|
conditions[key.strip.underscore.to_sym] = value.strip
|
15
19
|
end
|
16
20
|
end
|
17
21
|
|
22
|
+
# Interpret all lines as body if there are no header-link lines
|
23
|
+
if conditions.blank?
|
24
|
+
body = [header, body].join("\n\n")
|
25
|
+
end
|
26
|
+
|
18
27
|
filename_method = Rails::VERSION::MAJOR < 3 ? 'original_filename' : 'filename'
|
19
28
|
matching_header = ActionMailer::Base.deliveries.select do |mail|
|
20
29
|
[ conditions[:to].nil? || mail.to.include?(resolve_email conditions[:to]),
|
@@ -58,15 +67,7 @@ class MailFinder
|
|
58
67
|
end
|
59
68
|
|
60
69
|
def email_text_body(mail, type = '')
|
61
|
-
|
62
|
-
dom = Nokogiri::HTML(mail.html_part.body.to_s)
|
63
|
-
dom.at_css('body').text.gsub(/[\r\n]+/, "\n")
|
64
|
-
elsif mail.text_part && type != 'HTML'
|
65
|
-
mail.text_part.body.to_s
|
66
|
-
else
|
67
|
-
mail.body.to_s
|
68
|
-
end
|
69
|
-
body.gsub("\r\n", "\n") # The mail gem (>= 2.7.1) switched from \n to \r\n line breaks (LF to CRLF) in plain text mails.
|
70
|
+
Spreewald::MailToPlaintextConverter.new(mail, type).run
|
70
71
|
end
|
71
72
|
|
72
73
|
def show_mails(mails, only_header = false)
|
@@ -82,15 +83,13 @@ class MailFinder
|
|
82
83
|
end
|
83
84
|
|
84
85
|
def expected_body_regex(expected_body)
|
85
|
-
# To stay backwards-compatible, this will only check whether an email
|
86
|
-
# starts with the expected body.
|
87
86
|
expected = '\A\n' + Regexp.quote(expected_body.strip) + '\n\Z'
|
88
87
|
expected.gsub! '\n\*\n', '\n[\s\S]*\n'
|
89
88
|
expected.gsub! '\*\n', '.*\n'
|
90
89
|
expected.gsub! '\n\*', '\n.*'
|
91
90
|
|
92
91
|
expected.gsub! '\A\n', '\A'
|
93
|
-
expected.gsub! '\n\Z', '
|
92
|
+
expected.gsub! '\n\Z', '\Z'
|
94
93
|
|
95
94
|
Regexp.new(expected)
|
96
95
|
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
require 'nokogiri'
|
2
|
+
|
3
|
+
module Spreewald
|
4
|
+
class MailToPlaintextConverter
|
5
|
+
def initialize(mail, type = '')
|
6
|
+
@mail = mail
|
7
|
+
@type = type
|
8
|
+
end
|
9
|
+
|
10
|
+
def run
|
11
|
+
body = ''
|
12
|
+
if mail.multipart?
|
13
|
+
body = if mail.html_part && type != 'plain-text'
|
14
|
+
text_from_html(mail.html_part.body.to_s)
|
15
|
+
elsif mail.text_part && type != 'HTML'
|
16
|
+
mail.text_part.body.to_s
|
17
|
+
else
|
18
|
+
mail.body.to_s
|
19
|
+
end
|
20
|
+
else
|
21
|
+
if body_text_html?
|
22
|
+
body = text_from_html(mail.body.to_s)
|
23
|
+
else
|
24
|
+
body = mail.body.to_s
|
25
|
+
end
|
26
|
+
end
|
27
|
+
body.gsub("\r\n", "\n") # The mail gem (>= 2.7.1) switched from \n to \r\n line breaks (LF to CRLF) in plain text mails.
|
28
|
+
end
|
29
|
+
|
30
|
+
private
|
31
|
+
|
32
|
+
attr_reader :mail, :type
|
33
|
+
|
34
|
+
def body_text_html?
|
35
|
+
mail.body.to_s.include? "<html>"
|
36
|
+
end
|
37
|
+
|
38
|
+
def text_from_html(html)
|
39
|
+
Nokogiri::HTML(html).at_css('body').text.gsub(/[\r\n]+/, "\n")
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|