site_prism 2.15 → 2.15.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.
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