turnip-extra_steps 0.1.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.
@@ -0,0 +1,79 @@
1
+ # coding: UTF-8
2
+
3
+
4
+ # Steps to travel through time using [Timecop](https://github.com/jtrupiano/timecop).
5
+ #
6
+ # See [this article](https://makandracards.com/makandra/1222-useful-cucumber-steps-to-travel-through-time-with-timecop) for details.
7
+ # FILE_COMMENT_END
8
+
9
+
10
+ if defined?(Timecop)
11
+
12
+ module TimecopHarness
13
+
14
+ # When you have to make your rails app time zone aware you have to go 100%
15
+ # otherwise you are better off ignoring time zones at all.
16
+ # https://makandracards.com/makandra/8723-guide-to-localizing-a-rails-application
17
+
18
+ def use_timezones?
19
+ active_record_loaded = defined?(ActiveRecord::Base)
20
+ (!active_record_loaded || ActiveRecord::Base.default_timezone != :local) && Time.zone
21
+ end
22
+
23
+ def parse_time(str)
24
+ if use_timezones?
25
+ Time.zone.parse(str)
26
+ else
27
+ Time.parse(str)
28
+ end
29
+ end
30
+
31
+ def current_time
32
+ if use_timezones?
33
+ Time.current
34
+ else
35
+ Time.now
36
+ end
37
+ end
38
+
39
+ end
40
+
41
+ World(TimecopHarness)
42
+
43
+ # Example:
44
+ #
45
+ # Given the date is 2012-02-10
46
+ # Given the time is 2012-02-10 13:40
47
+ When /^the (?:date|time) is "?(\d{4}-\d{2}-\d{2}(?: \d{1,2}:\d{2})?)"?$/ do |time|
48
+ Timecop.travel(parse_time(time))
49
+ end
50
+
51
+ # Example:
52
+ #
53
+ # Given the time is 13:40
54
+ When /^the time is "?(\d{1,2}:\d{2})"?$/ do |time_without_date|
55
+ Timecop.travel(parse_time(time_without_date)) # date will be today
56
+ end
57
+
58
+ # Example:
59
+ #
60
+ # When it is 10 minutes later
61
+ # When it is a few hours earlier
62
+ When /^it is (\d+|a|some|a few) (seconds?|minutes?|hours?|days?|weeks?|months?|years?) (later|earlier)$/ do |amount, unit, direction|
63
+ amount = case amount
64
+ when 'a'
65
+ 1
66
+ when 'some', 'a few'
67
+ 10
68
+ else
69
+ amount.to_i
70
+ end
71
+ amount = -amount if direction == 'earlier'
72
+ Timecop.travel(current_time + amount.send(unit))
73
+ end
74
+
75
+ After do
76
+ Timecop.return
77
+ end
78
+
79
+ end
@@ -0,0 +1,5 @@
1
+ module Turnip
2
+ module ExtraSteps
3
+ VERSION = "0.1.0"
4
+ end
5
+ end
@@ -0,0 +1,760 @@
1
+ # coding: UTF-8
2
+
3
+ # Most of cucumber-rails' original web steps plus a few of our own.
4
+ #
5
+ # Note that cucumber-rails deprecated all its steps quite a while ago with the following
6
+ # deprecation notice. Decide for yourself whether you want to use them:
7
+ #
8
+ # > This file was generated by Cucumber-Rails and is only here to get you a head start
9
+ # > These step definitions are thin wrappers around the Capybara/Webrat API that lets you
10
+ # > visit pages, interact with widgets and make assertions about page content.
11
+ #
12
+ # > If you use these step definitions as basis for your features you will quickly end up
13
+ # > with features that are:
14
+ #
15
+ # > * Hard to maintain
16
+ # > * Verbose to read
17
+ #
18
+ # > A much better approach is to write your own higher level step definitions, following
19
+ # > the advice in the following blog posts:
20
+ #
21
+ # > * http://benmabey.com/2008/05/19/imperative-vs-declarative-scenarios-in-user-stories.html
22
+ # > * http://dannorth.net/2011/01/31/whose-domain-is-it-anyway/
23
+ # > * http://elabs.se/blog/15-you-re-cuking-it-wrong
24
+ #
25
+ # FILE_COMMENT_END
26
+
27
+ require 'turnip/extra_steps/support/tolerance_for_selenium_sync_issues'
28
+ require 'turnip/extra_steps/support/path_selector_fallbacks'
29
+ require 'turnip/extra_steps/support/step_fallback'
30
+ require 'turnip/extra_steps/support/custom_matchers'
31
+ require 'turnip/extra_steps/support/web_steps_helpers'
32
+ require 'uri'
33
+ require 'cgi'
34
+
35
+
36
+ # You can append `within [selector]` to any other web step
37
+ #
38
+ # Example:
39
+ #
40
+ # Then I should see "some text" within ".page_body"
41
+ #When /^(.*) within (.*[^:])$/ do |nested_step, parent|
42
+ step "Then I should see :text within :parent" do |text, parent|
43
+ with_scope(parent) { step(nested_step) }
44
+ end
45
+
46
+ # nodoc
47
+ #When /^(.*) within (.*[^:]):$/ do |nested_step, parent, table_or_string|
48
+ #with_scope(parent) { step("#{nested_step}:", table_or_string) }
49
+ #end
50
+
51
+ #Given /^(?:|I )am on (.+)$/ do |page_name|
52
+ step "I am on :page_name" do |page_name|
53
+ visit _path_to(page_name)
54
+ end
55
+
56
+ #When /^(?:|I )go to (.+)$/ do |page_name|
57
+ step "I go to :page_name" do |page_name|
58
+ visit _path_to(page_name)
59
+ end
60
+
61
+ #Then /^(?:|I )should be on (.+)$/ do |page_name|
62
+ step "I should be on :page_name" do |page_name|
63
+ patiently do
64
+ fragment = URI.parse(current_url).fragment
65
+ fragment.sub!(/[#?].*/, '') if fragment # most js frameworks will usually use ? and # for params, we dont care about those
66
+ current_path = URI.parse(current_url).path
67
+ current_path << "##{fragment}" if fragment.present?
68
+ expected_path = _path_to(page_name)
69
+
70
+ # Consider two pages equal if they only differ by a trailing slash.
71
+ current_path = expected_path if current_path.chomp("/") == expected_path.chomp("/")
72
+ current_path = expected_path if current_path.gsub("/#", "#") == expected_path.gsub("/#", "#")
73
+
74
+ expect(current_path).to eq(expected_path)
75
+ end
76
+ end
77
+
78
+ #When /^(?:|I )press "([^"]*)"$/ do |button|
79
+ step "I press on :button" do |button|
80
+ patiently do
81
+ click_button(button)
82
+ end
83
+ end
84
+
85
+ #When /^(?:|I )follow "([^"]*)"$/ do |link|
86
+ step "I follow :link" do |link|
87
+ patiently do
88
+ click_link(link)
89
+ end
90
+ end
91
+
92
+ # Fill in text field
93
+ #When /^(?:|I )fill in "([^"]*)" (?:with|for) "([^"]*)"$/ do |field, value|
94
+ step "I fill in :field with :value" do |field, value|
95
+ patiently do
96
+ fill_in(field, :with => value)
97
+ end
98
+ end
99
+
100
+ # Fill in text field with multi-line block
101
+ # You can use a doc string to supply multi-line text
102
+ #
103
+ # Example:
104
+ #
105
+ # When I fill in "some field" with:
106
+ # """
107
+ # Apple
108
+ # Banana
109
+ # Pear
110
+ # """
111
+ #When /^(?:|I )fill in "([^"]*)" (?:with|for):$/ do |field, value|
112
+ step "I fill in :field with:" do |field, value|
113
+ patiently do
114
+ fill_in(field, :with => value)
115
+ end
116
+ end
117
+
118
+ # Fill in text field
119
+ #When /^(?:|I )fill in "([^"]*)" (?:with|for) '(.*)'$/ do |field, value|
120
+ #step "I fill in :field with :value" do |field, value|
121
+ #patiently do
122
+ #fill_in(field, :with => value)
123
+ #end
124
+ #end
125
+
126
+ # Select from select box
127
+ #When /^(?:|I )select "([^"]*)" from "([^"]*)"$/ do |value, field|
128
+ step "I select :value from :field" do |value, field|
129
+ patiently do
130
+ select(value, :from => field)
131
+ end
132
+ end
133
+
134
+ # Check a checkbox
135
+ #When /^(?:|I )check "([^"]*)"$/ do |field|
136
+ step "I check :field" do |field|
137
+ patiently do
138
+ check(field)
139
+ end
140
+ end
141
+
142
+ # Uncheck a checkbox
143
+ #When /^(?:|I )uncheck "([^"]*)"$/ do |field|
144
+ step "I uncheck :field" do |field|
145
+ patiently do
146
+ uncheck(field)
147
+ end
148
+ end
149
+
150
+ # Select a radio button
151
+ #When /^(?:|I )choose "([^"]*)"$/ do |field|
152
+ step "I choose :field" do |field|
153
+ patiently do
154
+ choose(field)
155
+ end
156
+ end
157
+
158
+ # Attach a file to a file upload form field
159
+ #When /^(?:|I )attach the file "([^"]*)" to "([^"]*)"$/ do |path, field|
160
+ step "I attach the file :path to :field" do |path, field|
161
+ patiently do
162
+ attach_file(field, File.expand_path(path))
163
+ end
164
+ end
165
+
166
+ # Checks that some text appears on the page
167
+ #
168
+ # Note that this does not detect if the text might be hidden via CSS
169
+ #Then /^(?:|I )should see "([^"]*)"$/ do |text|
170
+ step "I should see :text" do |text|
171
+ patiently do
172
+ page.should have_content(text)
173
+ end
174
+ end
175
+
176
+ # Checks that a regexp appears on the page
177
+ #
178
+ # Note that this does not detect if the text might be hidden via CSS
179
+ #Then /^(?:|I )should see \/([^\/]*)\/$/ do |regexp|
180
+ step "I should see :regexp regexp" do |regexp|
181
+ regexp = Regexp.new(regexp)
182
+ patiently do
183
+ page.should have_xpath('//*', :text => regexp)
184
+ end
185
+ end
186
+
187
+ #Then /^(?:|I )should not see "([^"]*)"$/ do |text|
188
+ step "I should not see :text" do |text|
189
+ patiently do
190
+ page.should have_no_content(text)
191
+ end
192
+ end
193
+
194
+ #Then /^(?:|I )should not see \/([^\/]*)\/$/ do |regexp|
195
+ step "I should not see :regexp regexp" do |regexp|
196
+ patiently do
197
+ regexp = Regexp.new(regexp)
198
+ page.should have_no_xpath('//*', :text => regexp)
199
+ end
200
+ end
201
+
202
+
203
+ # Checks that an input field contains some value (allowing * as wildcard character)
204
+ #Then /^the "([^"]*)" field should (not )?contain "([^"]*)"$/ do |label, negate, expected_string|
205
+ step "the :label field :whether_to contain :expected_string" do |label, positive, expected_string|
206
+ patiently do
207
+ field = find_field(label)
208
+ field_value = case field.tag_name
209
+ when 'select'
210
+ options = field.all('option')
211
+ selected_option = options.detect(&:selected?) || options.first
212
+ if selected_option && selected_option.text.present?
213
+ selected_option.text.strip
214
+ else
215
+ ''
216
+ end
217
+ else
218
+ field.value
219
+ end
220
+ if positive
221
+ expect(field_value).to contain_with_wildcards(expected_string)
222
+ else
223
+ expect(field_value).not_to contain_with_wildcards(expected_string)
224
+ end
225
+ end
226
+ end
227
+
228
+ # Checks that a multiline textarea contains some value (allowing * as wildcard character)
229
+ #Then(/^the "(.*?)" field should (not )?contain:$/) do |label, negate, expected_string|
230
+ step "the :label field :whether_to contain:" do |label, positive, expected_string|
231
+ patiently do
232
+ field = find_field(label)
233
+ if positive
234
+ expect(field.value.chomp).to contain_with_wildcards(expected_string)
235
+ else
236
+ expect(field.value.chomp).not_to contain_with_wildcards(expected_string)
237
+ end
238
+ end
239
+ end
240
+
241
+ # Checks that a list of label/value pairs are visible as control inputs.
242
+ #
243
+ # Example:
244
+ #
245
+ # Then I should see a form with the following values:
246
+ # | E-mail | foo@bar.com |
247
+ # | Role | Administrator |
248
+ #
249
+ #Then /^I should see a form with the following values:$/ do |table|
250
+ step "I should see a form with the following values:" do |table|
251
+ expectations = table.raw
252
+ expectations.each do |label, expected_value|
253
+ step %(the "#{label}" field should contain "#{expected_value}")
254
+ end
255
+ end
256
+
257
+ # Checks that an input field was wrapped with a validation error
258
+ #Then /^the "([^"]*)" field should have the error "([^"]*)"$/ do |field, error_message|
259
+ step "the :field should have the error :error_message" do |field, error_message|
260
+ patiently do
261
+ element = find_field(field)
262
+ classes = element.find(:xpath, '..')[:class].split(' ')
263
+
264
+ form_for_input = element.find(:xpath, 'ancestor::form[1]')
265
+ using_formtastic = form_for_input[:class].include?('formtastic')
266
+ error_class = using_formtastic ? 'error' : 'field_with_errors'
267
+
268
+ classes.should include(error_class)
269
+
270
+ if using_formtastic
271
+ error_paragraph = element.find(:xpath, '../*[@class="inline-errors"][1]')
272
+ error_paragraph.should have_content(error_message)
273
+ else
274
+ page.should have_content("#{field.titlecase} #{error_message}")
275
+ end
276
+ end
277
+ end
278
+
279
+ #Then /^the "([^\"]*)" field should( not)? have an error$/ do |label, negate|
280
+ step "the :label field :whether_to have an error" do |label, positive|
281
+ patiently do
282
+ expectation = positive ? :should : :should_not
283
+ field = find_field(label)
284
+ field[:id].should be_present # prevent bad CSS selector if field lacks id
285
+ page.send(expectation, have_css(".field_with_errors ##{field[:id]}"))
286
+ end
287
+ end
288
+
289
+ #Then /^the "([^"]*)" field should have no error$/ do |field|
290
+ step "the :field should have no error" do |field|
291
+ patiently do
292
+ element = find_field(field)
293
+ classes = element.find(:xpath, '..')[:class].split(' ')
294
+ classes.should_not include('field_with_errors')
295
+ classes.should_not include('error')
296
+ end
297
+ end
298
+
299
+ # nodoc
300
+ #Then /^the "([^"]*)" checkbox should( not)? be checked$/ do |label, negate|
301
+ step "the :label checkbox :whether_to be checked" do |label, positive|
302
+ patiently do
303
+ field = find_field(label)
304
+ if positive
305
+ expect(field).to be_checked
306
+ else
307
+ expect(field).not_to be_checked
308
+ end
309
+ end
310
+ end
311
+
312
+ #Then /^the radio button "([^"]*)" should( not)? be (?:checked|selected)$/ do |field, negate|
313
+ step "the radio button :field :whether_to be checked/selected" do |positive, action|
314
+ patiently do
315
+ expectation = positive ? :has_checked_field? : :has_no_checked_field?
316
+ page.send(expectation, field).should == true
317
+ end
318
+ end
319
+
320
+ # Example:
321
+ #
322
+ # I should have the following query string:
323
+ # | locale | de |
324
+ # | currency_code | EUR |
325
+ #
326
+ # Succeeds when the URL contains the given `locale` and `currency_code` params
327
+ #Then /^(?:|I )should have the following query string:$/ do |expected_pairs|
328
+ step "I should have the following query string:" do |expected_pairs|
329
+ patiently do
330
+ query = URI.parse(current_url).query
331
+ actual_params = query ? CGI.parse(query) : {}
332
+ expected_params = {}
333
+ expected_pairs.rows_hash.each_pair{|k,v| expected_params[k] = v.split(',')}
334
+
335
+ actual_params.should == expected_params
336
+ end
337
+ end
338
+
339
+ # Open the current Capybara page using the `launchy` gem
340
+ #Then /^show me the page$/ do
341
+ step "show me the page" do
342
+ save_and_open_page
343
+ end
344
+
345
+
346
+ # Checks for the existance of an input field (given its id or label)
347
+ #Then /^I should( not)? see a field "([^"]*)"$/ do |negate, name|
348
+ step "I should :whether_to see a field :name" do |positive, name|
349
+ expectation = positive ? :should : :should_not
350
+ patiently do
351
+ begin
352
+ field = find_field(name)
353
+ rescue Capybara::ElementNotFound
354
+ # In Capybara 0.4+ #find_field raises an error instead of returning nil
355
+ end
356
+ field.send(expectation, be_present)
357
+ end
358
+ end
359
+
360
+ # Use this step to test for a number or money amount instead of a simple `Then I should see`
361
+ #
362
+ # Checks for an unexpected minus sign, correct decimal places etc.
363
+ #
364
+ # See [here](https://makandracards.com/makandra/1225-test-that-a-number-or-money-amount-is-shown-with-cucumber) for details
365
+ #Then /^I should( not)? see the (?:number|amount) ([\-\d,\.]+)(?: (.*?))?$/ do |negate, amount, unit|
366
+ step "I should :whether_to see the number/amount :amount :unit" do |positive, amount, unit|
367
+ no_minus = amount.starts_with?('-') ? '' : '[^\\-]'
368
+ nbsp = " "
369
+ regexp = Regexp.new(no_minus + "\\b" + Regexp.quote(amount) + (unit ? "( |#{nbsp}|&nbsp;)(#{unit}|#{Regexp.quote(HTMLEntities.new.encode(unit, :named))})" :"\\b"))
370
+ expectation = positive ? :should : :should_not
371
+ patiently do
372
+ page.body.send(expectation, match(regexp))
373
+ end
374
+ end
375
+
376
+ # Checks `Content-Type` HTTP header
377
+ #Then /^I should get a response with content-type "([^\"]*)"$/ do |expected_content_type|
378
+ step "I should get a response with context-type :expected_content_type" do |expected_content_type|
379
+ page.response_headers['Content-Type'].should =~ /\A#{Regexp.quote(expected_content_type)}($|;)/
380
+ end
381
+
382
+ # Checks `Content-Disposition` HTTP header
383
+ #
384
+ # Attention: Doesn't work with Selenium, see https://github.com/jnicklas/capybara#gotchas
385
+ #Then /^I should get a download with filename "([^\"]*)"$/ do |filename|
386
+ step "I should get a download with filename :filename" do |filename|
387
+ page.response_headers['Content-Disposition'].should =~ /filename="#{filename}"$/
388
+ end
389
+
390
+ # Checks that a certain option is selected for a text field
391
+ #Then /^"([^"]*)" should be selected for "([^"]*)"$/ do |value, field|
392
+ step ":value should be selected for :field" do |value, field|
393
+ step %(the "#{field}" field should contain "#{value}")
394
+ end
395
+
396
+ #Then /^nothing should be selected for "([^"]*)"?$/ do |field|
397
+ step "nothing should be selected for :field" do |field|
398
+ patiently do
399
+ select = find_field(field)
400
+ begin
401
+ select.find(:xpath, ".//option[@selected = 'selected']").should be_blank
402
+ rescue Capybara::ElementNotFound
403
+ end
404
+ end
405
+ end
406
+
407
+ # Checks for the presence of an option in a select
408
+ #Then /^"([^"]*)" should( not)? be an option for "([^"]*)"$/ do |value, negate, field|
409
+ step ":value :whether_to be an option for :field" do |value, positive, field|
410
+ patiently do
411
+ xpath = ".//option[text() = '#{value}']"
412
+ if positive
413
+ field_labeled(field).find(:xpath, xpath).should be_present
414
+ else
415
+ begin
416
+ field_labeled(field).find(:xpath, xpath).should_not be_present
417
+ rescue Capybara::ElementNotFound
418
+ end
419
+ end
420
+ end
421
+ end
422
+
423
+ # Like `Then I should see`, but with single instead of double quotes. In case
424
+ # the expected string contains quotes as well.
425
+ #Then /^(?:|I )should see '([^']*)'$/ do |text|
426
+ step "I should see :text" do |text|
427
+ patiently do
428
+ page.should have_content(text)
429
+ end
430
+ end
431
+
432
+ # Check that the raw HTML contains a string
433
+ #Then /^I should see "([^\"]*)" in the HTML$/ do |text|
434
+ step "I should see :text in the HTML" do |text|
435
+ patiently do
436
+ page.body.should include(text)
437
+ end
438
+ end
439
+
440
+ #Then /^I should not see "([^\"]*)" in the HTML$/ do |text|
441
+ step "I should not see :text in the HTML" do |text|
442
+ patiently do
443
+ page.body.should_not include(text)
444
+ end
445
+ end
446
+
447
+ # Checks that status code is 400..599
448
+ #Then /^I should see an error$/ do
449
+ step "I should see an error" do
450
+ (400 .. 599).should include(page.status_code)
451
+ end
452
+
453
+ #nodoc
454
+ #Then /^the window should be titled "([^"]*)"$/ do |title|
455
+ step "the window should be title :title" do |title|
456
+ patiently do
457
+ page.should have_css('title', :text => title)
458
+ end
459
+ end
460
+
461
+ #When /^I reload the page$/ do
462
+ step "I reload the page" do
463
+ case Capybara::current_driver
464
+ when :selenium
465
+ page.execute_script(<<-JAVASCRIPT)
466
+ window.location.reload(true);
467
+ JAVASCRIPT
468
+ else
469
+ visit current_path
470
+ end
471
+ end
472
+
473
+ # Checks that an element is actually present and visible, also considering styles.
474
+ # Within a selenium test, the browser is asked whether the element is really visible
475
+ # In a non-selenium test, we only check for `.hidden`, `.invisible` or `style: display:none`
476
+ #
477
+ # The step 'Then (the tag )?"..." should **not** be visible' is ambiguous. Please use 'Then (the tag )?"..." should be hidden' or 'Then I should not see "..."' instead.
478
+ #
479
+ # More details [here](https://makandracards.com/makandra/1049-capybara-check-that-a-page-element-is-hidden-via-css)
480
+ #Then /^(the tag )?"([^\"]+)" should( not)? be visible$/ do |tag, selector_or_text, hidden|
481
+ step "the tag :selector_or_text :whether_to be visible" do |selector_or_text, positive|
482
+ unless positive
483
+ warn "The step 'Then ... should not be visible' is ambiguous. Please use 'Then ... should be hidden' or 'Then I should not see ...' instead."
484
+ end
485
+
486
+ options = {}
487
+ options.store(:selector, selector_or_text)
488
+
489
+ positive ? assert_visible(options) : assert_hidden(options)
490
+ end
491
+
492
+ step ":selector_or_text :whether_to be visible" do |selector_or_text, positive|
493
+ unless positive
494
+ warn "The step 'Then ... should not be visible' is ambiguous. Please use 'Then ... should be hidden' or 'Then I should not see ...' instead."
495
+ end
496
+
497
+ options = {}
498
+ options.store(:text, selector_or_text)
499
+
500
+ positive ? assert_visible(options) : assert_hidden(options)
501
+ end
502
+
503
+
504
+
505
+ # Checks that an element is actually present and hidden, also considering styles.
506
+ # Within a selenium test, the browser is asked whether the element is really hidden.
507
+ # In a non-selenium test, we only check for `.hidden`, `.invisible` or `style: display:none`
508
+ #Then /^(the tag )?"([^\"]+)" should be hidden$/ do |tag, selector_or_text|
509
+ step "the tag :selector_or_text should be hidden" do |selector_or_text|
510
+ options = {}
511
+ options.store(:selector, selector_or_text)
512
+
513
+ assert_hidden(options)
514
+ end
515
+
516
+ #Then /^(the tag )?"([^\"]+)" should be hidden$/ do |tag, selector_or_text|
517
+ step ":selector_or_text should be hidden" do |selector_or_text|
518
+ options = {}
519
+ options.store(:text, selector_or_text)
520
+
521
+ assert_hidden(options)
522
+ end
523
+
524
+
525
+
526
+ # Click on some text that might not be a link
527
+ #When /^I click on "([^\"]+)"$/ do |text|
528
+ step "I click on :text" do |text|
529
+ patiently do
530
+ contains_text = %{contains(., \"#{text}\")}
531
+ # find the innermost selector that matches
532
+ element = page.find(:xpath, ".//*[#{contains_text} and not (./*[#{contains_text}])]")
533
+ element.click
534
+ end
535
+ end
536
+
537
+ # Use this step to check external links.
538
+ #
539
+ # Example:
540
+ #
541
+ # Then "Sponsor" should link to "http://makandra.com"
542
+ #
543
+ #Then /^"([^"]*)" should link to "([^"]*)"$/ do |link_label, target|
544
+ step ":link_label should link to :target" do |link_label, target|
545
+ patiently do
546
+ link = find_link(link_label)
547
+ link[:href].should =~ /#{Regexp.escape target}(\?[^\/]*)?$/ # ignore trailing timestamps
548
+ end
549
+ end
550
+
551
+ # Example:
552
+ #
553
+ # Then I should see an element ".page .container"
554
+ #
555
+ #Then /^I should (not )?see an element "([^"]*)"$/ do |negate, selector|
556
+ step "I :whether_to see an element :selector" do |positive, selector|
557
+ expectation = positive ? :should : :should_not
558
+ patiently do
559
+ page.send(expectation, have_css(selector))
560
+ end
561
+ end
562
+
563
+ # Checks that the result has content type `text/plain`
564
+ #Then /^I should get a text response$/ do
565
+ step "I should get a text response" do
566
+ step 'I should get a response with content-type "text/plain"'
567
+ end
568
+
569
+ # Click a link within an element matching the given selector. Will try to be clever
570
+ # and disregard elements that don't contain a matching link.
571
+ #
572
+ # Example:
573
+ #
574
+ # When I follow "Read more" inside any ".text_snippet"
575
+ #
576
+ #When /^I follow "([^"]*)" inside any "([^"]*)"$/ do |label, selector|
577
+ step "I follow :label inside my :selector" do
578
+ node = find("#{selector} a", :text => label)
579
+ node.click
580
+ end
581
+
582
+ #Then /^I should( not)? see "([^"]*)" inside any "([^"]*)"$/ do |negate, text, selector|
583
+ step "I :whether_to see :text inside my :selector" do |positive, text, selector|
584
+ expectation = positive ? :should : :should_not
585
+ page.send(expectation, have_css(selector, :text => text))
586
+ end
587
+
588
+ #When /^I fill in "([^"]*)" with "([^"]*)" inside any "([^"]*)"$/ do |field, value, selector|
589
+ step "I fill in :field with :value inside any :selector" do |field, value, selector|
590
+ containers = all(:css, selector)
591
+ input = nil
592
+ containers.detect do |container|
593
+ input = container.first(:xpath, XPath::HTML.fillable_field(field))
594
+ end
595
+ if input
596
+ input.set(value)
597
+ else
598
+ raise "Could not find an input field \"#{field}\" inside any \"#{selector}\""
599
+ end
600
+ end
601
+
602
+ #When /^I confirm the browser dialog$/ do
603
+ step "I confirm the browser dialog" do
604
+ page.driver.browser.switch_to.alert.accept
605
+ end
606
+
607
+ #When /^I cancel the browser dialog$/ do
608
+ step "I cancel the browser dialog" do
609
+ page.driver.browser.switch_to.alert.dismiss
610
+ end
611
+
612
+ #When /^I enter "([^"]*)" into the browser dialog$/ do |text|
613
+ step "I enter :text into the browser dialog" do
614
+ alert = page.driver.browser.switch_to.alert
615
+ alert.send_keys(text)
616
+ alert.accept
617
+ end
618
+
619
+ #When /^I switch to the new tab$/ do
620
+ step "I switch to the new tab" do
621
+ Capybara::current_driver == :selenium or raise("This step works only with selenium")
622
+ page.driver.browser.switch_to.window(page.driver.browser.window_handles.last)
623
+ end
624
+
625
+ # Checks that these strings are rendered in the given order in a single line or in multiple lines
626
+ #
627
+ # Example:
628
+ #
629
+ # Then I should see in this order:
630
+ # | Alpha Group |
631
+ # | Augsburg |
632
+ # | Berlin |
633
+ # | Beta Group |
634
+ #
635
+ #Then /^I should see in this order:?$/ do |text|
636
+ step "I should see in this order:" do |text|
637
+ if text.is_a?(String)
638
+ lines = text.split(/\n/)
639
+ else
640
+ lines = text.raw.flatten
641
+ end
642
+ lines = lines.collect { |line| line.gsub(/\s+/, ' ')}.collect(&:strip).reject(&:blank?)
643
+ pattern = lines.collect(&Regexp.method(:quote)).join('.*?')
644
+ pattern = Regexp.compile(pattern)
645
+ patiently do
646
+ page.text.gsub(/\s+/, ' ').should =~ pattern
647
+ end
648
+ end
649
+
650
+ # Tests that an input or button with the given label is disabled.
651
+ #Then /^the "([^\"]*)" (field|button) should( not)? be disabled$/ do |label, kind, negate|
652
+ step "the :label :kind :wether_to be disabled" do |label, kind, positive|
653
+ if kind == 'field'
654
+ element = find_field(label)
655
+ else
656
+ element = find_button(label)
657
+ end
658
+ expectation = positive ? :should : :should_not
659
+ ["false", "", nil].send(expectation, include(element[:disabled]))
660
+ end
661
+
662
+ # Tests that a field with the given label is visible.
663
+ #Then /^the "([^\"]*)" field should( not)? be visible$/ do |label, hidden|
664
+ step "the :label field :whether_to be visible" do |label, positive|
665
+ field = find_field(label)
666
+
667
+ case Capybara::current_driver
668
+ when :selenium, :webkit
669
+ patiently do
670
+ visibility_detecting_javascript = %[
671
+ (function(){
672
+ var field = $('##{field['id']}');
673
+ return(field.is(':visible'));
674
+ })();
675
+ ].gsub(/\n/, ' ')
676
+ page.evaluate_script(visibility_detecting_javascript).should == !hidden
677
+ end
678
+ else
679
+ expectation = positive ? :should : :should_not
680
+ field.send(expectation, be_visible)
681
+ end
682
+ end
683
+
684
+ # Waits for the page to finish loading and AJAX requests to finish.
685
+ #
686
+ # More details [here](https://makandracards.com/makandra/12139-waiting-for-page-loads-and-ajax-requests-to-finish-with-capybara).
687
+ #When /^I wait for the page to load$/ do
688
+ step "I wait for the page to load" do
689
+ if [:selenium, :webkit, :poltergeist].include?(Capybara.current_driver)
690
+ patiently do
691
+ # when no jQuery is loaded, we assume there are no pending AJAX requests
692
+ page.evaluate_script("typeof jQuery === 'undefined' || $.active == 0").should == true
693
+ end
694
+ end
695
+ page.has_content? ''
696
+ end
697
+
698
+ # Performs HTTP basic authentication with the given credentials and visits the given path.
699
+ #
700
+ # More details [here](https://makandracards.com/makandra/971-perform-http-basic-authentication-in-cucumber).
701
+ #When /^I perform basic authentication as "([^\"]*)\/([^\"]*)" and go to (.*)$/ do |user, password, page_name|
702
+ step "I perform basic authentication as :user/:password and go to :page_name" do |user, password, page_name|
703
+ path = _path_to(page_name)
704
+ if Capybara::current_driver == :selenium
705
+ visit("http://#{user}:#{password}@#{page.driver.rack_server.host}:#{page.driver.rack_server.port}#{path}")
706
+ else
707
+ authorizers = [
708
+ (page.driver.browser if page.driver.respond_to?(:browser)),
709
+ (self),
710
+ (page.driver)
711
+ ].compact
712
+ authorizer = authorizers.detect { |authorizer| authorizer.respond_to?(:basic_authorize) }
713
+ authorizer.basic_authorize(user, password)
714
+ visit path
715
+ end
716
+ end
717
+
718
+ # Goes to the previously viewed page.
719
+ #When /^I go back$/ do
720
+ step "I go back" do
721
+ case Capybara::current_driver
722
+ when :selenium, :webkit
723
+ page.evaluate_script('window.history.back()')
724
+ else
725
+ if page.driver.respond_to?(:browser)
726
+ visit page.driver.browser.last_request.env['HTTP_REFERER']
727
+ else
728
+ visit page.driver.last_request.env['HTTP_REFERER']
729
+ end
730
+ end
731
+ end
732
+
733
+ # Tests whether a select field is sorted. Uses Array#natural_sort, if defined;
734
+ # Array#sort else.
735
+ #Then /^the "(.*?)" select should( not)? be sorted$/ do |label, negate|
736
+ step "the :label select :whether_to be sorted" do |label, positive|
737
+ select = find_field(label)
738
+ options = select.all('option').reject { |o| o.value.blank? }
739
+ option_texts = options.collect(&:text)
740
+
741
+ if positive
742
+ expect(option_texts).to be_sorted
743
+ else
744
+ expect(option_texts).not_to be_sorted
745
+ end
746
+ end
747
+
748
+ placeholder :whether_to do
749
+ match /should not/ do
750
+ false
751
+ end
752
+
753
+ match /should/ do
754
+ true
755
+ end
756
+ end
757
+ # step 'I :whether_to see :text' do |positive, text|
758
+ # expectation = positive ? :to : :not_to
759
+ # expect(page.body).send expectation, eq(text)
760
+ # end