ae_page_objects 0.4.1 → 0.5.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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