ae_page_objects 1.1.1 → 1.1.2

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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 68a31d4f7c0a48fd15684969d3641bea3a09e1b6
4
+ data.tar.gz: e006b8bd4008fa3026d8c54de441f1a0d22b0e48
5
+ SHA512:
6
+ metadata.gz: 8c50624c46d4525d3ecb21e92379fd448f64a835e3bcd23a49e79f9f385c27292beb757b046e79f74d7c686a568841961f4ba0cfcb5ae2b8eb2a59b2ab776007
7
+ data.tar.gz: 102510b2a5d9668ac6fd5ae19cd2b516c37408fb6f254fa272a468c98e1c313ef3fc6545d22502ccc5a9d0516d29f887876a74b764b9b481139e831e0befa6be
@@ -39,7 +39,7 @@ module AePageObjects
39
39
  end
40
40
 
41
41
  autoload :Window, 'ae_page_objects/window'
42
-
42
+
43
43
  autoload :DocumentQuery, 'ae_page_objects/document_query'
44
44
  autoload :DocumentLoader, 'ae_page_objects/document_loader'
45
45
 
@@ -48,7 +48,7 @@ module AePageObjects
48
48
  autoload :DocumentProxy, 'ae_page_objects/document_proxy'
49
49
  autoload :Element, 'ae_page_objects/element'
50
50
  autoload :ElementProxy, 'ae_page_objects/element_proxy'
51
-
51
+
52
52
  autoload :Collection, 'ae_page_objects/elements/collection'
53
53
  autoload :Form, 'ae_page_objects/elements/form'
54
54
  autoload :Select, 'ae_page_objects/elements/select'
@@ -6,17 +6,17 @@ module AePageObjects
6
6
  super
7
7
  ensure_loaded!
8
8
  end
9
-
9
+
10
10
  private
11
11
 
12
12
  def loaded_locator
13
13
  end
14
-
14
+
15
15
  def ensure_loaded!
16
16
  if locator = loaded_locator
17
- find(*eval_locator(locator))
17
+ find(*eval_locator(locator))
18
18
  end
19
-
19
+
20
20
  self
21
21
  rescue Capybara::ElementNotFound => e
22
22
  raise LoadingElementFailed, e.message
@@ -13,13 +13,13 @@ module AePageObjects
13
13
 
14
14
  super
15
15
  end
16
-
16
+
17
17
  private
18
-
18
+
19
19
  def stale!
20
20
  @stale = true
21
21
  end
22
-
22
+
23
23
  end
24
24
  end
25
- end
25
+ end
@@ -7,7 +7,7 @@ module AePageObjects
7
7
  end
8
8
 
9
9
  private
10
-
10
+
11
11
  def ensure_loaded!
12
12
  unless Waiter.wait_for { self.class.can_load_from_current_url? }
13
13
  raise LoadingPageFailed, "#{self.class.name} cannot be loaded with url '#{current_url_without_params}'"
@@ -19,7 +19,7 @@ module AePageObjects
19
19
  raise LoadingPageFailed, e.message
20
20
  end
21
21
  end
22
-
22
+
23
23
  module VisitMethod
24
24
  def visit(*args)
25
25
  raise ArgumentError, "Cannot pass block to visit()" if block_given?
@@ -31,9 +31,9 @@ module AePageObjects
31
31
  new
32
32
  end
33
33
  end
34
-
34
+
35
35
  module ClassMethods
36
-
36
+
37
37
  def can_load_from_current_url?
38
38
  return true if paths.empty?
39
39
 
@@ -43,18 +43,18 @@ module AePageObjects
43
43
  site.path_recognizes_url?(path, url)
44
44
  end
45
45
  end
46
-
46
+
47
47
  private
48
-
48
+
49
49
  def paths
50
50
  @paths ||= []
51
51
  end
52
-
52
+
53
53
  def path(path_method)
54
54
  raise ArgumentError, "path must be a symbol or string" if ! path_method.is_a?(Symbol) && ! path_method.is_a?(String)
55
55
 
56
56
  paths << path_method
57
-
57
+
58
58
  extend VisitMethod
59
59
  end
60
60
  end
@@ -1,13 +1,13 @@
1
1
  module AePageObjects
2
2
  class RakeRouter < BasicRouter
3
-
3
+
4
4
  attr_reader :routes
5
-
5
+
6
6
  def initialize(rake_routes, mounted_prefix = '')
7
7
  @mounted_prefix = mounted_prefix || ""
8
8
  @routes = {}
9
9
  route_line_regex = /(\w+)(?:\s[A-Z]+)?\s+(\/.*)\(.:format\).*$/
10
-
10
+
11
11
  rake_routes.split("\n").each do |line|
12
12
  line = line.strip
13
13
  matches = route_line_regex.match(line)
@@ -16,7 +16,7 @@ module AePageObjects
16
16
  end
17
17
  end
18
18
  end
19
-
19
+
20
20
  def path_recognizes_url?(path, url)
21
21
  if path.is_a?(Symbol)
22
22
  route = @routes[path]
@@ -30,7 +30,7 @@ module AePageObjects
30
30
  if named_route.is_a?(String)
31
31
  return Path.new(@mounted_prefix + named_route)
32
32
  end
33
-
33
+
34
34
  if route = @routes[named_route]
35
35
  options = args.last.is_a?(Hash) ? args.pop : {}
36
36
  route.generate_path(options)
@@ -38,17 +38,17 @@ module AePageObjects
38
38
  end
39
39
 
40
40
  private
41
-
41
+
42
42
  class Path < String
43
43
  attr_reader :params, :regex
44
-
44
+
45
45
  def initialize(value)
46
46
  super(value.gsub(/(\/)+/, '/').sub(/\(\.\:format\)$/, ''))
47
-
47
+
48
48
  @params = parse_params
49
49
  @regex = generate_regex
50
50
  end
51
-
51
+
52
52
  def generate(param_values)
53
53
  param_values = HashSymbolizer.new(param_values).symbolize_keys
54
54
  @params.values.inject(self) do |path, param|
@@ -61,11 +61,11 @@ module AePageObjects
61
61
  # overwrite the required status with the optional
62
62
  {}.merge(required_params).merge(optional_params)
63
63
  end
64
-
64
+
65
65
  def find_params(using_regex)
66
66
  scan(using_regex).flatten.map(&:to_sym)
67
67
  end
68
-
68
+
69
69
  def optional_params
70
70
  {}.tap do |optional_params|
71
71
  find_params(/\(\/\:(\w+)\)/).each do |param_name|
@@ -73,7 +73,7 @@ module AePageObjects
73
73
  end
74
74
  end
75
75
  end
76
-
76
+
77
77
  def required_params
78
78
  {}.tap do |required_params|
79
79
  find_params(/\:(\w+)/).each do |param_name|
@@ -85,30 +85,30 @@ module AePageObjects
85
85
  def generate_regex
86
86
  regex_spec = @params.values.inject(self) do |regex_spec, param|
87
87
  param.replace_param_in_url(regex_spec)
88
- end
88
+ end
89
89
  Regexp.new regex_spec
90
90
  end
91
91
  end
92
-
92
+
93
93
  class Param < Struct.new(:name, :optional)
94
94
  include Comparable
95
95
 
96
96
  def optional?
97
97
  optional
98
98
  end
99
-
99
+
100
100
  def <=>(other)
101
101
  name.to_s <=> other.name.to_s
102
102
  end
103
-
103
+
104
104
  def eql?(other)
105
105
  name == other.name
106
106
  end
107
-
107
+
108
108
  def hash
109
109
  name.hash
110
110
  end
111
-
111
+
112
112
  def replace_param_in_url(url)
113
113
  if optional?
114
114
  url.gsub("(/:#{name})", '(\/.+)?')
@@ -116,7 +116,7 @@ module AePageObjects
116
116
  url.gsub(":#{name}", '(.+)')
117
117
  end
118
118
  end
119
-
119
+
120
120
  def substitute(url, values)
121
121
  if optional?
122
122
  if values[name]
@@ -130,13 +130,13 @@ module AePageObjects
130
130
  end
131
131
  end
132
132
  end
133
-
133
+
134
134
  class Route
135
135
  def initialize(spec, mounted_prefix)
136
136
  @path = Path.new(mounted_prefix + spec)
137
137
  @path.freeze
138
138
  end
139
-
139
+
140
140
  def matches?(url)
141
141
  url =~ @path.regex
142
142
  end
@@ -5,14 +5,6 @@ module AePageObjects
5
5
  @strategy = strategy
6
6
  end
7
7
 
8
- def default_document_class
9
- @default_document_class ||= @query.conditions.first.document_class
10
- end
11
-
12
- def permitted_types_dump
13
- @permitted_types_dump ||= @query.conditions.map(&:document_class).map(&:name).inspect
14
- end
15
-
16
8
  def load
17
9
  Waiter.wait_for do
18
10
  @query.conditions.each do |document_condition|
@@ -24,7 +16,7 @@ module AePageObjects
24
16
  nil
25
17
  end
26
18
 
27
- raise @strategy.document_not_loaded_error(self)
19
+ raise DocumentLoadError, @strategy.document_not_loaded_error_message(@query)
28
20
  end
29
21
  end
30
22
  end
@@ -9,9 +9,9 @@ module AePageObjects
9
9
  end
10
10
  end
11
11
 
12
- def initialize(loaded_page, document_loader)
13
- @loaded_page = loaded_page
14
- @document_loader = document_loader
12
+ def initialize(loaded_page, query)
13
+ @loaded_page = loaded_page
14
+ @query = query
15
15
  end
16
16
 
17
17
  def is_a?(document_class)
@@ -23,25 +23,25 @@ module AePageObjects
23
23
  return @loaded_page
24
24
  end
25
25
 
26
- raise DocumentLoadError, "#{document_class.name} not expected. Allowed types: #{@document_loader.permitted_types_dump}"
26
+ raise CastError, "Loaded page is not a #{document_class.name}. Allowed pages: #{@query.permitted_types_dump}"
27
27
  end
28
28
 
29
29
  private
30
30
 
31
31
  def implicit_document
32
- @implicit_document ||= as_a(implicit_document_class)
33
- end
34
-
35
- def implicit_document_class
36
- @implicit_document_class ||= @document_loader.default_document_class
32
+ if @loaded_page.is_a? @query.default_document_class
33
+ @loaded_page
34
+ else
35
+ raise CastError, "#{@query.default_document_class} expected, but #{@loaded_page.class} loaded"
36
+ end
37
37
  end
38
38
 
39
39
  def method_missing(name, *args, &block)
40
40
  implicit_document.__send__(name, *args, &block)
41
41
  end
42
42
 
43
- def respond_to?(*args)
44
- super || implicit_document_class.allocate.respond_to?(*args)
43
+ def respond_to_missing?(*args)
44
+ super || implicit_document.respond_to?(*args)
45
45
  end
46
46
  end
47
47
  end
@@ -64,5 +64,13 @@ module AePageObjects
64
64
  def matches(document_class, conditions = {}, &block_condition)
65
65
  @conditions << Condition.new(document_class, conditions, &block_condition)
66
66
  end
67
+
68
+ def default_document_class
69
+ conditions.first.document_class
70
+ end
71
+
72
+ def permitted_types_dump
73
+ conditions.map(&:document_class).map(&:name).inspect
74
+ end
67
75
  end
68
76
  end
@@ -6,24 +6,24 @@ module AePageObjects
6
6
  @parent = parent
7
7
  @locator = nil
8
8
  @name = nil
9
-
9
+
10
10
  configure(parse_options(options_or_locator))
11
11
 
12
12
  raise ArgumentError, ":name or :locator is required" unless @name || @locator
13
-
13
+
14
14
  @locator ||= default_locator
15
15
 
16
16
  super(scoped_node)
17
17
  end
18
-
18
+
19
19
  def document
20
20
  @document ||= begin
21
21
  node = self.parent
22
-
22
+
23
23
  until node.is_a?(::AePageObjects::Document)
24
24
  node = node.parent
25
25
  end
26
-
26
+
27
27
  node
28
28
  end
29
29
  end
@@ -60,26 +60,26 @@ module AePageObjects
60
60
  def name
61
61
  __name__
62
62
  end
63
-
63
+
64
64
  def to_s
65
65
  super.tap do |str|
66
66
  str << "@name:<#{@name}>; #@locator:<#{@locator}>"
67
67
  end
68
68
  end
69
-
69
+
70
70
  def using_default_locator?
71
71
  @locator == default_locator
72
72
  end
73
-
73
+
74
74
  private
75
-
75
+
76
76
  def configure(options)
77
77
  @locator = options.delete(:locator)
78
78
  @name = options.delete(:name)
79
79
 
80
80
  @name = @name.to_s if @name
81
81
  end
82
-
82
+
83
83
  def parse_options(options_or_locator)
84
84
  if options_or_locator.is_a?( Hash )
85
85
  HashSymbolizer.new(options_or_locator).symbolize_keys
@@ -87,11 +87,11 @@ module AePageObjects
87
87
  {:locator => options_or_locator}
88
88
  end
89
89
  end
90
-
90
+
91
91
  def default_locator
92
92
  @default_locator ||= Proc.new { "##{__full_name__}" }
93
93
  end
94
-
94
+
95
95
  def scoped_node
96
96
  if @locator
97
97
  locator = eval_locator(@locator)
@@ -99,7 +99,7 @@ module AePageObjects
99
99
  return parent.node.find(*locator)
100
100
  end
101
101
  end
102
-
102
+
103
103
  parent.node
104
104
  rescue Capybara::ElementNotFound => e
105
105
  raise LoadingElementFailed, e.message
@@ -2,20 +2,20 @@ require 'timeout'
2
2
 
3
3
  module AePageObjects
4
4
  class ElementProxy
5
-
5
+
6
6
  # Remove all instance methods so even things like class()
7
- # get handled by method_missing(). <lifted from activerecord>
8
- instance_methods.each do |m|
7
+ # get handled by method_missing(). <lifted from activerecord>
8
+ instance_methods.each do |m|
9
9
  unless m.to_s =~ /^(?:nil\?|send|object_id|to_a|tap)$|^__|^respond_to/
10
- undef_method m
10
+ undef_method m
11
11
  end
12
12
  end
13
-
13
+
14
14
  def initialize(element_class, *args)
15
15
  @element_class = element_class
16
16
  @args = args
17
17
  end
18
-
18
+
19
19
  # Provided so that visible? can be asked without
20
20
  # an explicit check for present? first.
21
21
  def visible?
@@ -24,7 +24,7 @@ module AePageObjects
24
24
  !! inst && inst.visible?
25
25
  end
26
26
  end
27
-
27
+
28
28
  def not_visible?
29
29
  Waiter.wait_for do
30
30
  inst = presence
@@ -35,19 +35,19 @@ module AePageObjects
35
35
  def present?
36
36
  ! presence.nil?
37
37
  end
38
-
38
+
39
39
  def not_present?
40
40
  Waiter.wait_for do
41
41
  ! present?
42
42
  end
43
43
  end
44
-
44
+
45
45
  def presence
46
46
  element
47
47
  rescue AePageObjects::LoadingElementFailed
48
48
  nil
49
49
  end
50
-
50
+
51
51
  def is_a?(type)
52
52
  type == @element_class || type == ElementProxy
53
53
  end
@@ -55,19 +55,19 @@ module AePageObjects
55
55
  def kind_of?(type)
56
56
  is_a?(type)
57
57
  end
58
-
58
+
59
59
  def method_missing(name, *args, &block)
60
60
  if name == "class"
61
61
  return @element_class
62
62
  end
63
-
63
+
64
64
  element.__send__(name, *args, &block)
65
65
  end
66
-
66
+
67
67
  def respond_to?(*args)
68
68
  super || @element_class.allocate.respond_to?(*args)
69
69
  end
70
-
70
+
71
71
  private
72
72
 
73
73
  def element
@@ -3,15 +3,15 @@ module AePageObjects
3
3
  def check
4
4
  node.set true
5
5
  end
6
-
6
+
7
7
  def uncheck
8
8
  node.set false
9
9
  end
10
-
10
+
11
11
  def checked?
12
12
  node.native.attribute('checked').to_s.eql?("true")
13
13
  end
14
-
14
+
15
15
  def unchecked?
16
16
  !checked?
17
17
  end
@@ -31,7 +31,7 @@ module AePageObjects
31
31
  def [](index)
32
32
  at(index)
33
33
  end
34
-
34
+
35
35
  def each
36
36
  (0..(size - 1)).each do |index|
37
37
  yield at(index)
@@ -47,10 +47,10 @@ module AePageObjects
47
47
  end
48
48
 
49
49
  private
50
-
50
+
51
51
  def configure(options)
52
52
  super
53
-
53
+
54
54
  @item_locator = options.delete(:item_locator) || default_item_locator
55
55
  end
56
56
 
@@ -1,8 +1,8 @@
1
1
  module AePageObjects
2
2
  class Form < Element
3
-
3
+
4
4
  private
5
-
5
+
6
6
  def default_locator
7
7
  end
8
8
 
@@ -18,4 +18,7 @@ module AePageObjects
18
18
 
19
19
  class DocumentLoadError < Error
20
20
  end
21
+
22
+ class CastError < Error
23
+ end
21
24
  end
@@ -14,9 +14,10 @@ module AePageObjects
14
14
  def find_document(*document_classes, &block)
15
15
  query = DocumentQuery.new(*document_classes, &block)
16
16
  document_loader = DocumentLoader.new(query, CrossWindowLoaderStrategy.new(@windows))
17
+ loaded_page = document_loader.load
17
18
 
18
- DocumentProxy.new(document_loader.load, document_loader)
19
+ DocumentProxy.new(loaded_page, query)
19
20
  end
20
21
  end
21
22
  end
22
- end
23
+ end
@@ -36,13 +36,13 @@ module AePageObjects
36
36
  nil
37
37
  end
38
38
 
39
- def document_not_loaded_error(document_loader)
39
+ def document_not_loaded_error_message(query)
40
40
  all_windows = @window_list.opened.map do |window|
41
41
  name = window.current_document && window.current_document.to_s || "<none>"
42
42
  {:window_handle => window.handle, :document => name }
43
43
  end
44
44
 
45
- DocumentLoadError.new("Couldn't find document with type in #{document_loader.permitted_types_dump} in any of the open windows: #{all_windows.inspect}")
45
+ "Couldn't find document with type in #{query.permitted_types_dump} in any of the open windows: #{all_windows.inspect}"
46
46
  end
47
47
  end
48
48
  end
@@ -11,8 +11,8 @@ module AePageObjects
11
11
  end
12
12
  end
13
13
 
14
- def document_not_loaded_error(document_loader)
15
- DocumentLoadError.new("Current window does not contain document with type in #{document_loader.permitted_types_dump}.")
14
+ def document_not_loaded_error_message(query)
15
+ "Current window does not contain document with type in #{query.permitted_types_dump}."
16
16
  end
17
17
 
18
18
  private
@@ -15,8 +15,9 @@ module AePageObjects
15
15
  def change_to(*document_classes, &block)
16
16
  query = DocumentQuery.new(*document_classes, &block)
17
17
  document_loader = DocumentLoader.new(query, SameWindowLoaderStrategy.new)
18
+ loaded_page = document_loader.load
18
19
 
19
- DocumentProxy.new(document_loader.load, document_loader)
20
+ DocumentProxy.new(loaded_page, query)
20
21
  end
21
22
  end
22
23
  end
@@ -1,3 +1,3 @@
1
1
  module AePageObjects
2
- VERSION = '1.1.1'.freeze
2
+ VERSION = '1.1.2'.freeze
3
3
  end
metadata CHANGED
@@ -1,54 +1,42 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: ae_page_objects
3
- version: !ruby/object:Gem::Version
4
- hash: 17
5
- prerelease:
6
- segments:
7
- - 1
8
- - 1
9
- - 1
10
- version: 1.1.1
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.1.2
11
5
  platform: ruby
12
- authors:
6
+ authors:
13
7
  - Donnie Tognazzini
14
8
  autorequire:
15
9
  bindir: bin
16
10
  cert_chain: []
17
-
18
- date: 2014-09-10 00:00:00 Z
19
- dependencies:
20
- - !ruby/object:Gem::Dependency
21
- version_requirements: &id001 !ruby/object:Gem::Requirement
22
- none: false
23
- requirements:
24
- - - ">="
25
- - !ruby/object:Gem::Version
26
- hash: 13
27
- segments:
28
- - 1
29
- - 1
30
- version: "1.1"
11
+ date: 2014-09-24 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: capybara
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - '>='
18
+ - !ruby/object:Gem::Version
19
+ version: '1.1'
31
20
  - - <
32
- - !ruby/object:Gem::Version
33
- hash: 5
34
- segments:
35
- - 2
36
- - 3
37
- version: "2.3"
38
- prerelease: false
39
- requirement: *id001
21
+ - !ruby/object:Gem::Version
22
+ version: '2.3'
40
23
  type: :runtime
41
- name: capybara
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ requirements:
27
+ - - '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '1.1'
30
+ - - <
31
+ - !ruby/object:Gem::Version
32
+ version: '2.3'
42
33
  description: Capybara Page Objects pattern
43
- email:
34
+ email:
44
35
  - engineering@appfolio.com
45
36
  executables: []
46
-
47
37
  extensions: []
48
-
49
38
  extra_rdoc_files: []
50
-
51
- files:
39
+ files:
52
40
  - lib/ae_page_objects.rb
53
41
  - lib/ae_page_objects/concerns/load_ensuring.rb
54
42
  - lib/ae_page_objects/concerns/staleable.rb
@@ -88,37 +76,27 @@ files:
88
76
  - lib/ae_page_objects/version.rb
89
77
  - lib/ae_page_objects/window.rb
90
78
  homepage: http://github.com/appfolio/ae_page_objects
91
- licenses:
79
+ licenses:
92
80
  - MIT
81
+ metadata: {}
93
82
  post_install_message:
94
83
  rdoc_options: []
95
-
96
- require_paths:
84
+ require_paths:
97
85
  - lib
98
- required_ruby_version: !ruby/object:Gem::Requirement
99
- none: false
100
- requirements:
101
- - - ">="
102
- - !ruby/object:Gem::Version
103
- hash: 3
104
- segments:
105
- - 0
106
- version: "0"
107
- required_rubygems_version: !ruby/object:Gem::Requirement
108
- none: false
109
- requirements:
110
- - - ">="
111
- - !ruby/object:Gem::Version
112
- hash: 3
113
- segments:
114
- - 0
115
- version: "0"
86
+ required_ruby_version: !ruby/object:Gem::Requirement
87
+ requirements:
88
+ - - '>='
89
+ - !ruby/object:Gem::Version
90
+ version: '0'
91
+ required_rubygems_version: !ruby/object:Gem::Requirement
92
+ requirements:
93
+ - - '>='
94
+ - !ruby/object:Gem::Version
95
+ version: '0'
116
96
  requirements: []
117
-
118
97
  rubyforge_project:
119
- rubygems_version: 1.8.25
98
+ rubygems_version: 2.1.11
120
99
  signing_key:
121
- specification_version: 3
100
+ specification_version: 4
122
101
  summary: Capybara Page Objects pattern
123
102
  test_files: []
124
-