selenium-webdriver 0.0.17 → 0.0.18

Sign up to get free protection for your applications and to get access to all the features.
Files changed (77) hide show
  1. data/chrome/prebuilt/Win32/Release/npchromedriver.dll +0 -0
  2. data/chrome/prebuilt/x64/Release/npchromedriver.dll +0 -0
  3. data/chrome/src/extension/background.js +64 -48
  4. data/chrome/src/extension/content_script.js +253 -132
  5. data/chrome/src/extension/manifest-nonwin.json +1 -1
  6. data/chrome/src/extension/manifest-win.json +1 -1
  7. data/chrome/src/extension/utils.js +8 -8
  8. data/chrome/src/rb/lib/selenium/webdriver/chrome.rb +9 -0
  9. data/chrome/src/rb/lib/selenium/webdriver/chrome/bridge.rb +38 -280
  10. data/chrome/src/rb/lib/selenium/webdriver/chrome/command_executor.rb +119 -117
  11. data/chrome/src/rb/lib/selenium/webdriver/chrome/launcher.rb +36 -26
  12. data/common/src/js/abstractcommandprocessor.js +9 -11
  13. data/common/src/js/command.js +159 -83
  14. data/common/src/js/core/RemoteRunner.html +2 -2
  15. data/common/src/js/core/TestRunner-splash.html +3 -3
  16. data/common/src/js/core/TestRunner.html +5 -17
  17. data/common/src/js/core/scripts/htmlutils.js +4208 -2506
  18. data/common/src/js/core/scripts/selenium-api.js +2 -2
  19. data/common/src/js/core/scripts/selenium-browserbot.js +66 -58
  20. data/common/src/js/core/scripts/selenium-version.js +1 -1
  21. data/common/src/js/localcommandprocessor.js +5 -19
  22. data/common/src/js/testcase.js +2 -0
  23. data/common/src/js/webdriver.js +63 -93
  24. data/common/src/js/webelement.js +40 -42
  25. data/common/src/rb/lib/selenium/webdriver.rb +23 -14
  26. data/common/src/rb/lib/selenium/webdriver/bridge_helper.rb +8 -35
  27. data/common/src/rb/lib/selenium/webdriver/child_process.rb +2 -0
  28. data/common/src/rb/lib/selenium/webdriver/core_ext/dir.rb +1 -0
  29. data/common/src/rb/lib/selenium/webdriver/core_ext/string.rb +5 -0
  30. data/common/src/rb/lib/selenium/webdriver/driver.rb +20 -15
  31. data/common/src/rb/lib/selenium/webdriver/driver_extensions/takes_screenshot.rb +7 -2
  32. data/common/src/rb/lib/selenium/webdriver/element.rb +11 -2
  33. data/common/src/rb/lib/selenium/webdriver/error.rb +9 -5
  34. data/common/src/rb/lib/selenium/webdriver/keys.rb +1 -2
  35. data/common/src/rb/lib/selenium/webdriver/navigation.rb +16 -0
  36. data/common/src/rb/lib/selenium/webdriver/options.rb +32 -0
  37. data/common/src/rb/lib/selenium/webdriver/platform.rb +17 -1
  38. data/firefox/prebuilt/Win32/Release/webdriver-firefox.dll +0 -0
  39. data/firefox/src/extension/components/dispatcher.js +492 -0
  40. data/firefox/src/extension/components/driver-component.js +4 -1
  41. data/firefox/src/extension/components/errorcode.js +70 -0
  42. data/firefox/src/extension/components/firefoxDriver.js +173 -154
  43. data/firefox/src/extension/components/nsCommandProcessor.js +171 -132
  44. data/firefox/src/extension/components/promptService.js +5 -5
  45. data/firefox/src/extension/components/request.js +219 -0
  46. data/firefox/src/extension/components/response.js +276 -0
  47. data/firefox/src/extension/components/session.js +281 -0
  48. data/firefox/src/extension/components/sessionstore.js +226 -0
  49. data/firefox/src/extension/components/socketListener.js +350 -100
  50. data/firefox/src/extension/components/utils.js +166 -98
  51. data/firefox/src/extension/components/webdriverserver.js +9 -5
  52. data/firefox/src/extension/components/wrappedElement.js +189 -166
  53. data/firefox/src/extension/install.rdf +1 -1
  54. data/firefox/src/rb/lib/selenium/webdriver/firefox.rb +2 -0
  55. data/firefox/src/rb/lib/selenium/webdriver/firefox/binary.rb +39 -33
  56. data/firefox/src/rb/lib/selenium/webdriver/firefox/bridge.rb +7 -421
  57. data/firefox/src/rb/lib/selenium/webdriver/firefox/extension_connection.rb +7 -64
  58. data/firefox/src/rb/lib/selenium/webdriver/firefox/launcher.rb +2 -3
  59. data/firefox/src/rb/lib/selenium/webdriver/firefox/profile.rb +54 -10
  60. data/firefox/src/rb/lib/selenium/webdriver/firefox/profiles_ini.rb +2 -0
  61. data/firefox/src/rb/lib/selenium/webdriver/firefox/util.rb +6 -0
  62. data/jobbie/prebuilt/Win32/Release/InternetExplorerDriver.dll +0 -0
  63. data/jobbie/prebuilt/x64/Release/InternetExplorerDriver.dll +0 -0
  64. data/jobbie/src/rb/lib/selenium/webdriver/ie.rb +2 -0
  65. data/jobbie/src/rb/lib/selenium/webdriver/ie/bridge.rb +38 -13
  66. data/jobbie/src/rb/lib/selenium/webdriver/ie/lib.rb +9 -2
  67. data/jobbie/src/rb/lib/selenium/webdriver/ie/util.rb +5 -0
  68. data/remote/client/src/rb/lib/selenium/webdriver/remote.rb +2 -0
  69. data/remote/client/src/rb/lib/selenium/webdriver/remote/bridge.rb +42 -38
  70. data/remote/client/src/rb/lib/selenium/webdriver/remote/commands.rb +56 -47
  71. data/remote/client/src/rb/lib/selenium/webdriver/remote/default_http_client.rb +26 -26
  72. data/remote/client/src/rb/lib/selenium/webdriver/remote/patron_http_client.rb +58 -0
  73. data/remote/client/src/rb/lib/selenium/webdriver/remote/response.rb +10 -12
  74. data/remote/client/src/rb/lib/selenium/webdriver/remote/server_error.rb +2 -17
  75. metadata +44 -23
  76. data/common/src/js/context.js +0 -58
  77. data/firefox/src/extension/components/context.js +0 -37
@@ -1,6 +1,8 @@
1
1
  module Selenium
2
2
  module WebDriver
3
3
  module Firefox
4
+
5
+ # @private
4
6
  class ExtensionConnection
5
7
 
6
8
  def initialize(host, port)
@@ -8,11 +10,15 @@ module Selenium
8
10
  @port = port
9
11
  end
10
12
 
13
+ def url
14
+ "http://#{@host}:#{@port}/hub"
15
+ end
16
+
11
17
  def connect(timeout = 20)
12
18
  Timeout.timeout(timeout) {
13
19
  loop do
14
20
  begin
15
- return new_socket
21
+ return TCPSocket.new(@host, @port).close
16
22
  rescue Errno::ECONNREFUSED, Errno::ENOTCONN, SocketError => e
17
23
  $stderr.puts "#{self} caught #{e.message} for #{@host}:#{@port}" if $DEBUG
18
24
  sleep 0.25
@@ -21,69 +27,6 @@ module Selenium
21
27
  }
22
28
  end
23
29
 
24
- def new_socket
25
- @socket = TCPSocket.new(@host, @port)
26
- @socket.sync = true
27
-
28
- @socket
29
- end
30
-
31
- def connected?
32
- @socket && !@socket.closed?
33
- end
34
-
35
- def send_string(str)
36
- str = <<-HTTP
37
- GET / HTTP/1.1
38
- Host: localhost
39
- Content-Length: #{str.length}
40
-
41
- #{str}
42
- HTTP
43
- @socket.write str
44
- @socket.flush
45
- end
46
-
47
- def quit
48
- command = {'commandName' => 'quit', 'context' => ''}
49
- send_string(command.to_json)
50
- ensure
51
- close
52
- end
53
-
54
- def close
55
- @socket.close if connected?
56
- end
57
-
58
- def read_response
59
- resp = ""
60
- received = ""
61
-
62
- until resp.include?("\n\n")
63
- received = @socket.recv 1
64
- if received
65
- resp += received
66
- end
67
- end
68
-
69
- length = Integer(resp.split(":").last.strip)
70
- json_string = ''
71
- bytes_received = 0
72
-
73
- until bytes_received == length
74
- read_string = @socket.recv(length - bytes_received)
75
-
76
- bytes_received += read_string.length
77
- json_string << read_string
78
- end
79
-
80
- if json_string.empty?
81
- raise Error::WebDriverError, "empty response from extension"
82
- end
83
-
84
- JSON.parse json_string
85
- end
86
-
87
30
  end # ExtensionConnection
88
31
  end # Firefox
89
32
  end # WebDriver
@@ -3,12 +3,13 @@ require "fcntl"
3
3
  module Selenium
4
4
  module WebDriver
5
5
  module Firefox
6
+
7
+ # @private
6
8
  class Launcher
7
9
 
8
10
  attr_reader :binary, :connection
9
11
  SOCKET_LOCK_TIMEOUT = 45
10
12
 
11
-
12
13
  def initialize(binary, port = DEFAULT_PORT, profile = DEFAULT_PROFILE_NAME)
13
14
  @binary = binary
14
15
  @port = port.to_i
@@ -82,7 +83,6 @@ module Selenium
82
83
  end
83
84
 
84
85
  @profile.delete_extensions_cache
85
-
86
86
  @profile.port = @port
87
87
  @profile.add_webdriver_extension(true)
88
88
  @profile.update_user_prefs
@@ -111,7 +111,6 @@ module Selenium
111
111
  begin
112
112
  connection = ExtensionConnection.new(@host, @port)
113
113
  connection.connect(1)
114
- connection.close
115
114
 
116
115
  connect
117
116
  return
@@ -36,7 +36,6 @@ module Selenium
36
36
  attr_accessor :port
37
37
 
38
38
  class << self
39
-
40
39
  def ini
41
40
  @ini ||= ProfilesIni.new
42
41
  end
@@ -44,9 +43,20 @@ module Selenium
44
43
  def from_name(name)
45
44
  ini[name]
46
45
  end
47
-
48
46
  end
49
47
 
48
+ #
49
+ # Create a new Profile instance
50
+ #
51
+ # @example User configured profile
52
+ #
53
+ # profile = Selenium::WebDriver::Firefox::Profile.new
54
+ # profile['network.proxy.http'] = 'localhost'
55
+ # profile['network.proxy.http_port'] = 9090
56
+ #
57
+ # driver = Selenium::WebDriver.for :firefox, :profile => profile
58
+ #
59
+
50
60
  def initialize(directory = nil)
51
61
  @directory = directory ? create_tmp_copy(directory) : Dir.mktmpdir("webdriver-profile")
52
62
 
@@ -60,6 +70,30 @@ module Selenium
60
70
  @native_events = DEFAULT_ENABLE_NATIVE_EVENTS
61
71
  @secure_ssl = DEFAULT_SECURE_SSL
62
72
  @load_no_focus_lib = DEFAULT_LOAD_NO_FOCUS_LIB
73
+
74
+ @additional_prefs = {}
75
+ end
76
+
77
+ #
78
+ # Set a preference for this particular profile.
79
+ # @see http://preferential.mozdev.org/preferences.html
80
+ #
81
+
82
+ def []=(key, value)
83
+ case value
84
+ when String
85
+ if Util.stringified?(value)
86
+ raise ArgumentError, "preference values must be plain strings: #{key.inspect} => #{value.inspect}"
87
+ end
88
+
89
+ value = %{"#{value}"}
90
+ when TrueClass, FalseClass, Integer, Float
91
+ value = value.to_s
92
+ else
93
+ raise TypeError, "invalid preference: #{value.inspect}:#{value.class}"
94
+ end
95
+
96
+ @additional_prefs[key.to_s] = value
63
97
  end
64
98
 
65
99
  def absolute_path
@@ -71,10 +105,16 @@ module Selenium
71
105
  end
72
106
 
73
107
  def update_user_prefs
74
- prefs = current_user_prefs.merge DEFAULT_PREFERENCES
75
- prefs['webdriver_firefox_port'] = @port
108
+ prefs = current_user_prefs
109
+
110
+ prefs.merge! OVERRIDABLE_PREFERENCES
111
+ prefs.merge! @additional_prefs
112
+ prefs.merge! DEFAULT_PREFERENCES
113
+
114
+ prefs['webdriver_firefox_port'] = @port
76
115
  prefs['webdriver_accept_untrusted_certs'] = 'true' unless secure_ssl?
77
- prefs['webdriver_enable_native_events'] = 'true' if native_events?
116
+ prefs['webdriver_enable_native_events'] = 'true' if native_events?
117
+ prefs["startup.homepage_welcome_url"] = prefs["browser.startup.homepage"] # If the user sets the home page, we should also start up there
78
118
 
79
119
  write_prefs prefs
80
120
  end
@@ -126,7 +166,7 @@ module Selenium
126
166
  end
127
167
 
128
168
  def user_prefs_path
129
- @user_prefs_js ||= File.join(directory, "user.js")
169
+ @user_prefs_path ||= File.join(directory, "user.js")
130
170
  end
131
171
 
132
172
  def delete_extensions_cache
@@ -188,11 +228,17 @@ module Selenium
188
228
  def write_prefs(prefs)
189
229
  File.open(user_prefs_path, "w") do |file|
190
230
  prefs.each do |key, value|
191
- file.puts "user_pref(#{key.inspect}, #{value});"
231
+ p key => value if $DEBUG
232
+ file.puts %{user_pref("#{key}", #{value});}
192
233
  end
193
234
  end
194
235
  end
195
236
 
237
+ OVERRIDABLE_PREFERENCES = {
238
+ "browser.startup.page" => '0',
239
+ "browser.startup.homepage" => '"about:blank"'
240
+ }.freeze
241
+
196
242
  DEFAULT_PREFERENCES = {
197
243
  "app.update.auto" => 'false',
198
244
  "app.update.enabled" => 'false',
@@ -205,7 +251,6 @@ module Selenium
205
251
  "browser.search.update" => 'false',
206
252
  "browser.sessionstore.resume_from_crash" => 'false',
207
253
  "browser.shell.checkDefaultBrowser" => 'false',
208
- "browser.startup.page" => '0',
209
254
  "browser.tabs.warnOnClose" => 'false',
210
255
  "browser.tabs.warnOnOpen" => 'false',
211
256
  "dom.disable_open_during_load" => 'false',
@@ -222,10 +267,9 @@ module Selenium
222
267
  "security.warn_viewing_mixed" => 'false',
223
268
  "security.warn_viewing_mixed.show_once" => 'false',
224
269
  "signon.rememberSignons" => 'false',
225
- "startup.homepage_welcome_url" => '"about:blank"',
226
270
  "javascript.options.showInConsole" => 'true',
227
271
  "browser.dom.window.dump.enabled" => 'true'
228
- }
272
+ }.freeze
229
273
 
230
274
  end # Profile
231
275
  end # Firefox
@@ -1,6 +1,8 @@
1
1
  module Selenium
2
2
  module WebDriver
3
3
  module Firefox
4
+
5
+ # @private
4
6
  class ProfilesIni
5
7
 
6
8
  def initialize
@@ -1,6 +1,8 @@
1
1
  module Selenium
2
2
  module WebDriver
3
3
  module Firefox
4
+
5
+ # @private
4
6
  module Util
5
7
  module_function
6
8
 
@@ -17,6 +19,10 @@ module Selenium
17
19
  end
18
20
  end
19
21
 
22
+ def stringified?(str)
23
+ str =~ /^".*"$/
24
+ end
25
+
20
26
  end # Util
21
27
  end # Firefox
22
28
  end # WebDriver
@@ -1,5 +1,7 @@
1
1
  module Selenium
2
2
  module WebDriver
3
+
4
+ # @private
3
5
  module IE
4
6
  # TODO: x64
5
7
  DLL = "#{WebDriver.root}/jobbie/prebuilt/Win32/Release/InternetExplorerDriver.dll"
@@ -2,6 +2,10 @@ module Selenium
2
2
  module WebDriver
3
3
  module IE
4
4
 
5
+ #
6
+ # @private
7
+ #
8
+
5
9
  class Bridge
6
10
  include Util
7
11
 
@@ -335,7 +339,7 @@ module Selenium
335
339
 
336
340
  def getElementAttribute(element_pointer, name)
337
341
  create_string do |string_pointer|
338
- check_error_code Lib.wdeGetAttribute(element_pointer, wstring_ptr(name), string_pointer),
342
+ check_error_code Lib.wdeGetAttribute(@driver_pointer, element_pointer, wstring_ptr(name), string_pointer),
339
343
  "unable to get attribute #{name.inspect}"
340
344
  end
341
345
  end
@@ -506,48 +510,69 @@ module Selenium
506
510
  script_result = pointer_ref.get_pointer(0)
507
511
 
508
512
  pointers_to_free << type_pointer = FFI::MemoryPointer.new(:int)
509
- result = Lib.wdGetScriptResultType(script_result, type_pointer)
513
+ result = Lib.wdGetScriptResultType(@driver_pointer, script_result, type_pointer)
510
514
 
511
515
  check_error_code result, "Cannot determine result type"
516
+ result_type = type_pointer.get_int(0)
512
517
 
513
- case type_pointer.get_int(0)
514
- when 1
518
+ case result_type
519
+ when 1 # String
515
520
  create_string do |wrapper|
516
521
  check_error_code Lib.wdGetStringScriptResult(script_result, wrapper), "Cannot extract string result"
517
522
  end
518
- when 2
523
+ when 2 # Long
519
524
  pointers_to_free << long_pointer = FFI::MemoryPointer.new(:long)
520
525
  check_error_code Lib.wdGetNumberScriptResult(script_result, long_pointer),
521
526
  "Cannot extract number result"
522
527
 
523
528
  long_pointer.get_long(0)
524
- when 3
529
+ when 3 # Boolean
525
530
  pointers_to_free << int_pointer = FFI::MemoryPointer.new(:int)
526
531
  check_error_code Lib.wdGetBooleanScriptResult(script_result, int_pointer),
527
532
  "Cannot extract boolean result"
528
533
 
529
534
  int_pointer.get_int(0) == 1
530
- when 4
531
- element_pointer = FFI::MemoryPointer.new(:pointer)
535
+ when 4 # WebElement
536
+ pointers_to_free << element_pointer = FFI::MemoryPointer.new(:pointer)
532
537
  check_error_code Lib.wdGetElementScriptResult(script_result, @driver_pointer, element_pointer),
533
538
  "Cannot extract element result"
534
539
 
535
540
  Element.new(self, element_pointer.get_pointer(0))
536
- when 5
541
+ when 5 # Nothing
537
542
  nil
538
- when 6
543
+ when 6 # Exception
539
544
  message = create_string do |string_pointer|
540
545
  check_error_code Lib.wdGetStringScriptResult(script_result, string_pointer), "Cannot extract string result"
541
546
  end
542
547
 
543
- raise WebDriverError, message
544
- when 7
548
+ raise Error::WebDriverError, message
549
+ when 7 # Double
545
550
  pointers_to_free << double_pointer = FFI::MemoryPointer.new(:double)
546
551
  check_error_code Lib.wdGetDoubleScriptResult(script_result, double_pointer), "Cannot extract double result"
547
552
 
548
553
  double_pointer.get_double(0)
554
+ when 8 # Array
555
+ pointers_to_free << array_length_pointer = FFI::MemoryPointer.new(:int)
556
+ check_error_code Lib.wdGetArrayLengthScriptResult(@driver_pointer, script_result, array_length_pointer),
557
+ "Cannot extract array length"
558
+
559
+ arr = []
560
+ array_length_pointer.get_int(0).times do |idx|
561
+ current_item_pointer = FFI::MemoryPointer.new(:pointer)
562
+ result_code = Lib.wdGetArrayItemFromScriptResult(@driver_pointer, script_result, idx, current_item_pointer)
563
+
564
+ # free the pointer if the call failed
565
+ if Error.for_code(result_code)
566
+ Lib.wdFreeScriptResult(current_item_pointer.get_pointer(0))
567
+ check_error_code result_code
568
+ end
569
+
570
+ arr << extract_return_value(current_item_pointer)
571
+ end
572
+
573
+ arr
549
574
  else
550
- raise WebDriverError, "Cannot determine result type"
575
+ raise Error::WebDriverError, "Cannot determine result type (#{result_type.inspect})"
551
576
  end
552
577
  ensure
553
578
  Lib.wdFreeScriptResult(script_result) if script_result
@@ -1,6 +1,11 @@
1
1
  module Selenium
2
2
  module WebDriver
3
3
  module IE
4
+
5
+ #
6
+ # @private
7
+ #
8
+
4
9
  module Lib
5
10
  extend FFI::Library
6
11
 
@@ -20,7 +25,7 @@ module Selenium
20
25
  attach_function :wdCopyString, [:pointer, :int, :pointer ], :int
21
26
  attach_function :wdeClear, [:pointer ], :int
22
27
  attach_function :wdeClick, [:pointer ], :int
23
- attach_function :wdeGetAttribute, [:pointer, :pointer, :pointer ], :int
28
+ attach_function :wdeGetAttribute, [:pointer, :pointer, :pointer, :pointer ], :int
24
29
  attach_function :wdeGetDetailsOnceScrolledOnToScreen, [:pointer, :pointer, :pointer, :pointer, :pointer, :pointer ], :int
25
30
  attach_function :wdeGetLocation, [:pointer, :pointer, :pointer ], :int
26
31
  attach_function :wdeGetSize, [:pointer, :pointer, :pointer ], :int
@@ -60,6 +65,8 @@ module Selenium
60
65
  attach_function :wdFreeString, [:pointer ], :int
61
66
  attach_function :wdFreeStringCollection, [:pointer ], :int
62
67
  attach_function :wdGet, [:pointer, :pointer ], :int
68
+ attach_function :wdGetArrayLengthScriptResult, [:pointer, :pointer, :pointer ], :int
69
+ attach_function :wdGetArrayItemFromScriptResult, [:pointer, :pointer, :int, :pointer ], :int
63
70
  attach_function :wdGetAllWindowHandles, [:pointer, :pointer ], :int
64
71
  attach_function :wdGetBooleanScriptResult, [:pointer, :pointer ], :int
65
72
  attach_function :wdGetCookies, [:pointer, :pointer ], :int
@@ -69,7 +76,7 @@ module Selenium
69
76
  attach_function :wdGetElementScriptResult, [:pointer, :pointer, :pointer ], :int
70
77
  attach_function :wdGetNumberScriptResult, [:pointer, :pointer ], :int
71
78
  attach_function :wdGetPageSource, [:pointer, :pointer ], :int
72
- attach_function :wdGetScriptResultType, [:pointer, :pointer ], :int
79
+ attach_function :wdGetScriptResultType, [:pointer, :pointer, :pointer ], :int
73
80
  attach_function :wdGetStringScriptResult, [:pointer, :pointer ], :int
74
81
  attach_function :wdGetTitle, [:pointer, :pointer ], :int
75
82
  attach_function :wdGetVisible, [:pointer, :pointer ], :int
@@ -1,6 +1,11 @@
1
1
  module Selenium
2
2
  module WebDriver
3
3
  module IE
4
+
5
+ #
6
+ # @private
7
+ #
8
+
4
9
  module Util
5
10
  CP_ACP = 0
6
11
  CP_OEMCP = 1
@@ -7,6 +7,8 @@ require "selenium/webdriver/remote/commands"
7
7
 
8
8
  module Selenium
9
9
  module WebDriver
10
+
11
+ # @private
10
12
  module Remote
11
13
 
12
14
  end