site_prism 3.7.3 → 4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/LICENSE.md +1 -1
- data/README.md +78 -110
- data/lib/site_prism/addressable_url_matcher.rb +1 -1
- data/lib/site_prism/deprecator.rb +3 -3
- data/lib/site_prism/dsl.rb +57 -81
- data/lib/site_prism/dsl_validator.rb +75 -0
- data/lib/site_prism/element_checker.rb +3 -19
- data/lib/site_prism/error.rb +6 -10
- data/lib/site_prism/loadable.rb +4 -5
- data/lib/site_prism/page.rb +39 -1
- data/lib/site_prism/rspec_matchers.rb +9 -3
- data/lib/site_prism/section.rb +12 -11
- data/lib/site_prism/timer.rb +10 -10
- data/lib/site_prism/version.rb +1 -1
- data/lib/site_prism/waiter.rb +4 -4
- data/lib/site_prism.rb +4 -12
- metadata +39 -59
- data/lib/site_prism/recursion_checker.rb +0 -77
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a42324a6a59bf20f2c35c519c130d94e314c5170b47ddf1c9f1d3faae98238d7
|
4
|
+
data.tar.gz: d17845d3b0131de25848bf85b86a7c696ef1160bdc4cf759bd43958d56742d00
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7e09efb630b6f8270c7c8bb23c9db92bcccaa09e54c0a7e9ef1a6f2a645f47d821bf912141588ccec1bb3c6aea73f181ff6c8e5b771116f84936d10f95e714ab
|
7
|
+
data.tar.gz: d1dee7191ea9c01a8cc03e0726ae55ec1de91fe1d9bbb0f6db73e0c6b8af261d598b59d4d1be54e0589e481613b40e574f0d406ac1242d6a2e4cd46a9480c08c
|
data/LICENSE.md
CHANGED
data/README.md
CHANGED
@@ -7,7 +7,7 @@ _A Page Object Model DSL for Capybara_
|
|
7
7
|
SitePrism gives you a simple, clean and semantic DSL for describing your site using the Page Object Model pattern,
|
8
8
|
for use with Capybara in automated acceptance testing.
|
9
9
|
|
10
|
-
Find the pretty documentation here: https://
|
10
|
+
Find the pretty documentation here: https://www.rubydoc.info/github/site-prism/site_prism
|
11
11
|
|
12
12
|
Make sure to add your project/company to https://github.com/site-prism/site_prism/wiki/Who-is-using-SitePrism
|
13
13
|
|
@@ -29,10 +29,9 @@ We have a brief set of setup docs [HERE](https://github.com/site-prism/site_pris
|
|
29
29
|
|
30
30
|
## Supported Rubies / Browsers
|
31
31
|
|
32
|
-
SitePrism is built and tested to work on Ruby 2.
|
33
|
-
|
34
|
-
|
35
|
-
such as 2.7, if for any other reason, to get a noticeable speed boost!
|
32
|
+
SitePrism is built and tested to work on Ruby 2.6 - 3.1.
|
33
|
+
If you are using SitePrism with Ruby 2.5-2.7 it is highly advisable to upgrade to a more modern
|
34
|
+
Ruby (v3+), if for any other reason, to get a performance improvement!
|
36
35
|
|
37
36
|
SitePrism should run on all major browsers. The gem's integration tests are run on Chrome and Firefox.
|
38
37
|
|
@@ -82,34 +81,34 @@ end
|
|
82
81
|
|
83
82
|
# now for some tests
|
84
83
|
|
85
|
-
When(
|
84
|
+
When('I navigate to the google home page') do
|
86
85
|
@home = Home.new
|
87
86
|
@home.load
|
88
87
|
end
|
89
88
|
|
90
|
-
Then(
|
91
|
-
@home.wait_until_menu_visible
|
89
|
+
Then('the home page should contain the menu and the search form') do
|
90
|
+
@home.wait_until_menu_visible(wait: 5)
|
92
91
|
expect(@home).to have_menu
|
93
92
|
expect(@home).to have_search_field
|
94
93
|
expect(@home).to have_search_button
|
95
94
|
end
|
96
95
|
|
97
|
-
When(
|
98
|
-
@home.search_field.
|
96
|
+
When('I search for Sausages') do
|
97
|
+
@home.search_field.send_keys('Sausages')
|
99
98
|
@home.search_button.click
|
100
99
|
end
|
101
100
|
|
102
|
-
Then(
|
101
|
+
Then('the search results page is displayed') do
|
103
102
|
@results_page = SearchResults.new
|
104
103
|
expect(@results_page).to be_displayed
|
105
104
|
end
|
106
105
|
|
107
|
-
Then(
|
108
|
-
@results_page.wait_until_search_results_visible
|
106
|
+
Then('the search results page contains 10 individual search results') do
|
107
|
+
@results_page.wait_until_search_results_visible(wait: 5)
|
109
108
|
expect(@results_page).to have_search_results(count: 10)
|
110
109
|
end
|
111
110
|
|
112
|
-
Then(
|
111
|
+
Then('the search results contain a link to the wikipedia sausages page') do
|
113
112
|
expect(@results_page.search_result_links).to include('http://en.wikipedia.org/wiki/Sausage')
|
114
113
|
end
|
115
114
|
```
|
@@ -135,7 +134,6 @@ require 'capybara'
|
|
135
134
|
require 'capybara/cucumber'
|
136
135
|
require 'selenium-webdriver'
|
137
136
|
require 'site_prism'
|
138
|
-
require 'site_prism/all_there' # Optional but needed to perform more complex matching
|
139
137
|
```
|
140
138
|
|
141
139
|
The driver creation is identical to how you would normally create a Capybara driver,
|
@@ -144,7 +142,7 @@ a sample Selenium one could look something like this...
|
|
144
142
|
```ruby
|
145
143
|
Capybara.register_driver :site_prism do |app|
|
146
144
|
browser = ENV.fetch('browser', 'firefox').to_sym
|
147
|
-
Capybara::Selenium::Driver.new(app, browser: browser,
|
145
|
+
Capybara::Selenium::Driver.new(app, browser: browser, options: options)
|
148
146
|
end
|
149
147
|
|
150
148
|
# Then tell Capybara to use the Driver you've just defined as its default driver
|
@@ -162,7 +160,6 @@ require 'capybara'
|
|
162
160
|
require 'capybara/rspec'
|
163
161
|
require 'selenium-webdriver'
|
164
162
|
require 'site_prism'
|
165
|
-
require 'site_prism/all_there' # Optional but needed to perform more complex matching
|
166
163
|
```
|
167
164
|
|
168
165
|
And again, as above, a sample driver is no different to a normal driver instantiation in Capybara.
|
@@ -176,7 +173,7 @@ to then use instances of those classes in your tests.
|
|
176
173
|
|
177
174
|
If a class represents a page then each element of the page is
|
178
175
|
represented by a method that, when called, returns a reference to that
|
179
|
-
element that can then be acted upon (clicked,
|
176
|
+
element that can then be acted upon (clicked, type in some text), or
|
180
177
|
queried (is it enabled? / visible?).
|
181
178
|
|
182
179
|
SitePrism is based around this concept, but goes further as you'll see
|
@@ -219,7 +216,7 @@ class Home < SitePrism::Page
|
|
219
216
|
end
|
220
217
|
```
|
221
218
|
|
222
|
-
Note that setting a URL is optional - you only need to set a url if you want to be able to
|
219
|
+
Note that setting a URL is **optional** - you only need to set a url if you want to be able to
|
223
220
|
navigate directly to that page. It makes sense to set the URL for a page model of a
|
224
221
|
home page or a login page, but probably not a search results page.
|
225
222
|
|
@@ -246,8 +243,7 @@ See https://github.com/sporkmonger/addressable for more details on parameterized
|
|
246
243
|
|
247
244
|
### Navigating to the Page
|
248
245
|
|
249
|
-
Once the URL has been set (using `set_url`), you can navigate directly
|
250
|
-
to the page using `#load`:
|
246
|
+
Once the URL has been set (using `set_url`), you can navigate directly to the page using `#load`:
|
251
247
|
|
252
248
|
```ruby
|
253
249
|
@home_page = Home.new
|
@@ -283,8 +279,6 @@ end
|
|
283
279
|
This will tell whichever capybara driver you have configured to
|
284
280
|
navigate to the URL set against that page's class.
|
285
281
|
|
286
|
-
See https://github.com/sporkmonger/addressable for more details on parameterized URLs.
|
287
|
-
|
288
282
|
### Verifying that a particular page is displayed
|
289
283
|
|
290
284
|
Automated tests often need to verify that a particular page is
|
@@ -320,8 +314,7 @@ wait time in seconds as the first argument like this:
|
|
320
314
|
#### Specifying parameter values for templated URLs
|
321
315
|
|
322
316
|
Sometimes you want to verify not just that the current URL matches the
|
323
|
-
template, but that you're looking at a specific page matching that
|
324
|
-
template.
|
317
|
+
template, but that you're looking at a specific page matching that template.
|
325
318
|
|
326
319
|
Given the previous example, if you wanted to ensure that the browser had loaded
|
327
320
|
account number 22, you could assert the following:
|
@@ -348,7 +341,7 @@ when comparing your page's URL template to the current_url:
|
|
348
341
|
@account_page.load(id: 22, query: { token: 'ca2786616a4285bc', color: 'irrelevant' })
|
349
342
|
|
350
343
|
expect(@account_page).to be_displayed(id: 22)
|
351
|
-
expect(@account_page.url_matches
|
344
|
+
expect(@account_page.url_matches.dig('query', 'token')).to eq('ca2786616a4285bc')
|
352
345
|
```
|
353
346
|
|
354
347
|
#### Falling back to basic regexp matchers
|
@@ -368,7 +361,7 @@ end
|
|
368
361
|
SitePrism's `#displayed?` predicate method allows for semantic code in your tests:
|
369
362
|
|
370
363
|
```ruby
|
371
|
-
Then(
|
364
|
+
Then('the account page is displayed') do
|
372
365
|
expect(@account_page).to be_displayed
|
373
366
|
expect(@some_other_page).not_to be_displayed
|
374
367
|
end
|
@@ -376,8 +369,7 @@ end
|
|
376
369
|
|
377
370
|
### Getting the Current Page's URL
|
378
371
|
|
379
|
-
SitePrism allows you to get the current page's URL. Here's how it's
|
380
|
-
done:
|
372
|
+
SitePrism allows you to get the current page's URL. Here's how it's done:
|
381
373
|
|
382
374
|
```ruby
|
383
375
|
class Account < SitePrism::Page
|
@@ -463,8 +455,8 @@ end
|
|
463
455
|
@home.load
|
464
456
|
|
465
457
|
@home.search_field #=> will return the capybara element found using the selector
|
466
|
-
@home.search_field.
|
467
|
-
@home.search_field
|
458
|
+
@home.search_field.send_keys('the search string')
|
459
|
+
@home.search_field['value'] #=> standard method on a capybara element (field); returns the string value
|
468
460
|
```
|
469
461
|
|
470
462
|
#### Testing for the existence of the element
|
@@ -493,16 +485,16 @@ end
|
|
493
485
|
...which makes for nice test code:
|
494
486
|
|
495
487
|
```ruby
|
496
|
-
Then(
|
488
|
+
Then('the search field exists') do
|
497
489
|
expect(@home).to have_search_field
|
498
490
|
end
|
499
491
|
```
|
500
492
|
|
501
493
|
#### Testing that an element does not exist
|
502
494
|
|
503
|
-
To test that an element does not exist on the page,
|
495
|
+
To test that an element does not exist on the page, you should not call
|
504
496
|
`#not_to have_search_field`. SitePrism supplies the `#has_no_<element>?` method
|
505
|
-
that should be used to test for non-existence.
|
497
|
+
that should be used instead to test for non-existence.
|
506
498
|
This method delegates to [Capybara::Node::Matchers#has_no_selector?](https://www.rubydoc.info/github/teamcapybara/capybara/master/Capybara/Node/Matchers#has_no_selector%3F-instance_method)
|
507
499
|
Using the above example:
|
508
500
|
|
@@ -515,7 +507,7 @@ Using the above example:
|
|
515
507
|
...which makes for nice test code:
|
516
508
|
|
517
509
|
```ruby
|
518
|
-
Then(
|
510
|
+
Then('the search field exists')do
|
519
511
|
expect(@home).to have_no_search_field #NB: NOT => expect(@home).not_to have_search_field
|
520
512
|
end
|
521
513
|
```
|
@@ -530,7 +522,7 @@ to become visible. You can customise the wait time by supplying a number
|
|
530
522
|
of seconds to wait in-line or configuring the default wait time.
|
531
523
|
|
532
524
|
```ruby
|
533
|
-
@home.wait_until_search_field_visible
|
525
|
+
@home.wait_until_search_field_visible # using the default wait time set
|
534
526
|
# or...
|
535
527
|
@home.wait_until_search_field_visible(wait: 10)
|
536
528
|
```
|
@@ -545,7 +537,7 @@ wait time for the element to become invisible. You can as with the visibility
|
|
545
537
|
waiter, customise the wait time in the same way.
|
546
538
|
|
547
539
|
```ruby
|
548
|
-
@home.wait_until_search_field_invisible
|
540
|
+
@home.wait_until_search_field_invisible # using the default wait time set
|
549
541
|
# or...
|
550
542
|
@home.wait_until_search_field_invisible(wait: 10)
|
551
543
|
```
|
@@ -664,7 +656,7 @@ Then the following method is available:
|
|
664
656
|
This in turn allows the following nice test code
|
665
657
|
|
666
658
|
```ruby
|
667
|
-
Then(
|
659
|
+
Then('there should be some names listed on the page') do
|
668
660
|
expect(@friends_page).to have_names #=> This only passes if there is at least one `name`
|
669
661
|
end
|
670
662
|
```
|
@@ -705,16 +697,16 @@ are present in the browser and `false` if they're not all there.
|
|
705
697
|
|
706
698
|
# and...
|
707
699
|
|
708
|
-
Then(
|
700
|
+
Then('the friends page contains all the expected elements') do
|
709
701
|
expect(@friends_page).to be_all_there
|
710
702
|
end
|
711
703
|
```
|
712
704
|
|
713
705
|
You may wish to have elements declared in a page object class that are not
|
714
706
|
always guaranteed to be present (success or error messages, etc.).
|
715
|
-
If you'd still like to test such a page with
|
716
|
-
|
717
|
-
included in
|
707
|
+
If you'd still like to test such a page with `#all_there?` you can declare
|
708
|
+
`.expected_elements` on your page class that narrows the elements
|
709
|
+
included in `#all_there?` check to those that definitely should be present.
|
718
710
|
|
719
711
|
```ruby
|
720
712
|
class TestPage < SitePrism::Page
|
@@ -749,18 +741,9 @@ for this at the moment are `:none` and `:one`
|
|
749
741
|
Passing `:none` (default), will not change the functionality. However passing in `:one` will cause
|
750
742
|
`site_prism` to recurse through all `section` / `sections` items defined in your present scope.
|
751
743
|
|
752
|
-
Work
|
744
|
+
Work to develop this is contained in the
|
753
745
|
[site_prism-all_there](http://www.github.com/site-prism/site_prism-all_there) repo. So head on over
|
754
|
-
there if you're interested in
|
755
|
-
|
756
|
-
NB: At the moment a "primitive" but working copy of this is hosted inside this gem. But if you wish to
|
757
|
-
use the bleeding edge version of the logic. Then simply set the following configuration parameter
|
758
|
-
|
759
|
-
```ruby
|
760
|
-
`require 'site_prism/all_there'`
|
761
|
-
|
762
|
-
SitePrism.use_all_there_gem = true
|
763
|
-
```
|
746
|
+
there if you're interested in this area more
|
764
747
|
|
765
748
|
### Getting the list of missing elements
|
766
749
|
|
@@ -840,15 +823,14 @@ class People < SitePrism::Section
|
|
840
823
|
end
|
841
824
|
|
842
825
|
class Home < SitePrism::Page
|
843
|
-
# section people_with_block will have `headline` and
|
844
|
-
# `footer` elements in it
|
826
|
+
# section people_with_block will have `headline` and `footer` elements in it
|
845
827
|
section :people_with_block, People do
|
846
828
|
element :headline, 'h2'
|
847
829
|
end
|
848
830
|
end
|
849
831
|
```
|
850
832
|
|
851
|
-
The 3rd argument (
|
833
|
+
The 3rd argument (Locator), can be omitted if you are re-using the same
|
852
834
|
locator for all references to the section Class. In order to do this,
|
853
835
|
simply tell SitePrism that you want to use default search arguments.
|
854
836
|
|
@@ -884,7 +866,7 @@ end
|
|
884
866
|
# the page and section in action
|
885
867
|
|
886
868
|
@home = Home.new
|
887
|
-
@home.menu #=> <
|
869
|
+
@home.menu #=> <Menu...>
|
888
870
|
```
|
889
871
|
|
890
872
|
When the `menu` method is called against `@home`, an instance of `Menu`
|
@@ -959,7 +941,7 @@ end
|
|
959
941
|
This then leads to some pretty test code ...
|
960
942
|
|
961
943
|
```ruby
|
962
|
-
Then(
|
944
|
+
Then('the home page menu contains a link to the various search functions') do
|
963
945
|
expect(@home.menu).to have_search
|
964
946
|
expect(@home.menu.search['href']).to include('google.com')
|
965
947
|
expect(@home.menu).to have_images
|
@@ -974,7 +956,7 @@ similar to Capybara's `within` method and allows for shorter test code
|
|
974
956
|
particularly with nested sections. Test code that might have to repeat the block name can be shortened up this way.
|
975
957
|
|
976
958
|
```ruby
|
977
|
-
Then(
|
959
|
+
Then('the home page menu contains a link to the various search functions') do
|
978
960
|
@home.menu.within do |menu|
|
979
961
|
expect(menu).to have_search
|
980
962
|
expect(menu.search['href']).to include('google.com')
|
@@ -984,10 +966,12 @@ Then(/^the home page menu contains a link to the various search functions$/) do
|
|
984
966
|
end
|
985
967
|
```
|
986
968
|
|
987
|
-
Note that on an individual section it's possible to pass a block directly to the section without using `within`.
|
969
|
+
Note that on an individual section it's possible to pass a block directly to the section without using `within`.
|
970
|
+
Because the block is executed only during `Section` initialization this won't work when accessing a single
|
971
|
+
Section from an array of Sections. For that reason we recommend using `within` which works in either case.
|
988
972
|
|
989
973
|
```ruby
|
990
|
-
Then(
|
974
|
+
Then('the home page menu contains a link to the various search functions') do
|
991
975
|
@home.menu do |menu| # possible, but prefer: `@home.menu.within`
|
992
976
|
expect(menu).to have_search
|
993
977
|
end
|
@@ -1139,26 +1123,22 @@ class Home < SitePrism::Page
|
|
1139
1123
|
section :login_and_registration, LoginRegistrationForm, 'div.login-registration'
|
1140
1124
|
end
|
1141
1125
|
|
1142
|
-
#
|
1126
|
+
# Then you could log in like so ...
|
1143
1127
|
|
1144
|
-
Then(
|
1128
|
+
Then('I sign in') do
|
1145
1129
|
@home = Home.new
|
1146
1130
|
@home.load
|
1147
|
-
|
1148
|
-
|
1149
|
-
@home.login_and_registration.login.username.set 'bob'
|
1150
|
-
@home.login_and_registration.login.password.set 'p4ssw0rd'
|
1131
|
+
@home.login_and_registration.login.username.send_keys('bob')
|
1132
|
+
@home.login_and_registration.login.password.send_keys('p4ssw0rd')
|
1151
1133
|
@home.login_and_registration.login.sign_in.click
|
1152
1134
|
end
|
1153
1135
|
|
1154
|
-
#
|
1136
|
+
# And you could sign up like so ...
|
1155
1137
|
|
1156
|
-
When(
|
1138
|
+
When('I sign up') do
|
1157
1139
|
@home = Home.new
|
1158
1140
|
@home.load
|
1159
|
-
|
1160
|
-
expect(@home.login_and_registration).to have_last_name
|
1161
|
-
@home.login_and_registration.first_name.set 'Bob'
|
1141
|
+
@home.login_and_registration.first_name.send_keys('Bob')
|
1162
1142
|
# ...
|
1163
1143
|
end
|
1164
1144
|
```
|
@@ -1198,7 +1178,7 @@ can be called in a page or a section.
|
|
1198
1178
|
|
1199
1179
|
The only difference between `section` and `sections` is that whereas the
|
1200
1180
|
first returns an instance of the supplied section class, the second
|
1201
|
-
returns
|
1181
|
+
returns a `Capybara::Result` containing as many instances of the section class as
|
1202
1182
|
there are capybara elements found by the supplied css selector. This is
|
1203
1183
|
better explained in the following example ...
|
1204
1184
|
|
@@ -1230,7 +1210,7 @@ end
|
|
1230
1210
|
This allows for pretty tests ...
|
1231
1211
|
|
1232
1212
|
```ruby
|
1233
|
-
Then(
|
1213
|
+
Then('there are lots of search_results') do
|
1234
1214
|
expect(@results_page.search_results.size).to eq(10)
|
1235
1215
|
|
1236
1216
|
@home.search_results.each do |result|
|
@@ -1245,12 +1225,14 @@ The css selector that is passed as the 3rd argument to the
|
|
1245
1225
|
elements. Each capybara element found using the css selector is used to
|
1246
1226
|
create a new instance of `SearchResults` and becomes its root
|
1247
1227
|
element. So if the css selector finds 3 `li` elements, calling
|
1248
|
-
`search_results` will return
|
1228
|
+
`search_results` will return a `Capybara::Result` containing 3 instances of
|
1249
1229
|
`SearchResults`, each with one of the `li` elements as it's root element.
|
1250
1230
|
|
1251
1231
|
##### Accessing Within a Collection of Sections
|
1252
1232
|
|
1253
|
-
When using an iterator such as `each` to pass a block through to a collection of sections it is
|
1233
|
+
When using an iterator such as `each` to pass a block through to a collection of sections it is
|
1234
|
+
possible to skip using `within`. However some caution is warranted when accessing the
|
1235
|
+
Sections directly from an array, as the block can only be executed when the section is being initialized. The following does not work:
|
1254
1236
|
|
1255
1237
|
```rb
|
1256
1238
|
@home.search_results.first do |result|
|
@@ -1314,7 +1296,7 @@ Here's how to test for the existence of the section:
|
|
1314
1296
|
This allows for some pretty tests ...
|
1315
1297
|
|
1316
1298
|
```ruby
|
1317
|
-
Then(
|
1299
|
+
Then('there are search results on the page') do
|
1318
1300
|
expect(@home).to have_search_results
|
1319
1301
|
end
|
1320
1302
|
```
|
@@ -1453,8 +1435,8 @@ The error message is ignored unless the boolean value is evaluated as falsey.
|
|
1453
1435
|
|
1454
1436
|
```ruby
|
1455
1437
|
class SomePage < SitePrism::Page
|
1456
|
-
element :
|
1457
|
-
load_validation { [
|
1438
|
+
element :foo, '.foo'
|
1439
|
+
load_validation { [has_foo?, 'did not have foo element!'] }
|
1458
1440
|
end
|
1459
1441
|
```
|
1460
1442
|
|
@@ -1500,8 +1482,8 @@ class FooPage < BasePage
|
|
1500
1482
|
section :form, '#form'
|
1501
1483
|
element :some_other_element, '.myelement'
|
1502
1484
|
|
1503
|
-
load_validation { [has_form
|
1504
|
-
load_validation { [has_some_other_element
|
1485
|
+
load_validation { [has_form?(wait: 5), 'form did not appear'] }
|
1486
|
+
load_validation { [has_some_other_element?(wait: 5), 'some other element did not appear'] }
|
1505
1487
|
end
|
1506
1488
|
```
|
1507
1489
|
|
@@ -1512,12 +1494,6 @@ the validations will be performed in the following order:
|
|
1512
1494
|
2. The `FooPage` validation will wait for the `form` element to be present.
|
1513
1495
|
3. The `FooPage` validation will wait for the `some_other_element` element to be present.
|
1514
1496
|
|
1515
|
-
**NB:** `SitePrism::Page` **used to** include a default load validation on
|
1516
|
-
`page.displayed?` however for v3 this has been removed. It is therefore
|
1517
|
-
necessary to re-define this if you want to retain the behaviour
|
1518
|
-
from site_prism v2. See [UPGRADING.md](https://github.com/site-prism/site_prism/blob/main/UPGRADING.md#default-load-validations)
|
1519
|
-
for more info on this.
|
1520
|
-
|
1521
1497
|
## Using Capybara Query Options
|
1522
1498
|
|
1523
1499
|
When querying an element, section or a collection of elements or sections,
|
@@ -1545,7 +1521,7 @@ fail if the page has not finished loading the section(s):
|
|
1545
1521
|
```ruby
|
1546
1522
|
@home = Home.new
|
1547
1523
|
# ...
|
1548
|
-
expect(@home.search_results.size).to
|
1524
|
+
expect(@home.search_results.size).to eq(25) # This may fail!
|
1549
1525
|
```
|
1550
1526
|
|
1551
1527
|
The above query can be rewritten to utilize the Capybara `:count` option
|
@@ -1556,16 +1532,16 @@ the page within the timeout:
|
|
1556
1532
|
|
1557
1533
|
```ruby
|
1558
1534
|
@home = Home.new
|
1559
|
-
@home.has_search_results?(count: 25)
|
1535
|
+
@home.has_search_results?(count: 25) # will wait default wait time
|
1560
1536
|
# OR
|
1561
|
-
@home.search_results(count: 25)
|
1537
|
+
@home.search_results(count: 25, wait: 5) # will wait 5 seconds
|
1562
1538
|
```
|
1563
1539
|
|
1564
1540
|
Now we can write pretty, non-failing tests without hard coding these options
|
1565
1541
|
into our page and section classes:
|
1566
1542
|
|
1567
1543
|
```ruby
|
1568
|
-
Then(
|
1544
|
+
Then('there are search results on the page') do
|
1569
1545
|
expect(@results_page).to have_search_results(count: 25)
|
1570
1546
|
end
|
1571
1547
|
```
|
@@ -1596,7 +1572,7 @@ The following element methods allow Capybara options to be passed as arguments t
|
|
1596
1572
|
## Test views with Page objects
|
1597
1573
|
|
1598
1574
|
It's possible to use the same page objects of integration tests for view tests, too,
|
1599
|
-
just pass the rendered HTML to the
|
1575
|
+
just pass the rendered HTML to the `load` method:
|
1600
1576
|
|
1601
1577
|
```ruby
|
1602
1578
|
require 'spec_helper'
|
@@ -1698,14 +1674,14 @@ class Home < SitePrism::Page
|
|
1698
1674
|
end
|
1699
1675
|
|
1700
1676
|
# cucumber step that performs login
|
1701
|
-
When(
|
1677
|
+
When('I log in') do
|
1702
1678
|
@home = Home.new
|
1703
1679
|
@home.load
|
1704
1680
|
|
1705
1681
|
@home.login_frame do |frame|
|
1706
1682
|
#`frame` is an instance of the `LoginFrame` class
|
1707
|
-
frame.username.
|
1708
|
-
frame.password.
|
1683
|
+
frame.username.send_keys('admin')
|
1684
|
+
frame.password.send_keys('p4ssword')
|
1709
1685
|
end
|
1710
1686
|
end
|
1711
1687
|
```
|
@@ -1748,14 +1724,6 @@ Capybara.using_wait_time(20) do
|
|
1748
1724
|
end
|
1749
1725
|
```
|
1750
1726
|
|
1751
|
-
## Using SitePrism with VCR
|
1752
|
-
|
1753
|
-
There's a SitePrism plugin called `site_prism.vcr` that lets you use
|
1754
|
-
SitePrism with the VCR gem. Check it out [HERE](https://github.com/dnesteryuk/site_prism.vcr)
|
1755
|
-
|
1756
|
-
Note that as of 2016 this plugin doesn't appear to have been under active development. Also it is
|
1757
|
-
still pinned to the `2.x` series of site_prism so use it of your own accord.
|
1758
|
-
|
1759
1727
|
# Epilogue
|
1760
1728
|
|
1761
1729
|
So, we've seen how to use SitePrism to put together page objects made up
|
@@ -1766,7 +1734,7 @@ all over the place. Here's an example of this common problem:
|
|
1766
1734
|
```ruby
|
1767
1735
|
@home = Home.new # <-- noise
|
1768
1736
|
@home.load
|
1769
|
-
@home.search_field.
|
1737
|
+
@home.search_field.send_keys('Sausages')
|
1770
1738
|
@home.search_field.search_button.click
|
1771
1739
|
@results_page = SearchResults.new # <-- noise
|
1772
1740
|
expect(@results_page).to have_search_result_items
|
@@ -1776,7 +1744,7 @@ The annoyance (and, later, maintenance nightmare) is having to create
|
|
1776
1744
|
`@home` and `@results_page`. It would be better to not have to create
|
1777
1745
|
instances of pages all over your tests.
|
1778
1746
|
|
1779
|
-
|
1747
|
+
One way you can deal with this problem is to create a class containing
|
1780
1748
|
methods that return instances of the pages. Eg:
|
1781
1749
|
|
1782
1750
|
```ruby
|
@@ -1813,17 +1781,17 @@ end
|
|
1813
1781
|
# and here's how to use it
|
1814
1782
|
|
1815
1783
|
#first line of the test...
|
1816
|
-
Given(
|
1784
|
+
Given('I start on the home page') do
|
1817
1785
|
@app = App.new
|
1818
1786
|
@app.home.load
|
1819
1787
|
end
|
1820
1788
|
|
1821
|
-
When(
|
1789
|
+
When('I search for Sausages') do
|
1822
1790
|
@app.home.search_field.set 'Sausages'
|
1823
1791
|
@app.home.search_button.click
|
1824
1792
|
end
|
1825
1793
|
|
1826
|
-
Then(
|
1794
|
+
Then('I am on the results page') do
|
1827
1795
|
expect(@app.results_page).to be_displayed
|
1828
1796
|
end
|
1829
1797
|
|
@@ -1833,8 +1801,8 @@ end
|
|
1833
1801
|
The only thing that needs instantiating is the `App` class - from then on
|
1834
1802
|
pages don't need to be initialized, they are now returned by methods on `@app`.
|
1835
1803
|
|
1836
|
-
It is possible to further optimise this, by using Cucumber/RSpec hooks,
|
1837
|
-
other things. However the investigation and optimisation of this (and other
|
1804
|
+
It is possible to further optimise this, by using Cucumber/RSpec hooks, memoization as well
|
1805
|
+
as many other things. However the investigation and optimisation of this (and other
|
1838
1806
|
aspects of SitePrism), is left as an exercise to the Reader.
|
1839
1807
|
|
1840
1808
|
Happy testing from all of the SitePrism team!
|
@@ -132,7 +132,7 @@ module SitePrism
|
|
132
132
|
# the substituted slug so that Addressable's URI parser can see it as such.
|
133
133
|
def slug_prefix(slug)
|
134
134
|
prefix = slug.match(/\A{([^A-Za-z]+)/)
|
135
|
-
prefix && prefix[1] || ''
|
135
|
+
(prefix && prefix[1]) || ''
|
136
136
|
end
|
137
137
|
|
138
138
|
# Generate a repeatable 5 character uniform alphabetical nonsense string
|
@@ -15,14 +15,14 @@ module SitePrism
|
|
15
15
|
warn("#{old} is being deprecated and should no longer be used.")
|
16
16
|
end
|
17
17
|
|
18
|
-
warn("#{old} will be removed in SitePrism
|
18
|
+
warn("#{old} will be removed in SitePrism v5. You have been warned!")
|
19
19
|
end
|
20
20
|
|
21
21
|
# @return SitePrism.logger.debug(msg)
|
22
22
|
#
|
23
23
|
# Tells the user that they are using functionality which is non-optimal
|
24
|
-
#
|
25
|
-
#
|
24
|
+
# The functionality should usually provide a reason for it being poor, as well as an
|
25
|
+
# optional way of upgrading to something different
|
26
26
|
#
|
27
27
|
# NB: As this is bubbled up at debug level, often users will not see this. So it will
|
28
28
|
# never be a candidate for removal directly
|