site_prism 3.7.3 → 4.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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