spreewald 2.5.0 → 2.9.0
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +23 -2
- data/README.md +48 -41
- data/examples/paths.rb +36 -0
- data/examples/selectors.rb +28 -0
- data/lib/spreewald/all_steps.rb +4 -1
- data/lib/spreewald/email_steps.rb +87 -55
- data/lib/spreewald/session_steps.rb +18 -0
- data/lib/spreewald/time_steps.rb +102 -0
- data/lib/spreewald/timecop_steps.rb +6 -76
- data/lib/spreewald/web_steps.rb +24 -16
- data/lib/spreewald_support/mail_finder.rb +71 -41
- data/lib/spreewald_support/tolerance_for_selenium_sync_issues.rb +9 -3
- data/lib/spreewald_support/version.rb +1 -1
- data/lib/spreewald_support/web_steps_helpers.rb +17 -0
- data/support/step_definition_file.rb +2 -0
- data/tests/rails-3_capybara-1/Gemfile +2 -1
- data/tests/rails-3_capybara-1/Gemfile.lock +3 -1
- data/tests/rails-3_capybara-2/Gemfile +2 -1
- data/tests/rails-3_capybara-2/Gemfile.lock +3 -1
- data/tests/rails-4_capybara-3/Gemfile.lock +1 -1
- data/tests/rails-4_capybara-3/features/browser_tab_steps.feature +1 -0
- data/tests/rails-4_capybara-3/features/session_steps.feature +1 -0
- data/tests/rails-4_capybara-3/features/time_steps.feature +1 -0
- data/tests/rails-6_capybara-3/.ruby-version +1 -1
- data/tests/rails-6_capybara-3/Gemfile.lock +1 -1
- data/tests/rails-6_capybara-3/features/browser_tab_steps.feature +1 -0
- data/tests/rails-6_capybara-3/features/session_steps.feature +1 -0
- data/tests/rails-6_capybara-3/features/time_steps.feature +1 -0
- data/tests/shared/app/controllers/downloads_controller.rb +1 -1
- data/tests/shared/app/views/forms/disabled_elements.html.haml +18 -0
- data/tests/shared/app/views/mailer/html_email_with_links.haml +2 -0
- data/tests/shared/app/views/mailer/text_email_with_links.text.erb +1 -0
- data/tests/shared/app/views/static_pages/session_1.haml +1 -0
- data/tests/shared/app/views/static_pages/session_2.haml +1 -0
- data/tests/shared/app/views/static_pages/session_3.haml +1 -0
- data/tests/shared/app/views/static_pages/time.html.haml +2 -0
- data/tests/shared/config/routes.rb +4 -0
- data/tests/shared/features/shared/email_steps.feature +69 -5
- data/tests/shared/features/shared/session_steps.feature +29 -0
- data/tests/shared/features/shared/time_steps.feature +31 -0
- data/tests/shared/features/shared/web_steps.feature +8 -2
- metadata +29 -3
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 05a2f0dc08e4a044c5da09e999a488eeeab8d0ef21fd26fccf9306651e27d6ba
|
|
4
|
+
data.tar.gz: bc1753072141059f502b634a9a7347e63c602a072bc04f2a9aaf73a98ebd9eca
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 0b59488dcad4d0e94203fdc4b28463f69b6ccf93011f42c19dbc84582f0cca5e988a1b69c5f74520142198023dda9362e60c595d58a1bdc5abdde5b8a9e093ab
|
|
7
|
+
data.tar.gz: f324ae1ccd2ee7dbe97a71c4fbf614cd6888dd91846b42d2d60d900ae085413e6da55669d58ebe8275519354f10cf1a2826c5ef08323f30140d756572143dc76
|
data/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,27 @@ All notable changes to this project will be documented in this file.
|
|
|
3
3
|
|
|
4
4
|
This project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
|
|
5
5
|
|
|
6
|
+
## 2.9.0
|
|
7
|
+
- The step `an email should have been sent with:` does now support wildcards (`*` at the end of a line to ignore the rest of the line, `*` as single character in a line to ignore multiple lines). The step also has better error messages if an email could not be found.
|
|
8
|
+
- The step `show me the emails` got an option to display only the email headers. Additionally, a new step `show me the email( header)?s with:` has been created to only show a subset of all sent emails, with a syntax similar to `an email should have been sent with:`.
|
|
9
|
+
- The email steps `an email should have been sent (from ...) (to ...) (cc ...) ...`, `that email should( not)? have the following lines in the body` and `that email should have the following content in the body:` have been deprecated in favor of `an email should have been sent with:`.
|
|
10
|
+
|
|
11
|
+
## 2.8.0
|
|
12
|
+
- Add radio buttons to the `the "..." (field|button|checkbox|radio button) should( not)? be disabled` step.
|
|
13
|
+
|
|
14
|
+
## 2.7.2
|
|
15
|
+
- Fix the step `I follow the ... link in the email` if the email contains non-HTTP(S) links
|
|
16
|
+
|
|
17
|
+
## 2.7.1
|
|
18
|
+
- Support RFC-compliant encoding of filenames in `Content-Disposition` header (e.g. send_data), as provided by Rails 6.
|
|
19
|
+
|
|
20
|
+
## 2.7.0
|
|
21
|
+
- Add a step modifier to control different Capybara sessions: `... in the browser session "..."`. (see issue [#66](https://github.com/makandra/spreewald/issues/66))
|
|
22
|
+
|
|
23
|
+
## 2.6.0
|
|
24
|
+
- The time steps do now work with the time helpers in ActiveSupport 4.1+ if the timecop gem is not included in the bundle. Please note that the two approaches branch. While ActiveSupport will freeze the time, Timecop will keep it running.
|
|
25
|
+
- The steps in the file `spreewald/timecop.rb` file were moved to `spreewald/time.rb` and importing `spreewald/timecop` directly is deprecated now.
|
|
26
|
+
|
|
6
27
|
## 2.5.0
|
|
7
28
|
- Add a set of steps to control browser tabs (Selenium only):
|
|
8
29
|
* `I open ... in a new browser tab`
|
|
@@ -32,7 +53,7 @@ This project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html
|
|
|
32
53
|
|
|
33
54
|
## 2.2.4
|
|
34
55
|
- Fix "..." field should have the error "..." test by removing old should syntax
|
|
35
|
-
- Add single-line mail step to
|
|
56
|
+
- Add single-line mail step to README
|
|
36
57
|
|
|
37
58
|
## 2.2.3
|
|
38
59
|
- Fix 'the window should be titled' step - closes: [#102](https://github.com/makandra/spreewald/issues/102)
|
|
@@ -52,7 +73,7 @@ This project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html
|
|
|
52
73
|
|
|
53
74
|
## 2.2.0
|
|
54
75
|
- Add a new step `I should( not)? see a link labeled "STRING"`.
|
|
55
|
-
- Refer to Capybara 3's new flag `Capybara.default_normalize_ws = true` in the
|
|
76
|
+
- Refer to Capybara 3's new flag `Capybara.default_normalize_ws = true` in the README,
|
|
56
77
|
|
|
57
78
|
## 2.1.3
|
|
58
79
|
The `I should(not )? see /REGEXP/` step no longer refuses slashes as part of the regular expression. You can thus match full domains and more.
|
data/README.md
CHANGED
|
@@ -216,7 +216,7 @@ the step definitions.
|
|
|
216
216
|
* **When I clear my e?mails**
|
|
217
217
|
|
|
218
218
|
|
|
219
|
-
* **Then (an
|
|
219
|
+
* **Then (an?|no)( HTML| plain-text|) e?mail should have been sent with:**
|
|
220
220
|
|
|
221
221
|
Example:
|
|
222
222
|
|
|
@@ -225,58 +225,48 @@ the step definitions.
|
|
|
225
225
|
From: max.mustermann@example.com
|
|
226
226
|
Reply-To: mmuster@gmail.com
|
|
227
227
|
To: john.doe@example.com
|
|
228
|
+
CC: jane.doe@example.com
|
|
229
|
+
BCC: johnny.doe@example.com
|
|
228
230
|
Subject: The subject may contain "quotes"
|
|
229
|
-
Attachments:
|
|
231
|
+
Attachments: image.jpg, attachment.pdf
|
|
230
232
|
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
a prefix.
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
* **Then (an|no) e?mail should have been sent(( |and|with|from "..."|bcc "..."|cc "..."|to "..."|the subject "..."|the body "..."|the attachments "...")+)**
|
|
240
|
-
|
|
241
|
-
Example:
|
|
233
|
+
This is the message body. You can use * as a wildcard to omit the rest
|
|
234
|
+
of a line *
|
|
235
|
+
Or you can omit multiple lines if the asterisk is the only
|
|
236
|
+
character in a single line, like this:
|
|
237
|
+
*
|
|
242
238
|
|
|
243
|
-
|
|
239
|
+
"""
|
|
244
240
|
|
|
245
|
-
|
|
241
|
+
Because of backwards-compatibility, the body currently only has to be a prefix
|
|
242
|
+
of the real body. However, this is deprecated and will be removed in a future
|
|
243
|
+
version. Use wildcards instead.
|
|
244
|
+
You may skip lines in the header, of course.
|
|
246
245
|
|
|
247
246
|
|
|
248
247
|
* **When I follow the (first|second|third)? link in the e?mail**
|
|
249
248
|
|
|
249
|
+
Please note that this step will only follow HTTP and HTTPS links.
|
|
250
|
+
Other links (such as mailto: or ftp:// links) are ignored.
|
|
251
|
+
|
|
250
252
|
|
|
251
253
|
* **Then no e?mail should have been sent**
|
|
252
254
|
|
|
253
255
|
|
|
254
|
-
* **Then I should see "..." in the e?mail**
|
|
256
|
+
* **Then I should see "..." in the( HTML| plain-text|) e?mail**
|
|
255
257
|
|
|
256
258
|
Checks that the last sent email includes some text
|
|
257
259
|
|
|
258
260
|
|
|
259
|
-
* **Then show me the e?
|
|
260
|
-
|
|
261
|
-
Print all sent emails to STDOUT.
|
|
261
|
+
* **Then show me the e?mail( header)?s**
|
|
262
262
|
|
|
263
|
-
|
|
264
|
-
* **Then that e?mail should( not)? have the following lines in the body:**
|
|
265
|
-
|
|
266
|
-
Example:
|
|
267
|
-
|
|
268
|
-
And that mail should have the following lines in the body:
|
|
269
|
-
"""
|
|
270
|
-
All of these lines
|
|
271
|
-
need to be present
|
|
272
|
-
"""
|
|
273
|
-
|
|
274
|
-
You may skip lines, of course. Note that you may also omit text at the end of each line.
|
|
263
|
+
Print all sent emails to STDOUT (optionally only the headers).
|
|
275
264
|
|
|
276
265
|
|
|
277
|
-
* **Then
|
|
266
|
+
* **Then show me the e?mail( header)?s with:**
|
|
278
267
|
|
|
279
|
-
|
|
268
|
+
Print a subset of all sent emails to STDOUT
|
|
269
|
+
This uses the same syntax as `Then an email should have been sent with:`
|
|
280
270
|
|
|
281
271
|
|
|
282
272
|
### file_attachment_steps.rb
|
|
@@ -286,6 +276,18 @@ the step definitions.
|
|
|
286
276
|
This step is deprecated and will be removed from spreewald. If you still want to use it, copy the code to your project's own steps.
|
|
287
277
|
|
|
288
278
|
|
|
279
|
+
### session_steps.rb
|
|
280
|
+
|
|
281
|
+
* **When ... in the browser session "..."**
|
|
282
|
+
|
|
283
|
+
You can append `in the browser session "name"` to any other step to execute
|
|
284
|
+
the step in a different browser session.
|
|
285
|
+
|
|
286
|
+
You may need to update other steps to allow multiple sessions (e.g. your
|
|
287
|
+
authentication steps have to support multiple logged in users).
|
|
288
|
+
More details [here](https://makandracards.com/makandra/474480-how-to-make-a-cucumber-test-work-with-multiple-browser-sessions).
|
|
289
|
+
|
|
290
|
+
|
|
289
291
|
### table_steps.rb
|
|
290
292
|
|
|
291
293
|
* **Then I should( not)? see a table with (exactly )?the following rows( in any order)?:?**
|
|
@@ -295,11 +297,14 @@ the step definitions.
|
|
|
295
297
|
See [this article](https://makandracards.com/makandra/763-cucumber-step-to-match-table-rows-with-capybara) for details.
|
|
296
298
|
|
|
297
299
|
|
|
298
|
-
###
|
|
300
|
+
### time_steps.rb
|
|
299
301
|
|
|
300
|
-
Steps to travel through time
|
|
302
|
+
Steps to travel through time
|
|
301
303
|
|
|
302
|
-
|
|
304
|
+
This uses [Timecop](https://github.com/jtrupiano/timecop) or Active Support 4.1+ to stub Time.now / Time.current.
|
|
305
|
+
The user is responsible for including one of the two gems.
|
|
306
|
+
|
|
307
|
+
Please note that the two approaches branch. While ActiveSupport will freeze the time, Timecop will keep it running.
|
|
303
308
|
|
|
304
309
|
|
|
305
310
|
* **When the (date|time) is "?(\d{4}-\d{2}-\d{2}( \d{1,2}:\d{2})?)"?**
|
|
@@ -317,7 +322,7 @@ See [this article](https://makandracards.com/makandra/1222-useful-cucumber-steps
|
|
|
317
322
|
Given the time is 13:40
|
|
318
323
|
|
|
319
324
|
|
|
320
|
-
* **When it is (\d+|
|
|
325
|
+
* **When it is (\d+|an?|some|a few) (seconds?|minutes?|hours?|days?|weeks?|months?|years?) (later|earlier)**
|
|
321
326
|
|
|
322
327
|
Example:
|
|
323
328
|
|
|
@@ -325,6 +330,8 @@ See [this article](https://makandracards.com/makandra/1222-useful-cucumber-steps
|
|
|
325
330
|
When it is a few hours earlier
|
|
326
331
|
|
|
327
332
|
|
|
333
|
+
|
|
334
|
+
|
|
328
335
|
### web_steps.rb
|
|
329
336
|
|
|
330
337
|
Most of cucumber-rails' original web steps plus a few of our own.
|
|
@@ -353,7 +360,7 @@ deprecation notice. Decide for yourself whether you want to use them:
|
|
|
353
360
|
|
|
354
361
|
* **When ... within ...**
|
|
355
362
|
|
|
356
|
-
You can append `within [selector]` to any other web step.
|
|
363
|
+
You can append `within [selector]` to any other web step, even multiple times.
|
|
357
364
|
Be aware that within will only look at the first element that matches.
|
|
358
365
|
If this is a problem for you following links, you might want to have a look
|
|
359
366
|
at the 'When I follow "..." inside any "..."'-step.
|
|
@@ -663,7 +670,7 @@ deprecation notice. Decide for yourself whether you want to use them:
|
|
|
663
670
|
|
|
664
671
|
Then "Sponsor" should link to "http://makandra.com/"
|
|
665
672
|
|
|
666
|
-
Don't forget the trailing slash. Otherwise you'll get the error
|
|
673
|
+
Don't forget the trailing slash. Otherwise you'll get the error
|
|
667
674
|
expected: /http:\/\/makandra.com(\?[^\/]*)?$/
|
|
668
675
|
got: "http://makandra.com/" (using =~)
|
|
669
676
|
|
|
@@ -698,9 +705,9 @@ deprecation notice. Decide for yourself whether you want to use them:
|
|
|
698
705
|
* **When I enter "..." into the browser dialog**
|
|
699
706
|
|
|
700
707
|
|
|
701
|
-
* **Then the "..." (field|button|checkbox) should( not)? be disabled**
|
|
708
|
+
* **Then the "..." (field|button|checkbox|radio button) should( not)? be disabled**
|
|
702
709
|
|
|
703
|
-
Tests that an input, button or
|
|
710
|
+
Tests that an input, button, checkbox or radio button with the given label is disabled.
|
|
704
711
|
|
|
705
712
|
|
|
706
713
|
* **Then the "..." field should( not)? be visible**
|
data/examples/paths.rb
CHANGED
|
@@ -13,6 +13,30 @@ module NavigationHelpers
|
|
|
13
13
|
when /^the home\s?page$/
|
|
14
14
|
root_path
|
|
15
15
|
|
|
16
|
+
when /^the (page|form) for the (.*?) above$/
|
|
17
|
+
action_prose = Regexp.last_match(1)
|
|
18
|
+
model_prose = Regexp.last_match(2)
|
|
19
|
+
route = "#{(action_prose == 'form') ? 'edit_' : ''}#{model_prose_to_route_segment(model_prose)}_path"
|
|
20
|
+
model = model_prose_to_class(model_prose)
|
|
21
|
+
send(route, model.reorder(:id).last!)
|
|
22
|
+
|
|
23
|
+
when /^the (page|form) for the (.*?) "(.*?)"$/
|
|
24
|
+
action_prose = Regexp.last_match(1)
|
|
25
|
+
model_prose = Regexp.last_match(2)
|
|
26
|
+
identifier = Regexp.last_match(3)
|
|
27
|
+
path_to_show_or_edit(action_prose, model_prose, identifier)
|
|
28
|
+
|
|
29
|
+
when /^the (.*?) (page|form) for "(.*?)"$/
|
|
30
|
+
model_prose = Regexp.last_match(1)
|
|
31
|
+
action_prose = Regexp.last_match(2)
|
|
32
|
+
identifier = Regexp.last_match(3)
|
|
33
|
+
path_to_show_or_edit(action_prose, model_prose, identifier)
|
|
34
|
+
|
|
35
|
+
when /^the (.*?) form$/
|
|
36
|
+
model_prose = Regexp.last_match(1)
|
|
37
|
+
route = "new_#{model_prose_to_route_segment(model_prose)}_path"
|
|
38
|
+
send(route)
|
|
39
|
+
|
|
16
40
|
else
|
|
17
41
|
begin
|
|
18
42
|
page_name =~ /^the (.*) page$/
|
|
@@ -24,6 +48,18 @@ module NavigationHelpers
|
|
|
24
48
|
end
|
|
25
49
|
end
|
|
26
50
|
end
|
|
51
|
+
|
|
52
|
+
private
|
|
53
|
+
|
|
54
|
+
def model_prose_to_class(model_prose)
|
|
55
|
+
model_prose.gsub(' ', '_').classify.constantize
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def model_prose_to_route_segment(model_prose)
|
|
59
|
+
model_prose = model_prose.downcase
|
|
60
|
+
model_prose.gsub(/[\ \/]/, '_')
|
|
61
|
+
end
|
|
62
|
+
|
|
27
63
|
end
|
|
28
64
|
|
|
29
65
|
World(NavigationHelpers)
|
data/examples/selectors.rb
CHANGED
|
@@ -12,6 +12,27 @@ module HtmlSelectorsHelpers
|
|
|
12
12
|
when "the page"
|
|
13
13
|
"html > body"
|
|
14
14
|
|
|
15
|
+
# Auto-mapper for BEM classes and ARIA labels
|
|
16
|
+
#
|
|
17
|
+
# Usage examples:
|
|
18
|
+
# the main menu -> '.main-menu, [aria-label="main menu"]'
|
|
19
|
+
# the item box's header -> '.item-box--header, [aria-label="item box's header"]'
|
|
20
|
+
# the slider's item that is current -> '.slider--item.is-current, [aria-label="slider's item that is current"]'
|
|
21
|
+
when /^the (.*)$/
|
|
22
|
+
match = Regexp.last_match(1)
|
|
23
|
+
match =~ /^(.+?)(?:'s (.+?))?(?: that (.+))?$/
|
|
24
|
+
|
|
25
|
+
bem_selector = '.'
|
|
26
|
+
bem_selector << selectorify(Regexp.last_match(1))
|
|
27
|
+
bem_selector << '--' << selectorify(Regexp.last_match(2)) if Regexp.last_match(2)
|
|
28
|
+
bem_selector << '.' << selectorify(Regexp.last_match(3)) if Regexp.last_match(3)
|
|
29
|
+
|
|
30
|
+
aria_selector = '[aria-label="'
|
|
31
|
+
aria_selector << match.gsub('"', '\\"')
|
|
32
|
+
aria_selector << '"]'
|
|
33
|
+
|
|
34
|
+
[bem_selector, aria_selector].join(', ')
|
|
35
|
+
|
|
15
36
|
# Add more mappings here.
|
|
16
37
|
# Here is an example that pulls values out of the Regexp:
|
|
17
38
|
#
|
|
@@ -35,6 +56,13 @@ module HtmlSelectorsHelpers
|
|
|
35
56
|
"Now, go and add a mapping in #{__FILE__}"
|
|
36
57
|
end
|
|
37
58
|
end
|
|
59
|
+
|
|
60
|
+
private
|
|
61
|
+
|
|
62
|
+
def selectorify(string)
|
|
63
|
+
string.gsub(/ /, '-')
|
|
64
|
+
end
|
|
65
|
+
|
|
38
66
|
end
|
|
39
67
|
|
|
40
68
|
World(HtmlSelectorsHelpers)
|
data/lib/spreewald/all_steps.rb
CHANGED
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
# coding: UTF-8
|
|
2
2
|
require 'rspec/matchers'
|
|
3
3
|
|
|
4
|
+
ALREADY_LOADED_FILES = %w[all_steps timecop_steps]
|
|
5
|
+
|
|
4
6
|
Dir[File.join(File.dirname(__FILE__), '*_steps.rb')].each do |f|
|
|
5
7
|
name = File.basename(f, '.rb')
|
|
6
|
-
|
|
8
|
+
|
|
9
|
+
unless ALREADY_LOADED_FILES.include?(name)
|
|
7
10
|
require "spreewald/#{name}"
|
|
8
11
|
end
|
|
9
12
|
end
|
|
@@ -17,54 +17,81 @@ end.overridable
|
|
|
17
17
|
# From: max.mustermann@example.com
|
|
18
18
|
# Reply-To: mmuster@gmail.com
|
|
19
19
|
# To: john.doe@example.com
|
|
20
|
+
# CC: jane.doe@example.com
|
|
21
|
+
# BCC: johnny.doe@example.com
|
|
20
22
|
# Subject: The subject may contain "quotes"
|
|
21
|
-
# Attachments:
|
|
23
|
+
# Attachments: image.jpg, attachment.pdf
|
|
24
|
+
#
|
|
25
|
+
# This is the message body. You can use * as a wildcard to omit the rest
|
|
26
|
+
# of a line *
|
|
27
|
+
# Or you can omit multiple lines if the asterisk is the only
|
|
28
|
+
# character in a single line, like this:
|
|
29
|
+
# *
|
|
22
30
|
#
|
|
23
|
-
# Message body goes here.
|
|
24
31
|
# """
|
|
25
32
|
#
|
|
26
|
-
#
|
|
27
|
-
#
|
|
28
|
-
#
|
|
29
|
-
|
|
33
|
+
# Because of backwards-compatibility, the body currently only has to be a prefix
|
|
34
|
+
# of the real body. However, this is deprecated and will be removed in a future
|
|
35
|
+
# version. Use wildcards instead.
|
|
36
|
+
# You may skip lines in the header, of course.
|
|
37
|
+
Then /^(an?|no)( HTML| plain-text|) e?mail should have been sent with:$/ do |mode, type, raw_data|
|
|
30
38
|
patiently do
|
|
31
|
-
raw_data.strip
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
39
|
+
results = MailFinder.find(raw_data, type.strip)
|
|
40
|
+
|
|
41
|
+
if mode == 'no'
|
|
42
|
+
expect(results).to be_empty
|
|
43
|
+
else
|
|
44
|
+
if results.one?
|
|
45
|
+
@mail = results.mails[0]
|
|
46
|
+
elsif results.many?
|
|
47
|
+
warn <<-WARNING
|
|
48
|
+
#{results.size} emails were found with the following conditions.
|
|
49
|
+
You may want to make the description more precise or clear the emails in between.
|
|
50
|
+
#{raw_data}
|
|
51
|
+
WARNING
|
|
52
|
+
else
|
|
53
|
+
message = <<-ERROR
|
|
54
|
+
No matching mail was found. There were #{ActionMailer::Base.deliveries.size} mails in total.
|
|
55
|
+
#{results.matching_header.size} of those had matching headers.
|
|
56
|
+
ERROR
|
|
57
|
+
if results.matching_header.empty?
|
|
58
|
+
message << "Expected\n" + '-' * 80 + "\n"
|
|
59
|
+
message << raw_data.split(/\n\n/, 2)[0] # Show the expected header
|
|
60
|
+
message << "\n" + '-' * 80 + "\n\n"
|
|
61
|
+
message << MailFinder.show_mails(ActionMailer::Base.deliveries, true)
|
|
62
|
+
else
|
|
63
|
+
message << "\nTried to match #{results.body_regex.inspect} in the following mails:\n"
|
|
64
|
+
message << results.matching_header.map { |mail| MailFinder.email_text_body(mail, type.strip).strip.inspect }.join("\n")
|
|
65
|
+
message << "\n"
|
|
66
|
+
end
|
|
67
|
+
raise RSpec::Expectations::ExpectationNotMetError.new(message)
|
|
38
68
|
end
|
|
39
69
|
end
|
|
40
|
-
conditions[:body] = body if body
|
|
41
|
-
@mail = MailFinder.find(conditions)
|
|
42
|
-
expectation = mode == 'no' ? 'not_to' : 'to'
|
|
43
|
-
expect(@mail).send(expectation, be_present)
|
|
44
70
|
end
|
|
45
71
|
end.overridable
|
|
46
72
|
|
|
47
|
-
#
|
|
48
|
-
#
|
|
49
|
-
# Then an email should have been sent from "max.mustermann@example.com" to "john.doe@example.com" with bcc "john.wane@example.com" and with cc "foo@bar.com" and the subject "The subject" and the body "The body" and the attachments "attachment.pdf"
|
|
50
|
-
#
|
|
51
|
-
# You may skip parts, of course.
|
|
73
|
+
# nodoc (deprecated)
|
|
52
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:`"
|
|
53
76
|
patiently do
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
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
|
|
63
88
|
expectation = mode == 'no' ? 'not_to' : 'to'
|
|
64
89
|
expect(@mail).send(expectation, be_present)
|
|
65
90
|
end
|
|
66
91
|
end.overridable
|
|
67
92
|
|
|
93
|
+
# Please note that this step will only follow HTTP and HTTPS links.
|
|
94
|
+
# Other links (such as mailto: or ftp:// links) are ignored.
|
|
68
95
|
When /^I follow the (first|second|third)? ?link in the e?mail$/ do |index_in_words|
|
|
69
96
|
mail = @mail || ActionMailer::Base.deliveries.last
|
|
70
97
|
index = { nil => 0, 'first' => 0, 'second' => 1, 'third' => 2 }[index_in_words]
|
|
@@ -72,7 +99,7 @@ When /^I follow the (first|second|third)? ?link in the e?mail$/ do |index_in_wor
|
|
|
72
99
|
|
|
73
100
|
paths = if mail.html_part
|
|
74
101
|
dom = Nokogiri::HTML(mail.html_part.body.to_s)
|
|
75
|
-
(dom / 'a[href]').map { |a| a['href'].match(url_pattern)[1] }
|
|
102
|
+
(dom / 'a[href]').map { |a| a['href'].match(url_pattern) }.compact.map { |match| match[1] }
|
|
76
103
|
else
|
|
77
104
|
mail_body = MailFinder.email_text_body(mail).to_s
|
|
78
105
|
mail_body.scan(url_pattern).flatten(1)
|
|
@@ -86,34 +113,38 @@ Then /^no e?mail should have been sent$/ do
|
|
|
86
113
|
end.overridable
|
|
87
114
|
|
|
88
115
|
# Checks that the last sent email includes some text
|
|
89
|
-
Then /^I should see "([^\"]*)" in the e?mail$/ do |text|
|
|
90
|
-
expect(MailFinder.email_text_body(ActionMailer::Base.deliveries.last)).to include(text)
|
|
116
|
+
Then /^I should see "([^\"]*)" in the( HTML| plain-text|) e?mail$/ do |text, type|
|
|
117
|
+
expect(MailFinder.email_text_body(ActionMailer::Base.deliveries.last, type.strip)).to include(text)
|
|
118
|
+
end.overridable
|
|
119
|
+
|
|
120
|
+
# Print all sent emails to STDOUT (optionally only the headers).
|
|
121
|
+
Then /^show me the e?mail( header)?s$/ do |only_header|
|
|
122
|
+
if ActionMailer::Base.deliveries.empty?
|
|
123
|
+
puts MailFinder.show_mails(ActionMailer::Base.deliveries, only_header)
|
|
124
|
+
else
|
|
125
|
+
puts "No emails found" if ActionMailer::Base.deliveries.empty?
|
|
126
|
+
end
|
|
127
|
+
|
|
91
128
|
end.overridable
|
|
92
129
|
|
|
93
|
-
# Print all sent emails to STDOUT
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
print "-" * 80
|
|
130
|
+
# Print a subset of all sent emails to STDOUT
|
|
131
|
+
# This uses the same syntax as `Then an email should have been sent with:`
|
|
132
|
+
Then /^show me the e?mail( header)?s with:$/ do |only_header, raw_data|
|
|
133
|
+
results = MailFinder.find(raw_data)
|
|
134
|
+
if results.empty?
|
|
135
|
+
if results.matching_header.empty?
|
|
136
|
+
puts "There are no emails matching the given header."
|
|
137
|
+
else
|
|
138
|
+
puts "There are no emails matching the given header and body, but #{results.matching_header.size} matching only the header."
|
|
139
|
+
end
|
|
104
140
|
end
|
|
141
|
+
|
|
142
|
+
print MailFinder.show_mails(results.mails, only_header)
|
|
105
143
|
end.overridable
|
|
106
144
|
|
|
107
|
-
#
|
|
108
|
-
#
|
|
109
|
-
# And that mail should have the following lines in the body:
|
|
110
|
-
# """
|
|
111
|
-
# All of these lines
|
|
112
|
-
# need to be present
|
|
113
|
-
# """
|
|
114
|
-
#
|
|
115
|
-
# You may skip lines, of course. Note that you may also omit text at the end of each line.
|
|
145
|
+
# nodoc (deprecated)
|
|
116
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:$/."
|
|
117
148
|
expectation = negate ? 'not_to' : 'to'
|
|
118
149
|
mail = @mail || ActionMailer::Base.deliveries.last
|
|
119
150
|
email_text_body = MailFinder.email_text_body(mail)
|
|
@@ -123,8 +154,9 @@ Then /^that e?mail should( not)? have the following lines in the body:$/ do |neg
|
|
|
123
154
|
end
|
|
124
155
|
end.overridable
|
|
125
156
|
|
|
126
|
-
#
|
|
157
|
+
# nodoc (deprecated)
|
|
127
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:$/."
|
|
128
160
|
mail = @mail || ActionMailer::Base.deliveries.last
|
|
129
161
|
expect(MailFinder.email_text_body(mail)).to include(body.strip)
|
|
130
162
|
end.overridable
|