site_prism 4.0.3 → 5.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/README.md +60 -54
- data/lib/site_prism/deprecator.rb +2 -21
- data/lib/site_prism/dsl/builder.rb +144 -0
- data/lib/site_prism/dsl/locators.rb +85 -0
- data/lib/site_prism/dsl/methods.rb +135 -0
- data/lib/site_prism/dsl/validator.rb +95 -0
- data/lib/site_prism/dsl.rb +14 -327
- data/lib/site_prism/element_checker.rb +2 -2
- data/lib/site_prism/error.rb +4 -1
- data/lib/site_prism/loadable.rb +13 -23
- data/lib/site_prism/logger.rb +1 -1
- data/lib/site_prism/page.rb +4 -15
- data/lib/site_prism/version.rb +1 -1
- data/lib/site_prism.rb +7 -3
- metadata +51 -36
- data/lib/site_prism/dsl_validator.rb +0 -75
@@ -0,0 +1,95 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module SitePrism
|
4
|
+
module DSL
|
5
|
+
# [SitePrism::DSL::Validator]
|
6
|
+
#
|
7
|
+
# This is the new validator module which will check all DSL items against a whitelist
|
8
|
+
# for any entries which break specific rules
|
9
|
+
#
|
10
|
+
# @api private
|
11
|
+
#
|
12
|
+
module Validator
|
13
|
+
attr_accessor :dsl_name_error
|
14
|
+
|
15
|
+
def name_invalid?(name)
|
16
|
+
prefix_invalid?(name) ||
|
17
|
+
suffix_invalid?(name) ||
|
18
|
+
characters_invalid?(name) ||
|
19
|
+
blacklisted?(name)
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
def prefix_invalid?(name)
|
25
|
+
return false unless prefix_blacklist.any? { |prefix| name.start_with?(prefix) }
|
26
|
+
|
27
|
+
log_failure(name, 'prefix')
|
28
|
+
end
|
29
|
+
|
30
|
+
def suffix_invalid?(name)
|
31
|
+
return false unless suffix_blacklist.any? { |prefix| name.end_with?(prefix) }
|
32
|
+
|
33
|
+
log_failure(name, 'suffix')
|
34
|
+
end
|
35
|
+
|
36
|
+
def characters_invalid?(name)
|
37
|
+
return false if name.match?(regex_permission)
|
38
|
+
|
39
|
+
log_failure(name, 'character(s)')
|
40
|
+
end
|
41
|
+
|
42
|
+
def blacklisted?(name)
|
43
|
+
return false unless blacklisted_names.include?(name)
|
44
|
+
|
45
|
+
log_failure(name, 'name (blacklisted entry)')
|
46
|
+
end
|
47
|
+
|
48
|
+
def regex_permission
|
49
|
+
/^[a-z]\w+$/
|
50
|
+
end
|
51
|
+
|
52
|
+
def prefix_blacklist
|
53
|
+
%w[
|
54
|
+
no_
|
55
|
+
_
|
56
|
+
]
|
57
|
+
end
|
58
|
+
|
59
|
+
def suffix_blacklist
|
60
|
+
%w[
|
61
|
+
_
|
62
|
+
?
|
63
|
+
]
|
64
|
+
end
|
65
|
+
|
66
|
+
def blacklisted_names
|
67
|
+
%w[
|
68
|
+
attributes
|
69
|
+
html
|
70
|
+
no
|
71
|
+
title
|
72
|
+
element
|
73
|
+
elements
|
74
|
+
section
|
75
|
+
sections
|
76
|
+
iframe
|
77
|
+
]
|
78
|
+
end
|
79
|
+
|
80
|
+
def log_failure(name, type)
|
81
|
+
self.dsl_name_error = "DSL item: #{name} has an invalid #{type}"
|
82
|
+
SitePrism.logger.debug(debug_error(type))
|
83
|
+
end
|
84
|
+
|
85
|
+
def debug_error(type)
|
86
|
+
case type
|
87
|
+
when 'prefix'; then "Invalid Prefixes: #{prefix_blacklist.join(', ')}."
|
88
|
+
when 'suffix'; then "Invalid Suffixes: #{suffix_blacklist.join(', ')}"
|
89
|
+
when 'character(s)'; then "Invalid DSL Names: #{blacklisted_names.join(', ')}"
|
90
|
+
else "DSL Charset REGEX: #{regex_permission.inspect}"
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
data/lib/site_prism/dsl.rb
CHANGED
@@ -1,17 +1,25 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require 'site_prism/dsl/builder'
|
4
|
+
require 'site_prism/dsl/methods'
|
5
|
+
require 'site_prism/dsl/locators'
|
6
|
+
require 'site_prism/dsl/validator'
|
7
|
+
|
3
8
|
module SitePrism
|
4
9
|
# [SitePrism::DSL]
|
5
10
|
#
|
6
|
-
# This is the core
|
7
|
-
#
|
8
|
-
#
|
11
|
+
# This is the core internal workings of SitePrism. It consists of four moving parts - plus some generic methods included here
|
12
|
+
# Builder -> The way in which the .build method generates lots of instance-methods on a SitePrism::Page or SitePrism::Section instance
|
13
|
+
# Methods -> The public DSL metaprogram methods, such as `element` or `section`
|
14
|
+
# Locators -> Our locator scoping logic within capybara. By and large leaning on `#to_capybara_node`
|
15
|
+
# Validators -> EXPERIMENTAL: A new module that ensures names of all DSL items conform to certain rules
|
9
16
|
#
|
10
|
-
# The whole package here can be thought of as [@api private]
|
11
17
|
module DSL
|
12
18
|
def self.included(klass)
|
13
|
-
klass.extend
|
14
|
-
klass.extend
|
19
|
+
klass.extend Builder
|
20
|
+
klass.extend Methods
|
21
|
+
klass.include Locators
|
22
|
+
klass.extend Validator
|
15
23
|
end
|
16
24
|
|
17
25
|
private
|
@@ -23,326 +31,5 @@ module SitePrism
|
|
23
31
|
SitePrism.logger.error("#{object.class}##{name} cannot accept runtime blocks")
|
24
32
|
raise SitePrism::UnsupportedBlockError
|
25
33
|
end
|
26
|
-
|
27
|
-
def _find(*find_args)
|
28
|
-
kwargs = find_args.pop
|
29
|
-
to_capybara_node.find(*find_args, **kwargs)
|
30
|
-
end
|
31
|
-
|
32
|
-
def _all(*find_args)
|
33
|
-
kwargs = find_args.pop
|
34
|
-
to_capybara_node.all(*find_args, **kwargs)
|
35
|
-
end
|
36
|
-
|
37
|
-
def element_exists?(*find_args)
|
38
|
-
kwargs = find_args.pop
|
39
|
-
to_capybara_node.has_selector?(*find_args, **kwargs)
|
40
|
-
end
|
41
|
-
|
42
|
-
def element_does_not_exist?(*find_args)
|
43
|
-
kwargs = find_args.pop
|
44
|
-
to_capybara_node.has_no_selector?(*find_args, **kwargs)
|
45
|
-
end
|
46
|
-
|
47
|
-
# Sanitize method called before calling any SitePrism DSL method or
|
48
|
-
# meta-programmed method. This ensures that the Capybara query is correct.
|
49
|
-
#
|
50
|
-
# Accepts any combination of arguments sent at DSL definition or runtime
|
51
|
-
# and combines them in such a way that Capybara can operate with them.
|
52
|
-
def merge_args(find_args, runtime_args, visibility_args = {})
|
53
|
-
find_args = find_args.dup
|
54
|
-
runtime_args = runtime_args.dup
|
55
|
-
options = visibility_args.dup
|
56
|
-
SitePrism.logger.debug("Initial args: #{find_args}, #{runtime_args}.")
|
57
|
-
|
58
|
-
recombine_args(find_args, runtime_args, options)
|
59
|
-
|
60
|
-
return [*find_args, *runtime_args, {}] if options.empty?
|
61
|
-
|
62
|
-
[*find_args, *runtime_args, options]
|
63
|
-
end
|
64
|
-
|
65
|
-
# Options re-combiner. This takes the original inputs and combines
|
66
|
-
# them such that there is only one hash passed as a final argument
|
67
|
-
# to Capybara.
|
68
|
-
#
|
69
|
-
# If the hash is empty, then the hash is omitted from the payload sent
|
70
|
-
# to Capybara, and the find / runtime arguments are sent alone.
|
71
|
-
#
|
72
|
-
# NB: If the +wait+ key is present in the options hash, even as false or 0, It will
|
73
|
-
# be set as the user-supplied value (So user error can be the cause for issues).
|
74
|
-
def recombine_args(find_args, runtime_args, options)
|
75
|
-
options.merge!(find_args.pop) if find_args.last.is_a? Hash
|
76
|
-
options.merge!(runtime_args.pop) if runtime_args.last.is_a? Hash
|
77
|
-
options[:wait] = Capybara.default_max_wait_time unless options.key?(:wait)
|
78
|
-
end
|
79
|
-
|
80
|
-
# [SitePrism::DSL::ClassMethods]
|
81
|
-
# This exposes all of the DSL definitions users will use when generating
|
82
|
-
# their POM classes.
|
83
|
-
#
|
84
|
-
# Many of these methods will be used in-line to allow users to generate a multitude of
|
85
|
-
# methods and locators for finding elements / sections on a page or section of a page
|
86
|
-
module ClassMethods
|
87
|
-
attr_reader :expected_items
|
88
|
-
|
89
|
-
# Sets the `expected_items` iVar on a class. This property is used in conjunction with
|
90
|
-
# `all_there?` to provide a way of granularising the check made to only interrogate a sub-set
|
91
|
-
# of DSL defined items
|
92
|
-
def expected_elements(*elements)
|
93
|
-
@expected_items = elements
|
94
|
-
end
|
95
|
-
|
96
|
-
# Creates an instance of a SitePrism Element - This will create several methods designed to
|
97
|
-
# Locate the element -> @return [Capybara::Node::Element]
|
98
|
-
# Check the elements presence or non-presence -> @return [Boolean]
|
99
|
-
# Wait for the elements to be present or not -> @return [TrueClass, SitePrism::Error]
|
100
|
-
# Validate certain properties about the element
|
101
|
-
def element(name, *find_args)
|
102
|
-
raise_if_build_time_block_supplied(self, name, block_given?, :element)
|
103
|
-
build(:element, name, *find_args) do
|
104
|
-
define_method(name) do |*runtime_args, &runtime_block|
|
105
|
-
raise_if_runtime_block_supplied(self, name, runtime_block, :element)
|
106
|
-
_find(*merge_args(find_args, runtime_args))
|
107
|
-
end
|
108
|
-
end
|
109
|
-
end
|
110
|
-
|
111
|
-
# Creates a enumerable instance of a SitePrism Element - This will create several methods designed to
|
112
|
-
# Locate the enumerable element -> @return [Capybara::Result]
|
113
|
-
# Check the elements presence or non-presence -> @return [Boolean]
|
114
|
-
# Wait for the elements to be present or not -> @return [TrueClass, SitePrism::Error]
|
115
|
-
# Validate certain properties about the elements
|
116
|
-
def elements(name, *find_args)
|
117
|
-
raise_if_build_time_block_supplied(self, name, block_given?, :elements)
|
118
|
-
build(:elements, name, *find_args) do
|
119
|
-
define_method(name) do |*runtime_args, &runtime_block|
|
120
|
-
raise_if_runtime_block_supplied(self, name, runtime_block, :elements)
|
121
|
-
_all(*merge_args(find_args, runtime_args))
|
122
|
-
end
|
123
|
-
end
|
124
|
-
end
|
125
|
-
|
126
|
-
# Creates an instance of a SitePrism Section - This will create several methods designed to
|
127
|
-
# Locate the section -> @return [SitePrism::Section]
|
128
|
-
# Check the section presence or non-presence -> @return [Boolean]
|
129
|
-
# Wait for the section to be present or not -> @return [TrueClass, SitePrism::Error]
|
130
|
-
# Validate certain properties about the section
|
131
|
-
def section(name, *args, &block)
|
132
|
-
section_class, find_args = extract_section_options(args, &block)
|
133
|
-
build(:section, name, *find_args) do
|
134
|
-
define_method(name) do |*runtime_args, &runtime_block|
|
135
|
-
section_element = _find(*merge_args(find_args, runtime_args))
|
136
|
-
section_class.new(self, section_element, &runtime_block)
|
137
|
-
end
|
138
|
-
end
|
139
|
-
end
|
140
|
-
|
141
|
-
# Creates an enumerable instance of a SitePrism Section - This will create several methods designed to
|
142
|
-
# Locate the sections -> @return [Array]
|
143
|
-
# Check the sections presence or non-presence -> @return [Boolean]
|
144
|
-
# Wait for the sections to be present or not -> @return [TrueClass, SitePrism::Error]
|
145
|
-
# Validate certain properties about the section
|
146
|
-
def sections(name, *args, &block)
|
147
|
-
section_class, find_args = extract_section_options(args, &block)
|
148
|
-
build(:sections, name, *find_args) do
|
149
|
-
define_method(name) do |*runtime_args, &runtime_block|
|
150
|
-
raise_if_runtime_block_supplied(self, name, runtime_block, :sections)
|
151
|
-
_all(*merge_args(find_args, runtime_args)).map do |element|
|
152
|
-
section_class.new(self, element)
|
153
|
-
end
|
154
|
-
end
|
155
|
-
end
|
156
|
-
end
|
157
|
-
|
158
|
-
def iframe(name, klass, *args)
|
159
|
-
raise_if_build_time_block_supplied(self, name, block_given?, :elements)
|
160
|
-
element_find_args = deduce_iframe_element_find_args(args)
|
161
|
-
scope_find_args = deduce_iframe_scope_find_args(args)
|
162
|
-
build(:iframe, name, *element_find_args) do
|
163
|
-
define_method(name) do |&block|
|
164
|
-
raise MissingBlockError unless block
|
165
|
-
|
166
|
-
within_frame(*scope_find_args) { block.call(klass.new) }
|
167
|
-
end
|
168
|
-
end
|
169
|
-
end
|
170
|
-
|
171
|
-
# Return a list of all mapped items on a SitePrism class instance (Page or Section)
|
172
|
-
# If legacy is set to true (Default) -> @return [Array]
|
173
|
-
# If legacy is set to false (New behaviour) -> @return [Hash]
|
174
|
-
def mapped_items(legacy: false)
|
175
|
-
return legacy_mapped_items if legacy
|
176
|
-
|
177
|
-
@mapped_items ||= { element: [], elements: [], section: [], sections: [], iframe: [] }
|
178
|
-
end
|
179
|
-
|
180
|
-
private
|
181
|
-
|
182
|
-
def build(type, name, *find_args)
|
183
|
-
raise InvalidDSLNameError if ENV.fetch('SITEPRISM_DSL_VALIDATION_ENABLED', nil) && invalid?(name)
|
184
|
-
|
185
|
-
if find_args.empty?
|
186
|
-
create_error_method(name)
|
187
|
-
else
|
188
|
-
map_item(type, name)
|
189
|
-
yield
|
190
|
-
end
|
191
|
-
add_helper_methods(name, type, *find_args)
|
192
|
-
end
|
193
|
-
|
194
|
-
def add_helper_methods(name, _type, *find_args)
|
195
|
-
create_existence_checker(name, *find_args)
|
196
|
-
create_nonexistence_checker(name, *find_args)
|
197
|
-
SitePrism::RSpecMatchers.new(name)._create_rspec_existence_matchers if defined?(RSpec)
|
198
|
-
create_visibility_waiter(name, *find_args)
|
199
|
-
create_invisibility_waiter(name, *find_args)
|
200
|
-
end
|
201
|
-
|
202
|
-
def create_helper_method(proposed_method_name, *find_args)
|
203
|
-
return create_error_method(proposed_method_name) if find_args.empty?
|
204
|
-
|
205
|
-
yield
|
206
|
-
end
|
207
|
-
|
208
|
-
def create_existence_checker(element_name, *find_args)
|
209
|
-
method_name = "has_#{element_name}?"
|
210
|
-
create_helper_method(method_name, *find_args) do
|
211
|
-
define_method(method_name) do |*runtime_args|
|
212
|
-
args = merge_args(find_args, runtime_args)
|
213
|
-
element_exists?(*args)
|
214
|
-
end
|
215
|
-
end
|
216
|
-
end
|
217
|
-
|
218
|
-
def create_nonexistence_checker(element_name, *find_args)
|
219
|
-
method_name = "has_no_#{element_name}?"
|
220
|
-
create_helper_method(method_name, *find_args) do
|
221
|
-
define_method(method_name) do |*runtime_args|
|
222
|
-
args = merge_args(find_args, runtime_args)
|
223
|
-
element_does_not_exist?(*args)
|
224
|
-
end
|
225
|
-
end
|
226
|
-
end
|
227
|
-
|
228
|
-
def create_visibility_waiter(element_name, *find_args)
|
229
|
-
method_name = "wait_until_#{element_name}_visible"
|
230
|
-
create_helper_method(method_name, *find_args) do
|
231
|
-
define_method(method_name) do |*runtime_args|
|
232
|
-
args = merge_args(find_args, runtime_args, visible: true)
|
233
|
-
return true if element_exists?(*args)
|
234
|
-
|
235
|
-
raise SitePrism::ElementVisibilityTimeoutError
|
236
|
-
end
|
237
|
-
end
|
238
|
-
end
|
239
|
-
|
240
|
-
def create_invisibility_waiter(element_name, *find_args)
|
241
|
-
method_name = "wait_until_#{element_name}_invisible"
|
242
|
-
create_helper_method(method_name, *find_args) do
|
243
|
-
define_method(method_name) do |*runtime_args|
|
244
|
-
args = merge_args(find_args, runtime_args, visible: true)
|
245
|
-
return true if element_does_not_exist?(*args)
|
246
|
-
|
247
|
-
raise SitePrism::ElementInvisibilityTimeoutError
|
248
|
-
end
|
249
|
-
end
|
250
|
-
end
|
251
|
-
|
252
|
-
def create_error_method(name)
|
253
|
-
SitePrism::Deprecator.deprecate(
|
254
|
-
'DSL definition with no find_args',
|
255
|
-
'DSL definition with at least 1 find_arg'
|
256
|
-
)
|
257
|
-
SitePrism.logger.error("#{name} has come from an item with no locators.")
|
258
|
-
define_method(name) { raise SitePrism::InvalidElementError }
|
259
|
-
end
|
260
|
-
|
261
|
-
def raise_if_build_time_block_supplied(parent_object, name, has_block, type)
|
262
|
-
return unless has_block
|
263
|
-
|
264
|
-
SitePrism.logger.debug("Type passed in: #{type}")
|
265
|
-
SitePrism.logger.error("#{name} has been defined as a '#{type}' item in #{parent_object}. It does not accept build-time blocks.")
|
266
|
-
raise SitePrism::UnsupportedBlockError
|
267
|
-
end
|
268
|
-
|
269
|
-
def legacy_mapped_items
|
270
|
-
@legacy_mapped_items ||= begin
|
271
|
-
SitePrism::Deprecator.deprecate(
|
272
|
-
'.mapped_items structure (internally), on a class',
|
273
|
-
'the new .mapped_items structure'
|
274
|
-
)
|
275
|
-
[]
|
276
|
-
end
|
277
|
-
end
|
278
|
-
|
279
|
-
def map_item(type, name)
|
280
|
-
mapped_items(legacy: true) << { type => name }
|
281
|
-
mapped_items[type] << name.to_sym
|
282
|
-
end
|
283
|
-
|
284
|
-
def deduce_iframe_scope_find_args(args)
|
285
|
-
warn_on_invalid_selector_input(args)
|
286
|
-
case args[0]
|
287
|
-
when Integer then [args[0]]
|
288
|
-
when String then [:css, args[0]]
|
289
|
-
else args
|
290
|
-
end
|
291
|
-
end
|
292
|
-
|
293
|
-
def deduce_iframe_element_find_args(args)
|
294
|
-
warn_on_invalid_selector_input(args)
|
295
|
-
case args[0]
|
296
|
-
when Integer then "iframe:nth-of-type(#{args[0] + 1})"
|
297
|
-
when String then [:css, args[0]]
|
298
|
-
else args
|
299
|
-
end
|
300
|
-
end
|
301
|
-
|
302
|
-
def warn_on_invalid_selector_input(args)
|
303
|
-
return unless looks_like_xpath?(args[0])
|
304
|
-
|
305
|
-
SitePrism.logger.warn('The arguments passed in look like xpath. Check your locators.')
|
306
|
-
SitePrism.logger.debug("Default locator strategy: #{Capybara.default_selector}")
|
307
|
-
end
|
308
|
-
|
309
|
-
def looks_like_xpath?(arg)
|
310
|
-
arg.is_a?(String) && arg.start_with?('/', './')
|
311
|
-
end
|
312
|
-
|
313
|
-
def extract_section_options(args, &block)
|
314
|
-
if args.first.is_a?(Class)
|
315
|
-
klass = args.shift
|
316
|
-
section_class = klass if klass <= SitePrism::Section
|
317
|
-
end
|
318
|
-
|
319
|
-
section_class = deduce_section_class(section_class, &block)
|
320
|
-
arguments = deduce_search_arguments(section_class, args)
|
321
|
-
[section_class, arguments]
|
322
|
-
end
|
323
|
-
|
324
|
-
def deduce_section_class(base_class, &block)
|
325
|
-
klass = base_class
|
326
|
-
klass = Class.new(klass || SitePrism::Section, &block) if block
|
327
|
-
return klass if klass
|
328
|
-
|
329
|
-
raise ArgumentError, 'You should provide descendant of SitePrism::Section class or/and a block as the second argument.'
|
330
|
-
end
|
331
|
-
|
332
|
-
def deduce_search_arguments(section_class, args)
|
333
|
-
extract_search_arguments(args) ||
|
334
|
-
extract_search_arguments(section_class.default_search_arguments) ||
|
335
|
-
invalidate_search_arguments!
|
336
|
-
end
|
337
|
-
|
338
|
-
def extract_search_arguments(args)
|
339
|
-
args if args && !args.empty?
|
340
|
-
end
|
341
|
-
|
342
|
-
def invalidate_search_arguments!
|
343
|
-
SitePrism.logger.error('Could not deduce search_arguments')
|
344
|
-
raise(ArgumentError, 'search arguments are needed in `section` definition or alternatively use `set_default_search_arguments`')
|
345
|
-
end
|
346
|
-
end
|
347
34
|
end
|
348
35
|
end
|
@@ -13,7 +13,7 @@ module SitePrism
|
|
13
13
|
# for how the definition of "every item" is derived.
|
14
14
|
#
|
15
15
|
# Example
|
16
|
-
#
|
16
|
+
# `@my_page.class.mapped_items`
|
17
17
|
# {
|
18
18
|
# element => [:button_one, :button_two],
|
19
19
|
# elements => [:button_collection_one, :button_collection_two],
|
@@ -21,7 +21,7 @@ module SitePrism
|
|
21
21
|
# sections => [:search_result],
|
22
22
|
# iframe => []
|
23
23
|
# }
|
24
|
-
#
|
24
|
+
# `@my_page.all_there?`
|
25
25
|
# => true - If the items above are all present
|
26
26
|
#
|
27
27
|
# Note that #elements_to_check will check the hash of mapped_items
|
data/lib/site_prism/error.rb
CHANGED
@@ -48,6 +48,9 @@ module SitePrism
|
|
48
48
|
# Generic Attribute validation family of errors inherit from this error
|
49
49
|
class AttributeValidationError < SitePrismError; end
|
50
50
|
|
51
|
-
# DSL items are not permitted to
|
51
|
+
# DSL items are not permitted to be named in certain ways
|
52
52
|
class InvalidDSLNameError < AttributeValidationError; end
|
53
|
+
|
54
|
+
# The version of the target gem is unsupported, so using that feature is not possible
|
55
|
+
class UnsupportedGemVersionError < SitePrismError; end
|
53
56
|
end
|
data/lib/site_prism/loadable.rb
CHANGED
@@ -13,10 +13,8 @@ module SitePrism
|
|
13
13
|
base.extend(ClassMethods)
|
14
14
|
end
|
15
15
|
|
16
|
-
# In certain circumstances, we cache that the page has already
|
17
|
-
#
|
18
|
-
# call `loaded?` a second time do not need to perform
|
19
|
-
# the load_validation queries against the page a second time.
|
16
|
+
# In certain circumstances, we cache that the page or section has already been "loaded" so that actions which
|
17
|
+
# call `loaded?` a second time do not need to perform the load_validation queries against the page a second time.
|
20
18
|
attr_accessor :loaded, :load_error
|
21
19
|
|
22
20
|
# Executes the given block after the page is loaded.
|
@@ -27,8 +25,7 @@ module SitePrism
|
|
27
25
|
# inside another when_loaded block.
|
28
26
|
previously_loaded = loaded
|
29
27
|
|
30
|
-
# Within the block, check (and cache) loaded?, to see whether the
|
31
|
-
# page has indeed loaded according to the rules defined by the user.
|
28
|
+
# Within the block, check (and cache) loaded?, to see whether the page has indeed loaded according to the rules defined by the user.
|
32
29
|
self.loaded = loaded?
|
33
30
|
|
34
31
|
# If the page hasn't loaded. Then crash and return the error message.
|
@@ -68,13 +65,12 @@ module SitePrism
|
|
68
65
|
end
|
69
66
|
|
70
67
|
# [SitePrism::Loadable::ClassMethods]
|
71
|
-
# This exposes all of the DSL definitions users will use when generating "
|
68
|
+
# This exposes all of the DSL definitions users will use when generating "Loadables"
|
72
69
|
#
|
73
|
-
# A "Loadable" is a definition whereby the page object once loaded must pass a boolean check
|
74
|
-
# These
|
70
|
+
# A "Loadable" is a definition whereby the page/section object once loaded must pass a boolean check
|
71
|
+
# These Loadables are typically provided using the method `load_validation`
|
75
72
|
module ClassMethods
|
76
|
-
# The list of load_validations.
|
77
|
-
# They will be executed in the order they are defined.
|
73
|
+
# The list of load_validations. They are executed in the order they are defined.
|
78
74
|
#
|
79
75
|
# @return [Array]
|
80
76
|
def load_validations
|
@@ -85,21 +81,15 @@ module SitePrism
|
|
85
81
|
end
|
86
82
|
end
|
87
83
|
|
88
|
-
# Appends a load validation block to the page class.
|
84
|
+
# Appends a load validation block to the page/section class.
|
89
85
|
#
|
90
|
-
# When `loaded?` is called, these blocks are instance_eval'd
|
91
|
-
#
|
92
|
-
# This allows users to wait for specific events to occur on
|
93
|
-
# the page or certain elements to be loaded before performing
|
94
|
-
# any actions on the page.
|
86
|
+
# When `loaded?` is called, these blocks are instance_eval'd against the current page instance. This allows users to wait for
|
87
|
+
# specific events to occur on the page or certain elements to be loaded before performing any actions on the page.
|
95
88
|
#
|
96
|
-
# @param block [&block] A block which returns true if the page
|
97
|
-
#
|
98
|
-
# This block can contain up to 2 elements in an array
|
99
|
-
# The first is the physical validation test to be truthily evaluated.
|
89
|
+
# @param block [&block] A block which returns true if the page loaded successfully, or false if it did not.
|
90
|
+
# This block can contain up to 2 elements in an array -> The first is the physical validation test to be truthily evaluated.
|
100
91
|
#
|
101
|
-
# If this does not pass, then the 2nd item (if defined), is output
|
102
|
-
# as an error message to the +FailedLoadValidationError+ that is thrown
|
92
|
+
# If this does not pass, then the 2nd item (if defined), is output as an error message on the +FailedLoadValidationError+
|
103
93
|
#
|
104
94
|
# @return [Proc]
|
105
95
|
def load_validation(&block)
|
data/lib/site_prism/logger.rb
CHANGED
@@ -10,7 +10,7 @@ module SitePrism
|
|
10
10
|
def create(output = $stdout)
|
11
11
|
logger = ::Logger.new(output)
|
12
12
|
logger.progname = 'SitePrism'
|
13
|
-
logger.level = :
|
13
|
+
logger.level = :WARN
|
14
14
|
logger.formatter = proc do |severity, time, progname, msg|
|
15
15
|
"#{time.strftime('%F %T')} - #{severity} - #{progname} - #{msg}\n"
|
16
16
|
end
|
data/lib/site_prism/page.rb
CHANGED
@@ -36,24 +36,12 @@ module SitePrism
|
|
36
36
|
# The specific url matcher that is used to validate the page is loaded.
|
37
37
|
# When one hasn't been previously set, use the url that was set as a direct Regexp exact matcher
|
38
38
|
#
|
39
|
-
# @return [Regexp]
|
39
|
+
# @return [Regexp || String]
|
40
40
|
def url_matcher
|
41
41
|
@url_matcher ||= url
|
42
42
|
end
|
43
43
|
end
|
44
44
|
|
45
|
-
# Where a Capybara HTML fragment has been directly injected into `#load` as a block return this loaded fragment
|
46
|
-
# Where a page has been directly navigated to through traditional means (i.e. Selenium), return an instance of the
|
47
|
-
# current Capybara session (With all applicable methods)
|
48
|
-
#
|
49
|
-
# @return [Capybara::Node::Simple || Capybara::Session]
|
50
|
-
def page
|
51
|
-
@_page ||= begin
|
52
|
-
SitePrism::Deprecator.deprecate('Calling #page on a SitePrism::Page instance')
|
53
|
-
to_capybara_node
|
54
|
-
end
|
55
|
-
end
|
56
|
-
|
57
45
|
# This scopes our calls inside Page correctly to the `Capybara::Session`
|
58
46
|
#
|
59
47
|
# @return [Capybara::Node::Simple || Capybara::Session]
|
@@ -182,8 +170,9 @@ module SitePrism
|
|
182
170
|
end
|
183
171
|
|
184
172
|
def load_html_string(string)
|
173
|
+
SitePrism::Deprecator.deprecate('Using an input fragment (Loading partials using html strings).')
|
185
174
|
@page = Capybara.string(string)
|
186
|
-
yield
|
175
|
+
yield to_capybara_node if block_given?
|
187
176
|
end
|
188
177
|
|
189
178
|
def load_html_website(html, &block)
|
@@ -195,7 +184,7 @@ module SitePrism
|
|
195
184
|
if with_validations
|
196
185
|
when_loaded(&block)
|
197
186
|
elsif block
|
198
|
-
yield
|
187
|
+
yield to_capybara_node
|
199
188
|
end
|
200
189
|
end
|
201
190
|
end
|
data/lib/site_prism/version.rb
CHANGED
data/lib/site_prism.rb
CHANGED
@@ -1,6 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require 'site_prism/error'
|
4
3
|
require 'site_prism/all_there'
|
5
4
|
|
6
5
|
require 'addressable/template'
|
@@ -8,10 +7,10 @@ require 'capybara/dsl'
|
|
8
7
|
require 'forwardable'
|
9
8
|
|
10
9
|
require 'site_prism/addressable_url_matcher'
|
11
|
-
require 'site_prism/dsl'
|
12
|
-
require 'site_prism/dsl_validator'
|
13
10
|
require 'site_prism/deprecator'
|
11
|
+
require 'site_prism/dsl'
|
14
12
|
require 'site_prism/element_checker'
|
13
|
+
require 'site_prism/error'
|
15
14
|
require 'site_prism/loadable'
|
16
15
|
require 'site_prism/logger'
|
17
16
|
require 'site_prism/page'
|
@@ -23,6 +22,11 @@ require 'site_prism/waiter'
|
|
23
22
|
# [SitePrism]
|
24
23
|
module SitePrism
|
25
24
|
class << self
|
25
|
+
# SitePrism will enforce strict validation on all generated DSL items i.e. `element`
|
26
|
+
# The validations are found inside the SitePrism::DSL::Validator module
|
27
|
+
# NB: To ensure no unwanted validation issues, this must be disabled BEFORE any page / section code is autoloaded
|
28
|
+
attr_accessor :dsl_validation_disabled
|
29
|
+
|
26
30
|
def configure
|
27
31
|
yield self
|
28
32
|
end
|