site_prism 2.15 → 2.15.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: f4e3fd2e00cf2bb78219d9f9fbeabd2f7508acc6
4
- data.tar.gz: 49f28a586eead92eaf7be65e8471a713a9d07f49
3
+ metadata.gz: 77f8efa7a200630bd4f6bb6c79afeb4e8e2a018f
4
+ data.tar.gz: ab7dd809c5018e60bbeb754e1c450c8cfc19b8a8
5
5
  SHA512:
6
- metadata.gz: 054cfa56172cf001d9c3e3b131f9fb382fe901034bbf913831189a6b091e01f4ddc2e73af69c9c60ac5c7ad5fe32e1dc615eca04e84fe4a5aec398166c430b16
7
- data.tar.gz: c539b113a2b70cb84467675346132599cc75512012860676ab21c53fd1b1e853d633809df6122d3bbaa0cc0295bc5ae2be5dc44626529799db25ac685c827ce0
6
+ metadata.gz: f3c9f957a980efd3262f028b211c8bb52a53d415a08e79e3b950b8d2ee90dad48bf74c2bd92a202f2fa4a4bae7f60d08d15d2176f539561ddfca7d98f81ce376
7
+ data.tar.gz: 3eba16133d0b5d874455f863aac542101137e446d3b81bd2e404f65dc69164572b2c5ff261db1b31cf2c797555ac9ada8166828e1ca2d1c34832db690c15ab64
data/README.md CHANGED
@@ -13,7 +13,7 @@ Make sure to add your project/company to https://github.com/natritmeyer/site_pri
13
13
 
14
14
  We love it when people want to get involved with our Open Source Project.
15
15
 
16
- We have a brief set of setup docs [HERE](https://github.com/natritmeyer/site_prism/development_setup.md)
16
+ We have a brief set of setup docs [HERE](https://github.com/natritmeyer/site_prism/blob/master/development_setup.md)
17
17
 
18
18
  ## Supported Rubies / Browsers
19
19
 
@@ -35,7 +35,7 @@ class Home < SitePrism::Page
35
35
  set_url_matcher /google.com\/?/
36
36
 
37
37
  element :search_field, 'input[name="q"]'
38
- element :search_button, "button[name='btnK']"
38
+ element :search_button, 'button[name="btnK"]'
39
39
  elements :footer_links, '#footer a'
40
40
  section :menu, MenuSection, '#gbx3'
41
41
  end
@@ -47,7 +47,7 @@ class SearchResults < SitePrism::Page
47
47
  sections :search_results, SearchResultSection, '#results li'
48
48
 
49
49
  def search_result_links
50
- search_results.map {|sr| sr.title['href']}
50
+ search_results.map { |result| result.title['href'] }
51
51
  end
52
52
  end
53
53
 
@@ -79,7 +79,7 @@ Then(/^the home page should contain the menu and the search form$/) do
79
79
  end
80
80
 
81
81
  When(/^I search for Sausages$/) do
82
- @home.search_field.set "Sausages"
82
+ @home.search_field.set 'Sausages'
83
83
  @home.search_button.click
84
84
  end
85
85
 
@@ -195,7 +195,7 @@ a simple example:
195
195
 
196
196
  ```ruby
197
197
  class UserProfile < SitePrism::Page
198
- set_url "/users{/username}"
198
+ set_url '/users{/username}'
199
199
  end
200
200
  ```
201
201
 
@@ -203,7 +203,7 @@ end
203
203
 
204
204
  ```ruby
205
205
  class Search < SitePrism::Page
206
- set_url "/search{?query*}"
206
+ set_url '/search{?query*}'
207
207
  end
208
208
  ```
209
209
 
@@ -225,7 +225,7 @@ The `#load` method takes parameters and will apply them to the URL. Using the ex
225
225
 
226
226
  ```ruby
227
227
  class UserProfile < SitePrism::Page
228
- set_url "/users{/username}"
228
+ set_url '/users{/username}'
229
229
  end
230
230
 
231
231
  @user_profile = UserProfile.new
@@ -237,7 +237,7 @@ end
237
237
 
238
238
  ```ruby
239
239
  class Search < SitePrism::Page
240
- set_url "/search{?query*}"
240
+ set_url '/search{?query*}'
241
241
  end
242
242
 
243
243
  @search = Search.new
@@ -259,7 +259,7 @@ currently viewed page. For example, with the following URL template:
259
259
 
260
260
  ```ruby
261
261
  class Account < SitePrism::Page
262
- set_url "/accounts/{id}{?query*}"
262
+ set_url '/accounts/{id}{?query*}'
263
263
  end
264
264
  ```
265
265
 
data/lib/site_prism.rb CHANGED
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'site_prism/exceptions'
3
+ require 'site_prism/error'
4
4
  require 'addressable/template'
5
5
 
6
6
  module SitePrism
@@ -5,11 +5,6 @@ require 'base64'
5
5
 
6
6
  module SitePrism
7
7
  class AddressableUrlMatcher
8
- COMPONENT_NAMES = %i[scheme user password host
9
- port path query fragment ].freeze
10
-
11
- COMPONENT_PREFIXES = { query: '?', fragment: '#' }.freeze
12
-
13
8
  attr_reader :pattern
14
9
 
15
10
  def initialize(pattern)
@@ -22,7 +17,7 @@ module SitePrism
22
17
  def mappings(url)
23
18
  uri = Addressable::URI.parse(url)
24
19
  result = {}
25
- COMPONENT_NAMES.each do |component|
20
+ component_names.each do |component|
26
21
  component_result = component_matches(component, uri)
27
22
  return nil unless component_result
28
23
 
@@ -62,7 +57,7 @@ module SitePrism
62
57
  end
63
58
 
64
59
  def extract_component_templates
65
- COMPONENT_NAMES.each_with_object({}) do |component, component_templates|
60
+ component_names.each_with_object({}) do |component, templates|
66
61
  component_url = to_substituted_uri.public_send(component).to_s
67
62
 
68
63
  next unless component_url && !component_url.empty?
@@ -71,15 +66,13 @@ module SitePrism
71
66
  component_url = component_url.sub(substituted_value, template_value)
72
67
  end
73
68
 
74
- component_templates[component] =
75
- Addressable::Template.new(component_url.to_s)
69
+ templates[component] = Addressable::Template.new(component_url)
76
70
  end
77
71
  end
78
72
 
79
- # Returns empty hash if the template omits the component,
80
- # a set of substitutions if the
81
- # provided URI component matches the template component,
82
- # or nil if the match fails.
73
+ # Returns empty hash if the template omits the component or a set of
74
+ # substitutions if the provided URI component matches the template
75
+ # component or nil if the match fails.
83
76
  def component_matches(component, uri)
84
77
  component_template = component_templates[component]
85
78
  return {} unless component_template
@@ -88,7 +81,7 @@ module SitePrism
88
81
  return mappings if mappings
89
82
  # to support Addressable's expansion of queries
90
83
  # ensure it's parsing the fragment as appropriate (e.g. {?params*})
91
- prefix = COMPONENT_PREFIXES[component]
84
+ prefix = component_prefixes[component]
92
85
  return nil unless prefix
93
86
  component_template.extract(prefix + component_url)
94
87
  end
@@ -129,10 +122,9 @@ module SitePrism
129
122
  pattern.scan(/{[^}]+}/)
130
123
  end
131
124
 
132
- # If a slug begins with non-alpha characters,
133
- # it may denote the start of a new component (e.g. query or fragment).
134
- # We emit this prefix as part of the substituted slug
135
- # so that Addressable's URI parser can see it as such.
125
+ # If a slug begins with non-alpha characters, it may denote the start of
126
+ # a new component (e.g. query or fragment). We emit thie prefix as part of
127
+ # the substituted slug so that Addressable's URI parser can see it as such.
136
128
  def slug_prefix(slug)
137
129
  prefix = slug.match(/\A{([^A-Za-z]+)/)
138
130
  prefix && prefix[1] || ''
@@ -144,5 +136,13 @@ module SitePrism
144
136
  sha = Digest::SHA1.digest(index.to_s)
145
137
  Base64.urlsafe_encode64(sha).gsub(/[^A-Za-z]/, '')[0..5]
146
138
  end
139
+
140
+ def component_names
141
+ %i[scheme user password host port path query fragment]
142
+ end
143
+
144
+ def component_prefixes
145
+ { query: '?', fragment: '#' }
146
+ end
147
147
  end
148
148
  end
@@ -12,8 +12,9 @@ module SitePrism
12
12
  Capybara.default_max_wait_time
13
13
  end
14
14
 
15
- def raise_if_block(obj, name, has_block)
15
+ def raise_if_block(obj, name, has_block, type)
16
16
  return unless has_block
17
+ warn "Type passed in: #{type}"
17
18
 
18
19
  raise SitePrism::UnsupportedBlock, "#{obj.class}##{name}"
19
20
  end
@@ -62,7 +63,7 @@ module SitePrism
62
63
  def element(name, *find_args)
63
64
  build(name, *find_args) do
64
65
  define_method(name) do |*runtime_args, &element_block|
65
- raise_if_block(self, name, !element_block.nil?)
66
+ raise_if_block(self, name, !element_block.nil?, :element)
66
67
  _find(*merge_args(find_args, runtime_args))
67
68
  end
68
69
  end
@@ -71,7 +72,7 @@ module SitePrism
71
72
  def elements(name, *find_args)
72
73
  build(name, *find_args) do
73
74
  define_method(name) do |*runtime_args, &element_block|
74
- raise_if_block(self, name, !element_block.nil?)
75
+ raise_if_block(self, name, !element_block.nil?, :elements)
75
76
  _all(*merge_args(find_args, runtime_args))
76
77
  end
77
78
  end
@@ -101,7 +102,7 @@ module SitePrism
101
102
  section_class, find_args = extract_section_options(args, &block)
102
103
  build(name, *find_args) do
103
104
  define_method(name) do |*runtime_args, &element_block|
104
- raise_if_block(self, name, !element_block.nil?)
105
+ raise_if_block(self, name, !element_block.nil?, :sections)
105
106
  _all(*merge_args(find_args, runtime_args)).map do |element|
106
107
  section_class.new(self, element)
107
108
  end
@@ -238,8 +239,7 @@ module SitePrism
238
239
 
239
240
  def create_no_selector(method_name)
240
241
  define_method(method_name) do
241
- raise SitePrism::NoSelectorForElement.new,
242
- "#{self.class.name} => :#{method_name} needs a selector"
242
+ raise SitePrism::NoSelectorForElement, "#{self.class}##{method_name}"
243
243
  end
244
244
  end
245
245
 
@@ -0,0 +1,90 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SitePrism
4
+ # Generic SitePrism family of errors which specific errors are children of
5
+ class SitePrismError < StandardError; end
6
+
7
+ # Generic PageLoad family of errors inherit from this error
8
+ class PageLoadError < SitePrismError; end
9
+
10
+ # A page calls #load with no URL set
11
+ class NoUrlForPageError < PageLoadError; end
12
+
13
+ # A page calls #displayed? with no URL matcher set
14
+ class NoUrlMatcherForPageError < PageLoadError; end
15
+
16
+ # The URL matcher was not recognised as a Regex or String and as such
17
+ # it couldn't be parsed by Addressable
18
+ class InvalidUrlMatcherError < PageLoadError
19
+ def message
20
+ warn 'Templated port numbers are unsupported.'
21
+
22
+ 'Your URL and/or matcher could not be interpreted.'
23
+ end
24
+ end
25
+
26
+ # A SitePrism defined DSL item was defined without a selector
27
+ class InvalidElementError < SitePrismError
28
+ def message
29
+ "#{super} has been derived from an item with no selectors defined."
30
+ end
31
+ end
32
+
33
+ # The condition that was being evaluated inside the block did not evaluate
34
+ # to true within the time limit
35
+ class TimeoutError < SitePrismError
36
+ def message
37
+ "Timed out after #{super}s."
38
+ end
39
+ end
40
+
41
+ # These errors are not yet migrated and are fired from their source
42
+ # They are raised when the meta-programmed method has not yielded true
43
+ # in the prescribed time limit
44
+ class ExistenceTimeoutError < TimeoutError; end
45
+ class NonExistenceTimeoutError < TimeoutError; end
46
+ class ElementVisibilityTimeoutError < TimeoutError; end
47
+ class ElementInvisibilityTimeoutError < TimeoutError; end
48
+
49
+ # A Block was passed to the method, which it cannot interpret
50
+ class UnsupportedBlockError < SitePrismError
51
+ def message
52
+ warn 'section and iframe are the only items which can accept a block.'
53
+
54
+ "#{super} does not accept blocks."
55
+ end
56
+ end
57
+
58
+ # A Block was required, but not passed into the iframe at runtime
59
+ class MissingBlockError < SitePrismError
60
+ def message
61
+ 'You can only use iFrames in a block context - Please pass in a block.'
62
+ end
63
+ end
64
+
65
+ # A page was loaded via #load - And then failed one of the load validations
66
+ # that was either pre-defined or defined by the user
67
+ class FailedLoadValidationError < PageLoadError
68
+ def message
69
+ if super == self.class.to_s
70
+ 'Failed to load - No reason specified.'
71
+ else
72
+ "Failed to load. Reason: #{super}"
73
+ end
74
+ end
75
+ end
76
+
77
+ # Legacy Error Code aliases for backwards compatibility
78
+ NoUrlForPage = NoUrlForPageError
79
+ NoUrlMatcherForPage = NoUrlMatcherForPageError
80
+ InvalidUrlMatcher = InvalidUrlMatcherError
81
+ NoSelectorForElement = InvalidElementError
82
+ TimeoutException = TimeoutError
83
+ TimeOutWaitingForExistenceError = Class.new(StandardError) # To avoid message leaking
84
+ TimeOutWaitingForNonExistenceError = Class.new(StandardError) # To avoid message leaking
85
+ TimeOutWaitingForElementVisibility = Class.new(StandardError) # To avoid message leaking
86
+ TimeOutWaitingForElementInvisibility = Class.new(StandardError) # To avoid message leaking
87
+ UnsupportedBlock = UnsupportedBlockError
88
+ BlockMissingError = MissingBlockError
89
+ NotLoadedError = FailedLoadValidationError
90
+ end
@@ -25,6 +25,10 @@ module SitePrism
25
25
  #
26
26
  # @param block [&block] A block which returns true if the page
27
27
  # loaded successfully, or false if it did not.
28
+ # This block can contain up to 2 elements in an array
29
+ # The first is the physical validation test to be truthily evaluated
30
+ # If this does not pass, then the 2nd item (If defined), is output
31
+ # as an error message to the NotLoadedError Error that will be thrown
28
32
  def load_validation(&block)
29
33
  _load_validations << block
30
34
  end
@@ -62,8 +66,7 @@ module SitePrism
62
66
  # Within the block, cache loaded? to optimize performance.
63
67
  self.loaded = loaded?
64
68
 
65
- message = "Failed to load because: #{load_error || 'no reason given'}"
66
- raise ::SitePrism::NotLoadedError, message unless loaded
69
+ raise SitePrism::NotLoadedError, load_error unless loaded
67
70
 
68
71
  yield self
69
72
  ensure
@@ -8,6 +8,7 @@ module SitePrism
8
8
  include ElementChecker
9
9
  include Loadable
10
10
  include ElementContainer
11
+ extend Forwardable
11
12
 
12
13
  attr_reader :root_element, :parent
13
14
 
@@ -42,12 +43,13 @@ module SitePrism
42
43
  page.visible?
43
44
  end
44
45
 
45
- def execute_script(input)
46
- Capybara.current_session.execute_script(input)
47
- end
46
+ def_delegators :capybara_session,
47
+ :execute_script,
48
+ :evaluate_script,
49
+ :within_frame
48
50
 
49
- def evaluate_script(input)
50
- Capybara.current_session.evaluate_script(input)
51
+ def capybara_session
52
+ Capybara.current_session
51
53
  end
52
54
 
53
55
  def parent_page
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module SitePrism
4
- VERSION = '2.15'.freeze
4
+ VERSION = '2.15.1'.freeze
5
5
  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: '2.15'
4
+ version: 2.15.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nat Ritmeyer
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2018-07-09 00:00:00.000000000 Z
12
+ date: 2018-07-20 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: addressable
@@ -34,7 +34,7 @@ dependencies:
34
34
  version: '2.14'
35
35
  - - "<"
36
36
  - !ruby/object:Gem::Version
37
- version: '3.1'
37
+ version: '3.3'
38
38
  type: :runtime
39
39
  prerelease: false
40
40
  version_requirements: !ruby/object:Gem::Requirement
@@ -44,7 +44,7 @@ dependencies:
44
44
  version: '2.14'
45
45
  - - "<"
46
46
  - !ruby/object:Gem::Version
47
- version: '3.1'
47
+ version: '3.3'
48
48
  - !ruby/object:Gem::Dependency
49
49
  name: cucumber
50
50
  requirement: !ruby/object:Gem::Requirement
@@ -105,16 +105,16 @@ dependencies:
105
105
  name: rubocop
106
106
  requirement: !ruby/object:Gem::Requirement
107
107
  requirements:
108
- - - "~>"
108
+ - - "<"
109
109
  - !ruby/object:Gem::Version
110
- version: '0.52'
110
+ version: '0.58'
111
111
  type: :development
112
112
  prerelease: false
113
113
  version_requirements: !ruby/object:Gem::Requirement
114
114
  requirements:
115
- - - "~>"
115
+ - - "<"
116
116
  - !ruby/object:Gem::Version
117
- version: '0.52'
117
+ version: '0.58'
118
118
  - !ruby/object:Gem::Dependency
119
119
  name: selenium-webdriver
120
120
  requirement: !ruby/object:Gem::Requirement
@@ -135,14 +135,14 @@ dependencies:
135
135
  requirements:
136
136
  - - "~>"
137
137
  - !ruby/object:Gem::Version
138
- version: '0.14'
138
+ version: '0.16'
139
139
  type: :development
140
140
  prerelease: false
141
141
  version_requirements: !ruby/object:Gem::Requirement
142
142
  requirements:
143
143
  - - "~>"
144
144
  - !ruby/object:Gem::Version
145
- version: '0.14'
145
+ version: '0.16'
146
146
  description: |-
147
147
  SitePrism gives you a simple, clean and semantic DSL for describing your site.
148
148
  SitePrism implements the Page Object Model pattern on top of Capybara.
@@ -159,7 +159,7 @@ files:
159
159
  - lib/site_prism/addressable_url_matcher.rb
160
160
  - lib/site_prism/element_checker.rb
161
161
  - lib/site_prism/element_container.rb
162
- - lib/site_prism/exceptions.rb
162
+ - lib/site_prism/error.rb
163
163
  - lib/site_prism/loadable.rb
164
164
  - lib/site_prism/page.rb
165
165
  - lib/site_prism/section.rb
@@ -1,40 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module SitePrism
4
- class NoUrlForPage < StandardError; end
5
- class NoUrlMatcherForPage < StandardError; end
6
-
7
- class InvalidUrlMatcher < StandardError
8
- def message
9
- "Could not automatically match your URL. \
10
- Templated port numbers are unsupported."
11
- end
12
- end
13
-
14
- class NoSelectorForElement < StandardError; end
15
-
16
- class TimeoutException < StandardError
17
- def message
18
- "Timed out after #{super}s while waiting for block to evaluate as true."
19
- end
20
- end
21
-
22
- class TimeOutWaitingForExistenceError < StandardError; end
23
- class TimeOutWaitingForNonExistenceError < StandardError; end
24
- class TimeOutWaitingForElementVisibility < StandardError; end
25
- class TimeOutWaitingForElementInvisibility < StandardError; end
26
-
27
- class UnsupportedBlock < StandardError
28
- def message
29
- "#{super} does not accept blocks, did you mean to define a (i)frame?"
30
- end
31
- end
32
-
33
- class BlockMissingError < StandardError
34
- def message
35
- 'You can only use iFrames in a block context. See docs for more details.'
36
- end
37
- end
38
-
39
- NotLoadedError = Class.new(StandardError)
40
- end