site_prism 3.5 → 3.7.2

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: 95c8d9ff0cf7f2b818a8b8cb987ca39f2b512138d572a08533b8466feae6cb63
4
- data.tar.gz: 6239a4a2cd9be9233396f2b221328645dcb50a56e531ee0d5b63faa3dbd9bf53
3
+ metadata.gz: 177884e3ba39ca8a9e1fa0025274c31dd1d765adbba6983f86150feeef4fa301
4
+ data.tar.gz: 0ecc59ece70808dbb774128d1cf5e7f3fcdaa4d449b27be29f403633b3535c24
5
5
  SHA512:
6
- metadata.gz: a9a7a79356b8f4c16aad85f923db99a549bba2c78ec23624f245504ce3bbffd7698bad6a572ddbb34cbf9f2406da76bda7ce5d2433d874270112025e5e9d79ea
7
- data.tar.gz: 897ae6d1b6a944b52bc5f36ebb81e2796657a276bfa41994fd0a5315031457d404b46408660556644eb262258c8033b72aa5d7400bd79d13f8085993575df826
6
+ metadata.gz: 5f402e20e4888f02d4c7695289239c1b4dfca44b47e90029699efe4ec050b2d173f78c1e427f1dbd0647c9b8238397f1c34d22697601b5f36689266f942729b7
7
+ data.tar.gz: 549ac4b1187a96807c34475961999bcfaa6761fceba70cf13bdcedfdce13c86b23aad1fa700bcda122841a057bd258023f26ffc270194a8258d98756b3bf294c
data/LICENSE.md CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2011-2019, The SitePrism team
1
+ Copyright (c) 2011-2021, The SitePrism team
2
2
 
3
3
  All rights reserved.
4
4
 
data/README.md CHANGED
@@ -7,23 +7,34 @@ _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: http://rdoc.info/gems/site_prism/frames
10
+ Find the pretty documentation here: https://rdoc.info/gems/site_prism/frames
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
 
14
+ ## Support
15
+
16
+ Support us with a monthly donation and help us continue our activities by supporting us as a [backer](https://opencollective.com/site-prism#backer)
17
+
18
+ Become a sponsor and get your logo on our README on Github with a link to your site. [How to Sponsor SitePrism?](https://opencollective.com/site-prism#sponsor)
19
+
20
+ Free Open Source software can only be maintained with the support of you. If you and/or your company find
21
+ value in SitePrism and would like to contribute financially to its ongoing maintenance and development,
22
+ then please do so. Visit the OpenCollective links above for more details.
23
+
14
24
  ## Developing / Contributing to SitePrism
15
25
 
16
26
  We love it when people want to get involved with our Open Source Project.
17
27
 
18
- We have a brief set of setup docs [HERE](https://github.com/site-prism/site_prism/blob/master/HACKING.md)
28
+ We have a brief set of setup docs [HERE](https://github.com/site-prism/site_prism/blob/main/HACKING.md)
19
29
 
20
30
  ## Supported Rubies / Browsers
21
31
 
22
- SitePrism is built and tested to work on Ruby 2.4 - 2.6. Ruby 2.3 (Now EOL), is supported but not tested against.
23
- If you are using SitePrism with Ruby 2.3 it is highly advisable to upgrade to a more modern Ruby
24
- such as 2.6 or 2.7, if for any other reason, to get a noticeable speed boost!
32
+ SitePrism is built and tested to work on Ruby 2.4 - 2.7. Ruby 2.4 (Now EOL), is supported but
33
+ this version will be removed from the Support Matrix in the coming months.
34
+ If you are using SitePrism with Ruby 2.4 it is highly advisable to upgrade to a more modern Ruby
35
+ such as 2.7, if for any other reason, to get a noticeable speed boost!
25
36
 
26
- SitePrism should run on all major browsers. The gem's integration tests are ran on Chrome and Firefox.
37
+ SitePrism should run on all major browsers. The gem's integration tests are run on Chrome and Firefox.
27
38
 
28
39
  If you find you cannot integrate nicely with SitePrism, please open an
29
40
  [issue request](https://github.com/site-prism/site_prism/issues/new)
@@ -298,7 +309,13 @@ expect(@account_page).to be_displayed
298
309
  ```
299
310
 
300
311
  Calling `#displayed?` will return true if the browser's current URL
301
- matches the page's template and false if it doesn't.
312
+ matches the page's template and false if it doesn't. It will wait for
313
+ `Capybara.default_max_wait_time` seconds or you can pass an explicit
314
+ wait time in seconds as the first argument like this:
315
+
316
+ ```ruby
317
+ @account_page.displayed?(10) # wait up to 10 seconds for display
318
+ ```
302
319
 
303
320
  #### Specifying parameter values for templated URLs
304
321
 
@@ -425,8 +442,11 @@ as a string.
425
442
  #### Accessing the individual element
426
443
 
427
444
  The `element` method will add a number of methods to instances of the
428
- particular Page class. The first method to be added is the name of the
429
- element. So using the following example:
445
+ particular Page class. The first method added is the name of the
446
+ element. It finds the element using [Capybara::Node::Finders#find](https://www.rubydoc.info/github/teamcapybara/capybara/master/Capybara/Node/Finders#find-instance_method)
447
+ returning a [Capybara::Node::Element](https://www.rubydoc.info/github/teamcapybara/capybara/master/Capybara/Node/Element) or
448
+ raising [Capybara::ElementNotFound](https://www.rubydoc.info/github/teamcapybara/capybara/master/Capybara/ElementNotFound)
449
+ if the element can not be found.
430
450
 
431
451
  ```ruby
432
452
  class Home < SitePrism::Page
@@ -450,7 +470,9 @@ end
450
470
  #### Testing for the existence of the element
451
471
 
452
472
  Another method added to the Page class by the `element` method is the
453
- `has_<element_name>?` method. Using the same example as above:
473
+ `has_<element_name>?` method.
474
+ This method delegates to [Capybara::Node::Matchers#has_selector?](https://www.rubydoc.info/github/teamcapybara/capybara/master/Capybara/Node/Matchers#has_selector%3F-instance_method).
475
+ Using the same example as above:
454
476
 
455
477
  ```ruby
456
478
  class Home < SitePrism::Page
@@ -480,7 +502,9 @@ end
480
502
 
481
503
  To test that an element does not exist on the page, it is not possible to just call
482
504
  `#not_to have_search_field`. SitePrism supplies the `#has_no_<element>?` method
483
- that should be used to test for non-existence. Using the above example:
505
+ that should be used to test for non-existence.
506
+ 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
+ Using the above example:
484
508
 
485
509
  ```ruby
486
510
  @home = Home.new
@@ -499,8 +523,9 @@ end
499
523
  #### Waiting for an element to become visible
500
524
 
501
525
  A method that gets added by calling `element` is the
502
- `wait_until_<element_name>_visible` method. Calling this method will
503
- cause the test to wait for Capybara's default wait time for the element
526
+ `wait_until_<element_name>_visible` method.
527
+ This method delegates to [Capybara::Node::Matchers#has_selector?](https://www.rubydoc.info/github/teamcapybara/capybara/master/Capybara/Node/Matchers#has_selector%3F-instance_method).
528
+ Calling this method will cause the test to wait for Capybara's default wait time for the element
504
529
  to become visible. You can customise the wait time by supplying a number
505
530
  of seconds to wait in-line or configuring the default wait time.
506
531
 
@@ -513,10 +538,11 @@ of seconds to wait in-line or configuring the default wait time.
513
538
  #### Waiting for an element to become invisible
514
539
 
515
540
  Another method added by calling `element` is the
516
- `wait_until_<element_name>_invisible` method. Calling this method will
517
- cause the test to wait for Capybara's default wait time for the element
518
- to become invisible. You can as with the visibility waiter, customise
519
- the wait time in the same way.
541
+ `wait_until_<element_name>_invisible` method.
542
+ 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).
543
+ Calling this method will cause the test to wait for Capybara's default
544
+ wait time for the element to become invisible. You can as with the visibility
545
+ waiter, customise the wait time in the same way.
520
546
 
521
547
  ```ruby
522
548
  @home.wait_until_search_field_invisible
@@ -736,6 +762,28 @@ use the bleeding edge version of the logic. Then simply set the following config
736
762
  SitePrism.use_all_there_gem = true
737
763
  ```
738
764
 
765
+ ### Getting the list of missing elements
766
+
767
+ If `#all_there?` returns false and you wish to get the list of missing elements for debugging purposes
768
+ you may want to use `#elements_missing` method. It will return all missing elements from the expected_elements list
769
+
770
+ If you do not provide a list of `expected_elements` this method will return all elements that are missing on the page;
771
+ from those which are defined.
772
+
773
+ ```ruby
774
+ class Home < SitePrism::Page
775
+ element :name, '#name'
776
+ element :address, '#address'
777
+ element :success_message, 'span.alert-success'
778
+
779
+ expected_elements :name, :address
780
+ end
781
+
782
+ # and... Only `address` is on the page
783
+
784
+ @test_page.elements_missing #=> [:name]
785
+ ```
786
+
739
787
  ## Sections
740
788
 
741
789
  SitePrism allows you to model sections of a page that appear on multiple
@@ -1467,7 +1515,7 @@ the validations will be performed in the following order:
1467
1515
  **NB:** `SitePrism::Page` **used to** include a default load validation on
1468
1516
  `page.displayed?` however for v3 this has been removed. It is therefore
1469
1517
  necessary to re-define this if you want to retain the behaviour
1470
- from site_prism v2. See [UPGRADING.md](https://github.com/site-prism/site_prism/blob/master/UPGRADING.md#default-load-validations)
1518
+ from site_prism v2. See [UPGRADING.md](https://github.com/site-prism/site_prism/blob/main/UPGRADING.md#default-load-validations)
1471
1519
  for more info on this.
1472
1520
 
1473
1521
  ## Using Capybara Query Options
@@ -1688,7 +1736,7 @@ end
1688
1736
  ```
1689
1737
 
1690
1738
  Note that even with implicit waits on you can dynamically modify the wait times
1691
- in any SitePrism method to help work-around special circumstances.
1739
+ in any SitePrism method to help work-around special circumstances.
1692
1740
 
1693
1741
  ```ruby
1694
1742
  # Option 1: using wait key assignment
data/lib/site_prism.rb CHANGED
@@ -3,15 +3,20 @@
3
3
  require 'site_prism/error'
4
4
  require 'addressable/template'
5
5
 
6
+ # [SitePrism] namespace
7
+ # We autoload our files underneath here to provide a slightly more optimal load solution
6
8
  module SitePrism
7
9
  autoload :AddressableUrlMatcher, 'site_prism/addressable_url_matcher'
8
- autoload :Deprecator, 'site_prism/deprecator'
9
10
  autoload :DSL, 'site_prism/dsl'
11
+ autoload :Deprecator, 'site_prism/deprecator'
10
12
  autoload :ElementChecker, 'site_prism/element_checker'
11
- autoload :RecursionChecker, 'site_prism/recursion_checker'
13
+ autoload :Loadable, 'site_prism/loadable'
12
14
  autoload :Logger, 'site_prism/logger'
13
15
  autoload :Page, 'site_prism/page'
16
+ autoload :RecursionChecker, 'site_prism/recursion_checker'
17
+ autoload :RspecMatchers, 'site_prism/rspec_matchers'
14
18
  autoload :Section, 'site_prism/section'
19
+ autoload :Timer, 'site_prism/timer'
15
20
  autoload :Waiter, 'site_prism/waiter'
16
21
 
17
22
  class << self
@@ -4,6 +4,10 @@ require 'digest'
4
4
  require 'base64'
5
5
 
6
6
  module SitePrism
7
+ # [SitePrism::AddressableUrlMatcher]
8
+ # Used in a couple of places to allow users to ...
9
+ # Specify patterns for loading webpages
10
+ # Pass in hashable args or query parameters for loading dynamic pages
7
11
  class AddressableUrlMatcher
8
12
  attr_reader :pattern
9
13
 
@@ -43,12 +47,10 @@ module SitePrism
43
47
  def all_expected_mappings_match?(expected_mappings, actual_mappings)
44
48
  expected_mappings.all? do |key, expected_value|
45
49
  actual_value = actual_mappings[key.to_s]
46
- if expected_value.is_a?(Numeric)
47
- actual_value == expected_value.to_s
48
- elsif expected_value.is_a?(Regexp)
49
- actual_value.match(expected_value)
50
- else
51
- expected_value == actual_value
50
+ case expected_value
51
+ when Numeric; then actual_value == expected_value.to_s
52
+ when Regexp; then actual_value.match(expected_value)
53
+ else expected_value == actual_value
52
54
  end
53
55
  end
54
56
  end
@@ -1,8 +1,13 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module SitePrism
4
+ # [SitePrism::Deprecator]
4
5
  class Deprecator
5
6
  class << self
7
+ # @return SitePrism.logger.warn(msg)
8
+ #
9
+ # Tells the user that they are using old functionality, which needs removing in the
10
+ # next major version
6
11
  def deprecate(old, new = nil)
7
12
  if new
8
13
  warn("#{old} is being deprecated and should no longer be used. Use #{new} instead.")
@@ -13,6 +18,14 @@ module SitePrism
13
18
  warn("#{old} will be removed in SitePrism v4. You have been warned!")
14
19
  end
15
20
 
21
+ # @return SitePrism.logger.debug(msg)
22
+ #
23
+ # Tells the user that they are using functionality which is non-optimal
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
+ #
27
+ # NB: As this is bubbled up at debug level, often users will not see this. So it will
28
+ # never be a candidate for removal directly
16
29
  def soft_deprecate(old, reason, new = nil)
17
30
  debug("The #{old} method is changing, as is SitePrism, and is now configurable.")
18
31
  debug("REASON: #{reason}.")
@@ -1,6 +1,13 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module SitePrism
4
+ # [SitePrism::DSL]
5
+ #
6
+ # This is the core Module Namespace for all of the public-facing DSL methods
7
+ # such as `element`. The code here is designed to be used through the defining
8
+ # of said items, and not to be instantiated directly.
9
+ #
10
+ # The whole package here can be thought of as [@api private]
4
11
  module DSL
5
12
  def self.included(klass)
6
13
  klass.extend ClassMethods
@@ -8,9 +15,28 @@ module SitePrism
8
15
 
9
16
  private
10
17
 
11
- # The default waiting time set by Capybara's configuration settings.
12
- def wait_time
13
- Capybara.default_max_wait_time
18
+ # Call `find` inside context set on page/section
19
+ def _find(*find_args)
20
+ kwargs = find_args.pop
21
+ page.find(*find_args, **kwargs)
22
+ end
23
+
24
+ # Call `all` inside context set on page/section
25
+ def _all(*find_args)
26
+ kwargs = find_args.pop
27
+ page.all(*find_args, **kwargs)
28
+ end
29
+
30
+ # Call `has_selector?` inside context set on page/section
31
+ def element_exists?(*find_args)
32
+ kwargs = find_args.pop
33
+ page.has_selector?(*find_args, **kwargs)
34
+ end
35
+
36
+ # Call `has_no_selector?` inside context set on page/section
37
+ def element_does_not_exist?(*find_args)
38
+ kwargs = find_args.pop
39
+ page.has_no_selector?(*find_args, **kwargs)
14
40
  end
15
41
 
16
42
  # Prevent users from calling methods with blocks when they shouldn't be.
@@ -68,21 +94,29 @@ module SitePrism
68
94
  #
69
95
  # If the hash is empty, then the hash is omitted from the payload sent
70
96
  # to Capybara, and the find / runtime arguments are sent alone.
97
+ #
98
+ # NB: If the +wait+ key is present in the options hash, even as false or 0, It will
99
+ # be set as the user-supplied value (So user error can be the cause for issues).
71
100
  def recombine_args(find_args, runtime_args, options)
72
101
  options.merge!(find_args.pop) if find_args.last.is_a? Hash
73
102
  options.merge!(runtime_args.pop) if runtime_args.last.is_a? Hash
74
- options[:wait] = wait_time unless wait_key_present?(options)
75
- end
76
-
77
- # Detect if the +wait+ key is present in the options hash.
78
- # Note that setting it to to false or 0, still will return true here.
79
- def wait_key_present?(options)
80
- options.key?(:wait)
103
+ options[:wait] = Capybara.default_max_wait_time unless options.key?(:wait)
81
104
  end
82
105
 
106
+ # SitePrism::DSL::ClassMethods
107
+ # This exposes all of the DSL definitions users will use when generating
108
+ # their POM classes.
109
+ #
110
+ # Many of these methods will be used in-line to allow users to generate a multitude of
111
+ # methods and locators for finding elements / sections on a page or section of a page
83
112
  module ClassMethods
84
113
  attr_reader :expected_items
85
114
 
115
+ # Creates an instance of a SitePrism Element - This will create several methods designed to
116
+ # Locate the element -> @return [Capybara::Node::Element]
117
+ # Check the elements presence or non-presence -> @return [Boolean]
118
+ # Wait for the elements to be present or not -> @return [TrueClass, SitePrism::Error]
119
+ # Validate certain properties about the element
86
120
  def element(name, *find_args)
87
121
  SitePrism::Deprecator.deprecate('Passing a block to :element') if block_given?
88
122
  build(:element, name, *find_args) do
@@ -94,6 +128,11 @@ module SitePrism
94
128
  end
95
129
  end
96
130
 
131
+ # Creates a enumerable instance of a SitePrism Element - This will create several methods designed to
132
+ # Locate the enumerable element -> @return [Capybara::Result]
133
+ # Check the elements presence or non-presence -> @return [Boolean]
134
+ # Wait for the elements to be present or not -> @return [TrueClass, SitePrism::Error]
135
+ # Validate certain properties about the elements
97
136
  def elements(name, *find_args)
98
137
  SitePrism::Deprecator.deprecate('Passing a block to :elements') if block_given?
99
138
  build(:elements, name, *find_args) do
@@ -105,10 +144,18 @@ module SitePrism
105
144
  end
106
145
  end
107
146
 
147
+ # Sets the `expected_items` iVar on a class. This property is used in conjunction with
148
+ # `all_there?` to provide a way of granularising the check made to only interrogate a sub-set
149
+ # of DSL defined items
108
150
  def expected_elements(*elements)
109
151
  @expected_items = elements
110
152
  end
111
153
 
154
+ # Creates an instance of a SitePrism Section - This will create several methods designed to
155
+ # Locate the section -> @return [SitePrism::Section]
156
+ # Check the section presence or non-presence -> @return [Boolean]
157
+ # Wait for the section to be present or not -> @return [TrueClass, SitePrism::Error]
158
+ # Validate certain properties about the section
112
159
  def section(name, *args, &block)
113
160
  section_class, find_args = extract_section_options(args, &block)
114
161
  build(:section, name, *find_args) do
@@ -120,6 +167,11 @@ module SitePrism
120
167
  end
121
168
  end
122
169
 
170
+ # Creates an enumerable instance of a SitePrism Section - This will create several methods designed to
171
+ # Locate the sections -> @return [Array]
172
+ # Check the sections presence or non-presence -> @return [Boolean]
173
+ # Wait for the sections to be present or not -> @return [TrueClass, SitePrism::Error]
174
+ # Validate certain properties about the section
123
175
  def sections(name, *args, &block)
124
176
  section_class, find_args = extract_section_options(args, &block)
125
177
  build(:sections, name, *find_args) do
@@ -145,12 +197,13 @@ module SitePrism
145
197
  end
146
198
  end
147
199
 
200
+ # Return a list of all mapped items on a SitePrism class instance (Page or Section)
201
+ # If legacy is set to true (Default) -> @return [Array]
202
+ # If legacy is set to false (New behaviour) -> @return [Hash]
148
203
  def mapped_items(legacy: true)
149
- if legacy
150
- old_mapped_items
151
- else
152
- new_mapped_items
153
- end
204
+ return old_mapped_items if legacy
205
+
206
+ new_mapped_items
154
207
  end
155
208
 
156
209
  private
@@ -165,13 +218,7 @@ module SitePrism
165
218
  end
166
219
 
167
220
  def new_mapped_items
168
- @new_mapped_items ||= {
169
- element: [],
170
- elements: [],
171
- section: [],
172
- sections: [],
173
- iframe: [],
174
- }
221
+ @new_mapped_items ||= { element: [], elements: [], section: [], sections: [], iframe: [] }
175
222
  end
176
223
 
177
224
  def build(type, name, *find_args)
@@ -192,27 +239,15 @@ module SitePrism
192
239
  def add_helper_methods(name, *find_args)
193
240
  create_existence_checker(name, *find_args)
194
241
  create_nonexistence_checker(name, *find_args)
195
- create_rspec_existence_matchers(name) if defined?(RSpec)
242
+ SitePrism::RspecMatchers.new(name)._create_rspec_existence_matchers if defined?(RSpec)
196
243
  create_visibility_waiter(name, *find_args)
197
244
  create_invisibility_waiter(name, *find_args)
198
245
  end
199
246
 
200
247
  def create_helper_method(proposed_method_name, *find_args)
201
- if find_args.empty?
202
- create_error_method(proposed_method_name)
203
- else
204
- yield
205
- end
206
- end
248
+ return create_error_method(proposed_method_name) if find_args.empty?
207
249
 
208
- def create_rspec_existence_matchers(element_name)
209
- matcher = "has_#{element_name}?"
210
- negated_matcher = "has_no_#{element_name}?"
211
-
212
- RSpec::Matchers.define "have_#{element_name}" do |*args|
213
- match { |actual| actual.public_send(matcher, *args) }
214
- match_when_negated { |actual| actual.public_send(negated_matcher, *args) }
215
- end
250
+ yield
216
251
  end
217
252
 
218
253
  def create_existence_checker(element_name, *find_args)
@@ -261,6 +296,10 @@ module SitePrism
261
296
 
262
297
  def create_error_method(name)
263
298
  SitePrism.logger.error("#{name} has come from an item with no locators.")
299
+ SitePrism::Deprecator.soft_deprecate(
300
+ 'DSL definition with no find_args',
301
+ 'All DSL elements should have find_args'
302
+ )
264
303
  define_method(name) { raise SitePrism::InvalidElementError }
265
304
  end
266
305
 
@@ -296,7 +335,7 @@ module SitePrism
296
335
  def extract_section_options(args, &block)
297
336
  if args.first.is_a?(Class)
298
337
  klass = args.shift
299
- section_class = klass if klass.ancestors.include?(SitePrism::Section)
338
+ section_class = klass if klass <= SitePrism::Section
300
339
  end
301
340
 
302
341
  section_class = deduce_section_class(section_class, &block)
@@ -306,23 +345,26 @@ module SitePrism
306
345
 
307
346
  def deduce_section_class(base_class, &block)
308
347
  klass = base_class
309
- klass = Class.new(klass || SitePrism::Section, &block) if block_given?
348
+ klass = Class.new(klass || SitePrism::Section, &block) if block
310
349
  return klass if klass
311
350
 
312
- raise ArgumentError, "You should provide descendant of \
313
- SitePrism::Section class or/and a block as the second argument."
351
+ raise ArgumentError, 'You should provide descendant of SitePrism::Section class or/and a block as the second argument.'
314
352
  end
315
353
 
316
354
  def deduce_search_arguments(section_class, args)
317
355
  extract_search_arguments(args) ||
318
356
  extract_search_arguments(section_class.default_search_arguments) ||
319
- raise(ArgumentError, "You should provide search arguments \
320
- in section creation or set_default_search_arguments within section class")
357
+ invalidate_search_arguments!
321
358
  end
322
359
 
323
360
  def extract_search_arguments(args)
324
361
  args if args && !args.empty?
325
362
  end
363
+
364
+ def invalidate_search_arguments!
365
+ SitePrism.logger.error('Could not deduce search_arguments')
366
+ raise(ArgumentError, 'search arguments are needed in `section` definition or alternatively use `set_default_search_arguments`')
367
+ end
326
368
  end
327
369
  end
328
370
  end
@@ -1,6 +1,11 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module SitePrism
4
+ # [SitePrism::ElementChecker]
5
+ #
6
+ # This allows users to run `#all_there?` checks on an instance.
7
+ #
8
+ # NB: This functionality is being removed in v4 in favour of the all_there gem
4
9
  module ElementChecker
5
10
  # Runnable in the scope of any SitePrism::Page or Section.
6
11
  # Returns +true+ when "every item" that is being checked is
@@ -21,20 +26,29 @@ module SitePrism
21
26
  # Override: 'one' => Perform one recursive dive into all section/sections
22
27
  # items and call #all_there? on all of those items too.
23
28
  def all_there?(recursion: :none)
24
- if recursion == :none
25
- elements_to_check.all? { |name| there?(name) }
26
- elsif recursion == :one
27
- all_there_with_recursion
29
+ case recursion
30
+ when :none; then elements_to_check.all? { |name| there?(name) }
31
+ when :one; then all_there_with_recursion
28
32
  else
29
33
  SitePrism.logger.debug("Input value '#{recursion}'. Valid values are :none or :one.")
30
34
  SitePrism.logger.error('Invalid recursion setting, Will not run #all_there?.')
31
35
  end
32
36
  end
33
37
 
38
+ # Returns each element that is currently present inside the scope being tested
39
+ #
40
+ # @return [Array]
34
41
  def elements_present
35
42
  _mapped_items.select { |name| there?(name) }
36
43
  end
37
44
 
45
+ # Returns each element that is not currently present inside the scope being tested
46
+ #
47
+ # @return [Array]
48
+ def elements_missing
49
+ elements_to_check.reject { |name| there?(name) }
50
+ end
51
+
38
52
  private
39
53
 
40
54
  def all_there_with_recursion
@@ -25,14 +25,6 @@ module SitePrism
25
25
  # Formerly known as `NoSelectorForElement`
26
26
  class InvalidElementError < SitePrismError; end
27
27
 
28
- # A tool like Timecop is being used to "freeze time" by overriding Time.now
29
- # and similar methods. In this case, our waiter functions won't work, because
30
- # Time.now does not change.
31
- # If you encounter this issue, check that you are not doing Timecop.freeze without
32
- # an accompanying Timecop.return.
33
- # Also check out Timecop.safe_mode https://github.com/travisjeffery/timecop#timecopsafe_mode
34
- class FrozenInTimeError < SitePrismError; end
35
-
36
28
  # The condition that was being evaluated inside the block did not evaluate
37
29
  # to true within the time limit
38
30
  # Formerly known as `TimeoutException`
@@ -1,6 +1,13 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module SitePrism
4
+ # [SitePrism::Loadable]
5
+ #
6
+ # SitePrism Loadable's are defined as checks or waiters which "must" pass before
7
+ # the rest of the loading logic can be performed on a class or section.
8
+ #
9
+ # Loadable's are primarily used with the `#load` method which will auto-execute them all
10
+ # in their defined order. But they can be used dynamically wherever desired.
4
11
  module Loadable
5
12
  module ClassMethods
6
13
  # The list of load_validations.
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'site_prism/loadable'
4
-
5
3
  module SitePrism
6
4
  class Page
7
5
  include Capybara::DSL
@@ -12,25 +10,36 @@ module SitePrism
12
10
  class << self
13
11
  attr_reader :url
14
12
 
13
+ # Sets and returns the specific url that will be loaded for a page object
14
+ #
15
+ # @return [String]
15
16
  def set_url(page_url)
16
17
  @url = page_url.to_s
17
18
  end
18
19
 
20
+ # Sets and returns the specific url matcher that will be used to validate the page is loaded
21
+ #
22
+ # @return [Regexp]
19
23
  def set_url_matcher(page_url_matcher)
20
24
  @url_matcher = page_url_matcher
21
25
  end
22
26
 
27
+ # The specific url matcher that is used to validate the page is loaded.
28
+ # When one hasn't been previously set, use the url that was set as a direct Regexp exact matcher
29
+ #
30
+ # @return [Regexp]
23
31
  def url_matcher
24
32
  @url_matcher ||= url
25
33
  end
26
34
  end
27
35
 
36
+ # Where a Capybara HTML fragment has been directly injected into `#load` as a block return this loaded fragment
37
+ # Where a page has been directly navigated to through traditional means (i.e. Selenium), return an instance of the
38
+ # current Capybara session (With all applicable methods)
39
+ #
40
+ # @return [Capybara::Node::Simple || Capybara::Session]
28
41
  def page
29
- if defined?(@page)
30
- @page
31
- else
32
- Capybara.current_session
33
- end
42
+ (defined?(@page) && @page) || Capybara.current_session
34
43
  end
35
44
 
36
45
  # Loads the page.
@@ -72,24 +81,19 @@ module SitePrism
72
81
  raise SitePrism::NoUrlMatcherForPageError unless url_matcher
73
82
 
74
83
  expected_mappings = args.last.is_a?(::Hash) ? args.pop : {}
75
- seconds = args&.first || wait_time
84
+ seconds = args&.first || Capybara.default_max_wait_time
76
85
  Waiter.wait_until_true(seconds) { url_matches?(expected_mappings) }
77
86
  end
78
87
 
79
- def url_matches(seconds = wait_time)
88
+ def url_matches(seconds = Capybara.default_max_wait_time)
80
89
  return unless displayed?(seconds)
90
+ return regexp_backed_matches if url_matcher.is_a?(Regexp)
81
91
 
82
- if url_matcher.is_a?(Regexp)
83
- regexp_backed_matches
84
- else
85
- template_backed_matches
86
- end
92
+ template_backed_matches
87
93
  end
88
94
 
89
95
  def url(expansion = {})
90
- return nil if self.class.url.nil?
91
-
92
- Addressable::Template.new(self.class.url).expand(expansion).to_s
96
+ self.class.url && Addressable::Template.new(self.class.url).expand(expansion).to_s
93
97
  end
94
98
 
95
99
  def url_matcher
@@ -102,26 +106,6 @@ module SitePrism
102
106
 
103
107
  private
104
108
 
105
- def _find(*find_args)
106
- kwargs = find_args.pop
107
- page.find(*find_args, **kwargs)
108
- end
109
-
110
- def _all(*find_args)
111
- kwargs = find_args.pop
112
- page.all(*find_args, **kwargs)
113
- end
114
-
115
- def element_exists?(*find_args)
116
- kwargs = find_args.pop
117
- page.has_selector?(*find_args, **kwargs)
118
- end
119
-
120
- def element_does_not_exist?(*find_args)
121
- kwargs = find_args.pop
122
- page.has_no_selector?(*find_args, **kwargs)
123
- end
124
-
125
109
  def regexp_backed_matches
126
110
  url_matcher.match(page.current_url)
127
111
  end
@@ -165,7 +149,7 @@ module SitePrism
165
149
  visit expanded_url
166
150
  if with_validations
167
151
  when_loaded(&block)
168
- elsif block_given?
152
+ elsif block
169
153
  yield self
170
154
  end
171
155
  end
@@ -3,6 +3,7 @@
3
3
  module SitePrism
4
4
  class RecursionChecker
5
5
  attr_reader :instance
6
+
6
7
  private :instance
7
8
 
8
9
  def initialize(instance)
@@ -28,7 +29,7 @@ module SitePrism
28
29
  expected(mapped_items, :elements),
29
30
  expected(mapped_items, :section),
30
31
  expected(mapped_items, :sections),
31
- expected(mapped_items, :iframe),
32
+ expected(mapped_items, :iframe)
32
33
  ]
33
34
  end
34
35
 
@@ -0,0 +1,48 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SitePrism
4
+ class RspecMatchers
5
+ attr_reader :element_name
6
+
7
+ def initialize(element_name)
8
+ @element_name = element_name
9
+ end
10
+
11
+ def _create_rspec_existence_matchers
12
+ SitePrism.logger.debug('Including all relevant matcher names / warnings in RSpec scope.')
13
+ create_rspec_existence_matchers(matcher, object_method, negated_object_method, warning)
14
+ end
15
+
16
+ private
17
+
18
+ def create_rspec_existence_matchers(matcher, object_method, negated_object_method, warning)
19
+ RSpec::Matchers.define(matcher) do |*args|
20
+ match { |actual| actual.public_send(object_method, *args) }
21
+ match_when_negated do |actual|
22
+ return actual.public_send(negated_object_method, *args) if actual.respond_to?(negated_object_method)
23
+
24
+ SitePrism.logger.debug(warning)
25
+ !actual.public_send(object_method, *args)
26
+ end
27
+ end
28
+ end
29
+
30
+ def matcher
31
+ "have_#{element_name}"
32
+ end
33
+
34
+ def object_method
35
+ "has_#{element_name}?"
36
+ end
37
+
38
+ def negated_object_method
39
+ "has_no_#{element_name}?"
40
+ end
41
+
42
+ def warning
43
+ "The RSpec matcher '#{matcher}' was added by SitePrism, but the object under test "\
44
+ "does not respond to '#{negated_object_method}' and is probably not a SitePrism object. "\
45
+ 'Falling back to the default RSpec matcher.'
46
+ end
47
+ end
48
+ end
@@ -1,10 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'site_prism/loadable'
4
-
5
3
  module SitePrism
6
4
  class Section
7
- include Capybara::DSL
8
5
  include ElementChecker
9
6
  include Loadable
10
7
  include DSL
@@ -12,48 +9,67 @@ module SitePrism
12
9
 
13
10
  attr_reader :root_element, :parent
14
11
 
15
- def self.set_default_search_arguments(*args)
16
- @default_search_arguments = args
17
- end
12
+ class << self
13
+ def set_default_search_arguments(*args)
14
+ @default_search_arguments = args
15
+ end
16
+
17
+ def default_search_arguments
18
+ return @default_search_arguments if @default_search_arguments
19
+
20
+ superclass.respond_to?(:default_search_arguments) && superclass.default_search_arguments
21
+ end
18
22
 
19
- def self.default_search_arguments
20
- @default_search_arguments ||
21
- (
22
- superclass.respond_to?(:default_search_arguments) &&
23
- superclass.default_search_arguments
24
- ) ||
25
- nil
23
+ private
24
+
25
+ def root_element_methods
26
+ ::Capybara::Session::NODE_METHODS + %i[native visible?]
27
+ end
28
+
29
+ def session_methods
30
+ ::Capybara::Session::DSL_METHODS - root_element_methods
31
+ end
26
32
  end
27
33
 
28
34
  def initialize(parent, root_element, &block)
29
35
  @parent = parent
30
36
  @root_element = root_element
31
- within(&block) if block_given?
37
+ within(&block) if block
32
38
  end
33
39
 
34
- def within
35
- Capybara.within(@root_element) { yield(self) }
40
+ # Send all root_element methods through `#root_element`
41
+ # NB: This requires a method called `#to_capybara_node` being created and
42
+ # then set to this value (Capybara agnostic API)
43
+ root_element_methods.each do |method|
44
+ def_delegators :root_element, method
36
45
  end
37
46
 
38
- # Capybara::DSL module "delegates" Capybara methods to the "page" method
39
- # as such we need to overload this method so that the correct scoping
40
- # occurs and calls within a section (For example section.find(element))
41
- # correctly scope to look within the section only
42
- def page
43
- return root_element if root_element
47
+ # Send all methods that previously acted on the `#page` method that existed previously
48
+ # through to the same location - But directly as `Capybara.current_session`
49
+ session_methods.each do |method|
50
+ def_delegators :capybara_session, method
51
+ end
44
52
 
45
- SitePrism.logger.warn('Root Element not found; Falling back to `super`')
46
- super
53
+ # This scopes our calls inside Section correctly to the `Capybara::Node::Element`
54
+ def to_capybara_node
55
+ root_element
47
56
  end
48
57
 
49
- def visible?
50
- page.visible?
58
+ # This allows us to return anything thats passed in as a block to the section at
59
+ # creation time, so that an anonymous section or such-like will have the extra methods
60
+ def within
61
+ Capybara.within(root_element) { yield(self) }
51
62
  end
52
63
 
53
- def_delegators :capybara_session,
54
- :execute_script,
55
- :evaluate_script,
56
- :within_frame
64
+ # This was the old API-style of delegating through the Capybara.page call and over-loading
65
+ # the method so we always went through our correct `root_element`
66
+ def page
67
+ SitePrism::Deprecator.deprecate('Using page inside section')
68
+ return root_element if root_element
69
+
70
+ SitePrism.logger.warn('Root Element not found; Falling back to Capybara.current_session')
71
+ capybara_session
72
+ end
57
73
 
58
74
  def capybara_session
59
75
  Capybara.current_session
@@ -64,31 +80,5 @@ module SitePrism
64
80
  candidate = candidate.parent until candidate.is_a?(SitePrism::Page)
65
81
  candidate
66
82
  end
67
-
68
- def native
69
- root_element.native
70
- end
71
-
72
- private
73
-
74
- def _find(*find_args)
75
- kwargs = find_args.pop
76
- page.find(*find_args, **kwargs)
77
- end
78
-
79
- def _all(*find_args)
80
- kwargs = find_args.pop
81
- page.all(*find_args, **kwargs)
82
- end
83
-
84
- def element_exists?(*find_args)
85
- kwargs = find_args.pop
86
- page.has_selector?(*find_args, **kwargs)
87
- end
88
-
89
- def element_does_not_exist?(*find_args)
90
- kwargs = find_args.pop
91
- page.has_no_selector?(*find_args, **kwargs)
92
- end
93
83
  end
94
84
  end
@@ -0,0 +1,65 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SitePrism
4
+ # [SitePrism::Timer]
5
+ #
6
+ # Used to count asynchronously towards an overall desired duration or condition (Block)
7
+ class Timer
8
+ attr_reader :wait_time
9
+
10
+ # Return &block
11
+ #
12
+ # Count towards a specified time (Supplied)
13
+ def self.run(wait_time, &block)
14
+ new(wait_time).run(&block)
15
+ end
16
+
17
+ def initialize(wait_time)
18
+ @wait_time = wait_time
19
+ @done = false
20
+ end
21
+
22
+ # Return Boolean
23
+ #
24
+ # Whether the timer has completed
25
+ def done?
26
+ @done == true
27
+ end
28
+
29
+ # Return &block
30
+ #
31
+ # Start the Timer and re-evaluate the block repeatedly
32
+ def run
33
+ start
34
+ yield self
35
+ ensure
36
+ stop
37
+ end
38
+
39
+ # Return [Boolean, Nil]
40
+ #
41
+ # Start the Timer in a separate process
42
+ def start
43
+ stop
44
+ return if wait_time.zero?
45
+
46
+ @done = false
47
+ @thread = Thread.start do
48
+ sleep wait_time
49
+ @done = true
50
+ end
51
+ end
52
+
53
+ # Return True
54
+ #
55
+ # Forcibly stop the timer, and kill any threads created by it
56
+ def stop
57
+ if @thread
58
+ @thread.kill
59
+ @thread.join
60
+ @thread = nil
61
+ end
62
+ @done = true
63
+ end
64
+ end
65
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module SitePrism
4
- VERSION = '3.5'
4
+ VERSION = '3.7.2'
5
5
  end
@@ -1,34 +1,22 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module SitePrism
4
+ # [SitePrism::Waiter]
4
5
  class Waiter
5
- class << self
6
- def wait_until_true(wait_time = Capybara.default_max_wait_time)
7
- start_time = Time.now
8
-
6
+ # @return Boolean
7
+ #
8
+ # A looper that will wait until the passed in block evaluates to true
9
+ # Alternatively it will time out once the wait_time is exceeded
10
+ def self.wait_until_true(wait_time = Capybara.default_max_wait_time)
11
+ Timer.run(wait_time) do |timer|
9
12
  loop do
10
13
  return true if yield
11
- break if Time.now - start_time > wait_time
14
+ break if timer.done?
12
15
 
13
16
  sleep(0.05)
14
-
15
- check_for_time_stopped!(start_time)
16
17
  end
17
-
18
18
  raise SitePrism::TimeoutError, "Timed out after #{wait_time}s."
19
19
  end
20
-
21
- private
22
-
23
- def check_for_time_stopped!(start_time)
24
- return unless start_time == Time.now
25
-
26
- raise(
27
- SitePrism::FrozenInTimeError,
28
- 'Time appears to be frozen. For more info, see ' \
29
- 'https://github.com/site-prism/site_prism/blob/master/lib/site_prism/error.rb'
30
- )
31
- end
32
20
  end
33
21
  end
34
22
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: site_prism
3
3
  version: !ruby/object:Gem::Version
4
- version: '3.5'
4
+ version: 3.7.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Luke Hill
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2020-06-04 00:00:00.000000000 Z
12
+ date: 2021-08-23 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: addressable
@@ -29,16 +29,16 @@ dependencies:
29
29
  name: capybara
30
30
  requirement: !ruby/object:Gem::Requirement
31
31
  requirements:
32
- - - "<="
32
+ - - "~>"
33
33
  - !ruby/object:Gem::Version
34
- version: '3.29'
34
+ version: '3.8'
35
35
  type: :runtime
36
36
  prerelease: false
37
37
  version_requirements: !ruby/object:Gem::Requirement
38
38
  requirements:
39
- - - "<="
39
+ - - "~>"
40
40
  - !ruby/object:Gem::Version
41
- version: '3.29'
41
+ version: '3.8'
42
42
  - !ruby/object:Gem::Dependency
43
43
  name: site_prism-all_there
44
44
  requirement: !ruby/object:Gem::Requirement
@@ -63,16 +63,22 @@ dependencies:
63
63
  name: cucumber
64
64
  requirement: !ruby/object:Gem::Requirement
65
65
  requirements:
66
- - - "~>"
66
+ - - ">="
67
67
  - !ruby/object:Gem::Version
68
- version: '3.1'
68
+ version: '4.0'
69
+ - - "<"
70
+ - !ruby/object:Gem::Version
71
+ version: '5.2'
69
72
  type: :development
70
73
  prerelease: false
71
74
  version_requirements: !ruby/object:Gem::Requirement
72
75
  requirements:
73
- - - "~>"
76
+ - - ">="
74
77
  - !ruby/object:Gem::Version
75
- version: '3.1'
78
+ version: '4.0'
79
+ - - "<"
80
+ - !ruby/object:Gem::Version
81
+ version: '5.2'
76
82
  - !ruby/object:Gem::Dependency
77
83
  name: pry-byebug
78
84
  requirement: !ruby/object:Gem::Requirement
@@ -91,114 +97,120 @@ dependencies:
91
97
  name: rake
92
98
  requirement: !ruby/object:Gem::Requirement
93
99
  requirements:
94
- - - ">="
100
+ - - "~>"
95
101
  - !ruby/object:Gem::Version
96
- version: '12.3'
102
+ version: '13.0'
97
103
  type: :development
98
104
  prerelease: false
99
105
  version_requirements: !ruby/object:Gem::Requirement
100
106
  requirements:
101
- - - ">="
107
+ - - "~>"
102
108
  - !ruby/object:Gem::Version
103
- version: '12.3'
109
+ version: '13.0'
104
110
  - !ruby/object:Gem::Dependency
105
111
  name: rspec
106
112
  requirement: !ruby/object:Gem::Requirement
107
113
  requirements:
108
114
  - - "~>"
109
115
  - !ruby/object:Gem::Version
110
- version: '3.8'
116
+ version: '3.9'
111
117
  type: :development
112
118
  prerelease: false
113
119
  version_requirements: !ruby/object:Gem::Requirement
114
120
  requirements:
115
121
  - - "~>"
116
122
  - !ruby/object:Gem::Version
117
- version: '3.8'
123
+ version: '3.9'
118
124
  - !ruby/object:Gem::Dependency
119
125
  name: rubocop
120
126
  requirement: !ruby/object:Gem::Requirement
121
127
  requirements:
122
128
  - - "~>"
123
129
  - !ruby/object:Gem::Version
124
- version: 0.75.0
130
+ version: 0.93.0
125
131
  type: :development
126
132
  prerelease: false
127
133
  version_requirements: !ruby/object:Gem::Requirement
128
134
  requirements:
129
135
  - - "~>"
130
136
  - !ruby/object:Gem::Version
131
- version: 0.75.0
137
+ version: 0.93.0
132
138
  - !ruby/object:Gem::Dependency
133
139
  name: rubocop-performance
134
140
  requirement: !ruby/object:Gem::Requirement
135
141
  requirements:
136
142
  - - "~>"
137
143
  - !ruby/object:Gem::Version
138
- version: 1.5.1
144
+ version: 1.10.1
139
145
  type: :development
140
146
  prerelease: false
141
147
  version_requirements: !ruby/object:Gem::Requirement
142
148
  requirements:
143
149
  - - "~>"
144
150
  - !ruby/object:Gem::Version
145
- version: 1.5.1
151
+ version: 1.10.1
146
152
  - !ruby/object:Gem::Dependency
147
153
  name: rubocop-rspec
148
154
  requirement: !ruby/object:Gem::Requirement
149
155
  requirements:
150
156
  - - "~>"
151
157
  - !ruby/object:Gem::Version
152
- version: 1.33.0
158
+ version: 1.44.0
153
159
  type: :development
154
160
  prerelease: false
155
161
  version_requirements: !ruby/object:Gem::Requirement
156
162
  requirements:
157
163
  - - "~>"
158
164
  - !ruby/object:Gem::Version
159
- version: 1.33.0
165
+ version: 1.44.0
160
166
  - !ruby/object:Gem::Dependency
161
167
  name: selenium-webdriver
162
168
  requirement: !ruby/object:Gem::Requirement
163
169
  requirements:
164
- - - "~>"
170
+ - - ">="
165
171
  - !ruby/object:Gem::Version
166
- version: '3.7'
172
+ version: '3.11'
173
+ - - "<"
174
+ - !ruby/object:Gem::Version
175
+ version: '4.1'
167
176
  type: :development
168
177
  prerelease: false
169
178
  version_requirements: !ruby/object:Gem::Requirement
170
179
  requirements:
171
- - - "~>"
180
+ - - ">="
172
181
  - !ruby/object:Gem::Version
173
- version: '3.7'
182
+ version: '3.11'
183
+ - - "<"
184
+ - !ruby/object:Gem::Version
185
+ version: '4.1'
174
186
  - !ruby/object:Gem::Dependency
175
187
  name: simplecov
176
188
  requirement: !ruby/object:Gem::Requirement
177
189
  requirements:
178
190
  - - "~>"
179
191
  - !ruby/object:Gem::Version
180
- version: '0.17'
192
+ version: '0.18'
181
193
  type: :development
182
194
  prerelease: false
183
195
  version_requirements: !ruby/object:Gem::Requirement
184
196
  requirements:
185
197
  - - "~>"
186
198
  - !ruby/object:Gem::Version
187
- version: '0.17'
199
+ version: '0.18'
188
200
  - !ruby/object:Gem::Dependency
189
201
  name: webdrivers
190
202
  requirement: !ruby/object:Gem::Requirement
191
203
  requirements:
192
204
  - - "~>"
193
205
  - !ruby/object:Gem::Version
194
- version: '4.0'
206
+ version: '4.5'
195
207
  type: :development
196
208
  prerelease: false
197
209
  version_requirements: !ruby/object:Gem::Requirement
198
210
  requirements:
199
211
  - - "~>"
200
212
  - !ruby/object:Gem::Version
201
- version: '4.0'
213
+ version: '4.5'
202
214
  description: SitePrism gives you a simple, clean and semantic DSL for describing your
203
215
  site. SitePrism implements the Page Object Model pattern on top of Capybara.
204
216
  email:
@@ -220,7 +232,9 @@ files:
220
232
  - lib/site_prism/logger.rb
221
233
  - lib/site_prism/page.rb
222
234
  - lib/site_prism/recursion_checker.rb
235
+ - lib/site_prism/rspec_matchers.rb
223
236
  - lib/site_prism/section.rb
237
+ - lib/site_prism/timer.rb
224
238
  - lib/site_prism/version.rb
225
239
  - lib/site_prism/waiter.rb
226
240
  homepage: https://github.com/site-prism/site_prism
@@ -228,7 +242,7 @@ licenses:
228
242
  - BSD-3-Clause
229
243
  metadata:
230
244
  bug_tracker_uri: https://github.com/site-prism/site_prism/issues
231
- changelog_uri: https://github.com/site-prism/site_prism/blob/master/CHANGELOG.md
245
+ changelog_uri: https://github.com/site-prism/site_prism/blob/main/CHANGELOG.md
232
246
  source_code_uri: https://github.com/site-prism/site_prism
233
247
  post_install_message:
234
248
  rdoc_options: []
@@ -238,14 +252,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
238
252
  requirements:
239
253
  - - ">="
240
254
  - !ruby/object:Gem::Version
241
- version: '2.3'
255
+ version: '2.4'
242
256
  required_rubygems_version: !ruby/object:Gem::Requirement
243
257
  requirements:
244
258
  - - ">="
245
259
  - !ruby/object:Gem::Version
246
260
  version: '0'
247
261
  requirements: []
248
- rubygems_version: 3.0.6
262
+ rubygems_version: 3.0.8
249
263
  signing_key:
250
264
  specification_version: 4
251
265
  summary: A Page Object Model DSL for Capybara