ae_page_objects 0.4.1 → 0.5.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.
@@ -23,6 +23,7 @@ module AePageObjects
23
23
  autoload :Visitable, 'ae_page_objects/concerns/visitable'
24
24
  end
25
25
 
26
+ autoload :Window, 'ae_page_objects/window'
26
27
  autoload :Node, 'ae_page_objects/node'
27
28
  autoload :Document, 'ae_page_objects/document'
28
29
  autoload :Element, 'ae_page_objects/element'
@@ -1,11 +1,16 @@
1
1
  module AePageObjects
2
2
  class Document < Node
3
3
  include Concerns::Visitable
4
+
5
+ attr_reader :window
4
6
 
5
7
  def initialize
6
8
  super(Capybara.current_session)
7
- end
8
9
 
10
+ @window = Window.current
11
+ @window.current_document = self
12
+ end
13
+
9
14
  def document
10
15
  self
11
16
  end
@@ -96,7 +96,7 @@ module AePageObjects
96
96
  if @locator
97
97
  locator = eval_locator(@locator)
98
98
  if ! locator.empty?
99
- return parent.find(*locator)
99
+ return parent.node.find(*locator)
100
100
  end
101
101
  end
102
102
 
@@ -1,9 +1,15 @@
1
1
  module AePageObjects
2
2
  class Collection < Element
3
+ include Enumerable
4
+
3
5
  class << self
4
6
  attr_accessor :item_class
5
7
 
6
- private
8
+ def default_item_locator
9
+ @default_item_locator ||= [:xpath, ".//*"]
10
+ end
11
+
12
+ private
7
13
  def inherited(subclass)
8
14
  subclass.item_class = self.item_class
9
15
  end
@@ -15,11 +21,15 @@ module AePageObjects
15
21
  self.class.item_class
16
22
  end
17
23
 
24
+ def item_xpath
25
+ @item_xpath ||= Capybara::Selector.normalize(*eval_locator(@item_locator)).xpaths.first
26
+ end
27
+
18
28
  def at(index, &block)
19
29
  if index >= size || index < 0
20
30
  nil
21
31
  else
22
- self.item_class.new(self, :name => index, :locator => [:xpath, "#{row_xpath}[#{index + 1}]"], &block)
32
+ item_at(index, &block)
23
33
  end
24
34
  end
25
35
 
@@ -33,43 +43,32 @@ module AePageObjects
33
43
  end
34
44
  end
35
45
 
36
- def all
37
- [].tap do |all|
38
- self.each { |item| all << item }
39
- end
40
- end
41
-
42
46
  def size
43
- node.all(:xpath, row_xpath).size
44
- end
45
-
46
- def first(&block)
47
- self.at(0, &block)
47
+ node.all(:xpath, item_xpath).size
48
48
  end
49
49
 
50
50
  def last(&block)
51
51
  self.at(size - 1, &block)
52
52
  end
53
-
54
- def add_more(&block)
55
- append
56
- last(&block)
57
- end
58
53
 
59
- def row_xpath
60
- @row_xpath || ".//*[contains(@class, 'item-list')]//*[contains(@class,'row') and not(contains(@style,'display'))]"
61
- end
62
-
63
- protected
54
+ private
64
55
 
65
56
  def configure(options)
66
57
  super
67
58
 
68
- @row_xpath = options.delete(:row_xpath)
59
+ @item_locator = options.delete(:item_locator) || self.class.default_item_locator
69
60
  end
70
-
71
- def append
72
- node.find('.js-add-item').click
61
+
62
+ def item_at(index, &block)
63
+ ElementProxy.new(item_class_at(index), self, :name => index, :locator => item_locator_at(index), &block)
64
+ end
65
+
66
+ def item_class_at(index)
67
+ item_class
68
+ end
69
+
70
+ def item_locator_at(index)
71
+ [:xpath, "#{item_xpath}[#{index + 1}]"]
73
72
  end
74
73
  end
75
74
  end
@@ -1,5 +1,6 @@
1
1
  module AePageObjects
2
2
  module Singleton
3
+
3
4
  def instance
4
5
  @instance ||= new
5
6
  end
@@ -1,3 +1,3 @@
1
1
  module AePageObjects
2
- VERSION = '0.4.1'.freeze
2
+ VERSION = '0.5.1'.freeze
3
3
  end
@@ -0,0 +1,126 @@
1
+ module AePageObjects
2
+ class Window
3
+
4
+ class Registry < Hash
5
+ def [](window_or_handle)
6
+ if window_or_handle.is_a?(Window)
7
+ super(window_or_handle.handle)
8
+ else
9
+ super(window_or_handle)
10
+ end
11
+ end
12
+
13
+ def add(window)
14
+ self[window.handle] = window
15
+ end
16
+
17
+ def remove(window)
18
+ self.delete(window.handle)
19
+ end
20
+ end
21
+
22
+ class HandleManager
23
+ def self.all
24
+ browser.window_handles
25
+ end
26
+
27
+ def self.current
28
+ # Accessing browser.window_handle tries to find an existing page, which will blow up
29
+ # if there isn't one. So... we look at the collection first as a guard.
30
+ if all.empty?
31
+ nil
32
+ else
33
+ browser.window_handle
34
+ end
35
+ end
36
+
37
+ def self.switch_to(handle)
38
+ browser.switch_to.window(handle)
39
+ end
40
+
41
+ def self.browser
42
+ Capybara.current_session.driver.browser
43
+ end
44
+
45
+ def self.close(handle)
46
+ all_handles_before_close = all()
47
+ more_than_one_window = (all_handles_before_close.size > 1)
48
+
49
+ # We must protect against closing the last window as doing so will quit the entire browser
50
+ # which would mess up subsequent tests.
51
+ # http://selenium.googlecode.com/git/docs/api/java/org/openqa/selenium/WebDriver.html#close()
52
+ return false unless more_than_one_window
53
+
54
+ current_handle_before_switch = current
55
+
56
+ # switch to the window to close
57
+ switch_to(handle)
58
+
59
+ browser.close
60
+
61
+ # need to switch back to something. Use whatever was switched from originally unless we just
62
+ # closed that window, in which case just pick something else.
63
+ switch_to(current_handle_before_switch == handle ? all.first : current_handle_before_switch)
64
+
65
+ true
66
+ end
67
+ end
68
+
69
+ class << self
70
+ def registry
71
+ @registry ||= Registry.new
72
+ end
73
+
74
+ def close_all
75
+ all.each(&:close)
76
+ end
77
+
78
+ def all
79
+ HandleManager.all.map do |handle|
80
+ find(handle)
81
+ end
82
+ end
83
+
84
+ def find(handle)
85
+ registry[handle] || create(handle)
86
+ end
87
+
88
+ def current
89
+ current_handle = HandleManager.current
90
+
91
+ find(current_handle) if current_handle
92
+ end
93
+
94
+ def create(handle)
95
+ new(registry, handle)
96
+ end
97
+ end
98
+
99
+ attr_reader :current_document, :handle
100
+
101
+ def initialize(registry, handle)
102
+ @registry = registry
103
+ @handle = handle
104
+ @current_document = nil
105
+
106
+ @registry.add(self)
107
+ end
108
+
109
+ def current_document=(document)
110
+ @current_document.send(:stale!) if @current_document
111
+ @current_document = document
112
+ end
113
+
114
+ def switch_to
115
+ HandleManager.switch_to(handle)
116
+ current_document
117
+ end
118
+
119
+ def close
120
+ if HandleManager.close(@handle)
121
+ self.current_document = nil
122
+ @registry.remove(self)
123
+ end
124
+ end
125
+ end
126
+ end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ae_page_objects
3
3
  version: !ruby/object:Gem::Version
4
- hash: 13
4
+ hash: 9
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
- - 4
8
+ - 5
9
9
  - 1
10
- version: 0.4.1
10
+ version: 0.5.1
11
11
  platform: ruby
12
12
  authors:
13
13
  - Donnie Tognazzini
@@ -15,10 +15,9 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2013-07-19 00:00:00 Z
18
+ date: 2013-10-26 00:00:00 Z
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
21
- type: :runtime
22
21
  name: capybara
23
22
  version_requirements: &id001 !ruby/object:Gem::Requirement
24
23
  none: false
@@ -30,54 +29,9 @@ dependencies:
30
29
  - 1
31
30
  - 1
32
31
  version: "1.1"
33
- requirement: *id001
34
- prerelease: false
35
- - !ruby/object:Gem::Dependency
36
- type: :development
37
- name: appraisal
38
- version_requirements: &id002 !ruby/object:Gem::Requirement
39
- none: false
40
- requirements:
41
- - - ~>
42
- - !ruby/object:Gem::Version
43
- hash: 9
44
- segments:
45
- - 0
46
- - 5
47
- - 1
48
- version: 0.5.1
49
- requirement: *id002
50
- prerelease: false
51
- - !ruby/object:Gem::Dependency
52
- type: :development
53
- name: mocha
54
- version_requirements: &id003 !ruby/object:Gem::Requirement
55
- none: false
56
- requirements:
57
- - - "="
58
- - !ruby/object:Gem::Version
59
- hash: 45
60
- segments:
61
- - 0
62
- - 13
63
- - 3
64
- version: 0.13.3
65
- requirement: *id003
66
- prerelease: false
67
- - !ruby/object:Gem::Dependency
68
- type: :development
69
- name: selenium-webdriver
70
- version_requirements: &id004 !ruby/object:Gem::Requirement
71
- none: false
72
- requirements:
73
- - - ">="
74
- - !ruby/object:Gem::Version
75
- hash: 3
76
- segments:
77
- - 0
78
- version: "0"
79
- requirement: *id004
80
32
  prerelease: false
33
+ type: :runtime
34
+ requirement: *id001
81
35
  description: Capybara Page Objects pattern
82
36
  email:
83
37
  - engineering@appfolio.com
@@ -113,6 +67,7 @@ files:
113
67
  - lib/ae_page_objects/util/internal_helpers.rb
114
68
  - lib/ae_page_objects/util/singleton.rb
115
69
  - lib/ae_page_objects/version.rb
70
+ - lib/ae_page_objects/window.rb
116
71
  homepage: http://github.com/appfolio/ae_page_objects
117
72
  licenses:
118
73
  - MIT