angular_webdriver 1.0.3 → 1.0.4
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 +4 -4
- data/lib/angular_webdriver.rb +5 -2
- data/lib/angular_webdriver/protractor/protractor.rb +32 -4
- data/lib/angular_webdriver/protractor/watir_patch.rb +185 -169
- data/lib/angular_webdriver/version.rb +1 -1
- data/release_notes.md +8 -0
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: bddebdc5e0805f1a225634f2472d982f3e29d7f5
|
4
|
+
data.tar.gz: 4725e12aef7fc193b367dc393d397b46149befb2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 881b3dac4df7917e4dd36dccc99349148ec86d90abf80d204fc76bfe5af181c42f02e32cfb6a80c71852b9e685ac0b56f3104eea682456ce1df8fbc2fb8fe940
|
7
|
+
data.tar.gz: 0d4ccf98664fe02f9708bae8b3f2556968c5b0b594a4141594cf4b7d8cba5c0ea064a51a31895a55bc285027e043af1411bdd1e79c3213154e7c2b233321a323
|
data/lib/angular_webdriver.rb
CHANGED
@@ -2,7 +2,12 @@ require_relative 'angular_webdriver/version'
|
|
2
2
|
|
3
3
|
require 'rubygems'
|
4
4
|
require 'selenium-webdriver'
|
5
|
+
require_relative 'angular_webdriver/protractor/webdriver_patch'
|
6
|
+
|
7
|
+
require_relative 'angular_webdriver/protractor/watir_patch'
|
8
|
+
AngularWebdriver.patch_watir # (1/2) before
|
5
9
|
require 'watir-webdriver'
|
10
|
+
AngularWebdriver.patch_watir # (2/2) after
|
6
11
|
|
7
12
|
require_relative 'angular_webdriver/protractor/by'
|
8
13
|
require_relative 'angular_webdriver/protractor/by_repeater_inner'
|
@@ -10,5 +15,3 @@ require_relative 'angular_webdriver/protractor/client_side_scripts'
|
|
10
15
|
require_relative 'angular_webdriver/protractor/protractor'
|
11
16
|
require_relative 'angular_webdriver/protractor/protractor_element'
|
12
17
|
require_relative 'angular_webdriver/protractor/rspec_helpers'
|
13
|
-
require_relative 'angular_webdriver/protractor/webdriver_patch'
|
14
|
-
require_relative 'angular_webdriver/protractor/watir_patch'
|
@@ -122,7 +122,7 @@ class Protractor
|
|
122
122
|
|
123
123
|
# data urls must be preserved and not have http:// prepended.
|
124
124
|
# data:<blah>
|
125
|
-
data_url
|
125
|
+
data_url = destination.start_with?('data:')
|
126
126
|
|
127
127
|
unless about_url || data_url
|
128
128
|
# URI.join doesn't allow for http://localhost:8081/#/ as a base_url
|
@@ -283,20 +283,48 @@ class Protractor
|
|
283
283
|
|
284
284
|
# must be local var for use with define element below.
|
285
285
|
protractor_element = AngularWebdriver::ProtractorElement.new @watir
|
286
|
+
driver = @driver
|
286
287
|
|
287
288
|
# Top level element method to enable protractor syntax.
|
288
289
|
# redefine element to point to the new protractor element instance.
|
289
290
|
#
|
290
291
|
# toplevel self enables by/element from within pry. rspec helpers enables
|
291
292
|
# by/element within rspec tests when used with install_rspec_helpers.
|
292
|
-
|
293
|
-
|
293
|
+
toplevel_main = eval('self', TOPLEVEL_BINDING)
|
294
|
+
[toplevel_main, AngularWebdriver::RSpecHelpers].each do |obj|
|
295
|
+
# define singleton on toplevel main, otherwise use regular define method
|
296
|
+
# if we use define singleton on the rspec helpers, then rspec won't
|
297
|
+
# be able to handle block parameters.
|
298
|
+
#
|
299
|
+
# Also rspec requires config.include AngularWebdriver::RSpecHelpers
|
300
|
+
# for the no_wait helper to accept the block parameter.
|
301
|
+
method_type = obj == toplevel_main ? :define_singleton_method : :define_method
|
302
|
+
|
303
|
+
obj.send method_type, :element do |*args|
|
294
304
|
protractor_element.element *args
|
295
305
|
end
|
296
306
|
|
297
|
-
obj.send
|
307
|
+
obj.send method_type, :by do
|
298
308
|
AngularWebdriver::By
|
299
309
|
end
|
310
|
+
|
311
|
+
obj.send method_type, :no_wait do |&block|
|
312
|
+
max_wait = driver.max_wait_seconds
|
313
|
+
max_page_wait = driver.max_page_wait_seconds
|
314
|
+
|
315
|
+
driver.set_max_wait 0
|
316
|
+
driver.set_max_page_wait 0
|
317
|
+
|
318
|
+
begin
|
319
|
+
raise ArgumentError, 'Tried to use no_wait without a block' unless block
|
320
|
+
result = block.call
|
321
|
+
ensure
|
322
|
+
driver.set_max_wait max_wait
|
323
|
+
driver.set_max_page_wait max_page_wait
|
324
|
+
end
|
325
|
+
|
326
|
+
result
|
327
|
+
end
|
300
328
|
end
|
301
329
|
|
302
330
|
self
|
@@ -1,209 +1,225 @@
|
|
1
|
-
require 'watir-webdriver/elements/element'
|
2
|
-
|
3
1
|
# match protractor semantics
|
4
2
|
# unfortunately setting always locate doesn't always locate.
|
5
|
-
Watir.always_locate = true
|
6
|
-
|
7
|
-
#
|
8
|
-
# This patch serves a few purposes. The first is matching Protractor semantics
|
9
|
-
# of lazy finding elements and always relocating elements (ex: element.text)
|
10
|
-
#
|
11
|
-
# The second is removing unnecessary bloatware from Watir which has a number
|
12
|
-
# of checks that don't make sense for angular.js testing. The specifics
|
13
|
-
# of this patch will change in the next Watir release. Currently version
|
14
|
-
# 0.7.0 is targeted.
|
15
|
-
#
|
16
|
-
# The third is teaching Watir about angular specific locators
|
17
|
-
#
|
18
|
-
# Design goal: element.all(by.binding('slowHttpStatus'))
|
19
|
-
# should not make any server requests
|
20
|
-
#
|
21
|
-
|
22
3
|
module Watir
|
4
|
+
@always_locate = true
|
5
|
+
end
|
23
6
|
|
24
|
-
|
25
|
-
# Return original selector.
|
26
|
-
# Method added for protractor compatibility
|
27
|
-
def locator
|
28
|
-
@selector
|
29
|
-
end
|
30
|
-
end
|
7
|
+
module AngularWebdriver
|
31
8
|
|
32
|
-
|
9
|
+
# Patch watir must be invoked before watir-webdriver is required to
|
10
|
+
# ensure the methods are defined before inheritance occurs.
|
11
|
+
# Then patch_watir must be invoked after requiring watir-webdriver to
|
12
|
+
# restore the methods that were overridden.
|
13
|
+
#
|
14
|
+
def self.patch_watir
|
33
15
|
#
|
34
|
-
#
|
16
|
+
# This patch serves a few purposes. The first is matching Protractor semantics
|
17
|
+
# of lazy finding elements and always relocating elements (ex: element.text)
|
18
|
+
#
|
19
|
+
# The second is removing unnecessary bloatware from Watir which has a number
|
20
|
+
# of checks that don't make sense for angular.js testing. The specifics
|
21
|
+
# of this patch will change in the next Watir release. Currently version
|
22
|
+
# 0.7.0 is targeted.
|
23
|
+
#
|
24
|
+
# The third is teaching Watir about angular specific locators
|
25
|
+
#
|
26
|
+
# Design goal: element.all(by.binding('slowHttpStatus'))
|
27
|
+
# should not make any server requests
|
35
28
|
#
|
36
29
|
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
define_method(:extract_selector) do |selectors|
|
44
|
-
selectors = AngularWebdriver::ByRepeaterInner.wrap_repeater selectors
|
45
|
-
|
46
|
-
upstream_extract_selector.bind(self).call selectors
|
30
|
+
::Watir::HTMLElementCollection.class_eval do
|
31
|
+
# Return original selector.
|
32
|
+
# Method added for protractor compatibility
|
33
|
+
def locator
|
34
|
+
@selector
|
35
|
+
end
|
47
36
|
end
|
48
37
|
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
#
|
38
|
+
::Watir::Container.module_eval do
|
39
|
+
#
|
40
|
+
# Alias of elements for Protractor
|
41
|
+
#
|
54
42
|
|
55
|
-
|
43
|
+
def all(*args)
|
44
|
+
elements(*args)
|
45
|
+
end
|
56
46
|
|
57
|
-
|
47
|
+
# Redefine extract_selector to wrap find by repeater
|
48
|
+
upstream_extract_selector = instance_method(:extract_selector)
|
49
|
+
define_method(:extract_selector) do |selectors|
|
50
|
+
selectors = AngularWebdriver::ByRepeaterInner.wrap_repeater selectors
|
58
51
|
|
59
|
-
|
60
|
-
|
61
|
-
yield
|
62
|
-
rescue Selenium::WebDriver::Error::StaleElementReferenceError
|
63
|
-
raise
|
64
|
-
end
|
52
|
+
upstream_extract_selector.bind(self).call selectors
|
53
|
+
end
|
65
54
|
|
66
|
-
|
67
|
-
assert_exists
|
68
|
-
element_call { @element.selected? }
|
69
|
-
end
|
55
|
+
end # ::Watir::Container.module_eval
|
70
56
|
|
71
|
-
# required for watir otherwise execute_script will fail
|
72
|
-
#
|
73
|
-
# e = browser.element(tag_name: 'div')
|
74
|
-
# driver.execute_script 'return arguments[0].tagName', e
|
75
|
-
# {"script":"return arguments[0].tagName","args":[{"ELEMENT":"0"}]}
|
76
57
|
#
|
77
|
-
#
|
78
|
-
# @see https://github.com/SeleniumHQ/selenium/wiki/JsonWireProtocol#basic-terms-and-concepts
|
58
|
+
# Base class for HTML elements.
|
79
59
|
#
|
80
|
-
# @api private
|
81
|
-
#
|
82
|
-
def to_json(*args)
|
83
|
-
assert_exists
|
84
|
-
{ ELEMENT: @element.ref }.to_json
|
85
|
-
end
|
86
60
|
|
87
|
-
#
|
88
|
-
# Required to trigger waitForAngular. Caching the element here will
|
89
|
-
# break the Protractor sync feature so this must be @element = locate.
|
90
|
-
def assert_exists
|
91
|
-
@element = locate
|
92
|
-
end
|
61
|
+
# Note the element class is different on master.
|
93
62
|
|
94
|
-
|
95
|
-
|
96
|
-
|
63
|
+
::Watir::Element.class_eval do
|
64
|
+
# Always raise on stale element ref error. Prevents infinite retry loop.
|
65
|
+
def element_call
|
66
|
+
yield
|
67
|
+
rescue Selenium::WebDriver::Error::StaleElementReferenceError
|
68
|
+
raise
|
69
|
+
end
|
97
70
|
|
98
|
-
|
99
|
-
|
100
|
-
|
71
|
+
# Rescue all exceptions. Guarantee that we'll return true or false.
|
72
|
+
#
|
73
|
+
# Returns true if element exists and false otherwise.
|
74
|
+
def exists?
|
75
|
+
assert_exists
|
76
|
+
true
|
77
|
+
rescue Exception
|
78
|
+
false
|
79
|
+
end
|
101
80
|
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
end
|
81
|
+
def selected?
|
82
|
+
assert_exists
|
83
|
+
element_call { @element.selected? }
|
84
|
+
end
|
107
85
|
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
86
|
+
# required for watir otherwise execute_script will fail
|
87
|
+
#
|
88
|
+
# e = browser.element(tag_name: 'div')
|
89
|
+
# driver.execute_script 'return arguments[0].tagName', e
|
90
|
+
# {"script":"return arguments[0].tagName","args":[{"ELEMENT":"0"}]}
|
91
|
+
#
|
92
|
+
# Convert to a WebElement JSON Object for transmission over the wire.
|
93
|
+
# @see https://github.com/SeleniumHQ/selenium/wiki/JsonWireProtocol#basic-terms-and-concepts
|
94
|
+
#
|
95
|
+
# @api private
|
96
|
+
#
|
97
|
+
def to_json(*args)
|
98
|
+
assert_exists
|
99
|
+
{ ELEMENT: @element.ref }.to_json
|
100
|
+
end
|
112
101
|
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
assert_exists
|
117
|
-
|
118
|
-
|
102
|
+
# Ensure that the element exists by always relocating it
|
103
|
+
# Required to trigger waitForAngular. Caching the element here will
|
104
|
+
# break the Protractor sync feature so this must be @element = locate.
|
105
|
+
def assert_exists
|
106
|
+
@element = locate
|
107
|
+
end
|
119
108
|
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
element_call { @element.clear }
|
124
|
-
end
|
109
|
+
def assert_not_stale
|
110
|
+
nil
|
111
|
+
end
|
125
112
|
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
# @param expression <String> The expression to evaluate.
|
130
|
-
#
|
131
|
-
# @return <Object> The result of the evaluation.
|
132
|
-
def evaluate expression
|
133
|
-
assert_exists
|
134
|
-
driver.protractor.evaluate @element, expression
|
135
|
-
end
|
113
|
+
def assert_enabled
|
114
|
+
nil
|
115
|
+
end
|
136
116
|
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
#
|
143
|
-
#
|
144
|
-
# rescue element not found
|
145
|
-
def present?
|
146
|
-
exists? && visible?
|
147
|
-
rescue Selenium::WebDriver::Error::NoSuchElementError, Selenium::WebDriver::Error::StaleElementReferenceError, UnknownObjectException
|
148
|
-
# if the element disappears between the exists? and visible? calls,
|
149
|
-
# consider it not present.
|
150
|
-
false
|
151
|
-
end
|
152
|
-
end
|
117
|
+
# Return original selector.
|
118
|
+
# Method added for protractor compatibility
|
119
|
+
def locator
|
120
|
+
@selector
|
121
|
+
end
|
153
122
|
|
123
|
+
# avoid context lookup
|
124
|
+
def locate
|
125
|
+
locator_class.new(@parent.wd, @selector, self.class.attribute_list).locate
|
126
|
+
end
|
154
127
|
|
155
|
-
|
156
|
-
|
157
|
-
|
128
|
+
# Invoke protractor.allowAnimations with freshly located element and
|
129
|
+
# optional value.
|
130
|
+
def allowAnimations value=nil
|
131
|
+
assert_exists
|
132
|
+
driver.protractor.allowAnimations @element, value
|
133
|
+
end
|
158
134
|
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
135
|
+
# Watir doesn't define a clear method on element so we have to provide one.
|
136
|
+
def clear
|
137
|
+
assert_exists
|
138
|
+
element_call { @element.clear }
|
139
|
+
end
|
164
140
|
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
141
|
+
# Evaluate an Angular expression as if it were on the scope
|
142
|
+
# of the current element.
|
143
|
+
#
|
144
|
+
# @param expression <String> The expression to evaluate.
|
145
|
+
#
|
146
|
+
# @return <Object> The result of the evaluation.
|
147
|
+
def evaluate expression
|
148
|
+
assert_exists
|
149
|
+
driver.protractor.evaluate @element, expression
|
150
|
+
end
|
169
151
|
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
152
|
+
#
|
153
|
+
# Returns true if the element exists and is visible on the page.
|
154
|
+
# Returns false if the element doesn't exist or isn't visible.
|
155
|
+
#
|
156
|
+
# @return [Boolean]
|
157
|
+
# @see Watir::Wait
|
158
|
+
#
|
159
|
+
#
|
160
|
+
# rescue element not found
|
161
|
+
def present?
|
162
|
+
exists? && visible?
|
163
|
+
rescue Exception
|
164
|
+
# if the element disappears between the exists? and visible? calls,
|
165
|
+
# consider it not present.
|
166
|
+
false
|
167
|
+
end
|
168
|
+
end # ::Watir::Element.class_eval
|
175
169
|
|
176
|
-
|
170
|
+
#
|
171
|
+
# The main class through which you control the browser.
|
172
|
+
#
|
177
173
|
|
178
|
-
|
179
|
-
|
174
|
+
::Watir::Browser.class_eval do
|
175
|
+
def assert_exists
|
176
|
+
# remove expensive window check
|
177
|
+
raise Exception::Error, 'browser was closed' if @closed
|
180
178
|
end
|
181
179
|
|
182
|
-
|
183
|
-
|
180
|
+
def inspect
|
181
|
+
nil # avoid expensive browser url and title lookup
|
182
|
+
end
|
183
|
+
end # ::Watir::Browser.class_eval
|
184
184
|
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
#
|
191
|
-
# see 'should find multiple buttons containing "text"' in locators_spec.rb
|
192
|
-
return @selector[:element] if @selector.is_a?(Hash) && @selector[:element].is_a?(Selenium::WebDriver::Element)
|
185
|
+
::Watir::ElementLocator.class_eval do
|
186
|
+
def validate_element(element)
|
187
|
+
tn = @selector[:tag_name]
|
188
|
+
return element unless tn # don't validate nil tag names
|
189
|
+
element_tag_name = element.tag_name.downcase
|
193
190
|
|
194
|
-
|
191
|
+
return if tn && !tag_name_matches?(element_tag_name, tn)
|
195
192
|
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
193
|
+
if element_tag_name == 'input'
|
194
|
+
return if @selector[:type] && @selector[:type] != element.attribute(:type)
|
195
|
+
end
|
196
|
+
|
197
|
+
element
|
200
198
|
end
|
201
199
|
|
202
|
-
#
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
200
|
+
# always raise element not found / stale reference error
|
201
|
+
def locate
|
202
|
+
# element.all(by.partialButtonText('text')).to_a[0].value creates the
|
203
|
+
# selector {:element=>#<Selenium::WebDriver::Element ...>}
|
204
|
+
# in that case we've already located the element.
|
205
|
+
#
|
206
|
+
# see 'should find multiple buttons containing "text"' in locators_spec.rb
|
207
|
+
return @selector[:element] if @selector.is_a?(Hash) && @selector[:element].is_a?(Selenium::WebDriver::Element)
|
208
|
+
|
209
|
+
e = by_id and return e # short-circuit if :id is given
|
210
|
+
|
211
|
+
if @selector.size == 1
|
212
|
+
element = find_first_by_one
|
213
|
+
else
|
214
|
+
element = find_first_by_multiple
|
215
|
+
end
|
216
|
+
|
217
|
+
# This actually only applies when finding by xpath/css - browser.text_field(:xpath, "//input[@type='radio']")
|
218
|
+
# We don't need to validate the element if we built the xpath ourselves.
|
219
|
+
# It is also used to alter behavior of methods locating more than one type of element
|
220
|
+
# (e.g. text_field locates both input and textarea)
|
221
|
+
validate_element(element) if element
|
222
|
+
end
|
223
|
+
end # ::Watir::ElementLocator.class_eval
|
224
|
+
end # def patch_watir
|
225
|
+
end # module AngularWebdriver
|
data/release_notes.md
CHANGED
@@ -1,3 +1,11 @@
|
|
1
|
+
#### v1.0.4 2015-06-07
|
2
|
+
|
3
|
+
- [a7965d7](https://github.com/bootstraponline/angular_webdriver/commit/a7965d7d1103bb802eabbdf11a37c9be8f9f3547) Release 1.0.4
|
4
|
+
- [bf94300](https://github.com/bootstraponline/angular_webdriver/commit/bf9430076da4a89a85050b92289b1fda34afe3f8) Fix and test rspec helpers
|
5
|
+
- [1d11610](https://github.com/bootstraponline/angular_webdriver/commit/1d11610441ed56addabc5be60fe35125151a7a75) Move no_wait into top level singleton
|
6
|
+
- [10f7ff9](https://github.com/bootstraponline/angular_webdriver/commit/10f7ff9ecbbdf0751752c751cebef4119eb86f94) Fix watir patch. Fix exists?
|
7
|
+
|
8
|
+
|
1
9
|
#### v1.0.3 2015-06-07
|
2
10
|
|
3
11
|
- [97d5f18](https://github.com/bootstraponline/angular_webdriver/commit/97d5f18e187d56bc8616fb65ec1e5b9bafa8c289) Release 1.0.3
|