site_prism 4.0.beta → 4.0.1

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.
@@ -15,7 +15,7 @@ module SitePrism
15
15
  warn("#{old} is being deprecated and should no longer be used.")
16
16
  end
17
17
 
18
- warn("#{old} will be removed in SitePrism v4. You have been warned!")
18
+ warn("#{old} will be removed in SitePrism v5. You have been warned!")
19
19
  end
20
20
 
21
21
  # @return SitePrism.logger.debug(msg)
@@ -27,9 +27,9 @@ module SitePrism
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
29
29
  def soft_deprecate(old, reason, new = nil)
30
- debug("The #{old} method is changing, as is SitePrism, and is now configurable.")
30
+ debug("The #{old} method is changing, as is SitePrism, and is now advised to be changed.")
31
31
  debug("REASON: #{reason}.")
32
- debug('Moving forwards into SitePrism v4, the default behaviour will change.')
32
+ debug('Moving forwards into SitePrism v5, the default behaviour will change.')
33
33
  debug("We advise you change to using #{new}") if new
34
34
  end
35
35
 
@@ -16,7 +16,7 @@ module SitePrism
16
16
 
17
17
  private
18
18
 
19
- def raise_if_block(object, name, has_block, type)
19
+ def raise_if_runtime_block_supplied(object, name, has_block, type)
20
20
  return unless has_block
21
21
 
22
22
  SitePrism.logger.debug("Type passed in: #{type}")
@@ -24,25 +24,21 @@ module SitePrism
24
24
  raise SitePrism::UnsupportedBlockError
25
25
  end
26
26
 
27
- # Call `find` inside `to_capybara_node` context (Either Capybara::Session or Capybara::Node::Element)
28
27
  def _find(*find_args)
29
28
  kwargs = find_args.pop
30
29
  to_capybara_node.find(*find_args, **kwargs)
31
30
  end
32
31
 
33
- # Call `all` inside `to_capybara_node` context (Either Capybara::Session or Capybara::Node::Element)
34
32
  def _all(*find_args)
35
33
  kwargs = find_args.pop
36
34
  to_capybara_node.all(*find_args, **kwargs)
37
35
  end
38
36
 
39
- # Call `has_selector?` inside `to_capybara_node` context (Either Capybara::Session or Capybara::Node::Element)
40
37
  def element_exists?(*find_args)
41
38
  kwargs = find_args.pop
42
39
  to_capybara_node.has_selector?(*find_args, **kwargs)
43
40
  end
44
41
 
45
- # Call `has_no_selector?` inside `to_capybara_node` context (Either Capybara::Session or Capybara::Node::Element)
46
42
  def element_does_not_exist?(*find_args)
47
43
  kwargs = find_args.pop
48
44
  to_capybara_node.has_no_selector?(*find_args, **kwargs)
@@ -103,10 +99,10 @@ module SitePrism
103
99
  # Wait for the elements to be present or not -> @return [TrueClass, SitePrism::Error]
104
100
  # Validate certain properties about the element
105
101
  def element(name, *find_args)
106
- raise_if_block(self, name, block_given?, :element)
102
+ raise_if_build_time_block_supplied(self, name, block_given?, :element)
107
103
  build(:element, name, *find_args) do
108
104
  define_method(name) do |*runtime_args, &runtime_block|
109
- raise_if_block(self, name, runtime_block, :element)
105
+ raise_if_runtime_block_supplied(self, name, runtime_block, :element)
110
106
  _find(*merge_args(find_args, runtime_args))
111
107
  end
112
108
  end
@@ -118,10 +114,10 @@ module SitePrism
118
114
  # Wait for the elements to be present or not -> @return [TrueClass, SitePrism::Error]
119
115
  # Validate certain properties about the elements
120
116
  def elements(name, *find_args)
121
- raise_if_block(self, name, block_given?, :elements)
117
+ raise_if_build_time_block_supplied(self, name, block_given?, :elements)
122
118
  build(:elements, name, *find_args) do
123
119
  define_method(name) do |*runtime_args, &runtime_block|
124
- raise_if_block(self, name, runtime_block, :elements)
120
+ raise_if_runtime_block_supplied(self, name, runtime_block, :elements)
125
121
  _all(*merge_args(find_args, runtime_args))
126
122
  end
127
123
  end
@@ -151,7 +147,7 @@ module SitePrism
151
147
  section_class, find_args = extract_section_options(args, &block)
152
148
  build(:sections, name, *find_args) do
153
149
  define_method(name) do |*runtime_args, &runtime_block|
154
- raise_if_block(self, name, runtime_block, :sections)
150
+ raise_if_runtime_block_supplied(self, name, runtime_block, :sections)
155
151
  _all(*merge_args(find_args, runtime_args)).map do |element|
156
152
  section_class.new(self, element)
157
153
  end
@@ -160,7 +156,7 @@ module SitePrism
160
156
  end
161
157
 
162
158
  def iframe(name, klass, *args)
163
- 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)
164
160
  element_find_args = deduce_iframe_element_find_args(args)
165
161
  scope_find_args = deduce_iframe_scope_find_args(args)
166
162
  build(:iframe, name, *element_find_args) do
@@ -175,10 +171,10 @@ module SitePrism
175
171
  # Return a list of all mapped items on a SitePrism class instance (Page or Section)
176
172
  # If legacy is set to true (Default) -> @return [Array]
177
173
  # If legacy is set to false (New behaviour) -> @return [Hash]
178
- def mapped_items(legacy: true)
179
- return old_mapped_items if legacy
174
+ def mapped_items(legacy: false)
175
+ return legacy_mapped_items if legacy
180
176
 
181
- new_mapped_items
177
+ @mapped_items ||= { element: [], elements: [], section: [], sections: [], iframe: [] }
182
178
  end
183
179
 
184
180
  private
@@ -192,13 +188,13 @@ module SitePrism
192
188
  map_item(type, name)
193
189
  yield
194
190
  end
195
- add_helper_methods(name, *find_args)
191
+ add_helper_methods(name, type, *find_args)
196
192
  end
197
193
 
198
- def add_helper_methods(name, *find_args)
194
+ def add_helper_methods(name, _type, *find_args)
199
195
  create_existence_checker(name, *find_args)
200
196
  create_nonexistence_checker(name, *find_args)
201
- SitePrism::RspecMatchers.new(name)._create_rspec_existence_matchers if defined?(RSpec)
197
+ SitePrism::RSpecMatchers.new(name)._create_rspec_existence_matchers if defined?(RSpec)
202
198
  create_visibility_waiter(name, *find_args)
203
199
  create_invisibility_waiter(name, *find_args)
204
200
  end
@@ -254,15 +250,15 @@ module SitePrism
254
250
  end
255
251
 
256
252
  def create_error_method(name)
257
- SitePrism.logger.error("#{name} has come from an item with no locators.")
258
- SitePrism::Deprecator.soft_deprecate(
253
+ SitePrism::Deprecator.deprecate(
259
254
  'DSL definition with no find_args',
260
- 'All DSL elements should have find_args'
255
+ 'DSL definition with at least 1 find_arg'
261
256
  )
257
+ SitePrism.logger.error("#{name} has come from an item with no locators.")
262
258
  define_method(name) { raise SitePrism::InvalidElementError }
263
259
  end
264
260
 
265
- def raise_if_block(parent_object, name, has_block, type)
261
+ def raise_if_build_time_block_supplied(parent_object, name, has_block, type)
266
262
  return unless has_block
267
263
 
268
264
  SitePrism.logger.debug("Type passed in: #{type}")
@@ -270,22 +266,19 @@ module SitePrism
270
266
  raise SitePrism::UnsupportedBlockError
271
267
  end
272
268
 
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: [] }
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
284
277
  end
285
278
 
286
279
  def map_item(type, name)
287
- old_mapped_items << { type => name }
288
- new_mapped_items[type] << name.to_sym
280
+ mapped_items(legacy: true) << { type => name }
281
+ mapped_items[type] << name.to_sym
289
282
  end
290
283
 
291
284
  def deduce_iframe_scope_find_args(args)
@@ -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
@@ -13,10 +13,16 @@ module SitePrism
13
13
  # for how the definition of "every item" is derived.
14
14
  #
15
15
  # Example
16
- # @my_page.mapped_items
17
- # { element => :button_one, element => :button_two, section => :filters }
16
+ # @my_page.class.mapped_items
17
+ # {
18
+ # element => [:button_one, :button_two],
19
+ # elements => [:button_collection_one, :button_collection_two],
20
+ # section => [:filters],
21
+ # sections => [:search_result],
22
+ # iframe => []
23
+ # }
18
24
  # @my_page.all_there?
19
- # => true - If the three items above are all present
25
+ # => true - If the items above are all present
20
26
  #
21
27
  # Note that #elements_to_check will check the hash of mapped_items
22
28
  #
@@ -26,13 +32,7 @@ module SitePrism
26
32
  # Override: 'one' => Perform one recursive dive into all section/sections
27
33
  # items and call #all_there? on all of those items too.
28
34
  def all_there?(recursion: :none)
29
- case recursion
30
- when :none; then elements_to_check.all? { |name| there?(name) }
31
- when :one; then SitePrism::AllThere::RecursionChecker.new(self).all_there?
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
35
+ SitePrism::AllThere::RecursionChecker.new(self).all_there?(recursion: recursion)
36
36
  end
37
37
 
38
38
  # Returns each element that is currently present inside the scope being tested
@@ -51,8 +51,6 @@ module SitePrism
51
51
 
52
52
  private
53
53
 
54
- # If the page or section has expected_items set, return expected_items that are mapped
55
- # otherwise just return the list of all mapped_items
56
54
  def elements_to_check
57
55
  if _expected_items
58
56
  SitePrism.logger.debug('Expected Items has been set.')
@@ -63,7 +61,7 @@ module SitePrism
63
61
  end
64
62
 
65
63
  def _mapped_items
66
- self.class.mapped_items(legacy: false).values.flatten.uniq
64
+ self.class.mapped_items.values.flatten.uniq
67
65
  end
68
66
 
69
67
  def _expected_items
@@ -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)
@@ -9,7 +9,7 @@ module SitePrism
9
9
  # through clicking buttons or filling in fields, or verbosely loaded by using the `#load` method
10
10
  #
11
11
  # All method calls made whilst on a page are scoped using `#to_capybara_node` which defaults to the
12
- # current Capybara session
12
+ # current Capybara session or the `@page` that has been loaded in-line
13
13
  class Page
14
14
  include Capybara::DSL
15
15
  include ElementChecker
@@ -48,12 +48,17 @@ module SitePrism
48
48
  #
49
49
  # @return [Capybara::Node::Simple || Capybara::Session]
50
50
  def page
51
- (defined?(@page) && @page) || Capybara.current_session
51
+ @_page ||= begin
52
+ SitePrism::Deprecator.deprecate('Calling #page on a SitePrism::Page instance')
53
+ to_capybara_node
54
+ end
52
55
  end
53
56
 
54
57
  # This scopes our calls inside Page correctly to the `Capybara::Session`
58
+ #
59
+ # @return [Capybara::Node::Simple || Capybara::Session]
55
60
  def to_capybara_node
56
- page
61
+ (defined?(@page) && @page) || Capybara.current_session
57
62
  end
58
63
 
59
64
  # Loads the page.
@@ -85,12 +90,21 @@ module SitePrism
85
90
  return_yield || true
86
91
  end
87
92
 
93
+ # Returns true if the page is displayed within the requisite time
94
+ # Returns false if the page is not displayed within the requisite time
95
+ #
96
+ # @return [Boolean]
88
97
  def displayed?(*args)
89
98
  wait_until_displayed(*args)
90
99
  rescue SitePrism::TimeoutError
91
100
  false
92
101
  end
93
102
 
103
+ # Wait until the page is displayed according to input arguments
104
+ # If no url_matcher is provided we don't know how to determine if the page is displayed. So we return an error
105
+ # Then we wait until the url matches the expected mappings
106
+ #
107
+ # @return [Boolean]
94
108
  def wait_until_displayed(*args)
95
109
  raise SitePrism::NoUrlMatcherForPageError unless url_matcher
96
110
 
@@ -99,6 +113,13 @@ module SitePrism
99
113
  Waiter.wait_until_true(seconds) { url_matches?(expected_mappings) }
100
114
  end
101
115
 
116
+ # Return the matching information of a page
117
+ #
118
+ # Return nil if the page is not displayed correctly
119
+ # Return the regex matches if we have provided a regexp style url_matcher
120
+ # Otherwise fall back to an addressable-style template of matches
121
+ #
122
+ # @return [Nil || MatchData || Hash]
102
123
  def url_matches(seconds = Capybara.default_max_wait_time)
103
124
  return unless displayed?(seconds)
104
125
  return regexp_backed_matches if url_matcher.is_a?(Regexp)
@@ -106,14 +127,24 @@ module SitePrism
106
127
  template_backed_matches
107
128
  end
108
129
 
130
+ # Returns the templated url from the set_url property defined during the page definition
131
+ # Returns `nil` if there was not a property set (i.e. the page should not be directly loaded)
132
+ #
133
+ # @return [NilClass || String]
109
134
  def url(expansion = {})
110
135
  self.class.url && Addressable::Template.new(self.class.url).expand(expansion).to_s
111
136
  end
112
137
 
138
+ # Returns the url_matcher property defined during the page definition
139
+ #
140
+ # @return [Regexp]
113
141
  def url_matcher
114
142
  self.class.url_matcher
115
143
  end
116
144
 
145
+ # Returns true if the page is secure, otherwise returns false
146
+ #
147
+ # @return [Boolean]
117
148
  def secure?
118
149
  page.current_url.start_with?('https')
119
150
  end
@@ -4,13 +4,16 @@ module SitePrism
4
4
  #
5
5
  # @api private
6
6
  #
7
- class RspecMatchers
7
+ class RSpecMatchers
8
8
  attr_reader :element_name
9
9
 
10
10
  def initialize(element_name)
11
11
  @element_name = element_name
12
12
  end
13
13
 
14
+ # Create the positive and negative rspec matchers that will use the SitePrism boolean methods
15
+ #
16
+ # @return [Symbol]
14
17
  def _create_rspec_existence_matchers
15
18
  SitePrism.logger.debug('Including all relevant matcher names / warnings in RSpec scope.')
16
19
  create_rspec_existence_matchers(matcher, object_method, negated_object_method, warning)
@@ -43,8 +46,8 @@ module SitePrism
43
46
  end
44
47
 
45
48
  def warning
46
- "The RSpec matcher '#{matcher}' was added by SitePrism, but the object under test "\
47
- "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. " \
48
51
  'Falling back to the default RSpec matcher.'
49
52
  end
50
53
  end
@@ -72,13 +72,6 @@ module SitePrism
72
72
  Capybara.within(root_element) { yield(self) }
73
73
  end
74
74
 
75
- # This was the old API-style of delegating through the Capybara.page call and over-loading
76
- # the method so we always went through our correct `root_element`
77
- def page
78
- SitePrism.logger.fatal('This is not supposed to be used. All delegation now happens automatically!')
79
- raise SitePrism::SitePrismError
80
- end
81
-
82
75
  def capybara_session
83
76
  Capybara.current_session
84
77
  end
@@ -1,15 +1,12 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module SitePrism
4
- # [SitePrism::Timer]
5
4
  #
6
- # Used to count asynchronously towards an overall desired duration or condition (Block)
5
+ # @api private
6
+ #
7
7
  class Timer
8
8
  attr_reader :wait_time
9
9
 
10
- # Return &block
11
- #
12
- # Count towards a specified time (Supplied)
13
10
  def self.run(wait_time, &block)
14
11
  new(wait_time).run(&block)
15
12
  end
@@ -19,16 +16,10 @@ module SitePrism
19
16
  @done = false
20
17
  end
21
18
 
22
- # Return Boolean
23
- #
24
- # Whether the timer has completed
25
19
  def done?
26
20
  @done == true
27
21
  end
28
22
 
29
- # Return &block
30
- #
31
- # Start the Timer and re-evaluate the block repeatedly
32
23
  def run
33
24
  start
34
25
  yield self
@@ -36,9 +27,8 @@ module SitePrism
36
27
  stop
37
28
  end
38
29
 
39
- # Return [Boolean, Nil]
40
- #
41
- # Start the Timer in a separate process
30
+ private
31
+
42
32
  def start
43
33
  stop
44
34
  return if wait_time.zero?
@@ -50,9 +40,6 @@ module SitePrism
50
40
  end
51
41
  end
52
42
 
53
- # Return True
54
- #
55
- # Forcibly stop the timer, and kill any threads created by it
56
43
  def stop
57
44
  if @thread
58
45
  @thread.kill
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module SitePrism
4
- VERSION = '4.0.beta'
4
+ VERSION = '4.0.1'
5
5
  end
@@ -3,10 +3,10 @@
3
3
  module SitePrism
4
4
  # [SitePrism::Waiter]
5
5
  class Waiter
6
- # @return Boolean
7
- #
8
6
  # A looper that will wait until the passed in block evaluates to true
9
7
  # Alternatively it will time out once the wait_time is exceeded
8
+ #
9
+ # @return [Boolean]
10
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
data/lib/site_prism.rb CHANGED
@@ -2,25 +2,25 @@
2
2
 
3
3
  require 'site_prism/error'
4
4
  require 'site_prism/all_there'
5
+
5
6
  require 'addressable/template'
6
7
  require 'forwardable'
7
8
 
8
- # [SitePrism] namespace
9
- # We autoload our files underneath here to provide a slightly more optimal load solution
10
- module SitePrism
11
- autoload :AddressableUrlMatcher, 'site_prism/addressable_url_matcher'
12
- autoload :DSL, 'site_prism/dsl'
13
- autoload :DSLValidator, 'site_prism/dsl_validator'
14
- autoload :Deprecator, 'site_prism/deprecator'
15
- autoload :ElementChecker, 'site_prism/element_checker'
16
- autoload :Loadable, 'site_prism/loadable'
17
- autoload :Logger, 'site_prism/logger'
18
- autoload :Page, 'site_prism/page'
19
- autoload :RspecMatchers, 'site_prism/rspec_matchers'
20
- autoload :Section, 'site_prism/section'
21
- autoload :Timer, 'site_prism/timer'
22
- autoload :Waiter, 'site_prism/waiter'
9
+ require 'site_prism/addressable_url_matcher'
10
+ require 'site_prism/dsl'
11
+ require 'site_prism/dsl_validator'
12
+ require 'site_prism/deprecator'
13
+ require 'site_prism/element_checker'
14
+ require 'site_prism/loadable'
15
+ require 'site_prism/logger'
16
+ require 'site_prism/page'
17
+ require 'site_prism/rspec_matchers'
18
+ require 'site_prism/section'
19
+ require 'site_prism/timer'
20
+ require 'site_prism/waiter'
23
21
 
22
+ # [SitePrism]
23
+ module SitePrism
24
24
  class << self
25
25
  def configure
26
26
  yield self