spreewald 2.7.0 → 2.99.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 02a43b32f16090f64a87cea6adc814baaceb590ef8388863224620f782565e25
4
- data.tar.gz: d474b73278a9b3c309c0898e83e1238715012f38cce70e3d8d13d77f9bcd8680
3
+ metadata.gz: 00603bf8e54cec9e5ceab37fec65ebc1ed2e0a83b753a2eb63b7c1481470cd0b
4
+ data.tar.gz: 713310e4fd479da1786534a0c6c33769483d87b6199e47ff2fa432f9333245a2
5
5
  SHA512:
6
- metadata.gz: c8c2ca98760710ddbda7a2aca39ec3208a1a01ab57e842a448dd14d5b3ba969834d6dc08638440e6979140f2fa22ef2ee152276ae2ae19363ef7294cad213cf5
7
- data.tar.gz: 9eea3e603ab1e9cb5d3346c948f09ee3b8c4bbfdd811b76eef3a0fc778c3015c48a85f97c31d6be8833f94e22d2d4ed159ab374b1aa345f51ffeba7d0f5fa23e
6
+ metadata.gz: 1ac94e470ce28516b0aa09dac529631a4208a4eb8dc8ae9959c6d8cbecc779521d74f569f5041a71a2bcd71a1a23a52b4e48a9decc991fed8e5db5e07c5a17a8
7
+ data.tar.gz: 9d66b30b3fa449c0e69f16b654ccacb4ee10349cf2eb34f328a08cf45cc5390fd73aad455d63232f75ca8df4e9e320763ef8aff39b711108d46dd553f2b2c25c
@@ -3,6 +3,31 @@ 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.99.1
7
+
8
+ - Reintroduced support for emails with CRLF line ending
9
+
10
+ ## 2.99.0
11
+ - The following steps were deprecated and will be removed in the upcoming major version:
12
+ - `/^the "([^"]*)" field should have no error$/` (see [#134](https://github.com/makandra/spreewald/issues/134))
13
+ - `/^I should get a text response$/` (see [#135](https://github.com/makandra/spreewald/issues/135))
14
+ - `/^I wait for the page to load$/` (see [#136](https://github.com/makandra/spreewald/issues/136))
15
+ - The step `and disabled` modifier of the step `/^the "([^"]*)" checkbox should( not)? be checked( and disabled)?$/` has been deprecated.
16
+
17
+ ## 2.9.0
18
+ - 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.
19
+ - 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:`.
20
+ - 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:`.
21
+
22
+ ## 2.8.0
23
+ - Add radio buttons to the `the "..." (field|button|checkbox|radio button) should( not)? be disabled` step.
24
+
25
+ ## 2.7.2
26
+ - Fix the step `I follow the ... link in the email` if the email contains non-HTTP(S) links
27
+
28
+ ## 2.7.1
29
+ - Support RFC-compliant encoding of filenames in `Content-Disposition` header (e.g. send_data), as provided by Rails 6.
30
+
6
31
  ## 2.7.0
7
32
  - Add a step modifier to control different Capybara sessions: `... in the browser session "..."`. (see issue [#66](https://github.com/makandra/spreewald/issues/66))
8
33
 
@@ -55,7 +80,7 @@ This project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html
55
80
  * It can now be composed with the 'within' step
56
81
  * It can now truly match negative numbers
57
82
  * It dropped the hidden dependency on the HTMLEntities gem
58
- * Fix URLs to the GitHub repository of Spreewald as part of the `_path_to` and `_selector_for` error handling. (see issue [#82](https://github.com/makandra/spreewald/issues/82))
83
+ * Fix URLs to the GitHub repository of Spreewald as part of the `_path_to` and `_selector_for` error handling. (see issue [#82](https://github.com/makandra/spreewald/issues/82))
59
84
 
60
85
  ## 2.2.0
61
86
  - Add a new step `I should( not)? see a link labeled "STRING"`.
@@ -88,7 +113,7 @@ The "it should work" step now takes an optional reason.
88
113
  The word "within" can now be used in arguments for other steps without causing errors ([Issue #53](https://github.com/makandra/spreewald/issues/80))
89
114
 
90
115
  ## 1.12.3
91
- Prevent wall of warnings when `Then console` is used multiple times in on test run ([issue](https://github.com/makandra/spreewald/issues/80))
116
+ Prevent wall of warnings when `Then console` is used multiple times in on test run ([issue](https://github.com/makandra/spreewald/issues/80))
92
117
 
93
118
  ## 1.12.2
94
119
  Always check the current driver by its class (see [issue](https://github.com/makandra/spreewald/issues/74))
@@ -102,4 +127,3 @@ Always check the current driver by its class (see [issue](https://github.com/mak
102
127
  ## 1.11.6 2018-08-28
103
128
  - Added CHANGELOG
104
129
  - Replaced `field_labeled` with `find_field` (https://github.com/teamcapybara/capybara/blob/master/History.md#removed)
105
-
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|no) e?mail should have been sent with:**
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
- Message body goes here.
232
- """
233
-
234
- You may skip lines in the header, of course. Note that the mail body is only checked for
235
- _inclusion_. That means you can only test a prefix of the body. The subject may also be
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
- 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"
239
+ """
244
240
 
245
- You may skip parts, of course.
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?mails**
261
+ * **Then show me the e?mail( header)?s**
260
262
 
261
- Print all sent emails to STDOUT.
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 that e?mail should have the following (|content in the )body:**
266
+ * **Then show me the e?mail( header)?s with:**
278
267
 
279
- Checks that the text should be included anywhere in the retrieved email body
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
@@ -680,7 +670,7 @@ deprecation notice. Decide for yourself whether you want to use them:
680
670
 
681
671
  Then "Sponsor" should link to "http://makandra.com/"
682
672
 
683
- 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
684
674
  expected: /http:\/\/makandra.com(\?[^\/]*)?$/
685
675
  got: "http://makandra.com/" (using =~)
686
676
 
@@ -715,9 +705,9 @@ deprecation notice. Decide for yourself whether you want to use them:
715
705
  * **When I enter "..." into the browser dialog**
716
706
 
717
707
 
718
- * **Then the "..." (field|button|checkbox) should( not)? be disabled**
708
+ * **Then the "..." (field|button|checkbox|radio button) should( not)? be disabled**
719
709
 
720
- Tests that an input, button or checkbox with the given label is disabled.
710
+ Tests that an input, button, checkbox or radio button with the given label is disabled.
721
711
 
722
712
 
723
713
  * **Then the "..." field should( not)? be visible**
@@ -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
- # You may skip lines in the header, of course. Note that the mail body is only checked for
27
- # _inclusion_. That means you can only test a prefix of the body. The subject may also be
28
- # a prefix.
29
- Then /^(an|no) e?mail should have been sent with:$/ do |mode, raw_data|
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
- header, body = raw_data.split(/\n\n/, 2) # 2: maximum number of fields
33
- conditions = {}
34
- header.split("\n").each do |row|
35
- if row.match(/^[a-z\-]+: /i)
36
- key, value = row.split(": ", 2)
37
- conditions[key.underscore.to_sym] = value
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
- # Example:
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
- conditions = {}
55
- conditions[:to] = $1 if query =~ /to "([^"]+)"/
56
- conditions[:Cc] = $1 if query =~ /cc "([^"]+)"/
57
- conditions[:bcc] = $1 if query =~ /bcc "([^"]+)"/
58
- conditions[:from] = $1 if query =~ /from "([^"]+)"/
59
- conditions[:subject] = $1 if query =~ /the subject "([^"]+)"/
60
- conditions[:body] = $1 if query =~ /the body "([^"]+)"/
61
- conditions[:attachments] = $1 if query =~ /the attachments "([^"]+)"/
62
- @mail = MailFinder.find(conditions)
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
- Then /^show me the e?mails$/ do
95
- ActionMailer::Base.deliveries.each_with_index do |mail, i|
96
- puts "E-Mail ##{i}"
97
- print "-" * 80
98
- puts [ "From: #{mail.from}",
99
- "To: #{mail.to}",
100
- "Subject: #{mail.subject}",
101
- "\n" + MailFinder.email_text_body(mail)
102
- ].join("\n")
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
- # Example:
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
- # Checks that the text should be included anywhere in the retrieved email body
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
@@ -397,6 +397,7 @@ Then /^the "([^\"]*)" field should( not)? have an error$/ do |label, negate|
397
397
  end.overridable
398
398
 
399
399
  Then /^the "([^"]*)" field should have no error$/ do |field|
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.'
400
401
  patiently do
401
402
  element = find_field(field)
402
403
  classes = element.find(:xpath, '..')[:class].split(' ')
@@ -408,6 +409,10 @@ end.overridable
408
409
  Then /^the "([^"]*)" checkbox should( not)? be checked( and disabled)?$/ do |label, negate, disabled|
409
410
  expectation = negate ? :not_to : :to
410
411
 
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
+
411
416
  patiently do
412
417
  field = if Spreewald::Comparison.compare_versions(Capybara::VERSION, :<, "2.1")
413
418
  find_field(label)
@@ -463,7 +468,18 @@ end.overridable
463
468
  #
464
469
  # Attention: Doesn't work with Selenium, see https://github.com/jnicklas/capybara#gotchas
465
470
  Then /^I should get a download with filename "([^\"]*)"$/ do |filename|
466
- expect(page.response_headers['Content-Disposition']).to match /filename="#{Regexp.escape(filename)}"(;|$)/
471
+ content_disposition = page.response_headers['Content-Disposition']
472
+ expect(content_disposition).to be_present
473
+
474
+ fields = content_disposition.split(/;\s*/)
475
+
476
+ # Rails 6+ encodes filenames as defined in https://tools.ietf.org/html/rfc5987.
477
+ # If available, we prefer the UTF-8 filename.
478
+ download_filename = [/^filename\*=UTF-8''(.+)/, /^filename="(.+?)"/].each do |regexp|
479
+ matched_filename = fields.map { |field| field.scan(regexp).flatten.first }.compact.first
480
+ break CGI.unescape(matched_filename) if matched_filename
481
+ end
482
+ expect(download_filename).to eq(filename)
467
483
  end.overridable
468
484
 
469
485
  # Checks that a certain option is selected for a text field
@@ -595,7 +611,7 @@ end.overridable(priority: -5) # priority lower than within
595
611
  #
596
612
  # Then "Sponsor" should link to "http://makandra.com/"
597
613
  #
598
- # Don't forget the trailing slash. Otherwise you'll get the error
614
+ # Don't forget the trailing slash. Otherwise you'll get the error
599
615
  # expected: /http:\/\/makandra.com(\?[^\/]*)?$/
600
616
  # got: "http://makandra.com/" (using =~)
601
617
  Then /^"([^"]*)" should link to "([^"]*)"$/ do |link_label, target|
@@ -607,6 +623,7 @@ end.overridable
607
623
 
608
624
  # Checks that the result has content type `text/plain`
609
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.'
610
627
  step 'I should get a response with content-type "text/plain"'
611
628
  end.overridable
612
629
 
@@ -659,23 +676,20 @@ When /^I enter "([^"]*)" into the browser dialog$/ do |text|
659
676
  end
660
677
  end.overridable
661
678
 
662
- # Tests that an input, button or checkbox with the given label is disabled.
663
- Then /^the "([^\"]*)" (field|button|checkbox) should( not)? be disabled$/ do |label, kind, negate|
679
+ # Tests that an input, button, checkbox or radio button with the given label is disabled.
680
+ Then /^the "([^\"]*)" (field|button|checkbox|radio button) should( not)? be disabled$/ do |label, kind, negate|
681
+ element = if kind == 'button'
682
+ find_with_disabled(:button, label)
683
+ else
684
+ find_with_disabled(:field, label)
685
+ end
686
+
664
687
  if Spreewald::Comparison.compare_versions(Capybara::VERSION, :<, "2.1")
665
- if kind == 'field' || kind == 'checkbox'
666
- element = find_field(label)
667
- else
668
- element = find_button(label)
669
- end
670
688
  expect(element[:disabled]).send(negate ? :to : :not_to, eq(nil))
671
689
  else
672
- if kind == 'field' || kind == 'checkbox'
673
- element = find_field(label, disabled: !negate)
674
- else
675
- element = find_button(label, disabled: !negate)
676
- end
677
- expect(element).to be_present
690
+ expect(!!element.disabled?).to be !negate
678
691
  end
692
+
679
693
  end.overridable
680
694
 
681
695
  # Tests that a field with the given label is visible.
@@ -701,6 +715,7 @@ end.overridable
701
715
  #
702
716
  # More details [here](https://makandracards.com/makandra/12139-waiting-for-page-loads-and-ajax-requests-to-finish-with-capybara).
703
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'
704
719
  if javascript_capable?
705
720
  patiently do
706
721
  # when no jQuery is loaded, we assume there are no pending AJAX requests
@@ -5,22 +5,38 @@ class MailFinder
5
5
 
6
6
  attr_accessor :user_identity
7
7
 
8
- def find(conditions)
8
+ def find(raw_data, type = '')
9
+ header, body = raw_data.split(/\n\n/, 2) # 2: maximum number of fields
10
+ conditions = {}
11
+ header.split("\n").each do |row|
12
+ if row.match(/^[A-Za-z\-]+: /i)
13
+ key, value = row.split(": ", 2)
14
+ conditions[key.strip.underscore.to_sym] = value.strip
15
+ end
16
+ end
17
+
9
18
  filename_method = Rails::VERSION::MAJOR < 3 ? 'original_filename' : 'filename'
10
- ActionMailer::Base.deliveries.detect do |mail|
11
- mail_body = email_text_body(mail)
19
+ matching_header = ActionMailer::Base.deliveries.select do |mail|
12
20
  [ conditions[:to].nil? || mail.to.include?(resolve_email conditions[:to]),
13
21
  conditions[:cc].nil? || mail.cc && mail.cc.include?(resolve_email conditions[:cc]),
14
22
  conditions[:bcc].nil? || mail.bcc && mail.bcc.include?(resolve_email conditions[:bcc]),
15
23
  conditions[:from].nil? || mail.from.include?(resolve_email conditions[:from]),
16
24
  conditions[:reply_to].nil? || mail.reply_to.include?(resolve_email conditions[:reply_to]),
17
25
  conditions[:subject].nil? || mail.subject.include?(conditions[:subject]),
18
- conditions[:body].nil? || mail_body.include?(conditions[:body]),
19
26
  conditions[:attachments].nil? || conditions[:attachments].split(/\s*,\s*/).sort == Array(mail.attachments).collect(&:"#{filename_method}").sort
20
27
  ].all?
21
- end.tap do |mail|
22
- log(mail)
23
28
  end
29
+
30
+ matching_mails = if body
31
+ body_regex = expected_body_regex(body)
32
+ matching_header.select do |mail|
33
+ body_regex =~ email_text_body(mail, type).strip
34
+ end
35
+ else
36
+ matching_header
37
+ end
38
+
39
+ Results.new(matching_mails, matching_header, body_regex)
24
40
  end
25
41
 
26
42
  def resolve_email(identity)
@@ -31,46 +47,61 @@ class MailFinder
31
47
  end
32
48
  end
33
49
 
34
- def log(mail)
35
- if mail.present?
36
- File.open("log/test_mails.log", "a") do |file|
37
- file << "From: #{mail.from}\n"
38
- file << "To: #{mail.to.join(', ')}\n" if mail.to
39
- file << "Subject: #{mail.subject}\n\n"
40
- file << email_text_body(mail)
41
- file << "\n-------------------------\n\n"
42
- end
43
- end
50
+ def header_representation(mail)
51
+ header = ""
52
+ header << "From: #{mail.from}\n"
53
+ header << "Reply-To: #{mail.reply_to.join(', ')}\n" if mail.reply_to
54
+ header << "To: #{mail.to.join(', ')}\n" if mail.to
55
+ header << "CC: #{mail.cc.join(', ')}\n" if mail.cc
56
+ header << "BCC: #{mail.bcc.join(', ')}\n" if mail.bcc
57
+ header << "Subject: #{mail.subject}\n"
44
58
  end
45
59
 
46
- def email_text_body(mail)
47
- body = if mail.parts.any?
48
- mail_bodies = mail.parts.map { |part|
49
- if part.header.to_s.include?('Quoted-printable')
50
- if Rails.version.starts_with?('2.3')
51
- part.body.to_s
52
- else
53
- part.decoded
54
- end
55
- elsif part.content_type.include?('multipart/alternative')
56
- part.parts.map(&:decoded)
57
- else
58
- part.decoded
59
- end
60
- }
61
- utf8_parts = mail_bodies.flatten.select{ |part|
62
- encoding = part.try(:encoding)
63
- encoding.nil? or # Ruby < 1.9.1
64
- encoding.name == 'UTF-8' # Ruby > 1.9.1
65
- }
66
- utf8_parts.join('\n')
67
- elsif mail.body.respond_to? :raw_source
68
- mail.body.raw_source
60
+ def email_text_body(mail, type = '')
61
+ body = if mail.html_part && type != 'plain-text'
62
+ dom = Nokogiri::HTML(mail.html_part.body.to_s)
63
+ dom.at_css('body').text.gsub(/\n\n/, "\n")
64
+ elsif mail.text_part && type != 'HTML'
65
+ mail.text_part.body.to_s
69
66
  else
70
- mail.body
67
+ mail.body.to_s
71
68
  end
72
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.
73
70
  end
74
71
 
72
+ def show_mails(mails, only_header = false)
73
+ message = ""
74
+ mails.each_with_index do |mail, i|
75
+ message << "E-Mail ##{i}\n"
76
+ message << "-" * 80 + "\n"
77
+ message << header_representation(mail)
78
+ message << "\n" + email_text_body(mail).strip + "\n" unless only_header
79
+ message << "-" * 80 + "\n\n"
80
+ end
81
+ message
82
+ end
83
+
84
+ 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
+ expected = '\A\n' + Regexp.quote(expected_body.strip) + '\n\Z'
88
+ expected.gsub! '\n\*\n', '\n[\s\S]*\n'
89
+ expected.gsub! '\*\n', '.*\n'
90
+
91
+ expected.gsub! '\A\n', '\A'
92
+ expected.gsub! '\n\Z', '' # Change '' to '\Z' to force that the whole body matches
93
+
94
+ Regexp.new(expected)
95
+ end
96
+
97
+ end
98
+ end
99
+
100
+ class MailFinder::Results < Struct.new(:mails, :matching_header, :body_regex)
101
+ extend Forwardable
102
+ delegate [:size, :one?, :empty?] => :mails
103
+
104
+ def many?
105
+ size > 1
75
106
  end
76
107
  end
@@ -1,3 +1,3 @@
1
1
  module Spreewald
2
- VERSION = '2.7.0'
2
+ VERSION = '2.99.1'
3
3
  end
@@ -1,3 +1,5 @@
1
+ require 'spreewald_support/comparison'
2
+
1
3
  module WebStepsHelpers
2
4
 
3
5
  def assert_visible(options)
@@ -8,6 +10,21 @@ module WebStepsHelpers
8
10
  visibility_test(options.merge(:expectation => :hidden))
9
11
  end
10
12
 
13
+ def find_with_disabled(*args, **options, &optional_filter_block)
14
+ if Spreewald::Comparison.compare_versions(Capybara::VERSION, :<, "2.0")
15
+ find(:xpath, XPath::HTML.send(args[0], args[1])) # Versions < 2.0 will find both enabled and disabled fields, nothing to do
16
+ elsif Spreewald::Comparison.compare_versions(Capybara::VERSION, :<, "2.6")
17
+ begin
18
+ find(*args, **options, disabled: false, &optional_filter_block)
19
+ rescue Capybara::ElementNotFound
20
+ find(*args, **options, disabled: true, &optional_filter_block)
21
+ end
22
+ else
23
+ options_with_disabled = { disabled: :all }.merge(options)
24
+ find(*args, **options_with_disabled, &optional_filter_block)
25
+ end
26
+ end
27
+
11
28
  private
12
29
 
13
30
  def visibility_test(options)
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: ../..
3
3
  specs:
4
- spreewald (2.7.0)
4
+ spreewald (2.99.1)
5
5
  cucumber
6
6
  cucumber_priority (>= 0.3.0)
7
7
  rspec (>= 2.13.0)
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: ../..
3
3
  specs:
4
- spreewald (2.7.0)
4
+ spreewald (2.99.1)
5
5
  cucumber
6
6
  cucumber_priority (>= 0.3.0)
7
7
  rspec (>= 2.13.0)
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: ../..
3
3
  specs:
4
- spreewald (2.7.0)
4
+ spreewald (2.99.1)
5
5
  cucumber
6
6
  cucumber_priority (>= 0.3.0)
7
7
  rspec (>= 2.13.0)
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: ../..
3
3
  specs:
4
- spreewald (2.7.0)
4
+ spreewald (2.99.1)
5
5
  cucumber
6
6
  cucumber_priority (>= 0.3.0)
7
7
  rspec (>= 2.13.0)
@@ -17,7 +17,15 @@ class SpreewaldMailer < ApplicationMailer
17
17
  :subject => SUBJECT
18
18
  )
19
19
  end
20
-
20
+
21
+ def email_crlf
22
+ email
23
+ end
24
+
25
+ def email_with_umlauts
26
+ email
27
+ end
28
+
21
29
  def html_email_with_links
22
30
  email
23
31
  end
@@ -1,7 +1,7 @@
1
1
  class DownloadsController < ApplicationController
2
2
 
3
3
  def spreadsheet
4
- send_data File.read("#{Rails.root}/public/fixture_files/spreadsheet.ods"), filename: 'test.ods'
4
+ send_data File.read("#{Rails.root}/public/fixture_files/spreadsheet.ods"), filename: 'test - example (today).ods'
5
5
  end
6
6
 
7
7
  end
@@ -9,6 +9,16 @@ class EmailsController < ApplicationController
9
9
  render_nothing
10
10
  end
11
11
 
12
+ def send_crlf_email
13
+ deliver :email_crlf
14
+ render_nothing
15
+ end
16
+
17
+ def send_email_with_umlauts
18
+ deliver :email_with_umlauts
19
+ render_nothing
20
+ end
21
+
12
22
  def send_html_email_with_links
13
23
  deliver :html_email_with_links
14
24
  render_nothing
@@ -21,6 +21,14 @@ class Mailer < ActionMailer::Base
21
21
  )
22
22
  end
23
23
 
24
+ def email_crlf
25
+ email
26
+ end
27
+
28
+ def email_with_umlauts
29
+ email
30
+ end
31
+
24
32
  def html_email_with_links
25
33
  email
26
34
  end
@@ -42,6 +50,10 @@ class Mailer < ActionMailer::Base
42
50
  body BODY
43
51
  end
44
52
 
53
+ def email_crlf
54
+ email
55
+ end
56
+
45
57
  def html_email_with_links
46
58
  email
47
59
  end
@@ -51,3 +51,21 @@
51
51
 
52
52
  = label_tag 'enabled_field_2', 'Enabled field #2'
53
53
  = text_field_tag 'enabled_field_2', 'value'
54
+
55
+ -# radio buttons
56
+ = form_tag do
57
+ - selected = false
58
+ = label_tag 'disabled_radio_1', 'Disabled radio button #1'
59
+ = radio_button_tag 'disabled_radio', '1', selected, disabled: true
60
+
61
+ = label_tag 'disabled_radio_2', 'Disabled radio button #2'
62
+ = radio_button_tag 'disabled_radio', '2', selected, disabled: ''
63
+
64
+ = label_tag 'disabled_radio_3', 'Disabled radio button #3'
65
+ = radio_button_tag 'disabled_radio', '3', selected, disabled: 'aaa'
66
+
67
+ = label_tag 'enabled_radio_1', 'Enabled radio button #1'
68
+ = radio_button_tag 'enabled_radio', '1', selected, disabled: false
69
+
70
+ = label_tag 'enabled_radio_2', 'Enabled radio button #2'
71
+ = radio_button_tag 'enabled_radio', '2', selected
@@ -0,0 +1,5 @@
1
+ Body
2
+ with
3
+ CRLF
4
+ line
5
+ breaks
@@ -3,4 +3,6 @@
3
3
  %body
4
4
  %img(src="https://www.example.com/image.png")
5
5
  %a(href="https://www.example.com/static_pages/link_target") Click me
6
+ %a(href="mailto:user@example.com") mailto links should be ignored
7
+ %a(href="ftp://ftp.example.com/") FTP links are also ignored
6
8
  %a(href="https://www.example.com/static_pages/second_link_target") Other link
@@ -1,6 +1,7 @@
1
1
  Hello!
2
2
 
3
3
  First link: https://www.example.com/static_pages/link_target
4
+ Ignored link: ftp://ftp.example.com/
4
5
  Second link: https://www.example.com/static_pages/second_link_target
5
6
 
6
7
  Bye!
@@ -6,6 +6,8 @@ Rails.application.routes.draw do
6
6
 
7
7
  get '/emails/do_nothing', to: 'emails#do_nothing'
8
8
  get '/emails/send_email', to: 'emails#send_email'
9
+ get '/emails/send_crlf_email', to: 'emails#send_crlf_email'
10
+ get '/emails/send_email_with_umlauts', to: 'emails#send_email_with_umlauts'
9
11
  get '/emails/send_html_email_with_links', to: 'emails#send_html_email_with_links'
10
12
  get '/emails/send_text_email_with_links', to: 'emails#send_text_email_with_links'
11
13
 
@@ -1,10 +1,10 @@
1
1
  Feature: Test Spreewald's email steps
2
-
2
+
3
3
  Scenario: /^no e?mail should have been sent$/
4
4
  When I go to "/emails/do_nothing"
5
5
  Then the following step should succeed:
6
6
  | no email should have been sent |
7
-
7
+
8
8
  When I go to "/emails/send_email"
9
9
  Then the following step should fail:
10
10
  | no email should have been sent |
@@ -50,6 +50,53 @@ Feature: Test Spreewald's email steps
50
50
  '''
51
51
  """
52
52
 
53
+ # Test with end-of-line wildcards
54
+ Then the following multiline step should succeed:
55
+ """
56
+ Then an email should have been sent with:
57
+ '''
58
+ From: from@example.com
59
+ Reply-To: reply-to@example.com
60
+ To: to@example.com
61
+ Subject: SUBJECT
62
+
63
+ Bo*
64
+ wi*
65
+ li*
66
+ br*
67
+ '''
68
+ """
69
+
70
+ # Test with multiple-line wildcards
71
+ Then the following multiline step should succeed:
72
+ """
73
+ Then an email should have been sent with:
74
+ '''
75
+ From: from@example.com
76
+ Reply-To: reply-to@example.com
77
+ To: to@example.com
78
+ Subject: SUBJECT
79
+
80
+ Body
81
+ *
82
+ breaks
83
+ '''
84
+ """
85
+
86
+ # Test with the whole body being a multiple-line wildcard
87
+ Then the following multiline step should succeed:
88
+ """
89
+ Then an email should have been sent with:
90
+ '''
91
+ From: from@example.com
92
+ Reply-To: reply-to@example.com
93
+ To: to@example.com
94
+ Subject: SUBJECT
95
+
96
+ *
97
+ '''
98
+ """
99
+
53
100
  # Test with incorrect From header
54
101
  Then the following multiline step should fail:
55
102
  """
@@ -148,12 +195,29 @@ Feature: Test Spreewald's email steps
148
195
  with
149
196
  line
150
197
  breaks
151
-
198
+
152
199
  MORE-BODY
153
200
  '''
154
201
  """
155
202
 
156
- Scenario: /^(an|no) e?mail should have been sent((?: |and|with|from "[^"]+"|bcc "[^"]+"|cc "[^"]+"|to "[^"]+"|the subject "[^"]+"|the body "[^"]+"|the attachments "[^"]+")+)$/
203
+ # Test body with wildcard not at the end of a line
204
+ Then the following multiline step should fail:
205
+ """
206
+ Then an email should have been sent with:
207
+ '''
208
+ From: from@example.com
209
+ Reply-To: reply-to@example.com
210
+ To: to@example.com
211
+ Subject: SUBJECT
212
+
213
+ Body
214
+ *th
215
+ line
216
+ break
217
+ '''
218
+ """
219
+
220
+ Scenario: Scenario: /^(an|no) e?mail should have been sent((?: |and|with|from "[^"]+"|bcc "[^"]+"|cc "[^"]+"|to "[^"]+"|the subject "[^"]+"|the body "[^"]+"|the attachments "[^"]+")+)$/
157
221
  When I go to "/emails/send_email"
158
222
 
159
223
  # Test with correct conditions
@@ -181,7 +245,7 @@ Feature: Test Spreewald's email steps
181
245
  '''
182
246
  """
183
247
 
184
- # Test with wrong body lines
248
+ # Test with wrong body lines
185
249
  Then the following multiline step should fail:
186
250
  """
187
251
  Then that email should have the following lines in the body:
@@ -215,6 +279,41 @@ Feature: Test Spreewald's email steps
215
279
  '''
216
280
  """
217
281
 
282
+ When I clear my emails
283
+ And I go to "/emails/send_crlf_email"
284
+
285
+ Then the following multiline step should succeed:
286
+ """
287
+ Then an email should have been sent with:
288
+ '''
289
+ From: from@example.com
290
+ Reply-To: reply-to@example.com
291
+ To: to@example.com
292
+ Subject: SUBJECT
293
+
294
+ Body
295
+ with
296
+ CRLF
297
+ line
298
+ breaks
299
+ '''
300
+ """
301
+
302
+ When I clear my emails
303
+ And I go to "/emails/send_email_with_umlauts"
304
+
305
+ Then the following multiline step should succeed:
306
+ """
307
+ Then an email should have been sent with:
308
+ '''
309
+ From: from@example.com
310
+ Reply-To: reply-to@example.com
311
+ To: to@example.com
312
+ Subject: SUBJECT
313
+
314
+ Viele Grüße
315
+ '''
316
+ """
218
317
 
219
318
  Scenario: /^I follow the (first|second|third)? ?link in the e?mail$/ (HTML e-mail body)
220
319
  When I go to "/emails/send_html_email_with_links"
@@ -85,7 +85,7 @@ Feature: Web steps
85
85
  Scenario: /^I go back$/
86
86
  Given I go to "/static_pages/link_to_home"
87
87
  And I follow "Home"
88
-
88
+
89
89
  When I go back
90
90
  Then I should be on "/static_pages/link_to_home"
91
91
 
@@ -290,7 +290,7 @@ Feature: Web steps
290
290
 
291
291
  Scenario: /^I should get a download with filename "([^\"]*)"$/
292
292
  When I go to "/downloads/spreadsheet"
293
- Then I should get a download with filename "test.ods"
293
+ Then I should get a download with filename "test - example (today).ods"
294
294
 
295
295
 
296
296
  Scenario: /^I should( not)? see a link labeled "([^"]*)"$/
@@ -341,6 +341,12 @@ Feature: Web steps
341
341
  But the "Enabled field #1" field should not be disabled
342
342
  And the "Enabled field #2" field should not be disabled
343
343
 
344
+ # radio buttons
345
+ And the "Disabled radio button #1" radio button should be disabled
346
+ And the "Disabled radio button #2" radio button should be disabled
347
+ And the "Disabled radio button #3" radio button should be disabled
348
+ But the "Enabled radio button #1" radio button should not be disabled
349
+ And the "Enabled radio button #2" radio button should not be disabled
344
350
 
345
351
  Scenario: /^the window should be titled "([^"]*)"$/
346
352
  When I go to "/static_pages/home"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: spreewald
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.7.0
4
+ version: 2.99.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tobias Kraze
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-08-12 00:00:00.000000000 Z
11
+ date: 2020-11-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: cucumber
@@ -348,6 +348,8 @@ files:
348
348
  - tests/shared/app/views/layouts/mailer.html.erb
349
349
  - tests/shared/app/views/layouts/mailer.text.erb
350
350
  - tests/shared/app/views/mailer/email.text.erb
351
+ - tests/shared/app/views/mailer/email_crlf.text.erb
352
+ - tests/shared/app/views/mailer/email_with_umlauts.text.erb
351
353
  - tests/shared/app/views/mailer/html_email_with_links.haml
352
354
  - tests/shared/app/views/mailer/text_email_with_links.text.erb
353
355
  - tests/shared/app/views/spreewald_mailer
@@ -410,7 +412,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
410
412
  - !ruby/object:Gem::Version
411
413
  version: '0'
412
414
  requirements: []
413
- rubygems_version: 3.1.2
415
+ rubygems_version: 3.0.3
414
416
  signing_key:
415
417
  specification_version: 4
416
418
  summary: Collection of useful cucumber steps.
@@ -579,6 +581,8 @@ test_files:
579
581
  - tests/shared/app/views/layouts/mailer.html.erb
580
582
  - tests/shared/app/views/layouts/mailer.text.erb
581
583
  - tests/shared/app/views/mailer/email.text.erb
584
+ - tests/shared/app/views/mailer/email_crlf.text.erb
585
+ - tests/shared/app/views/mailer/email_with_umlauts.text.erb
582
586
  - tests/shared/app/views/mailer/html_email_with_links.haml
583
587
  - tests/shared/app/views/mailer/text_email_with_links.text.erb
584
588
  - tests/shared/app/views/spreewald_mailer