site_prism 3.5 → 3.6

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 95c8d9ff0cf7f2b818a8b8cb987ca39f2b512138d572a08533b8466feae6cb63
4
- data.tar.gz: 6239a4a2cd9be9233396f2b221328645dcb50a56e531ee0d5b63faa3dbd9bf53
3
+ metadata.gz: 1ec5104247e3512bd7ebf0a48c579cc92041ef21b9c130531ef0cb4ff5a52f88
4
+ data.tar.gz: a44ff822766bb37ff023048349037c0467ae47333d4b421bc53d8a59cb2af087
5
5
  SHA512:
6
- metadata.gz: a9a7a79356b8f4c16aad85f923db99a549bba2c78ec23624f245504ce3bbffd7698bad6a572ddbb34cbf9f2406da76bda7ce5d2433d874270112025e5e9d79ea
7
- data.tar.gz: 897ae6d1b6a944b52bc5f36ebb81e2796657a276bfa41994fd0a5315031457d404b46408660556644eb262258c8033b72aa5d7400bd79d13f8085993575df826
6
+ metadata.gz: 1a6991ecd0110bb53533fb848c40753a13067aed17913f2dd261a5d0b4c8c1747f9f54d1be83d954856037e6cbd24abd665d498b74ff0ad835ab1bea1e0a084a
7
+ data.tar.gz: bcfe1f63bcaf2b20c64241c03b1c9c718628609fa0bdaa67c01a78b02964b809135aa815e6b0073d4272235226eda5ad802b8b6852d8b118d0806d96e09e2068
data/README.md CHANGED
@@ -736,6 +736,28 @@ use the bleeding edge version of the logic. Then simply set the following config
736
736
  SitePrism.use_all_there_gem = true
737
737
  ```
738
738
 
739
+ ### Getting the list of missing elements
740
+
741
+ If `#all_there?` returns false and you wish to get the list of missing elements for debugging purposes
742
+ you may want to use `#elements_missing` method. It will return all missing elements from the expected_elements list
743
+
744
+ If you do not provide a list of `expected_elements` this method will return all elements that are missing on the page;
745
+ from those which are defined.
746
+
747
+ ```ruby
748
+ class Home < SitePrism::Page
749
+ element :name, '#name'
750
+ element :address, '#address'
751
+ element :success_message, 'span.alert-success'
752
+
753
+ expected_elements :name, :address
754
+ end
755
+
756
+ # and... Only `address` is on the page
757
+
758
+ @test_page.elements_missing #=> [:name]
759
+ ```
760
+
739
761
  ## Sections
740
762
 
741
763
  SitePrism allows you to model sections of a page that appear on multiple
@@ -1688,7 +1710,7 @@ end
1688
1710
  ```
1689
1711
 
1690
1712
  Note that even with implicit waits on you can dynamically modify the wait times
1691
- in any SitePrism method to help work-around special circumstances.
1713
+ in any SitePrism method to help work-around special circumstances.
1692
1714
 
1693
1715
  ```ruby
1694
1716
  # Option 1: using wait key assignment
@@ -5,13 +5,16 @@ require 'addressable/template'
5
5
 
6
6
  module SitePrism
7
7
  autoload :AddressableUrlMatcher, 'site_prism/addressable_url_matcher'
8
- autoload :Deprecator, 'site_prism/deprecator'
9
8
  autoload :DSL, 'site_prism/dsl'
9
+ autoload :Deprecator, 'site_prism/deprecator'
10
10
  autoload :ElementChecker, 'site_prism/element_checker'
11
- autoload :RecursionChecker, 'site_prism/recursion_checker'
11
+ autoload :Loadable, 'site_prism/loadable'
12
12
  autoload :Logger, 'site_prism/logger'
13
13
  autoload :Page, 'site_prism/page'
14
+ autoload :RecursionChecker, 'site_prism/recursion_checker'
15
+ autoload :RspecMatchers, 'site_prism/rspec_matchers'
14
16
  autoload :Section, 'site_prism/section'
17
+ autoload :Timer, 'site_prism/timer'
15
18
  autoload :Waiter, 'site_prism/waiter'
16
19
 
17
20
  class << self
@@ -8,6 +8,30 @@ module SitePrism
8
8
 
9
9
  private
10
10
 
11
+ # Call `find` inside context set on page/section
12
+ def _find(*find_args)
13
+ kwargs = find_args.pop
14
+ page.find(*find_args, **kwargs)
15
+ end
16
+
17
+ # Call `all` inside context set on page/section
18
+ def _all(*find_args)
19
+ kwargs = find_args.pop
20
+ page.all(*find_args, **kwargs)
21
+ end
22
+
23
+ # Call `has_selector?` inside context set on page/section
24
+ def element_exists?(*find_args)
25
+ kwargs = find_args.pop
26
+ page.has_selector?(*find_args, **kwargs)
27
+ end
28
+
29
+ # Call `has_no_selector?` inside context set on page/section
30
+ def element_does_not_exist?(*find_args)
31
+ kwargs = find_args.pop
32
+ page.has_no_selector?(*find_args, **kwargs)
33
+ end
34
+
11
35
  # The default waiting time set by Capybara's configuration settings.
12
36
  def wait_time
13
37
  Capybara.default_max_wait_time
@@ -170,7 +194,7 @@ module SitePrism
170
194
  elements: [],
171
195
  section: [],
172
196
  sections: [],
173
- iframe: [],
197
+ iframe: []
174
198
  }
175
199
  end
176
200
 
@@ -192,7 +216,7 @@ module SitePrism
192
216
  def add_helper_methods(name, *find_args)
193
217
  create_existence_checker(name, *find_args)
194
218
  create_nonexistence_checker(name, *find_args)
195
- create_rspec_existence_matchers(name) if defined?(RSpec)
219
+ SitePrism::RspecMatchers.new(name)._create_rspec_existence_matchers if defined?(RSpec)
196
220
  create_visibility_waiter(name, *find_args)
197
221
  create_invisibility_waiter(name, *find_args)
198
222
  end
@@ -205,16 +229,6 @@ module SitePrism
205
229
  end
206
230
  end
207
231
 
208
- def create_rspec_existence_matchers(element_name)
209
- matcher = "has_#{element_name}?"
210
- negated_matcher = "has_no_#{element_name}?"
211
-
212
- RSpec::Matchers.define "have_#{element_name}" do |*args|
213
- match { |actual| actual.public_send(matcher, *args) }
214
- match_when_negated { |actual| actual.public_send(negated_matcher, *args) }
215
- end
216
- end
217
-
218
232
  def create_existence_checker(element_name, *find_args)
219
233
  method_name = "has_#{element_name}?"
220
234
  create_helper_method(method_name, *find_args) do
@@ -35,6 +35,10 @@ module SitePrism
35
35
  _mapped_items.select { |name| there?(name) }
36
36
  end
37
37
 
38
+ def elements_missing
39
+ elements_to_check.reject { |name| there?(name) }
40
+ end
41
+
38
42
  private
39
43
 
40
44
  def all_there_with_recursion
@@ -25,14 +25,6 @@ module SitePrism
25
25
  # Formerly known as `NoSelectorForElement`
26
26
  class InvalidElementError < SitePrismError; end
27
27
 
28
- # A tool like Timecop is being used to "freeze time" by overriding Time.now
29
- # and similar methods. In this case, our waiter functions won't work, because
30
- # Time.now does not change.
31
- # If you encounter this issue, check that you are not doing Timecop.freeze without
32
- # an accompanying Timecop.return.
33
- # Also check out Timecop.safe_mode https://github.com/travisjeffery/timecop#timecopsafe_mode
34
- class FrozenInTimeError < SitePrismError; end
35
-
36
28
  # The condition that was being evaluated inside the block did not evaluate
37
29
  # to true within the time limit
38
30
  # Formerly known as `TimeoutException`
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'site_prism/loadable'
4
-
5
3
  module SitePrism
6
4
  class Page
7
5
  include Capybara::DSL
@@ -26,11 +24,7 @@ module SitePrism
26
24
  end
27
25
 
28
26
  def page
29
- if defined?(@page)
30
- @page
31
- else
32
- Capybara.current_session
33
- end
27
+ (defined?(@page) && @page) || Capybara.current_session
34
28
  end
35
29
 
36
30
  # Loads the page.
@@ -78,18 +72,13 @@ module SitePrism
78
72
 
79
73
  def url_matches(seconds = wait_time)
80
74
  return unless displayed?(seconds)
75
+ return regexp_backed_matches if url_matcher.is_a?(Regexp)
81
76
 
82
- if url_matcher.is_a?(Regexp)
83
- regexp_backed_matches
84
- else
85
- template_backed_matches
86
- end
77
+ template_backed_matches
87
78
  end
88
79
 
89
80
  def url(expansion = {})
90
- return nil if self.class.url.nil?
91
-
92
- Addressable::Template.new(self.class.url).expand(expansion).to_s
81
+ self.class.url && Addressable::Template.new(self.class.url).expand(expansion).to_s
93
82
  end
94
83
 
95
84
  def url_matcher
@@ -102,26 +91,6 @@ module SitePrism
102
91
 
103
92
  private
104
93
 
105
- def _find(*find_args)
106
- kwargs = find_args.pop
107
- page.find(*find_args, **kwargs)
108
- end
109
-
110
- def _all(*find_args)
111
- kwargs = find_args.pop
112
- page.all(*find_args, **kwargs)
113
- end
114
-
115
- def element_exists?(*find_args)
116
- kwargs = find_args.pop
117
- page.has_selector?(*find_args, **kwargs)
118
- end
119
-
120
- def element_does_not_exist?(*find_args)
121
- kwargs = find_args.pop
122
- page.has_no_selector?(*find_args, **kwargs)
123
- end
124
-
125
94
  def regexp_backed_matches
126
95
  url_matcher.match(page.current_url)
127
96
  end
@@ -28,7 +28,7 @@ module SitePrism
28
28
  expected(mapped_items, :elements),
29
29
  expected(mapped_items, :section),
30
30
  expected(mapped_items, :sections),
31
- expected(mapped_items, :iframe),
31
+ expected(mapped_items, :iframe)
32
32
  ]
33
33
  end
34
34
 
@@ -0,0 +1,50 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SitePrism
4
+ class RspecMatchers
5
+ attr_reader :element_name
6
+
7
+ def initialize(element_name)
8
+ @element_name = element_name
9
+ end
10
+
11
+ def _create_rspec_existence_matchers
12
+ SitePrism.logger.debug('Including all relevant matcher names / warnings in RSpec scope.')
13
+ create_rspec_existence_matchers(matcher, object_method, negated_object_method, warning)
14
+ end
15
+
16
+ private
17
+
18
+ def create_rspec_existence_matchers(matcher, object_method, negated_object_method, warning)
19
+ RSpec::Matchers.define(matcher) do |*args|
20
+ match { |actual| actual.public_send(object_method, *args) }
21
+ match_when_negated do |actual|
22
+ if actual.respond_to?(negated_object_method)
23
+ return actual.public_send(negated_object_method, *args)
24
+ end
25
+
26
+ SitePrism.logger.debug(warning)
27
+ !actual.public_send(object_method, *args)
28
+ end
29
+ end
30
+ end
31
+
32
+ def matcher
33
+ "have_#{element_name}"
34
+ end
35
+
36
+ def object_method
37
+ "has_#{element_name}?"
38
+ end
39
+
40
+ def negated_object_method
41
+ "has_no_#{element_name}?"
42
+ end
43
+
44
+ def warning
45
+ "The RSpec matcher '#{matcher}' was added by SitePrism, but the object under test "\
46
+ "does not respond to '#{negated_object_method}' and is probably not a SitePrism object. "\
47
+ 'Falling back to the default RSpec matcher.'
48
+ end
49
+ end
50
+ end
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'site_prism/loadable'
4
-
5
3
  module SitePrism
6
4
  class Section
7
5
  include Capybara::DSL
@@ -68,27 +66,5 @@ module SitePrism
68
66
  def native
69
67
  root_element.native
70
68
  end
71
-
72
- private
73
-
74
- def _find(*find_args)
75
- kwargs = find_args.pop
76
- page.find(*find_args, **kwargs)
77
- end
78
-
79
- def _all(*find_args)
80
- kwargs = find_args.pop
81
- page.all(*find_args, **kwargs)
82
- end
83
-
84
- def element_exists?(*find_args)
85
- kwargs = find_args.pop
86
- page.has_selector?(*find_args, **kwargs)
87
- end
88
-
89
- def element_does_not_exist?(*find_args)
90
- kwargs = find_args.pop
91
- page.has_no_selector?(*find_args, **kwargs)
92
- end
93
69
  end
94
70
  end
@@ -0,0 +1,47 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SitePrism
4
+ class Timer
5
+ attr_reader :wait_time
6
+
7
+ def self.run(wait_time, &block)
8
+ new(wait_time).run(&block)
9
+ end
10
+
11
+ def initialize(wait_time)
12
+ @wait_time = wait_time
13
+ @done = false
14
+ end
15
+
16
+ def done?
17
+ @done == true
18
+ end
19
+
20
+ def run
21
+ start
22
+ yield self
23
+ ensure
24
+ stop
25
+ end
26
+
27
+ def start
28
+ stop
29
+ return if wait_time.zero?
30
+
31
+ @done = false
32
+ @thread = Thread.start do
33
+ sleep wait_time
34
+ @done = true
35
+ end
36
+ end
37
+
38
+ def stop
39
+ if @thread
40
+ @thread.kill
41
+ @thread.join
42
+ @thread = nil
43
+ end
44
+ @done = true
45
+ end
46
+ end
47
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module SitePrism
4
- VERSION = '3.5'
4
+ VERSION = '3.6'
5
5
  end
@@ -2,33 +2,20 @@
2
2
 
3
3
  module SitePrism
4
4
  class Waiter
5
- class << self
6
- def wait_until_true(wait_time = Capybara.default_max_wait_time)
7
- start_time = Time.now
5
+ def self.sleep_duration
6
+ 0.05
7
+ end
8
8
 
9
+ def self.wait_until_true(wait_time = Capybara.default_max_wait_time)
10
+ Timer.run(wait_time) do |timer|
9
11
  loop do
10
12
  return true if yield
11
- break if Time.now - start_time > wait_time
12
-
13
- sleep(0.05)
13
+ break if timer.done?
14
14
 
15
- check_for_time_stopped!(start_time)
15
+ sleep(sleep_duration)
16
16
  end
17
-
18
17
  raise SitePrism::TimeoutError, "Timed out after #{wait_time}s."
19
18
  end
20
-
21
- private
22
-
23
- def check_for_time_stopped!(start_time)
24
- return unless start_time == Time.now
25
-
26
- raise(
27
- SitePrism::FrozenInTimeError,
28
- 'Time appears to be frozen. For more info, see ' \
29
- 'https://github.com/site-prism/site_prism/blob/master/lib/site_prism/error.rb'
30
- )
31
- end
32
19
  end
33
20
  end
34
21
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: site_prism
3
3
  version: !ruby/object:Gem::Version
4
- version: '3.5'
4
+ version: '3.6'
5
5
  platform: ruby
6
6
  authors:
7
7
  - Luke Hill
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2020-06-04 00:00:00.000000000 Z
12
+ date: 2020-08-17 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: addressable
@@ -29,6 +29,9 @@ dependencies:
29
29
  name: capybara
30
30
  requirement: !ruby/object:Gem::Requirement
31
31
  requirements:
32
+ - - ">="
33
+ - !ruby/object:Gem::Version
34
+ version: '3.8'
32
35
  - - "<="
33
36
  - !ruby/object:Gem::Version
34
37
  version: '3.29'
@@ -36,6 +39,9 @@ dependencies:
36
39
  prerelease: false
37
40
  version_requirements: !ruby/object:Gem::Requirement
38
41
  requirements:
42
+ - - ">="
43
+ - !ruby/object:Gem::Version
44
+ version: '3.8'
39
45
  - - "<="
40
46
  - !ruby/object:Gem::Version
41
47
  version: '3.29'
@@ -121,14 +127,14 @@ dependencies:
121
127
  requirements:
122
128
  - - "~>"
123
129
  - !ruby/object:Gem::Version
124
- version: 0.75.0
130
+ version: 0.81.0
125
131
  type: :development
126
132
  prerelease: false
127
133
  version_requirements: !ruby/object:Gem::Requirement
128
134
  requirements:
129
135
  - - "~>"
130
136
  - !ruby/object:Gem::Version
131
- version: 0.75.0
137
+ version: 0.81.0
132
138
  - !ruby/object:Gem::Dependency
133
139
  name: rubocop-performance
134
140
  requirement: !ruby/object:Gem::Requirement
@@ -161,16 +167,22 @@ dependencies:
161
167
  name: selenium-webdriver
162
168
  requirement: !ruby/object:Gem::Requirement
163
169
  requirements:
164
- - - "~>"
170
+ - - ">="
171
+ - !ruby/object:Gem::Version
172
+ version: '3.9'
173
+ - - "<"
165
174
  - !ruby/object:Gem::Version
166
- version: '3.7'
175
+ version: '4.1'
167
176
  type: :development
168
177
  prerelease: false
169
178
  version_requirements: !ruby/object:Gem::Requirement
170
179
  requirements:
171
- - - "~>"
180
+ - - ">="
181
+ - !ruby/object:Gem::Version
182
+ version: '3.9'
183
+ - - "<"
172
184
  - !ruby/object:Gem::Version
173
- version: '3.7'
185
+ version: '4.1'
174
186
  - !ruby/object:Gem::Dependency
175
187
  name: simplecov
176
188
  requirement: !ruby/object:Gem::Requirement
@@ -191,14 +203,14 @@ dependencies:
191
203
  requirements:
192
204
  - - "~>"
193
205
  - !ruby/object:Gem::Version
194
- version: '4.0'
206
+ version: '4.1'
195
207
  type: :development
196
208
  prerelease: false
197
209
  version_requirements: !ruby/object:Gem::Requirement
198
210
  requirements:
199
211
  - - "~>"
200
212
  - !ruby/object:Gem::Version
201
- version: '4.0'
213
+ version: '4.1'
202
214
  description: SitePrism gives you a simple, clean and semantic DSL for describing your
203
215
  site. SitePrism implements the Page Object Model pattern on top of Capybara.
204
216
  email:
@@ -220,7 +232,9 @@ files:
220
232
  - lib/site_prism/logger.rb
221
233
  - lib/site_prism/page.rb
222
234
  - lib/site_prism/recursion_checker.rb
235
+ - lib/site_prism/rspec_matchers.rb
223
236
  - lib/site_prism/section.rb
237
+ - lib/site_prism/timer.rb
224
238
  - lib/site_prism/version.rb
225
239
  - lib/site_prism/waiter.rb
226
240
  homepage: https://github.com/site-prism/site_prism
@@ -238,7 +252,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
238
252
  requirements:
239
253
  - - ">="
240
254
  - !ruby/object:Gem::Version
241
- version: '2.3'
255
+ version: '2.4'
242
256
  required_rubygems_version: !ruby/object:Gem::Requirement
243
257
  requirements:
244
258
  - - ">="