site_prism 3.7.3 → 4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -11,65 +11,39 @@ 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
 
18
- # Call `find` inside `to_capybara_node` context (Either Capybara::Session or Capybara::Node::Element)
19
+ def raise_if_runtime_block_supplied(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
+
19
27
  def _find(*find_args)
20
28
  kwargs = find_args.pop
21
29
  to_capybara_node.find(*find_args, **kwargs)
22
30
  end
23
31
 
24
- # Call `all` inside `to_capybara_node` context (Either Capybara::Session or Capybara::Node::Element)
25
32
  def _all(*find_args)
26
33
  kwargs = find_args.pop
27
34
  to_capybara_node.all(*find_args, **kwargs)
28
35
  end
29
36
 
30
- # Call `has_selector?` inside `to_capybara_node` context (Either Capybara::Session or Capybara::Node::Element)
31
37
  def element_exists?(*find_args)
32
38
  kwargs = find_args.pop
33
39
  to_capybara_node.has_selector?(*find_args, **kwargs)
34
40
  end
35
41
 
36
- # Call `has_no_selector?` inside `to_capybara_node` context (Either Capybara::Session or Capybara::Node::Element)
37
42
  def element_does_not_exist?(*find_args)
38
43
  kwargs = find_args.pop
39
44
  to_capybara_node.has_no_selector?(*find_args, **kwargs)
40
45
  end
41
46
 
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
47
  # Sanitize method called before calling any SitePrism DSL method or
74
48
  # meta-programmed method. This ensures that the Capybara query is correct.
75
49
  #
@@ -112,17 +86,23 @@ module SitePrism
112
86
  module ClassMethods
113
87
  attr_reader :expected_items
114
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
+
115
96
  # Creates an instance of a SitePrism Element - This will create several methods designed to
116
97
  # Locate the element -> @return [Capybara::Node::Element]
117
98
  # Check the elements presence or non-presence -> @return [Boolean]
118
99
  # Wait for the elements to be present or not -> @return [TrueClass, SitePrism::Error]
119
100
  # Validate certain properties about the element
120
101
  def element(name, *find_args)
121
- SitePrism::Deprecator.deprecate('Passing a block to :element') if block_given?
102
+ raise_if_build_time_block_supplied(self, name, block_given?, :element)
122
103
  build(:element, name, *find_args) do
123
- define_method(name) do |*runtime_args, &element_block|
124
- warn_if_dsl_collision(self, name)
125
- raise_if_block(self, name, !element_block.nil?, :element)
104
+ define_method(name) do |*runtime_args, &runtime_block|
105
+ raise_if_runtime_block_supplied(self, name, runtime_block, :element)
126
106
  _find(*merge_args(find_args, runtime_args))
127
107
  end
128
108
  end
@@ -134,23 +114,15 @@ module SitePrism
134
114
  # Wait for the elements to be present or not -> @return [TrueClass, SitePrism::Error]
135
115
  # Validate certain properties about the elements
136
116
  def elements(name, *find_args)
137
- SitePrism::Deprecator.deprecate('Passing a block to :elements') if block_given?
117
+ raise_if_build_time_block_supplied(self, name, block_given?, :elements)
138
118
  build(:elements, name, *find_args) do
139
- define_method(name) do |*runtime_args, &element_block|
140
- warn_if_dsl_collision(self, name)
141
- raise_if_block(self, name, !element_block.nil?, :elements)
119
+ define_method(name) do |*runtime_args, &runtime_block|
120
+ raise_if_runtime_block_supplied(self, name, runtime_block, :elements)
142
121
  _all(*merge_args(find_args, runtime_args))
143
122
  end
144
123
  end
145
124
  end
146
125
 
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
126
  # Creates an instance of a SitePrism Section - This will create several methods designed to
155
127
  # Locate the section -> @return [SitePrism::Section]
156
128
  # Check the section presence or non-presence -> @return [Boolean]
@@ -160,7 +132,6 @@ module SitePrism
160
132
  section_class, find_args = extract_section_options(args, &block)
161
133
  build(:section, name, *find_args) do
162
134
  define_method(name) do |*runtime_args, &runtime_block|
163
- warn_if_dsl_collision(self, name)
164
135
  section_element = _find(*merge_args(find_args, runtime_args))
165
136
  section_class.new(self, section_element, &runtime_block)
166
137
  end
@@ -175,8 +146,8 @@ module SitePrism
175
146
  def sections(name, *args, &block)
176
147
  section_class, find_args = extract_section_options(args, &block)
177
148
  build(:sections, name, *find_args) do
178
- define_method(name) do |*runtime_args, &element_block|
179
- raise_if_block(self, name, !element_block.nil?, :sections)
149
+ define_method(name) do |*runtime_args, &runtime_block|
150
+ raise_if_runtime_block_supplied(self, name, runtime_block, :sections)
180
151
  _all(*merge_args(find_args, runtime_args)).map do |element|
181
152
  section_class.new(self, element)
182
153
  end
@@ -185,7 +156,7 @@ module SitePrism
185
156
  end
186
157
 
187
158
  def iframe(name, klass, *args)
188
- SitePrism.logger.debug('Block passed into iFrame construct at build time') if block_given?
159
+ raise_if_build_time_block_supplied(self, name, block_given?, :elements)
189
160
  element_find_args = deduce_iframe_element_find_args(args)
190
161
  scope_find_args = deduce_iframe_scope_find_args(args)
191
162
  build(:iframe, name, *element_find_args) do
@@ -200,46 +171,30 @@ module SitePrism
200
171
  # Return a list of all mapped items on a SitePrism class instance (Page or Section)
201
172
  # If legacy is set to true (Default) -> @return [Array]
202
173
  # If legacy is set to false (New behaviour) -> @return [Hash]
203
- def mapped_items(legacy: true)
204
- return old_mapped_items if legacy
174
+ def mapped_items(legacy: false)
175
+ return legacy_mapped_items if legacy
205
176
 
206
- new_mapped_items
177
+ @mapped_items ||= { element: [], elements: [], section: [], sections: [], iframe: [] }
207
178
  end
208
179
 
209
180
  private
210
181
 
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
182
  def build(type, name, *find_args)
183
+ raise InvalidDSLNameError if ENV.fetch('SITEPRISM_DSL_VALIDATION_ENABLED', nil) && invalid?(name)
184
+
225
185
  if find_args.empty?
226
186
  create_error_method(name)
227
187
  else
228
188
  map_item(type, name)
229
189
  yield
230
190
  end
231
- add_helper_methods(name, *find_args)
191
+ add_helper_methods(name, type, *find_args)
232
192
  end
233
193
 
234
- def map_item(type, name)
235
- old_mapped_items << { type => name }
236
- new_mapped_items[type] << name.to_sym
237
- end
238
-
239
- def add_helper_methods(name, *find_args)
194
+ def add_helper_methods(name, _type, *find_args)
240
195
  create_existence_checker(name, *find_args)
241
196
  create_nonexistence_checker(name, *find_args)
242
- SitePrism::RspecMatchers.new(name)._create_rspec_existence_matchers if defined?(RSpec)
197
+ SitePrism::RSpecMatchers.new(name)._create_rspec_existence_matchers if defined?(RSpec)
243
198
  create_visibility_waiter(name, *find_args)
244
199
  create_invisibility_waiter(name, *find_args)
245
200
  end
@@ -295,14 +250,35 @@ module SitePrism
295
250
  end
296
251
 
297
252
  def create_error_method(name)
298
- SitePrism.logger.error("#{name} has come from an item with no locators.")
299
- SitePrism::Deprecator.soft_deprecate(
253
+ SitePrism::Deprecator.deprecate(
300
254
  'DSL definition with no find_args',
301
- 'All DSL elements should have find_args'
255
+ 'DSL definition with at least 1 find_arg'
302
256
  )
257
+ SitePrism.logger.error("#{name} has come from an item with no locators.")
303
258
  define_method(name) { raise SitePrism::InvalidElementError }
304
259
  end
305
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
+ SitePrism::Deprecator.deprecate(
271
+ '.mapped_items structure (internally), on a class',
272
+ 'Thew new .mapped_items structure'
273
+ )
274
+ @legacy_mapped_items ||= []
275
+ end
276
+
277
+ def map_item(type, name)
278
+ mapped_items(legacy: true) << { type => name }
279
+ mapped_items[type] << name.to_sym
280
+ end
281
+
306
282
  def deduce_iframe_scope_find_args(args)
307
283
  warn_on_invalid_selector_input(args)
308
284
  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
@@ -1,11 +1,11 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module SitePrism
4
+ #
4
5
  # [SitePrism::ElementChecker]
5
6
  #
6
7
  # This allows users to run `#all_there?` checks on an instance.
7
8
  #
8
- # NB: This functionality is being removed in v4 in favour of the all_there gem
9
9
  module ElementChecker
10
10
  # Runnable in the scope of any SitePrism::Page or Section.
11
11
  # Returns +true+ when "every item" that is being checked is
@@ -26,13 +26,7 @@ module SitePrism
26
26
  # Override: 'one' => Perform one recursive dive into all section/sections
27
27
  # items and call #all_there? on all of those items too.
28
28
  def all_there?(recursion: :none)
29
- case recursion
30
- when :none; then elements_to_check.all? { |name| there?(name) }
31
- when :one; then all_there_with_recursion
32
- else
33
- SitePrism.logger.debug("Input value '#{recursion}'. Valid values are :none or :one.")
34
- SitePrism.logger.error('Invalid recursion setting, Will not run #all_there?.')
35
- end
29
+ SitePrism::AllThere::RecursionChecker.new(self).all_there?(recursion: recursion)
36
30
  end
37
31
 
38
32
  # Returns each element that is currently present inside the scope being tested
@@ -51,16 +45,6 @@ module SitePrism
51
45
 
52
46
  private
53
47
 
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
- # If the page or section has expected_items set, return expected_items that are mapped
63
- # otherwise just return the list of all mapped_items
64
48
  def elements_to_check
65
49
  if _expected_items
66
50
  SitePrism.logger.debug('Expected Items has been set.')
@@ -71,7 +55,7 @@ module SitePrism
71
55
  end
72
56
 
73
57
  def _mapped_items
74
- self.class.mapped_items(legacy: false).values.flatten.uniq
58
+ self.class.mapped_items.values.flatten.uniq
75
59
  end
76
60
 
77
61
  def _expected_items
@@ -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
@@ -43,10 +43,11 @@ module SitePrism
43
43
 
44
44
  # Check if the page is loaded.
45
45
  #
46
- # On failure, if an error was reported by a failing validation,
47
- # it will be available via the `load_error` accessor.
46
+ # On failure, if an error was reported by a failing validation, it will be available via the `load_error` accessor
48
47
  #
49
- # @return [Boolean] True if the page loaded successfully; otherwise false.
48
+ # It will return true if the page has been loaded successfully; otherwise it returns false
49
+ #
50
+ # @return [Boolean]
50
51
  def loaded?
51
52
  self.load_error = nil
52
53
 
@@ -57,8 +58,6 @@ module SitePrism
57
58
 
58
59
  private
59
60
 
60
- # If any load validations from page subclasses returns false,
61
- # immediately return false.
62
61
  def load_validations_pass?
63
62
  self.class.load_validations.all? do |validation|
64
63
  passed, message = instance_eval(&validation)
@@ -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 or the `@page` that has been loaded in-line
4
13
  class Page
5
14
  include Capybara::DSL
6
15
  include ElementChecker
@@ -39,12 +48,15 @@ module SitePrism
39
48
  #
40
49
  # @return [Capybara::Node::Simple || Capybara::Session]
41
50
  def page
51
+ SitePrism::Deprecator.deprecate('Calling #page on a SitePrism::Page instance')
42
52
  (defined?(@page) && @page) || Capybara.current_session
43
53
  end
44
54
 
45
55
  # This scopes our calls inside Page correctly to the `Capybara::Session`
56
+ #
57
+ # @return [Capybara::Node::Simple || Capybara::Session]
46
58
  def to_capybara_node
47
- page
59
+ (defined?(@page) && @page) || Capybara.current_session
48
60
  end
49
61
 
50
62
  # Loads the page.
@@ -76,12 +88,21 @@ module SitePrism
76
88
  return_yield || true
77
89
  end
78
90
 
91
+ # Returns true if the page is displayed within the requisite time
92
+ # Returns false if the page is not displayed within the requisite time
93
+ #
94
+ # @return [Boolean]
79
95
  def displayed?(*args)
80
96
  wait_until_displayed(*args)
81
97
  rescue SitePrism::TimeoutError
82
98
  false
83
99
  end
84
100
 
101
+ # Wait until the page is displayed according to input arguments
102
+ # If no url_matcher is provided we don't know how to determine if the page is displayed. So we return an error
103
+ # Then we wait until the url matches the expected mappings
104
+ #
105
+ # @return [Boolean]
85
106
  def wait_until_displayed(*args)
86
107
  raise SitePrism::NoUrlMatcherForPageError unless url_matcher
87
108
 
@@ -90,6 +111,13 @@ module SitePrism
90
111
  Waiter.wait_until_true(seconds) { url_matches?(expected_mappings) }
91
112
  end
92
113
 
114
+ # Return the matching information of a page
115
+ #
116
+ # Return nil if the page is not displayed correctly
117
+ # Return the regex matches if we have provided a regexp style url_matcher
118
+ # Otherwise fall back to an addressable-style template of matches
119
+ #
120
+ # @return [Nil || MatchData || Hash]
93
121
  def url_matches(seconds = Capybara.default_max_wait_time)
94
122
  return unless displayed?(seconds)
95
123
  return regexp_backed_matches if url_matcher.is_a?(Regexp)
@@ -97,14 +125,24 @@ module SitePrism
97
125
  template_backed_matches
98
126
  end
99
127
 
128
+ # Returns the templated url from the set_url property defined during the page definition
129
+ # Returns `nil` if there was not a property set (i.e. the page should not be directly loaded)
130
+ #
131
+ # @return [NilClass || String]
100
132
  def url(expansion = {})
101
133
  self.class.url && Addressable::Template.new(self.class.url).expand(expansion).to_s
102
134
  end
103
135
 
136
+ # Returns the url_matcher property defined during the page definition
137
+ #
138
+ # @return [Regexp]
104
139
  def url_matcher
105
140
  self.class.url_matcher
106
141
  end
107
142
 
143
+ # Returns true if the page is secure, otherwise returns false
144
+ #
145
+ # @return [Boolean]
108
146
  def secure?
109
147
  page.current_url.start_with?('https')
110
148
  end
@@ -1,13 +1,19 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module SitePrism
4
- class RspecMatchers
4
+ #
5
+ # @api private
6
+ #
7
+ class RSpecMatchers
5
8
  attr_reader :element_name
6
9
 
7
10
  def initialize(element_name)
8
11
  @element_name = element_name
9
12
  end
10
13
 
14
+ # Create the positive and negative rspec matchers that will use the SitePrism boolean methods
15
+ #
16
+ # @return [Symbol]
11
17
  def _create_rspec_existence_matchers
12
18
  SitePrism.logger.debug('Including all relevant matcher names / warnings in RSpec scope.')
13
19
  create_rspec_existence_matchers(matcher, object_method, negated_object_method, warning)
@@ -40,8 +46,8 @@ module SitePrism
40
46
  end
41
47
 
42
48
  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. "\
49
+ "The RSpec matcher '#{matcher}' was added by SitePrism, but the object under test " \
50
+ "does not respond to '#{negated_object_method}' and is probably not a SitePrism object. " \
45
51
  'Falling back to the default RSpec matcher.'
46
52
  end
47
53
  end
@@ -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,22 +64,14 @@ module SitePrism
55
64
  root_element
56
65
  end
57
66
 
58
- # This allows us to return anything thats passed in as a block to the section at
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
63
74
 
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
73
-
74
75
  def capybara_session
75
76
  Capybara.current_session
76
77
  end
@@ -7,9 +7,9 @@ module SitePrism
7
7
  class Timer
8
8
  attr_reader :wait_time
9
9
 
10
- # Return &block
11
- #
12
10
  # Count towards a specified time (Supplied)
11
+ #
12
+ # @return [Proc]
13
13
  def self.run(wait_time, &block)
14
14
  new(wait_time).run(&block)
15
15
  end
@@ -19,16 +19,16 @@ module SitePrism
19
19
  @done = false
20
20
  end
21
21
 
22
- # Return Boolean
23
- #
24
22
  # Whether the timer has completed
23
+ #
24
+ # @return [Boolean]
25
25
  def done?
26
26
  @done == true
27
27
  end
28
28
 
29
- # Return &block
30
- #
31
29
  # Start the Timer and re-evaluate the block repeatedly
30
+ #
31
+ # @return [Proc]
32
32
  def run
33
33
  start
34
34
  yield self
@@ -36,9 +36,9 @@ module SitePrism
36
36
  stop
37
37
  end
38
38
 
39
- # Return [Boolean, Nil]
40
- #
41
39
  # Start the Timer in a separate process
40
+ #
41
+ # Return [True]
42
42
  def start
43
43
  stop
44
44
  return if wait_time.zero?
@@ -50,9 +50,9 @@ module SitePrism
50
50
  end
51
51
  end
52
52
 
53
- # Return True
54
- #
55
53
  # Forcibly stop the timer, and kill any threads created by it
54
+ #
55
+ # Return [True]
56
56
  def stop
57
57
  if @thread
58
58
  @thread.kill