spreewald 4.2.2 → 4.3.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (83) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/test.yml +0 -5
  3. data/CHANGELOG.md +22 -0
  4. data/Gemfile.lock +3 -3
  5. data/Gemfile.ruby266.lock +59 -42
  6. data/Gemfile.ruby300.lock +37 -53
  7. data/README.md +10 -19
  8. data/Rakefile +5 -11
  9. data/examples/paths.rb +7 -0
  10. data/features/binary.feature +12 -8
  11. data/lib/spreewald/web_steps.rb +53 -50
  12. data/lib/spreewald_support/field_errors.rb +56 -0
  13. data/lib/spreewald_support/version.rb +1 -1
  14. data/support/step_definition.rb +11 -0
  15. data/support/step_manager.rb +1 -1
  16. data/tests/rails-6_capybara-3/Gemfile.lock +1 -1
  17. data/tests/rails-6_capybara-3/features/step_definitions/field_error_steps.rb +12 -0
  18. data/tests/shared/app/controllers/forms_controller.rb +11 -2
  19. data/tests/shared/app/controllers/static_pages_controller.rb +3 -0
  20. data/tests/shared/app/views/forms/invalid_bootstrap3_form.html.haml +16 -0
  21. data/tests/shared/app/views/forms/invalid_bootstrap4_form.html.haml +18 -0
  22. data/tests/shared/app/views/forms/invalid_custom_form.html.haml +19 -0
  23. data/tests/shared/app/views/forms/{invalid_form.html.haml → invalid_rails_form.html.haml} +0 -0
  24. data/tests/shared/app/views/static_pages/should_see.haml +7 -0
  25. data/tests/shared/config/routes.rb +5 -1
  26. data/tests/shared/features/shared/iframe_steps.feature +1 -2
  27. data/tests/shared/features/shared/web_steps.feature +72 -15
  28. metadata +15 -112
  29. data/Gemfile.ruby245 +0 -10
  30. data/Gemfile.ruby245.lock +0 -73
  31. data/tests/rails-4_capybara-2/Gemfile +0 -24
  32. data/tests/rails-4_capybara-2/Gemfile.lock +0 -230
  33. data/tests/rails-4_capybara-2/README.rdoc +0 -28
  34. data/tests/rails-4_capybara-2/Rakefile +0 -6
  35. data/tests/rails-4_capybara-2/app +0 -1
  36. data/tests/rails-4_capybara-2/bin/bundle +0 -3
  37. data/tests/rails-4_capybara-2/bin/rails +0 -4
  38. data/tests/rails-4_capybara-2/bin/rake +0 -4
  39. data/tests/rails-4_capybara-2/bin/setup +0 -29
  40. data/tests/rails-4_capybara-2/config/application.rb +0 -35
  41. data/tests/rails-4_capybara-2/config/boot.rb +0 -3
  42. data/tests/rails-4_capybara-2/config/cucumber.yml +0 -8
  43. data/tests/rails-4_capybara-2/config/database.yml +0 -18
  44. data/tests/rails-4_capybara-2/config/environment.rb +0 -5
  45. data/tests/rails-4_capybara-2/config/environments/development.rb +0 -28
  46. data/tests/rails-4_capybara-2/config/environments/test.rb +0 -42
  47. data/tests/rails-4_capybara-2/config/initializers/backtrace_silencers.rb +0 -7
  48. data/tests/rails-4_capybara-2/config/initializers/cookies_serializer.rb +0 -3
  49. data/tests/rails-4_capybara-2/config/initializers/filter_parameter_logging.rb +0 -4
  50. data/tests/rails-4_capybara-2/config/initializers/inflections.rb +0 -16
  51. data/tests/rails-4_capybara-2/config/initializers/mime_types.rb +0 -4
  52. data/tests/rails-4_capybara-2/config/initializers/session_store.rb +0 -3
  53. data/tests/rails-4_capybara-2/config/initializers/silence_deprecation_warnings.rb +0 -11
  54. data/tests/rails-4_capybara-2/config/initializers/to_time_preserves_timezone.rb +0 -10
  55. data/tests/rails-4_capybara-2/config/initializers/wrap_parameters.rb +0 -14
  56. data/tests/rails-4_capybara-2/config/locales/en.yml +0 -23
  57. data/tests/rails-4_capybara-2/config/routes.rb +0 -1
  58. data/tests/rails-4_capybara-2/config/secrets.yml +0 -22
  59. data/tests/rails-4_capybara-2/config.ru +0 -4
  60. data/tests/rails-4_capybara-2/db +0 -1
  61. data/tests/rails-4_capybara-2/features/browser_tab_steps.feature +0 -1
  62. data/tests/rails-4_capybara-2/features/development_steps.feature +0 -1
  63. data/tests/rails-4_capybara-2/features/email_steps.feature +0 -1
  64. data/tests/rails-4_capybara-2/features/iframe_steps.feature +0 -1
  65. data/tests/rails-4_capybara-2/features/overriding.feature +0 -1
  66. data/tests/rails-4_capybara-2/features/session_steps.feature +0 -1
  67. data/tests/rails-4_capybara-2/features/step_definitions/overriding_steps.rb +0 -1
  68. data/tests/rails-4_capybara-2/features/step_definitions/test_steps.rb +0 -1
  69. data/tests/rails-4_capybara-2/features/support/env.rb +0 -66
  70. data/tests/rails-4_capybara-2/features/support/paths.rb +0 -1
  71. data/tests/rails-4_capybara-2/features/support/selectors.rb +0 -1
  72. data/tests/rails-4_capybara-2/features/support/selenium.rb +0 -1
  73. data/tests/rails-4_capybara-2/features/table_steps.feature +0 -1
  74. data/tests/rails-4_capybara-2/features/time_steps.feature +0 -1
  75. data/tests/rails-4_capybara-2/features/web_steps.feature +0 -1
  76. data/tests/rails-4_capybara-2/lib/tasks/cucumber.rake +0 -65
  77. data/tests/rails-4_capybara-2/log/.keep +0 -0
  78. data/tests/rails-4_capybara-2/public/404.html +0 -67
  79. data/tests/rails-4_capybara-2/public/422.html +0 -67
  80. data/tests/rails-4_capybara-2/public/500.html +0 -66
  81. data/tests/rails-4_capybara-2/public/favicon.ico +0 -0
  82. data/tests/rails-4_capybara-2/public/fixture_files +0 -1
  83. data/tests/rails-4_capybara-2/script/cucumber +0 -10
@@ -31,6 +31,7 @@ require 'spreewald_support/custom_matchers'
31
31
  require 'spreewald_support/web_steps_helpers'
32
32
  require 'spreewald_support/driver_info'
33
33
  require 'spreewald_support/comparison'
34
+ require 'spreewald_support/field_errors'
34
35
  require 'uri'
35
36
  require 'cgi'
36
37
 
@@ -167,32 +168,23 @@ end.overridable
167
168
  # Checks that some text appears on the page
168
169
  #
169
170
  # Note that this does not detect if the text might be hidden via CSS
170
- Then /^(?:|I )should see "([^"]*)"$/ do |text|
171
+ Then /^(?:|I )should( not)? see "([^"]*)"$/ do |negate, text|
172
+ expectation = negate ? :not_to : :to
173
+
171
174
  patiently do
172
- expect(page).to have_content(text)
175
+ expect(page).send(expectation, have_content(text))
173
176
  end
174
177
  end.overridable
175
178
 
176
179
  # Checks that a regexp appears on the page
177
180
  #
178
181
  # Note that this does not detect if the text might be hidden via CSS
179
- Then /^(?:|I )should see \/(.*)\/$/ do |regexp|
182
+ Then /^(?:|I )should( not)? see \/(.*)\/$/ do |negate, regexp|
183
+ expectation = negate ? :not_to : :to
180
184
  regexp = Regexp.new(regexp)
181
- patiently do
182
- expect(page).to have_xpath('.//descendant-or-self::*', :text => regexp)
183
- end
184
- end.overridable
185
185
 
186
- Then /^(?:|I )should not see "([^"]*)"$/ do |text|
187
186
  patiently do
188
- expect(page).to have_no_content(text)
189
- end
190
- end.overridable
191
-
192
- Then /^(?:|I )should not see \/(.*)\/$/ do |regexp|
193
- patiently do
194
- regexp = Regexp.new(regexp)
195
- expect(page).to have_no_xpath('.//descendant-or-self::*', :text => regexp)
187
+ expect(page).send(expectation, have_xpath('.//descendant-or-self::*', text: regexp))
196
188
  end
197
189
  end.overridable
198
190
 
@@ -239,22 +231,20 @@ end.overridable(priority: -5) # priority lower than within
239
231
 
240
232
  # Like `Then I should see`, but with single instead of double quotes. In case
241
233
  # the expected string contains quotes as well.
242
- Then /^(?:|I )should see '([^']*)'$/ do |text|
234
+ Then /^(?:|I )should( not)? see '([^']*)'$/ do |negate, text|
235
+ expectation = negate ? :not_to : :to
236
+
243
237
  patiently do
244
- expect(page).to have_content(text)
238
+ expect(page).send(expectation, have_content(text))
245
239
  end
246
240
  end.overridable
247
241
 
248
242
  # Check that the raw HTML contains a string
249
- Then /^I should see "([^\"]*)" in the HTML$/ do |text|
250
- patiently do
251
- expect(page.body).to include(text)
252
- end
253
- end.overridable
243
+ Then /^I should( not)? see "([^\"]*)" in the HTML$/ do |negate, text|
244
+ expectation = negate ? :not_to : :to
254
245
 
255
- Then /^I should not see "([^\"]*)" in the HTML$/ do |text|
256
246
  patiently do
257
- expect(page.body).not_to include(text)
247
+ expect(page.body).send(expectation, include(text))
258
248
  end
259
249
  end.overridable
260
250
 
@@ -271,7 +261,7 @@ end.overridable
271
261
  # Then I should see the element ".panel"
272
262
  # Then I should not see an element ".sidebar"
273
263
  # Then I should not see the element ".sidebar"
274
- Then /^I should (not )?see (?:an|the) element "([^"]+)"$/ do |negate, selector|
264
+ Then /^I should( not)? see (?:an|the) element "([^"]+)"$/ do |negate, selector|
275
265
  expectation = negate ? :not_to : :to
276
266
  patiently do
277
267
  expect(page).send(expectation, have_css(selector))
@@ -286,7 +276,7 @@ end.overridable
286
276
  # Then I should see the element for the panel
287
277
  # Then I should not see an element for the sidebar
288
278
  # Then I should not see the element for the sidebar
289
- Then /^I should (not )?see (?:an|the) element for (.*?)$/ do |negate, locator|
279
+ Then /^I should( not)? see (?:an|the) element for (.*?)$/ do |negate, locator|
290
280
  expectation = negate ? :not_to : :to
291
281
  selector = _selector_for(locator)
292
282
  patiently do
@@ -325,7 +315,7 @@ Then /^I should( not)? see a link labeled "([^"]*)"$/ do |negate, label|
325
315
  end.overridable
326
316
 
327
317
  # Checks that an input field contains some value (allowing * as wildcard character)
328
- Then /^the "([^"]*)" field should (not )?contain "([^"]*)"$/ do |label, negate, expected_string|
318
+ Then /^the "([^"]*)" field should( not)? contain "([^"]*)"$/ do |label, negate, expected_string|
329
319
  patiently do
330
320
  field = find_with_disabled(:field, label)
331
321
  field_value = case field.tag_name
@@ -345,7 +335,7 @@ Then /^the "([^"]*)" field should (not )?contain "([^"]*)"$/ do |label, negate,
345
335
  end.overridable
346
336
 
347
337
  # Checks that a multiline textarea contains some value (allowing * as wildcard character)
348
- Then(/^the "(.*?)" field should (not )?contain:$/) do |label, negate, expected_string|
338
+ Then(/^the "(.*?)" field should( not)? contain:$/) do |label, negate, expected_string|
349
339
  patiently do
350
340
  field = find_with_disabled(:field, label)
351
341
  expect(field.value.chomp).send(negate ? :not_to : :to, contain_with_wildcards(expected_string))
@@ -370,17 +360,28 @@ end.overridable
370
360
  Then /^the "([^"]*)" field should have the error "([^"]*)"$/ do |field, error_message|
371
361
  patiently do
372
362
  element = find_with_disabled(:field, field)
373
- classes = element.find(:xpath, '..')[:class].split(' ')
363
+ field_error_finder = Spreewald::FieldErrorFinder.new(page, element)
364
+ expect(field_error_finder.error_present?).to eq true
374
365
 
375
- form_for_input = element.find(:xpath, 'ancestor::form[1]')
376
- using_formtastic = form_for_input && form_for_input.has_css?('.formtastic')
377
- error_class = using_formtastic ? 'error' : 'field_with_errors'
366
+ if Spreewald.field_error_class
367
+ unless Spreewald.error_message_xpath_selector
368
+ raise ArgumentError, 'No XPath was specified for the custom error message element.'
369
+ end
370
+ end
378
371
 
379
- expect(classes).to include(error_class)
372
+ error_message_element = case
373
+ when Spreewald.error_message_xpath_selector
374
+ element.find(:xpath, Spreewald.error_message_xpath_selector)
375
+ when field_error_finder.bootstrap3_error?
376
+ element.find(:xpath, 'parent::*/child::*[@class="help-block"]')
377
+ when field_error_finder.bootstrap45_error?
378
+ element.find(:xpath, 'parent::*/child::*[@class="invalid-feedback"]')
379
+ else
380
+ nil
381
+ end
380
382
 
381
- if using_formtastic
382
- error_paragraph = element.find(:xpath, '../*[@class="inline-errors"][1]')
383
- expect(error_paragraph).to have_content(error_message)
383
+ if error_message_element
384
+ expect(error_message_element).to have_content(error_message)
384
385
  else
385
386
  expect(page).to have_content("#{field.titlecase} #{error_message}")
386
387
  end
@@ -390,9 +391,10 @@ end.overridable
390
391
  Then /^the "([^\"]*)" field should( not)? have an error$/ do |label, negate|
391
392
  patiently do
392
393
  expectation = negate ? :not_to : :to
393
- field = find_with_disabled(:field, label)
394
- expect(field[:id]).to be_present # prevent bad CSS selector if field lacks id
395
- expect(page).send(expectation, have_css(".field_with_errors ##{field[:id]}"))
394
+ element = find_with_disabled(:field, label)
395
+ field_error_finder = Spreewald::FieldErrorFinder.new(page, element)
396
+
397
+ expect(field_error_finder.error_present?).public_send(expectation, (eq true))
396
398
  end
397
399
  end.overridable
398
400
 
@@ -648,18 +650,19 @@ end.overridable
648
650
 
649
651
  # Tests that an input, button, checkbox or radio button with the given label is disabled.
650
652
  Then /^the "([^\"]*)" (field|button|checkbox|radio button) should( not)? be disabled$/ do |label, kind, negate|
651
- element = if kind == 'button'
652
- find_with_disabled(:button, label)
653
- else
654
- find_with_disabled(:field, label)
655
- end
653
+ patiently do
654
+ element = if kind == 'button'
655
+ find_with_disabled(:button, label)
656
+ else
657
+ find_with_disabled(:field, label)
658
+ end
656
659
 
657
- if Spreewald::Comparison.compare_versions(Capybara::VERSION, :<, "2.1")
658
- expect(element[:disabled]).send(negate ? :to : :not_to, eq(nil))
659
- else
660
- expect(!!element.disabled?).to be !negate
660
+ if Spreewald::Comparison.compare_versions(Capybara::VERSION, :<, "2.1")
661
+ expect(element[:disabled]).send(negate ? :to : :not_to, eq(nil))
662
+ else
663
+ expect(!!element.disabled?).to be !negate
664
+ end
661
665
  end
662
-
663
666
  end.overridable
664
667
 
665
668
  # Tests that a field with the given label is visible.
@@ -0,0 +1,56 @@
1
+ require 'spreewald_support/driver_info'
2
+
3
+ module Spreewald
4
+ def self.field_error_class
5
+ self.instance_variable_get('@field_error_class')
6
+ end
7
+
8
+ def self.field_error_class=(error_class)
9
+ self.instance_variable_set('@field_error_class', error_class)
10
+ end
11
+
12
+ def self.error_message_xpath_selector
13
+ self.instance_variable_get('@error_message_xpath_selector')
14
+ end
15
+
16
+ # The XPath to the HTML-element that renders your validation/error message.
17
+ # The current node to start from is the input-field that is validated.
18
+ def self.error_message_xpath_selector=(message_selector)
19
+ self.instance_variable_set('@error_message_xpath_selector', message_selector)
20
+ end
21
+
22
+ class FieldErrorFinder
23
+ include Spreewald::DriverInfo
24
+
25
+ def initialize(page, element)
26
+ @page = page
27
+ @element = element
28
+ end
29
+
30
+ def error_present?
31
+ custom_error? || bootstrap3_error? || bootstrap45_error? || rails_error?
32
+ end
33
+
34
+ def custom_error?
35
+ Spreewald.field_error_class && @element.has_xpath?("ancestor-or-self::div[contains(@class, \"#{Spreewald.field_error_class}\")]")
36
+ end
37
+
38
+ def bootstrap3_error?
39
+ @element.has_xpath?('ancestor::div[@class="form-group has-error"]')
40
+ end
41
+
42
+ def bootstrap45_error?
43
+ element_classes = @element[:class] &.split(' ') || []
44
+ invalid_elements = if javascript_capable?
45
+ @page.all(':invalid') # Collect all invalid elements as Bootstrap 4 and 5 support client validation
46
+ end
47
+
48
+ element_classes.include?('is-invalid') || (invalid_elements && invalid_elements.include?(@element))
49
+ end
50
+
51
+ def rails_error?
52
+ parent_element_classes = @element.find(:xpath, '..')[:class] &.split(' ') || []
53
+ parent_element_classes.include?('field_with_errors')
54
+ end
55
+ end
56
+ end
@@ -1,3 +1,3 @@
1
1
  module Spreewald
2
- VERSION = '4.2.2'
2
+ VERSION = '4.3.4'
3
3
  end
@@ -33,6 +33,11 @@ class StepDefinition
33
33
  "#{kind} #{pretty_step}"
34
34
  end
35
35
 
36
+ def matches_search?(search)
37
+ regexp = Regexp.new(search)
38
+ step =~ regexp || matches_without_optional_negation?(regexp)
39
+ end
40
+
36
41
  private
37
42
 
38
43
  def pretty_step
@@ -45,4 +50,10 @@ class StepDefinition
45
50
  end
46
51
  end
47
52
 
53
+ def matches_without_optional_negation?(regexp)
54
+ without_negation = step.gsub('( not)?', '').gsub('(not )?', '')
55
+ with_negation = step.gsub('( not)?', ' not').gsub('(not )?', 'not ')
56
+ with_negation =~ regexp || without_negation =~ regexp
57
+ end
58
+
48
59
  end
@@ -17,7 +17,7 @@ class StepManager
17
17
  def steps(search = nil)
18
18
  step_files.collect(&:real_steps).flatten.
19
19
  sort_by { |step| [STEP_KINDS.index(step.kind), step.to_s.downcase] }.
20
- select { |definition| search.nil? or definition.step =~ Regexp.new(search) }
20
+ select { |definition| search.nil? || definition.matches_search?(search) }
21
21
  end
22
22
 
23
23
  private
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: ../..
3
3
  specs:
4
- spreewald (4.2.2)
4
+ spreewald (4.3.4)
5
5
  cucumber
6
6
  cucumber_priority (>= 0.3.0)
7
7
  rspec (>= 2.13.0)
@@ -0,0 +1,12 @@
1
+ Then /^I set the custom field error class to "([^"]+)"$/ do |error_class|
2
+ Spreewald.field_error_class = error_class
3
+ end
4
+
5
+ Then /^I set the custom error message xpath to "(.+)"$/ do |error_message_xpath|
6
+ Spreewald.error_message_xpath_selector = error_message_xpath
7
+ end
8
+
9
+ After('@field_errors') do
10
+ Spreewald.field_error_class = nil
11
+ Spreewald.error_message_xpath_selector = nil
12
+ end
@@ -15,7 +15,16 @@ class FormsController < ApplicationController
15
15
  def select_fields
16
16
  end
17
17
 
18
- def invalid_form
18
+ def invalid_rails_form
19
19
  end
20
20
 
21
- end
21
+ def invalid_bootstrap3_form
22
+ end
23
+
24
+ def invalid_bootstrap4_form
25
+ end
26
+
27
+ def invalid_custom_form
28
+ end
29
+
30
+ end
@@ -33,6 +33,9 @@ class StaticPagesController < ApplicationController
33
33
  def see_element
34
34
  end
35
35
 
36
+ def should_see
37
+ end
38
+
36
39
  def tab_1
37
40
  end
38
41
 
@@ -0,0 +1,16 @@
1
+ = form_tag do
2
+ .form-group.has-error
3
+ = label_tag 'text_control', 'A'
4
+ = text_field_tag 'text_control', 'Text control value'
5
+ .help-block 'A is invalid'
6
+ .form-group.has-error
7
+ = label_tag 'textarea_control_1', 'B'
8
+ = text_area_tag 'textarea_control_1', "Textarea control line 1\nTextarea control line 2\n"
9
+ .help-block 'B is invalid'
10
+ .form-group.has-error
11
+ = label_tag 'disabled_control', 'Disabled'
12
+ = text_field_tag 'disabled_control', "Disabled control value", disabled: true
13
+ .help-block 'Disabled is invalid'
14
+ .form-group
15
+ = label_tag 'textarea_control_2', 'C'
16
+ = text_area_tag 'textarea_control_2', "Textarea control line 1\nTextarea control line 2\n"
@@ -0,0 +1,18 @@
1
+ = form_tag do
2
+ .form-group
3
+ = label_tag 'text_control', 'A'
4
+ - # Client validation
5
+ = text_field_tag 'text_control', '', class: 'form-control', required: true
6
+ .invalid-feedback 'A is invalid'
7
+ .form-group
8
+ = label_tag 'textarea_control_1', 'B'
9
+ = text_area_tag 'textarea_control_1', '', class: 'form-control', required: true
10
+ .invalid-feedback 'B is invalid'
11
+ .form-group
12
+ = label_tag 'disabled_control', 'Disabled'
13
+ - # Server validation
14
+ = text_field_tag 'disabled_control', "Disabled control value", class: 'form-control is-invalid', disabled: true
15
+ .invalid-feedback 'Disabled is invalid'
16
+ .form-group
17
+ = label_tag 'textarea_control_2', 'C'
18
+ = text_area_tag 'textarea_control_2', "Textarea control line 1\nTextarea control line 2\n"
@@ -0,0 +1,19 @@
1
+ = form_tag do
2
+ .form-group.my-error
3
+ = label_tag 'text_control', 'A'
4
+ = text_field_tag 'text_control', 'Text control value'
5
+ %p.my-error-description
6
+ A is invalid
7
+ .form-group.my-error
8
+ = label_tag 'textarea_control_1', 'B'
9
+ = text_area_tag 'textarea_control_1', "Textarea control line 1\nTextarea control line 2\n"
10
+ %p.my-error-description
11
+ B is invalid
12
+ .form-group.my-error
13
+ = label_tag 'disabled_control', 'Disabled'
14
+ = text_field_tag 'disabled_control', "Disabled control value", disabled: true
15
+ %p.my-error-description
16
+ Disabled is invalid
17
+ .form-group
18
+ = label_tag 'textarea_control_2', 'C'
19
+ = text_area_tag 'textarea_control_2', "Textarea control line 1\nTextarea control line 2\n"
@@ -0,0 +1,7 @@
1
+ %p Normal text
2
+
3
+ %p Some text matching a regular expression
4
+
5
+ %p Some text with "quotes"
6
+
7
+ %p Some text in the <b>HTML</b>
@@ -23,7 +23,10 @@ Rails.application.routes.draw do
23
23
  get '/forms/form1', to: 'forms#form1'
24
24
  get '/forms/form2', to: 'forms#form2'
25
25
  get '/forms/select_fields', to: 'forms#select_fields'
26
- get '/forms/invalid_form', to: 'forms#invalid_form'
26
+ get '/forms/invalid_rails_form', to: 'forms#invalid_rails_form'
27
+ get '/forms/invalid_bootstrap3_form', to: 'forms#invalid_bootstrap3_form'
28
+ get '/forms/invalid_bootstrap4_form', to: 'forms#invalid_bootstrap4_form'
29
+ get '/forms/invalid_custom_form', to: 'forms#invalid_custom_form'
27
30
 
28
31
  get '/iframes/iframe_1_content', to: 'iframes#iframe_1_content'
29
32
  get '/iframes/iframe_2_content', to: 'iframes#iframe_2_content'
@@ -41,6 +44,7 @@ Rails.application.routes.draw do
41
44
  get '/static_pages/session_1', to: 'static_pages#session_1'
42
45
  get '/static_pages/session_2', to: 'static_pages#session_2'
43
46
  get '/static_pages/session_3', to: 'static_pages#session_3'
47
+ get '/static_pages/should_see', to: 'static_pages#should_see'
44
48
  get '/static_pages/tab_1', to: 'static_pages#tab_1'
45
49
  get '/static_pages/tab_2', to: 'static_pages#tab_2'
46
50
  get '/static_pages/tab_3', to: 'static_pages#tab_3'
@@ -1,7 +1,6 @@
1
1
  @javascript
2
2
  Feature: iframe Steps
3
3
 
4
- @not-capybara-2
5
4
  Scenario: Switch between iframes
6
5
  Given I go to "/static_pages/iframe"
7
6
  Then I should not see "Kiwi"
@@ -35,4 +34,4 @@ Feature: iframe Steps
35
34
  And I should see a table with the following rows inside the 2nd iframe:
36
35
  | Color | Fruit |
37
36
  | Red | Cherry |
38
- But I should not see "Content on main page" inside the 1st iframe
37
+ But I should not see "Content on main page" inside the 1st iframe
@@ -1,6 +1,6 @@
1
1
  Feature: Web steps
2
2
 
3
- Scenario: /^the "([^"]*)" field should (not )?contain "([^"]*)"$/
3
+ Scenario: /^the "([^"]*)" field should( not)? contain "([^"]*)"$/
4
4
  When I go to "/forms/form1"
5
5
  Then the "Text control" field should contain "Text control value"
6
6
  Then the "Text control" field should not contain "false text"
@@ -11,7 +11,7 @@ Feature: Web steps
11
11
  Then the "Empty control" field should contain ""
12
12
 
13
13
 
14
- Scenario: /^the "([^"]*)" field should (not )?contain:/
14
+ Scenario: /^the "([^"]*)" field should( not)? contain:/
15
15
  When I go to "/forms/form2"
16
16
  Then the "Text control" field should contain:
17
17
  """
@@ -31,20 +31,57 @@ Feature: Web steps
31
31
  """
32
32
  """
33
33
 
34
-
34
+ @javascript @field_errors
35
35
  Scenario: /^the "([^\"]*)" field should( not)? have an error$/
36
- When I go to "/forms/invalid_form"
36
+ When I go to "/forms/invalid_rails_form"
37
+ Then the "A" field should have an error
38
+ Then the "B" field should have an error
39
+ Then the "Disabled" field should have an error
40
+ Then the "C" field should not have an error
41
+
42
+ When I go to "/forms/invalid_bootstrap3_form"
37
43
  Then the "A" field should have an error
38
44
  Then the "B" field should have an error
39
45
  Then the "Disabled" field should have an error
40
46
  Then the "C" field should not have an error
41
47
 
48
+ When I go to "/forms/invalid_bootstrap4_form"
49
+ Then the "A" field should have an error
50
+ Then the "B" field should have an error
51
+ Then the "Disabled" field should have an error
52
+ Then the "C" field should not have an error
53
+
54
+ When I set the custom field error class to "my-error"
55
+ And I go to "/forms/invalid_custom_form"
56
+ Then the "A" field should have an error
57
+ Then the "B" field should have an error
58
+ Then the "Disabled" field should have an error
59
+ Then the "C" field should not have an error
60
+
61
+
62
+ @javascript @field_errors
42
63
  Scenario: /^the "([^"]*)" field should have the error "([^"]*)"$/
43
- When I go to "/forms/invalid_form"
64
+ When I go to "/forms/invalid_rails_form"
44
65
  Then the "A" field should have the error "is invalid"
45
66
  Then the "B" field should have the error "is invalid"
46
67
  Then the "Disabled" field should have the error "is invalid"
47
68
 
69
+ When I go to "/forms/invalid_bootstrap3_form"
70
+ Then the "A" field should have the error "is invalid"
71
+ Then the "B" field should have the error "is invalid"
72
+ Then the "Disabled" field should have the error "is invalid"
73
+
74
+ When I go to "/forms/invalid_bootstrap4_form"
75
+ Then the "A" field should have the error "is invalid"
76
+ Then the "B" field should have the error "is invalid"
77
+ Then the "Disabled" field should have the error "is invalid"
78
+
79
+ When I set the custom field error class to "my-error"
80
+ And I set the custom error message xpath to "parent::*/child::*[contains(@class, "my-error-description")]"
81
+ And I go to "/forms/invalid_custom_form"
82
+ Then the "A" field should have the error "is invalid"
83
+ Then the "B" field should have the error "is invalid"
84
+ Then the "Disabled" field should have the error "is invalid"
48
85
 
49
86
  Scenario: /^I should see a form with the following values:$/
50
87
  When I go to "/forms/form1"
@@ -200,7 +237,7 @@ Feature: Web steps
200
237
  And "div with style: display: none" should be hidden within ".container"
201
238
 
202
239
 
203
- Scenario: /^I should (not )?see (?:an|the) element "([^"]+)"$/
240
+ Scenario: /^I should( not)? see (?:an|the) element "([^"]+)"$/
204
241
  When I go to "/static_pages/see_element"
205
242
  Then I should see an element ".panel"
206
243
  And I should see the element ".panel"
@@ -210,7 +247,7 @@ Feature: Web steps
210
247
  But I should not see the element ".timeline"
211
248
 
212
249
 
213
- Scenario: /^I should (not )?see (?:an|the) element for (.*?)$/
250
+ Scenario: /^I should( not)? see (?:an|the) element for (.*?)$/
214
251
  When I go to "/static_pages/see_element"
215
252
  Then I should see an element for a panel
216
253
  And I should see the element for a panel
@@ -220,7 +257,26 @@ Feature: Web steps
220
257
  And I should not see the element for the timeline
221
258
 
222
259
 
223
- Scenario: /^((?:|I )should see "([^"]*)" within (.*[^:])$/
260
+ Scenario: /^((?:|I )should( not)? see "([^"]*)"$/
261
+ When I go to "/static_pages/should_see"
262
+ Then I should see "Normal text"
263
+ But I should not see "Some special text"
264
+
265
+
266
+ Scenario: /^((?:|I )should( not)? see '([^']*)'$/
267
+ When I go to "/static_pages/should_see"
268
+ Then I should see 'Some text with "quotes"'
269
+ But I should not see 'Some special text with "quotes"'
270
+
271
+
272
+ Scenario: /^I should( not)? see "([^\"]*)" in the HTML$/
273
+ When I go to "/static_pages/should_see"
274
+ Then I should see "Some text in the <b>HTML</b>" in the HTML
275
+ And I should see "Some text in the HTML"
276
+ But I should not see "Some text in the <strong>HTML</strong>" in the HTML
277
+
278
+
279
+ Scenario: /^((?:|I )should( not)? see "([^"]*)" within (.*[^:])$/
224
280
  When I go to "/static_pages/within"
225
281
  Then I should see "Role" within ".table"
226
282
  And I should see "Permissions" within a table
@@ -232,7 +288,8 @@ Feature: Web steps
232
288
  And I should not see "Outside Table" within a table
233
289
  But I should see "Outside Table"
234
290
 
235
- Scenario: /^(?:|I )should see \/([^\/]*)\/$/
291
+
292
+ Scenario: /^(?:|I )should( not)? see \/([^\/]*)\/$/
236
293
  When I go to "/static_pages/within"
237
294
  Then I should see /Shared Text/
238
295
  And I should see /Unique Text/
@@ -241,13 +298,8 @@ Feature: Web steps
241
298
  But I should not see /Nonsense/
242
299
  And I should not see /http://other-domain.com/
243
300
 
244
- # making sure it works with a within scope correctly when the same element is available outside
245
- Then I should not see /Outside Table/ within ".table"
246
- And I should not see /Outside Table/ within a table
247
- But I should see /Outside Table/
248
-
249
301
 
250
- Scenario: /^(?:|I )should see \/([^\/]*)\/ within (.*[^:])$/
302
+ Scenario: /^(?:|I )should( not)? see \/([^\/]*)\/ within (.*[^:])$/
251
303
  When I go to "/static_pages/within"
252
304
  Then I should see /Shared Text/ within ".scoped-element"
253
305
  And I should see /Shared Text/ within ".unrelated-element"
@@ -257,6 +309,11 @@ Feature: Web steps
257
309
  But I should not see /Unique Text/ within ".unrelated-element"
258
310
  And I should not see /http://other-domain.com/ within ".unrelated-element"
259
311
 
312
+ # making sure it works with a within scope correctly when the same element is available outside
313
+ Then I should not see /Outside Table/ within ".table"
314
+ And I should not see /Outside Table/ within a table
315
+ But I should see /Outside Table/
316
+
260
317
 
261
318
  Scenario: /^(.*) within (.*[^:])$/ with a Capybara::Node::Element
262
319
  When I go to "/static_pages/within"