selenium-webdriver 2.1.0 → 2.2.0

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.
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