site_prism 3.7.3 → 4.0.beta
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 +3 -13
- data/lib/site_prism/addressable_url_matcher.rb +1 -1
- data/lib/site_prism/deprecator.rb +2 -2
- data/lib/site_prism/dsl.rb +52 -67
- data/lib/site_prism/dsl_validator.rb +75 -0
- data/lib/site_prism/element_checker.rb +1 -9
- data/lib/site_prism/error.rb +6 -10
- data/lib/site_prism/page.rb +9 -0
- data/lib/site_prism/rspec_matchers.rb +3 -0
- data/lib/site_prism/section.rb +14 -6
- data/lib/site_prism/version.rb +1 -1
- data/lib/site_prism/waiter.rb +2 -2
- data/lib/site_prism.rb +3 -11
- metadata +25 -39
- 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: 4ebb39462fdc078aff996d358cfadeb4feddbb443cb0655340efa51f4d4af80d
|
4
|
+
data.tar.gz: 2913da09df5462bcf924d3598d8d9f6f4e996c65951acb31694d0dea67990b4d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: '080072c82a3df37666dd079600cd75db84be14b2f73e2f06227bdf48e45f8ff2783a64d122c05e12c8eda54462491a6c0f3d3e935b48fad54278dcf4eab0d841'
|
7
|
+
data.tar.gz: 79157445566537187b9578113b3a3100aa13dbf4cbb615f9e8563dc6d1264177eaab62d9caa2fa79f152118aa1c919a5607477492fa33b1d2b23c6f2bf162b49
|
data/LICENSE.md
CHANGED
data/README.md
CHANGED
@@ -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
|
|
@@ -753,15 +752,6 @@ Work alongside developing this functionality further is being continued in the
|
|
753
752
|
[site_prism-all_there](http://www.github.com/site-prism/site_prism-all_there) repo. So head on over
|
754
753
|
there if you're interested in how this feature will work going forwards
|
755
754
|
|
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
|
-
```
|
764
|
-
|
765
755
|
### Getting the list of missing elements
|
766
756
|
|
767
757
|
If `#all_there?` returns false and you wish to get the list of missing elements for debugging purposes
|
@@ -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
|
@@ -21,8 +21,8 @@ module SitePrism
|
|
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
|
data/lib/site_prism/dsl.rb
CHANGED
@@ -11,10 +11,19 @@ module SitePrism
|
|
11
11
|
module DSL
|
12
12
|
def self.included(klass)
|
13
13
|
klass.extend ClassMethods
|
14
|
+
klass.extend DSLValidator
|
14
15
|
end
|
15
16
|
|
16
17
|
private
|
17
18
|
|
19
|
+
def raise_if_block(object, name, has_block, type)
|
20
|
+
return unless has_block
|
21
|
+
|
22
|
+
SitePrism.logger.debug("Type passed in: #{type}")
|
23
|
+
SitePrism.logger.error("#{object.class}##{name} cannot accept runtime blocks")
|
24
|
+
raise SitePrism::UnsupportedBlockError
|
25
|
+
end
|
26
|
+
|
18
27
|
# Call `find` inside `to_capybara_node` context (Either Capybara::Session or Capybara::Node::Element)
|
19
28
|
def _find(*find_args)
|
20
29
|
kwargs = find_args.pop
|
@@ -39,37 +48,6 @@ module SitePrism
|
|
39
48
|
to_capybara_node.has_no_selector?(*find_args, **kwargs)
|
40
49
|
end
|
41
50
|
|
42
|
-
# Prevent users from calling methods with blocks when they shouldn't be.
|
43
|
-
#
|
44
|
-
# Example (Triggering error):
|
45
|
-
#
|
46
|
-
# class MyPage
|
47
|
-
# element :sample, '.css-locator' do
|
48
|
-
# puts "This won't be output"
|
49
|
-
# end
|
50
|
-
# end
|
51
|
-
#
|
52
|
-
# At runtime this will generate a `SitePrism::UnsupportedBlockError`
|
53
|
-
#
|
54
|
-
# The only DSL keywords that can use blocks are :section and :iframe
|
55
|
-
def raise_if_block(obj, name, has_block, type)
|
56
|
-
return unless has_block
|
57
|
-
|
58
|
-
SitePrism.logger.debug("Type passed in: #{type}")
|
59
|
-
SitePrism.logger.warn('section / iFrame can only accept blocks.')
|
60
|
-
SitePrism.logger.error("#{obj.class}##{name} does not accept blocks")
|
61
|
-
|
62
|
-
raise SitePrism::UnsupportedBlockError
|
63
|
-
end
|
64
|
-
|
65
|
-
# Warn users from naming the elements starting with no_
|
66
|
-
def warn_if_dsl_collision(obj, name)
|
67
|
-
return unless name.to_s.start_with?('no_')
|
68
|
-
|
69
|
-
SitePrism.logger.warn("#{obj.class}##{name} should not start with no_")
|
70
|
-
SitePrism::Deprecator.deprecate('Using no_ prefix in DSL definition')
|
71
|
-
end
|
72
|
-
|
73
51
|
# Sanitize method called before calling any SitePrism DSL method or
|
74
52
|
# meta-programmed method. This ensures that the Capybara query is correct.
|
75
53
|
#
|
@@ -112,17 +90,23 @@ module SitePrism
|
|
112
90
|
module ClassMethods
|
113
91
|
attr_reader :expected_items
|
114
92
|
|
93
|
+
# Sets the `expected_items` iVar on a class. This property is used in conjunction with
|
94
|
+
# `all_there?` to provide a way of granularising the check made to only interrogate a sub-set
|
95
|
+
# of DSL defined items
|
96
|
+
def expected_elements(*elements)
|
97
|
+
@expected_items = elements
|
98
|
+
end
|
99
|
+
|
115
100
|
# Creates an instance of a SitePrism Element - This will create several methods designed to
|
116
101
|
# Locate the element -> @return [Capybara::Node::Element]
|
117
102
|
# Check the elements presence or non-presence -> @return [Boolean]
|
118
103
|
# Wait for the elements to be present or not -> @return [TrueClass, SitePrism::Error]
|
119
104
|
# Validate certain properties about the element
|
120
105
|
def element(name, *find_args)
|
121
|
-
|
106
|
+
raise_if_block(self, name, block_given?, :element)
|
122
107
|
build(:element, name, *find_args) do
|
123
|
-
define_method(name) do |*runtime_args, &
|
124
|
-
|
125
|
-
raise_if_block(self, name, !element_block.nil?, :element)
|
108
|
+
define_method(name) do |*runtime_args, &runtime_block|
|
109
|
+
raise_if_block(self, name, runtime_block, :element)
|
126
110
|
_find(*merge_args(find_args, runtime_args))
|
127
111
|
end
|
128
112
|
end
|
@@ -134,23 +118,15 @@ module SitePrism
|
|
134
118
|
# Wait for the elements to be present or not -> @return [TrueClass, SitePrism::Error]
|
135
119
|
# Validate certain properties about the elements
|
136
120
|
def elements(name, *find_args)
|
137
|
-
|
121
|
+
raise_if_block(self, name, block_given?, :elements)
|
138
122
|
build(:elements, name, *find_args) do
|
139
|
-
define_method(name) do |*runtime_args, &
|
140
|
-
|
141
|
-
raise_if_block(self, name, !element_block.nil?, :elements)
|
123
|
+
define_method(name) do |*runtime_args, &runtime_block|
|
124
|
+
raise_if_block(self, name, runtime_block, :elements)
|
142
125
|
_all(*merge_args(find_args, runtime_args))
|
143
126
|
end
|
144
127
|
end
|
145
128
|
end
|
146
129
|
|
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
|
150
|
-
def expected_elements(*elements)
|
151
|
-
@expected_items = elements
|
152
|
-
end
|
153
|
-
|
154
130
|
# Creates an instance of a SitePrism Section - This will create several methods designed to
|
155
131
|
# Locate the section -> @return [SitePrism::Section]
|
156
132
|
# Check the section presence or non-presence -> @return [Boolean]
|
@@ -160,7 +136,6 @@ module SitePrism
|
|
160
136
|
section_class, find_args = extract_section_options(args, &block)
|
161
137
|
build(:section, name, *find_args) do
|
162
138
|
define_method(name) do |*runtime_args, &runtime_block|
|
163
|
-
warn_if_dsl_collision(self, name)
|
164
139
|
section_element = _find(*merge_args(find_args, runtime_args))
|
165
140
|
section_class.new(self, section_element, &runtime_block)
|
166
141
|
end
|
@@ -175,8 +150,8 @@ module SitePrism
|
|
175
150
|
def sections(name, *args, &block)
|
176
151
|
section_class, find_args = extract_section_options(args, &block)
|
177
152
|
build(:sections, name, *find_args) do
|
178
|
-
define_method(name) do |*runtime_args, &
|
179
|
-
raise_if_block(self, name,
|
153
|
+
define_method(name) do |*runtime_args, &runtime_block|
|
154
|
+
raise_if_block(self, name, runtime_block, :sections)
|
180
155
|
_all(*merge_args(find_args, runtime_args)).map do |element|
|
181
156
|
section_class.new(self, element)
|
182
157
|
end
|
@@ -208,20 +183,9 @@ module SitePrism
|
|
208
183
|
|
209
184
|
private
|
210
185
|
|
211
|
-
def old_mapped_items
|
212
|
-
SitePrism::Deprecator.soft_deprecate(
|
213
|
-
'.mapped_items on a class',
|
214
|
-
'To allow easier recursion through the items in conjunction with #all_there?',
|
215
|
-
'.mapped_items(legacy: false)'
|
216
|
-
)
|
217
|
-
@old_mapped_items ||= []
|
218
|
-
end
|
219
|
-
|
220
|
-
def new_mapped_items
|
221
|
-
@new_mapped_items ||= { element: [], elements: [], section: [], sections: [], iframe: [] }
|
222
|
-
end
|
223
|
-
|
224
186
|
def build(type, name, *find_args)
|
187
|
+
raise InvalidDSLNameError if ENV.fetch('SITEPRISM_DSL_VALIDATION_ENABLED', nil) && invalid?(name)
|
188
|
+
|
225
189
|
if find_args.empty?
|
226
190
|
create_error_method(name)
|
227
191
|
else
|
@@ -231,11 +195,6 @@ module SitePrism
|
|
231
195
|
add_helper_methods(name, *find_args)
|
232
196
|
end
|
233
197
|
|
234
|
-
def map_item(type, name)
|
235
|
-
old_mapped_items << { type => name }
|
236
|
-
new_mapped_items[type] << name.to_sym
|
237
|
-
end
|
238
|
-
|
239
198
|
def add_helper_methods(name, *find_args)
|
240
199
|
create_existence_checker(name, *find_args)
|
241
200
|
create_nonexistence_checker(name, *find_args)
|
@@ -303,6 +262,32 @@ module SitePrism
|
|
303
262
|
define_method(name) { raise SitePrism::InvalidElementError }
|
304
263
|
end
|
305
264
|
|
265
|
+
def raise_if_block(parent_object, name, has_block, type)
|
266
|
+
return unless has_block
|
267
|
+
|
268
|
+
SitePrism.logger.debug("Type passed in: #{type}")
|
269
|
+
SitePrism.logger.error("#{name} has been defined as a '#{type}' item in #{parent_object}. It does not accept build-time blocks.")
|
270
|
+
raise SitePrism::UnsupportedBlockError
|
271
|
+
end
|
272
|
+
|
273
|
+
def old_mapped_items
|
274
|
+
SitePrism::Deprecator.soft_deprecate(
|
275
|
+
'.mapped_items on a class',
|
276
|
+
'To allow easier recursion through the items in conjunction with #all_there?',
|
277
|
+
'.mapped_items(legacy: false)'
|
278
|
+
)
|
279
|
+
@old_mapped_items ||= []
|
280
|
+
end
|
281
|
+
|
282
|
+
def new_mapped_items
|
283
|
+
@new_mapped_items ||= { element: [], elements: [], section: [], sections: [], iframe: [] }
|
284
|
+
end
|
285
|
+
|
286
|
+
def map_item(type, name)
|
287
|
+
old_mapped_items << { type => name }
|
288
|
+
new_mapped_items[type] << name.to_sym
|
289
|
+
end
|
290
|
+
|
306
291
|
def deduce_iframe_scope_find_args(args)
|
307
292
|
warn_on_invalid_selector_input(args)
|
308
293
|
case args[0]
|
@@ -0,0 +1,75 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module SitePrism
|
4
|
+
# [SitePrism::DSLValidator]
|
5
|
+
#
|
6
|
+
# This is the new validator module which will check all DSL items against a whitelist
|
7
|
+
# for any entries which are prohibited
|
8
|
+
module DSLValidator
|
9
|
+
def invalid?(name)
|
10
|
+
prefix_invalid?(name) ||
|
11
|
+
suffix_invalid?(name) ||
|
12
|
+
characters_invalid?(name) ||
|
13
|
+
blacklisted?(name)
|
14
|
+
end
|
15
|
+
|
16
|
+
private
|
17
|
+
|
18
|
+
def prefix_invalid?(name)
|
19
|
+
prefix_blacklist.any? { |prefix| name.start_with?(prefix) }.tap { |result| log_failure(name, 'prefix') unless result }
|
20
|
+
end
|
21
|
+
|
22
|
+
def suffix_invalid?(name)
|
23
|
+
suffix_blacklist.any? { |prefix| name.end_with?(prefix) }.tap { |result| log_failure(name, 'suffix') unless result }
|
24
|
+
end
|
25
|
+
|
26
|
+
def characters_invalid?(name)
|
27
|
+
!name.match?(regex_permission).tap { |result| log_failure(name, 'character(s)') unless result }
|
28
|
+
end
|
29
|
+
|
30
|
+
def blacklisted?(name)
|
31
|
+
blacklisted_names.include?(name).tap { |result| log_failure(name, 'name (blacklisted entry)') unless result }
|
32
|
+
end
|
33
|
+
|
34
|
+
def regex_permission
|
35
|
+
/^[a-z]\w+$/
|
36
|
+
end
|
37
|
+
|
38
|
+
def prefix_blacklist
|
39
|
+
%w[
|
40
|
+
no_
|
41
|
+
_
|
42
|
+
]
|
43
|
+
end
|
44
|
+
|
45
|
+
def suffix_blacklist
|
46
|
+
%w[
|
47
|
+
_
|
48
|
+
?
|
49
|
+
]
|
50
|
+
end
|
51
|
+
|
52
|
+
def blacklisted_names
|
53
|
+
%w[
|
54
|
+
attributes
|
55
|
+
html
|
56
|
+
no
|
57
|
+
title
|
58
|
+
]
|
59
|
+
end
|
60
|
+
|
61
|
+
def log_failure(name, type)
|
62
|
+
SitePrism.logger.error("DSL item: #{name} has an invalid #{type}")
|
63
|
+
SitePrism.logger.debug(debug_error(type))
|
64
|
+
end
|
65
|
+
|
66
|
+
def debug_error(type)
|
67
|
+
case type
|
68
|
+
when 'prefix'; then "Invalid Prefixes: #{prefix_blacklist.join(', ')}."
|
69
|
+
when 'suffix'; then "Invalid Suffixes: #{suffix_blacklist.join(', ')}"
|
70
|
+
when 'character(s)'; then "Invalid DSL Names: #{blacklisted_names.join(', ')}"
|
71
|
+
else "DSL Charset REGEX: #{regex_permission.inspect}"
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
@@ -28,7 +28,7 @@ module SitePrism
|
|
28
28
|
def all_there?(recursion: :none)
|
29
29
|
case recursion
|
30
30
|
when :none; then elements_to_check.all? { |name| there?(name) }
|
31
|
-
when :one; then
|
31
|
+
when :one; then SitePrism::AllThere::RecursionChecker.new(self).all_there?
|
32
32
|
else
|
33
33
|
SitePrism.logger.debug("Input value '#{recursion}'. Valid values are :none or :one.")
|
34
34
|
SitePrism.logger.error('Invalid recursion setting, Will not run #all_there?.')
|
@@ -51,14 +51,6 @@ module SitePrism
|
|
51
51
|
|
52
52
|
private
|
53
53
|
|
54
|
-
def all_there_with_recursion
|
55
|
-
if SitePrism.use_all_there_gem
|
56
|
-
SitePrism::AllThere::RecursionChecker.new(self).all_there?
|
57
|
-
else
|
58
|
-
RecursionChecker.new(self).all_there?
|
59
|
-
end
|
60
|
-
end
|
61
|
-
|
62
54
|
# If the page or section has expected_items set, return expected_items that are mapped
|
63
55
|
# otherwise just return the list of all mapped_items
|
64
56
|
def elements_to_check
|
data/lib/site_prism/error.rb
CHANGED
@@ -8,50 +8,46 @@ module SitePrism
|
|
8
8
|
class PageLoadError < SitePrismError; end
|
9
9
|
|
10
10
|
# A page calls #load with no URL set
|
11
|
-
# Formerly known as `NoUrlForPage`
|
12
11
|
class NoUrlForPageError < PageLoadError; end
|
13
12
|
|
14
13
|
# A page calls #displayed? with no URL matcher set
|
15
|
-
# Formerly known as `NoUrlMatcherForPage`
|
16
14
|
class NoUrlMatcherForPageError < PageLoadError; end
|
17
15
|
|
18
16
|
# The URL matcher was not recognised as a Regex or String and as such
|
19
17
|
# it couldn't be parsed by Addressable. It also could be caused by
|
20
18
|
# the usage of templated port numbers - which aren't supported
|
21
|
-
# Formerly known as `InvalidUrlMatcher`
|
22
19
|
class InvalidUrlMatcherError < PageLoadError; end
|
23
20
|
|
24
21
|
# A SitePrism defined DSL item was defined without a selector
|
25
|
-
# Formerly known as `NoSelectorForElement`
|
26
22
|
class InvalidElementError < SitePrismError; end
|
27
23
|
|
28
24
|
# The condition that was being evaluated inside the block did not evaluate
|
29
25
|
# to true within the time limit
|
30
|
-
# Formerly known as `TimeoutException`
|
31
26
|
class TimeoutError < SitePrismError; end
|
32
27
|
|
33
28
|
# The wait_until_*_visible meta-programmed method didn't evaluate to true
|
34
29
|
# within the prescribed time limit
|
35
|
-
# Formerly known as `TimeOutWaitingForElementVisibility`
|
36
30
|
class ElementVisibilityTimeoutError < TimeoutError; end
|
37
31
|
|
38
32
|
# The wait_until_*_invisible meta-programmed method didn't evaluate to true
|
39
33
|
# within the prescribed time limit
|
40
|
-
# Formerly known as `TimeOutWaitingForElementInvisibility`
|
41
34
|
class ElementInvisibilityTimeoutError < TimeoutError; end
|
42
35
|
|
43
36
|
# Generic Block validation family of errors inherit from this error
|
44
37
|
class BlockError < SitePrismError; end
|
45
38
|
|
46
39
|
# A Block was passed to the method, which it cannot interpret
|
47
|
-
# Formerly known as `UnsupportedBlock`
|
48
40
|
class UnsupportedBlockError < BlockError; end
|
49
41
|
|
50
42
|
# A Block was required, but not supplied
|
51
|
-
# Formerly known as `BlockMissingError`
|
52
43
|
class MissingBlockError < BlockError; end
|
53
44
|
|
54
45
|
# A page was loaded then failed one of the validations defined by the user
|
55
|
-
# Formerly known as `NotLoadedError`
|
56
46
|
class FailedLoadValidationError < PageLoadError; end
|
47
|
+
|
48
|
+
# Generic Attribute validation family of errors inherit from this error
|
49
|
+
class AttributeValidationError < SitePrismError; end
|
50
|
+
|
51
|
+
# DSL items are not permitted to start with certain prefixes
|
52
|
+
class InvalidDSLNameError < AttributeValidationError; end
|
57
53
|
end
|
data/lib/site_prism/page.rb
CHANGED
@@ -1,6 +1,15 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module SitePrism
|
4
|
+
# [SitePrism::Page]
|
5
|
+
#
|
6
|
+
# SitePrism Pages are the top level construct of the POM framework
|
7
|
+
#
|
8
|
+
# Instances of this class represent a full web page that can either be dynamically navigated to
|
9
|
+
# through clicking buttons or filling in fields, or verbosely loaded by using the `#load` method
|
10
|
+
#
|
11
|
+
# All method calls made whilst on a page are scoped using `#to_capybara_node` which defaults to the
|
12
|
+
# current Capybara session
|
4
13
|
class Page
|
5
14
|
include Capybara::DSL
|
6
15
|
include ElementChecker
|
data/lib/site_prism/section.rb
CHANGED
@@ -1,6 +1,15 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module SitePrism
|
4
|
+
# [SitePrism::Section]
|
5
|
+
#
|
6
|
+
# SitePrism Sections are the mid level construct of the POM framework
|
7
|
+
#
|
8
|
+
# Instances of this class represent a a part of a web page that can either sit inside a SitePrism::Page
|
9
|
+
# or sit inside another N sections, which then eventually will sit inside a page
|
10
|
+
#
|
11
|
+
# All method calls made whilst on a page are scoped using `#to_capybara_node` which will be represented by
|
12
|
+
# the current `#root_element`. This is the locator for the section itself and is a mandatory argument
|
4
13
|
class Section
|
5
14
|
include ElementChecker
|
6
15
|
include Loadable
|
@@ -55,8 +64,10 @@ module SitePrism
|
|
55
64
|
root_element
|
56
65
|
end
|
57
66
|
|
58
|
-
# This allows us to return anything
|
67
|
+
# This allows us to return anything that's passed in as a block to the section at
|
59
68
|
# creation time, so that an anonymous section or such-like will have the extra methods
|
69
|
+
#
|
70
|
+
# This can also be used manually at runtime to allow people to abbreviate their calls
|
60
71
|
def within
|
61
72
|
Capybara.within(root_element) { yield(self) }
|
62
73
|
end
|
@@ -64,11 +75,8 @@ module SitePrism
|
|
64
75
|
# This was the old API-style of delegating through the Capybara.page call and over-loading
|
65
76
|
# the method so we always went through our correct `root_element`
|
66
77
|
def page
|
67
|
-
SitePrism
|
68
|
-
|
69
|
-
|
70
|
-
SitePrism.logger.warn('Root Element not found; Falling back to Capybara.current_session')
|
71
|
-
capybara_session
|
78
|
+
SitePrism.logger.fatal('This is not supposed to be used. All delegation now happens automatically!')
|
79
|
+
raise SitePrism::SitePrismError
|
72
80
|
end
|
73
81
|
|
74
82
|
def capybara_session
|
data/lib/site_prism/version.rb
CHANGED
data/lib/site_prism/waiter.rb
CHANGED
@@ -7,13 +7,13 @@ module SitePrism
|
|
7
7
|
#
|
8
8
|
# A looper that will wait until the passed in block evaluates to true
|
9
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)
|
10
|
+
def self.wait_until_true(wait_time = Capybara.default_max_wait_time, sleep_duration = 0.05)
|
11
11
|
Timer.run(wait_time) do |timer|
|
12
12
|
loop do
|
13
13
|
return true if yield
|
14
14
|
break if timer.done?
|
15
15
|
|
16
|
-
sleep(
|
16
|
+
sleep(sleep_duration)
|
17
17
|
end
|
18
18
|
raise SitePrism::TimeoutError, "Timed out after #{wait_time}s."
|
19
19
|
end
|
data/lib/site_prism.rb
CHANGED
@@ -1,27 +1,27 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require 'site_prism/error'
|
4
|
+
require 'site_prism/all_there'
|
4
5
|
require 'addressable/template'
|
6
|
+
require 'forwardable'
|
5
7
|
|
6
8
|
# [SitePrism] namespace
|
7
9
|
# We autoload our files underneath here to provide a slightly more optimal load solution
|
8
10
|
module SitePrism
|
9
11
|
autoload :AddressableUrlMatcher, 'site_prism/addressable_url_matcher'
|
10
12
|
autoload :DSL, 'site_prism/dsl'
|
13
|
+
autoload :DSLValidator, 'site_prism/dsl_validator'
|
11
14
|
autoload :Deprecator, 'site_prism/deprecator'
|
12
15
|
autoload :ElementChecker, 'site_prism/element_checker'
|
13
16
|
autoload :Loadable, 'site_prism/loadable'
|
14
17
|
autoload :Logger, 'site_prism/logger'
|
15
18
|
autoload :Page, 'site_prism/page'
|
16
|
-
autoload :RecursionChecker, 'site_prism/recursion_checker'
|
17
19
|
autoload :RspecMatchers, 'site_prism/rspec_matchers'
|
18
20
|
autoload :Section, 'site_prism/section'
|
19
21
|
autoload :Timer, 'site_prism/timer'
|
20
22
|
autoload :Waiter, 'site_prism/waiter'
|
21
23
|
|
22
24
|
class << self
|
23
|
-
attr_reader :use_all_there_gem
|
24
|
-
|
25
25
|
def configure
|
26
26
|
yield self
|
27
27
|
end
|
@@ -72,13 +72,5 @@ module SitePrism
|
|
72
72
|
def log_level
|
73
73
|
%i[DEBUG INFO WARN ERROR FATAL UNKNOWN][logger.level]
|
74
74
|
end
|
75
|
-
|
76
|
-
# Whether you wish to use the new experimental all_there dependent gem
|
77
|
-
# This will be enforced from site_prism v4 onwards as this is where
|
78
|
-
# the development of this functionality will be focused
|
79
|
-
def use_all_there_gem=(value)
|
80
|
-
logger.debug("Setting use_all_there_gem to #{value}")
|
81
|
-
@use_all_there_gem = value
|
82
|
-
end
|
83
75
|
end
|
84
76
|
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:
|
4
|
+
version: 4.0.beta
|
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:
|
12
|
+
date: 2022-11-28 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: addressable
|
@@ -43,56 +43,42 @@ dependencies:
|
|
43
43
|
name: site_prism-all_there
|
44
44
|
requirement: !ruby/object:Gem::Requirement
|
45
45
|
requirements:
|
46
|
-
- - "
|
46
|
+
- - ">"
|
47
47
|
- !ruby/object:Gem::Version
|
48
|
-
version:
|
48
|
+
version: '1'
|
49
49
|
- - "<"
|
50
50
|
- !ruby/object:Gem::Version
|
51
|
-
version: '
|
51
|
+
version: '2'
|
52
52
|
type: :runtime
|
53
53
|
prerelease: false
|
54
54
|
version_requirements: !ruby/object:Gem::Requirement
|
55
55
|
requirements:
|
56
|
-
- - "
|
56
|
+
- - ">"
|
57
57
|
- !ruby/object:Gem::Version
|
58
|
-
version:
|
58
|
+
version: '1'
|
59
59
|
- - "<"
|
60
60
|
- !ruby/object:Gem::Version
|
61
|
-
version: '
|
61
|
+
version: '2'
|
62
62
|
- !ruby/object:Gem::Dependency
|
63
63
|
name: cucumber
|
64
64
|
requirement: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
66
|
- - ">"
|
67
67
|
- !ruby/object:Gem::Version
|
68
|
-
version: '
|
68
|
+
version: '6'
|
69
69
|
- - "<"
|
70
70
|
- !ruby/object:Gem::Version
|
71
|
-
version: '
|
71
|
+
version: '9'
|
72
72
|
type: :development
|
73
73
|
prerelease: false
|
74
74
|
version_requirements: !ruby/object:Gem::Requirement
|
75
75
|
requirements:
|
76
76
|
- - ">"
|
77
77
|
- !ruby/object:Gem::Version
|
78
|
-
version: '
|
78
|
+
version: '6'
|
79
79
|
- - "<"
|
80
80
|
- !ruby/object:Gem::Version
|
81
|
-
version: '
|
82
|
-
- !ruby/object:Gem::Dependency
|
83
|
-
name: pry-byebug
|
84
|
-
requirement: !ruby/object:Gem::Requirement
|
85
|
-
requirements:
|
86
|
-
- - ">="
|
87
|
-
- !ruby/object:Gem::Version
|
88
|
-
version: '0'
|
89
|
-
type: :development
|
90
|
-
prerelease: false
|
91
|
-
version_requirements: !ruby/object:Gem::Requirement
|
92
|
-
requirements:
|
93
|
-
- - ">="
|
94
|
-
- !ruby/object:Gem::Version
|
95
|
-
version: '0'
|
81
|
+
version: '9'
|
96
82
|
- !ruby/object:Gem::Dependency
|
97
83
|
name: rspec
|
98
84
|
requirement: !ruby/object:Gem::Requirement
|
@@ -113,42 +99,42 @@ dependencies:
|
|
113
99
|
requirements:
|
114
100
|
- - "~>"
|
115
101
|
- !ruby/object:Gem::Version
|
116
|
-
version: 1.
|
102
|
+
version: 1.28.0
|
117
103
|
type: :development
|
118
104
|
prerelease: false
|
119
105
|
version_requirements: !ruby/object:Gem::Requirement
|
120
106
|
requirements:
|
121
107
|
- - "~>"
|
122
108
|
- !ruby/object:Gem::Version
|
123
|
-
version: 1.
|
109
|
+
version: 1.28.0
|
124
110
|
- !ruby/object:Gem::Dependency
|
125
111
|
name: rubocop-performance
|
126
112
|
requirement: !ruby/object:Gem::Requirement
|
127
113
|
requirements:
|
128
114
|
- - "~>"
|
129
115
|
- !ruby/object:Gem::Version
|
130
|
-
version: 1.
|
116
|
+
version: 1.13.0
|
131
117
|
type: :development
|
132
118
|
prerelease: false
|
133
119
|
version_requirements: !ruby/object:Gem::Requirement
|
134
120
|
requirements:
|
135
121
|
- - "~>"
|
136
122
|
- !ruby/object:Gem::Version
|
137
|
-
version: 1.
|
123
|
+
version: 1.13.0
|
138
124
|
- !ruby/object:Gem::Dependency
|
139
125
|
name: rubocop-rspec
|
140
126
|
requirement: !ruby/object:Gem::Requirement
|
141
127
|
requirements:
|
142
128
|
- - "~>"
|
143
129
|
- !ruby/object:Gem::Version
|
144
|
-
version: 2.
|
130
|
+
version: 2.7.0
|
145
131
|
type: :development
|
146
132
|
prerelease: false
|
147
133
|
version_requirements: !ruby/object:Gem::Requirement
|
148
134
|
requirements:
|
149
135
|
- - "~>"
|
150
136
|
- !ruby/object:Gem::Version
|
151
|
-
version: 2.
|
137
|
+
version: 2.7.0
|
152
138
|
- !ruby/object:Gem::Dependency
|
153
139
|
name: selenium-webdriver
|
154
140
|
requirement: !ruby/object:Gem::Requirement
|
@@ -158,7 +144,7 @@ dependencies:
|
|
158
144
|
version: '3.13'
|
159
145
|
- - "<"
|
160
146
|
- !ruby/object:Gem::Version
|
161
|
-
version: '
|
147
|
+
version: '5'
|
162
148
|
type: :development
|
163
149
|
prerelease: false
|
164
150
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -168,7 +154,7 @@ dependencies:
|
|
168
154
|
version: '3.13'
|
169
155
|
- - "<"
|
170
156
|
- !ruby/object:Gem::Version
|
171
|
-
version: '
|
157
|
+
version: '5'
|
172
158
|
- !ruby/object:Gem::Dependency
|
173
159
|
name: simplecov
|
174
160
|
requirement: !ruby/object:Gem::Requirement
|
@@ -212,12 +198,12 @@ files:
|
|
212
198
|
- lib/site_prism/addressable_url_matcher.rb
|
213
199
|
- lib/site_prism/deprecator.rb
|
214
200
|
- lib/site_prism/dsl.rb
|
201
|
+
- lib/site_prism/dsl_validator.rb
|
215
202
|
- lib/site_prism/element_checker.rb
|
216
203
|
- lib/site_prism/error.rb
|
217
204
|
- lib/site_prism/loadable.rb
|
218
205
|
- lib/site_prism/logger.rb
|
219
206
|
- lib/site_prism/page.rb
|
220
|
-
- lib/site_prism/recursion_checker.rb
|
221
207
|
- lib/site_prism/rspec_matchers.rb
|
222
208
|
- lib/site_prism/section.rb
|
223
209
|
- lib/site_prism/timer.rb
|
@@ -238,14 +224,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
238
224
|
requirements:
|
239
225
|
- - ">="
|
240
226
|
- !ruby/object:Gem::Version
|
241
|
-
version: '2.
|
227
|
+
version: '2.5'
|
242
228
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
243
229
|
requirements:
|
244
|
-
- - "
|
230
|
+
- - ">"
|
245
231
|
- !ruby/object:Gem::Version
|
246
|
-
version:
|
232
|
+
version: 1.3.1
|
247
233
|
requirements: []
|
248
|
-
rubygems_version: 3.0.
|
234
|
+
rubygems_version: 3.0.3.1
|
249
235
|
signing_key:
|
250
236
|
specification_version: 4
|
251
237
|
summary: A Page Object Model DSL for Capybara
|
@@ -1,77 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module SitePrism
|
4
|
-
class RecursionChecker
|
5
|
-
attr_reader :instance
|
6
|
-
|
7
|
-
private :instance
|
8
|
-
|
9
|
-
def initialize(instance)
|
10
|
-
@instance = instance
|
11
|
-
end
|
12
|
-
|
13
|
-
def all_there?
|
14
|
-
regular_items_all_there = expected_item_map.flatten.all? { |name| there?(name) }
|
15
|
-
return false unless regular_items_all_there
|
16
|
-
|
17
|
-
section_all_there =
|
18
|
-
section_classes_to_check.all?(&:all_there?)
|
19
|
-
return false unless section_all_there
|
20
|
-
|
21
|
-
# Returning this final check here is fine, as the previous two checks must
|
22
|
-
# have returned +true+ in order to hit this part of the method-call
|
23
|
-
sections_classes_to_check.all?(&:all_there?)
|
24
|
-
end
|
25
|
-
|
26
|
-
def expected_item_map
|
27
|
-
[
|
28
|
-
expected(mapped_items, :element),
|
29
|
-
expected(mapped_items, :elements),
|
30
|
-
expected(mapped_items, :section),
|
31
|
-
expected(mapped_items, :sections),
|
32
|
-
expected(mapped_items, :iframe)
|
33
|
-
]
|
34
|
-
end
|
35
|
-
|
36
|
-
def expected(_map, type)
|
37
|
-
mapped_items[type].select { |name| elements_to_check.include?(name) }
|
38
|
-
end
|
39
|
-
|
40
|
-
def section_classes_to_check
|
41
|
-
expected_item_map[2].map { |name| instance.send(name) }
|
42
|
-
end
|
43
|
-
|
44
|
-
def sections_classes_to_check
|
45
|
-
expected_item_map[3].map { |name| instance.send(name) }.flatten
|
46
|
-
end
|
47
|
-
|
48
|
-
private
|
49
|
-
|
50
|
-
# If the page or section has expected_items set, return expected_items that are mapped
|
51
|
-
# otherwise just return the list of all mapped_items
|
52
|
-
def elements_to_check
|
53
|
-
if _expected_items
|
54
|
-
SitePrism.logger.debug('Expected Items has been set.')
|
55
|
-
_mapped_items.select { |name| _expected_items.include?(name) }
|
56
|
-
else
|
57
|
-
_mapped_items
|
58
|
-
end
|
59
|
-
end
|
60
|
-
|
61
|
-
def _mapped_items
|
62
|
-
mapped_items.values.flatten.uniq
|
63
|
-
end
|
64
|
-
|
65
|
-
def _expected_items
|
66
|
-
instance.class.expected_items
|
67
|
-
end
|
68
|
-
|
69
|
-
def there?(name)
|
70
|
-
instance.send("has_#{name}?")
|
71
|
-
end
|
72
|
-
|
73
|
-
def mapped_items
|
74
|
-
@mapped_items ||= instance.class.mapped_items(legacy: false)
|
75
|
-
end
|
76
|
-
end
|
77
|
-
end
|