selenium-webdriver 2.1.0 → 2.2.0

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGES CHANGED
@@ -1,3 +1,11 @@
1
+ 2.2.0 (2011-07-26)
2
+ ==================
3
+
4
+ * Add ability to listen for WebDriver events
5
+ * Fix Android/iPhone bridges to work similar to others (https://github.com/jnicklas/capybara/issues/425)
6
+ * Various atoms fixes
7
+ * Element equality now works properly with the remote server (#251).
8
+
1
9
  2.1.0 (2011-07-18)
2
10
  ==================
3
11
 
@@ -35,11 +35,12 @@ module Selenium
35
35
 
36
36
  autoload :Android, 'selenium/webdriver/android'
37
37
  autoload :Chrome, 'selenium/webdriver/chrome'
38
+ autoload :Firefox, 'selenium/webdriver/firefox'
38
39
  autoload :IE, 'selenium/webdriver/ie'
39
40
  autoload :IPhone, 'selenium/webdriver/iphone'
40
- autoload :Remote, 'selenium/webdriver/remote'
41
- autoload :Firefox, 'selenium/webdriver/firefox'
42
41
  autoload :Opera, 'selenium/webdriver/opera'
42
+ autoload :Remote, 'selenium/webdriver/remote'
43
+ autoload :Support, 'selenium/webdriver/support'
43
44
 
44
45
  # @api private
45
46
 
@@ -71,6 +72,11 @@ module Selenium
71
72
  # WebDriver.for :firefox, :profile => Profile.new
72
73
  # WebDriver.for :remote, :url => "http://localhost:4444/wd/hub", :desired_capabilities => caps
73
74
  #
75
+ # One special argument is not passed on to the bridges, :listener. You can pass a listener for this option
76
+ # to get notified of WebDriver events. The passed object must respond to #call or implement the methods from AbstractEventListener.
77
+ #
78
+ # @see Selenium::WebDriver::Support::AbstractEventListener
79
+ #
74
80
 
75
81
  def self.for(*args)
76
82
  WebDriver::Driver.for(*args)
@@ -78,5 +84,3 @@ module Selenium
78
84
 
79
85
  end # WebDriver
80
86
  end # Selenium
81
-
82
- Thread.abort_on_exception = true
@@ -3,17 +3,16 @@ module Selenium
3
3
  module Android
4
4
  class Bridge < Remote::Bridge
5
5
 
6
- DEFAULT_URL = "http://#{Platform.localhost}:8080/hub"
7
-
8
- def initialize(opts = nil)
9
- if opts
10
- super
11
- else
12
- super(
13
- :url => DEFAULT_URL,
14
- :desired_capabilities => capabilities
15
- )
16
- end
6
+ DEFAULT_URL = "http://#{Platform.localhost}:8080/hub/"
7
+
8
+ def initialize(opts = {})
9
+ remote_opts = {
10
+ :url => opts.fetch(:url, DEFAULT_URL),
11
+ :desired_capabilities => opts.fetch(:desired_capabilities, capabilities),
12
+ :http_client => opts[:http_client]
13
+ }
14
+
15
+ super remote_opts
17
16
  end
18
17
 
19
18
  def browser
@@ -23,7 +22,8 @@ module Selenium
23
22
  def driver_extensions
24
23
  [
25
24
  DriverExtensions::TakesScreenshot,
26
- DriverExtensions::Rotatable
25
+ DriverExtensions::Rotatable,
26
+ DriverExtensions::HasInputDevices
27
27
  ]
28
28
  end
29
29
 
@@ -21,27 +21,31 @@ module Selenium
21
21
  # @see Selenium::WebDriver.for
22
22
  #
23
23
 
24
- def for(browser, *args)
24
+ def for(browser, opts = {})
25
+ listener = opts.delete(:listener)
26
+
25
27
  bridge = case browser
26
28
  when :firefox, :ff
27
- Firefox::Bridge.new(*args)
29
+ Firefox::Bridge.new(opts)
28
30
  when :remote
29
- Remote::Bridge.new(*args)
31
+ Remote::Bridge.new(opts)
30
32
  when :ie, :internet_explorer
31
- IE::Bridge.new(*args)
33
+ IE::Bridge.new(opts)
32
34
  when :chrome
33
- Chrome::Bridge.new(*args)
35
+ Chrome::Bridge.new(opts)
34
36
  when :android
35
- Android::Bridge.new(*args)
37
+ Android::Bridge.new(opts)
36
38
  when :iphone
37
- IPhone::Bridge.new(*args)
39
+ IPhone::Bridge.new(opts)
38
40
  when :opera
39
- Opera::Bridge.new(*args)
41
+ Opera::Bridge.new(opts)
40
42
  else
41
43
  raise ArgumentError, "unknown driver: #{browser.inspect}"
42
44
  end
43
45
 
44
- new(bridge)
46
+ bridge = Support::EventFiringBridge.new(bridge, listener) if listener
47
+
48
+ new(bridge)
45
49
  end
46
50
  end
47
51
 
@@ -270,7 +274,7 @@ module Selenium
270
274
  def capabilities
271
275
  bridge.capabilities
272
276
  end
273
-
277
+
274
278
  #
275
279
  # @api private
276
280
  # @see SearchContext
@@ -3,8 +3,6 @@ module Selenium
3
3
  class Element
4
4
  include SearchContext
5
5
 
6
- attr_reader :bridge
7
-
8
6
  #
9
7
  # Creates a new Element
10
8
  #
@@ -255,6 +253,10 @@ module Selenium
255
253
 
256
254
  private
257
255
 
256
+ def bridge
257
+ @bridge
258
+ end
259
+
258
260
  def selectable?
259
261
  tn = tag_name.downcase
260
262
  type = attribute(:type).to_s.downcase
@@ -3,16 +3,16 @@ module Selenium
3
3
  module SearchContext
4
4
 
5
5
  FINDERS = {
6
- :class => 'ClassName',
7
- :class_name => 'ClassName',
8
- :css => 'CssSelector',
9
- :id => 'Id',
10
- :link => 'LinkText',
11
- :link_text => 'LinkText',
12
- :name => 'Name',
13
- :partial_link_text => 'PartialLinkText',
14
- :tag_name => 'TagName',
15
- :xpath => 'Xpath',
6
+ :class => 'class name',
7
+ :class_name => 'class name',
8
+ :css => 'css selector',
9
+ :id => 'id',
10
+ :link => 'link text',
11
+ :link_text => 'link text',
12
+ :name => 'name',
13
+ :partial_link_text => 'partial link text',
14
+ :tag_name => 'tag name',
15
+ :xpath => 'xpath',
16
16
  }
17
17
 
18
18
  #
@@ -38,10 +38,7 @@ module Selenium
38
38
  raise ArgumentError, "cannot find element by #{how.inspect}"
39
39
  end
40
40
 
41
- meth = "findElementBy#{by}"
42
- what = what.to_s
43
-
44
- bridge.send meth, ref, what
41
+ bridge.find_element_by by, what.to_s, ref
45
42
  end
46
43
 
47
44
  #
@@ -61,10 +58,7 @@ module Selenium
61
58
  raise ArgumentError, "cannot find elements by #{how.inspect}"
62
59
  end
63
60
 
64
- meth = "findElementsBy#{by}"
65
- what = what.to_s
66
-
67
- bridge.send meth, ref, what
61
+ bridge.find_elements_by by, what.to_s, ref
68
62
  end
69
63
 
70
64
  private
@@ -5,15 +5,14 @@ module Selenium
5
5
 
6
6
  DEFAULT_URL = "http://#{Platform.localhost}:3001/hub/"
7
7
 
8
- def initialize(opts = nil)
9
- if opts
10
- super
11
- else
12
- super(
13
- :url => DEFAULT_URL,
14
- :desired_capabilities => capabilities
15
- )
16
- end
8
+ def initialize(opts = {})
9
+ remote_opts = {
10
+ :url => opts.fetch(:url, DEFAULT_URL),
11
+ :desired_capabilities => opts.fetch(:desired_capabilities, capabilities),
12
+ :http_client => opts[:http_client]
13
+ }
14
+
15
+ super remote_opts
17
16
  end
18
17
 
19
18
  def browser
@@ -21,7 +20,10 @@ module Selenium
21
20
  end
22
21
 
23
22
  def driver_extensions
24
- []
23
+ [
24
+ DriverExtensions::TakesScreenshot,
25
+ DriverExtensions::HasInputDevices
26
+ ]
25
27
  end
26
28
 
27
29
  def capabilities
@@ -228,72 +228,6 @@ module Selenium
228
228
  execute :deleteAllCookies
229
229
  end
230
230
 
231
- # finding elements
232
-
233
- def findElementByClassName(parent, class_name)
234
- find_element_by 'class name', class_name, parent
235
- end
236
-
237
- def findElementsByClassName(parent, class_name)
238
- find_elements_by 'class name', class_name, parent
239
- end
240
-
241
- def findElementByCssSelector(parent, selector)
242
- find_element_by 'css selector', selector, parent
243
- end
244
-
245
- def findElementsByCssSelector(parent, selector)
246
- find_elements_by 'css selector', selector, parent
247
- end
248
-
249
- def findElementById(parent, id)
250
- find_element_by 'id', id, parent
251
- end
252
-
253
- def findElementsById(parent, id)
254
- find_elements_by 'id', id, parent
255
- end
256
-
257
- def findElementByLinkText(parent, link_text)
258
- find_element_by 'link text', link_text, parent
259
- end
260
-
261
- def findElementsByLinkText(parent, link_text)
262
- find_elements_by 'link text', link_text, parent
263
- end
264
-
265
- def findElementByPartialLinkText(parent, link_text)
266
- find_element_by 'partial link text', link_text, parent
267
- end
268
-
269
- def findElementsByPartialLinkText(parent, link_text)
270
- find_elements_by 'partial link text', link_text, parent
271
- end
272
-
273
- def findElementByName(parent, name)
274
- find_element_by 'name', name, parent
275
- end
276
-
277
- def findElementsByName(parent, name)
278
- find_elements_by 'name', name, parent
279
- end
280
-
281
- def findElementByTagName(parent, tag_name)
282
- find_element_by 'tag name', tag_name, parent
283
- end
284
-
285
- def findElementsByTagName(parent, tag_name)
286
- find_elements_by 'tag name', tag_name, parent
287
- end
288
-
289
- def findElementByXpath(parent, xpath)
290
- find_element_by 'xpath', xpath, parent
291
- end
292
-
293
- def findElementsByXpath(parent, xpath)
294
- find_elements_by 'xpath', xpath, parent
295
- end
296
-
297
231
  def clickElement(element)
298
232
  execute :clickElement, :id => element
299
233
  end
@@ -411,8 +345,6 @@ module Selenium
411
345
  execute :elementEquals, :id => element.ref, :other => other.ref
412
346
  end
413
347
 
414
- private
415
-
416
348
  def find_element_by(how, what, parent = nil)
417
349
  if parent
418
350
  id = execute :findChildElement, {:id => parent}, {:using => how, :value => what}
@@ -433,6 +365,8 @@ module Selenium
433
365
  ids.map { |id| Element.new self, element_id_from(id) }
434
366
  end
435
367
 
368
+ private
369
+
436
370
  def assert_javascript_enabled
437
371
  unless capabilities.javascript_enabled?
438
372
  raise Error::UnsupportedOperationError, "underlying webdriver instance does not support javascript"
@@ -0,0 +1,3 @@
1
+ require 'selenium/webdriver/support/event_firing_bridge'
2
+ require 'selenium/webdriver/support/abstract_event_listener'
3
+ require 'selenium/webdriver/support/block_event_listener'
@@ -0,0 +1,28 @@
1
+ module Selenium
2
+ module WebDriver
3
+ module Support
4
+
5
+ class AbstractEventListener
6
+ def before_navigate_to(url) end
7
+ def after_navigate_to(url) end
8
+ def before_navigate_back() end
9
+ def after_navigate_back() end
10
+ def before_navigate_forward() end
11
+ def after_navigate_forward() end
12
+ def before_find(by, what) end
13
+ def after_find(by, what) end
14
+ def before_click(element) end
15
+ def after_click(element) end
16
+ def before_change_value_of(element) end
17
+ def after_change_value_of(element) end
18
+ def before_execute_script(script) end
19
+ def after_execute_script(script) end
20
+ def before_quit() end
21
+ def after_quit() end
22
+ def before_close() end
23
+ def after_close() end
24
+ end
25
+
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,17 @@
1
+ module Selenium
2
+ module WebDriver
3
+ module Support
4
+
5
+ class BlockEventListener
6
+ def initialize(callback)
7
+ @callback = callback
8
+ end
9
+
10
+ def method_missing(meth, *args, &blk)
11
+ @callback.call meth, *args
12
+ end
13
+ end
14
+
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,108 @@
1
+ module Selenium
2
+ module WebDriver
3
+ module Support
4
+
5
+ #
6
+ # @api private
7
+ #
8
+
9
+ class EventFiringBridge
10
+ def initialize(delegate, listener)
11
+ @delegate = delegate
12
+
13
+ if listener.respond_to? :call
14
+ @listener = BlockEventListener.new(listener)
15
+ else
16
+ @listener = listener
17
+ end
18
+ end
19
+
20
+ def get(url)
21
+ dispatch(:navigate_to, url) {
22
+ @delegate.get(url)
23
+ }
24
+ end
25
+
26
+ def goForward
27
+ dispatch(:navigate_forward) {
28
+ @delegate.goForward
29
+ }
30
+ end
31
+
32
+ def goBack
33
+ dispatch(:navigate_back) {
34
+ @delegate.goBack
35
+ }
36
+ end
37
+
38
+ def clickElement(ref)
39
+ dispatch(:click, create_element(ref)) {
40
+ @delegate.clickElement(ref)
41
+ }
42
+ end
43
+
44
+ def clearElement(ref)
45
+ dispatch(:change_value_of, create_element(ref)) {
46
+ @delegate.clearElement(ref)
47
+ }
48
+ end
49
+
50
+ def sendKeysToElement(ref, keys)
51
+ dispatch(:change_value_of, create_element(ref)) {
52
+ @delegate.sendKeysToElement(ref, keys)
53
+ }
54
+ end
55
+
56
+ def find_element_by(how, what, parent = nil)
57
+ e = dispatch(:find, how, what) {
58
+ @delegate.find_element_by how, what, parent
59
+ }
60
+
61
+ Element.new self, e.ref
62
+ end
63
+
64
+ def find_elements_by(how, what, parent = nil)
65
+ es = dispatch(:find, how, what) {
66
+ @delegate.find_elements_by(how, what, parent)
67
+ }
68
+
69
+ es.map { |e| Element.new self, e.ref }
70
+ end
71
+
72
+ def executeScript(script, *args)
73
+ dispatch(:execute_script, script) {
74
+ @delegate.executeScript(script, *args)
75
+ }
76
+ end
77
+
78
+ def quit
79
+ dispatch(:quit) { @delegate.quit }
80
+ end
81
+
82
+ def close
83
+ dispatch(:close) { @delegate.close }
84
+ end
85
+
86
+ private
87
+
88
+ def create_element(ref)
89
+ # hmm. we're not passing self here to not fire events for potential calls made by the listener
90
+ Element.new @delegate, ref
91
+ end
92
+
93
+ def dispatch(name, *args, &blk)
94
+ @listener.__send__("before_#{name}", *args)
95
+ returned = yield
96
+ @listener.__send__("after_#{name}", *args)
97
+
98
+ returned
99
+ end
100
+
101
+ def method_missing(meth, *args, &blk)
102
+ @delegate.__send__(meth, *args, &blk)
103
+ end
104
+ end # EventFiringBridge
105
+
106
+ end # Support
107
+ end # WebDriver
108
+ end # Selenium
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: selenium-webdriver
3
3
  version: !ruby/object:Gem::Version
4
- hash: 11
4
+ hash: 7
5
5
  prerelease:
6
6
  segments:
7
7
  - 2
8
- - 1
8
+ - 2
9
9
  - 0
10
- version: 2.1.0
10
+ version: 2.2.0
11
11
  platform: ruby
12
12
  authors:
13
13
  - Jari Bakken
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2011-07-18 00:00:00 Z
18
+ date: 2011-07-26 00:00:00 Z
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
21
21
  name: json_pure
@@ -210,6 +210,10 @@ files:
210
210
  - lib/selenium/webdriver/remote/response.rb
211
211
  - lib/selenium/webdriver/remote/server_error.rb
212
212
  - lib/selenium/webdriver/remote.rb
213
+ - lib/selenium/webdriver/support/abstract_event_listener.rb
214
+ - lib/selenium/webdriver/support/block_event_listener.rb
215
+ - lib/selenium/webdriver/support/event_firing_bridge.rb
216
+ - lib/selenium/webdriver/support.rb
213
217
  - lib/selenium/webdriver.rb
214
218
  - lib/selenium-client.rb
215
219
  - lib/selenium-webdriver.rb