browserstack-webdriver 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (202) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGES +791 -0
  3. data/README.md +31 -0
  4. data/build.desc +334 -0
  5. data/lib/selenium-client.rb +2 -0
  6. data/lib/selenium-webdriver.rb +1 -0
  7. data/lib/selenium/client.rb +37 -0
  8. data/lib/selenium/client/base.rb +132 -0
  9. data/lib/selenium/client/driver.rb +10 -0
  10. data/lib/selenium/client/errors.rb +9 -0
  11. data/lib/selenium/client/extensions.rb +118 -0
  12. data/lib/selenium/client/idiomatic.rb +488 -0
  13. data/lib/selenium/client/javascript_expression_builder.rb +116 -0
  14. data/lib/selenium/client/javascript_frameworks/jquery.rb +13 -0
  15. data/lib/selenium/client/javascript_frameworks/prototype.rb +13 -0
  16. data/lib/selenium/client/legacy_driver.rb +1720 -0
  17. data/lib/selenium/client/protocol.rb +104 -0
  18. data/lib/selenium/client/selenium_helper.rb +34 -0
  19. data/lib/selenium/rake/server_task.rb +157 -0
  20. data/lib/selenium/server.rb +248 -0
  21. data/lib/selenium/webdriver.rb +71 -0
  22. data/lib/selenium/webdriver/android.rb +9 -0
  23. data/lib/selenium/webdriver/android/bridge.rb +47 -0
  24. data/lib/selenium/webdriver/chrome.rb +26 -0
  25. data/lib/selenium/webdriver/chrome/bridge.rb +120 -0
  26. data/lib/selenium/webdriver/chrome/profile.rb +90 -0
  27. data/lib/selenium/webdriver/chrome/service.rb +75 -0
  28. data/lib/selenium/webdriver/common.rb +44 -0
  29. data/lib/selenium/webdriver/common/action_builder.rb +352 -0
  30. data/lib/selenium/webdriver/common/alert.rb +30 -0
  31. data/lib/selenium/webdriver/common/bridge_helper.rb +67 -0
  32. data/lib/selenium/webdriver/common/core_ext/base64.rb +9 -0
  33. data/lib/selenium/webdriver/common/core_ext/dir.rb +42 -0
  34. data/lib/selenium/webdriver/common/core_ext/string.rb +5 -0
  35. data/lib/selenium/webdriver/common/driver.rb +301 -0
  36. data/lib/selenium/webdriver/common/driver_extensions/has_browser_connection.rb +17 -0
  37. data/lib/selenium/webdriver/common/driver_extensions/has_input_devices.rb +39 -0
  38. data/lib/selenium/webdriver/common/driver_extensions/has_location.rb +25 -0
  39. data/lib/selenium/webdriver/common/driver_extensions/has_remote_status.rb +13 -0
  40. data/lib/selenium/webdriver/common/driver_extensions/has_session_id.rb +22 -0
  41. data/lib/selenium/webdriver/common/driver_extensions/has_touch_screen.rb +19 -0
  42. data/lib/selenium/webdriver/common/driver_extensions/has_web_storage.rb +22 -0
  43. data/lib/selenium/webdriver/common/driver_extensions/rotatable.rb +45 -0
  44. data/lib/selenium/webdriver/common/driver_extensions/takes_screenshot.rb +43 -0
  45. data/lib/selenium/webdriver/common/driver_extensions/uploads_files.rb +46 -0
  46. data/lib/selenium/webdriver/common/element.rb +293 -0
  47. data/lib/selenium/webdriver/common/error.rb +207 -0
  48. data/lib/selenium/webdriver/common/file_reaper.rb +47 -0
  49. data/lib/selenium/webdriver/common/html5/local_storage.rb +42 -0
  50. data/lib/selenium/webdriver/common/html5/location.rb +0 -0
  51. data/lib/selenium/webdriver/common/html5/session_storage.rb +44 -0
  52. data/lib/selenium/webdriver/common/html5/shared_web_storage.rb +42 -0
  53. data/lib/selenium/webdriver/common/json_helper.rb +34 -0
  54. data/lib/selenium/webdriver/common/keyboard.rb +55 -0
  55. data/lib/selenium/webdriver/common/keys.rb +109 -0
  56. data/lib/selenium/webdriver/common/log_entry.rb +29 -0
  57. data/lib/selenium/webdriver/common/logs.rb +23 -0
  58. data/lib/selenium/webdriver/common/mouse.rb +72 -0
  59. data/lib/selenium/webdriver/common/navigation.rb +43 -0
  60. data/lib/selenium/webdriver/common/options.rb +136 -0
  61. data/lib/selenium/webdriver/common/platform.rb +218 -0
  62. data/lib/selenium/webdriver/common/port_prober.rb +42 -0
  63. data/lib/selenium/webdriver/common/profile_helper.rb +67 -0
  64. data/lib/selenium/webdriver/common/proxy.rb +149 -0
  65. data/lib/selenium/webdriver/common/search_context.rb +92 -0
  66. data/lib/selenium/webdriver/common/socket_poller.rb +105 -0
  67. data/lib/selenium/webdriver/common/target_locator.rb +81 -0
  68. data/lib/selenium/webdriver/common/timeouts.rb +38 -0
  69. data/lib/selenium/webdriver/common/touch_action_builder.rb +64 -0
  70. data/lib/selenium/webdriver/common/touch_screen.rb +105 -0
  71. data/lib/selenium/webdriver/common/wait.rb +63 -0
  72. data/lib/selenium/webdriver/common/window.rb +104 -0
  73. data/lib/selenium/webdriver/common/zipper.rb +82 -0
  74. data/lib/selenium/webdriver/firefox.rb +37 -0
  75. data/lib/selenium/webdriver/firefox/binary.rb +158 -0
  76. data/lib/selenium/webdriver/firefox/bridge.rb +70 -0
  77. data/lib/selenium/webdriver/firefox/extension.rb +52 -0
  78. data/lib/selenium/webdriver/firefox/launcher.rb +106 -0
  79. data/lib/selenium/webdriver/firefox/profile.rb +263 -0
  80. data/lib/selenium/webdriver/firefox/profiles_ini.rb +62 -0
  81. data/lib/selenium/webdriver/firefox/socket_lock.rb +61 -0
  82. data/lib/selenium/webdriver/firefox/util.rb +29 -0
  83. data/lib/selenium/webdriver/ie.rb +19 -0
  84. data/lib/selenium/webdriver/ie/bridge.rb +68 -0
  85. data/lib/selenium/webdriver/ie/server.rb +86 -0
  86. data/lib/selenium/webdriver/iphone.rb +9 -0
  87. data/lib/selenium/webdriver/iphone/bridge.rb +45 -0
  88. data/lib/selenium/webdriver/opera.rb +24 -0
  89. data/lib/selenium/webdriver/opera/bridge.rb +112 -0
  90. data/lib/selenium/webdriver/opera/service.rb +49 -0
  91. data/lib/selenium/webdriver/phantomjs.rb +22 -0
  92. data/lib/selenium/webdriver/phantomjs/bridge.rb +59 -0
  93. data/lib/selenium/webdriver/phantomjs/service.rb +90 -0
  94. data/lib/selenium/webdriver/remote.rb +22 -0
  95. data/lib/selenium/webdriver/remote/bridge.rb +644 -0
  96. data/lib/selenium/webdriver/remote/capabilities.rb +267 -0
  97. data/lib/selenium/webdriver/remote/commands.rb +193 -0
  98. data/lib/selenium/webdriver/remote/http/common.rb +74 -0
  99. data/lib/selenium/webdriver/remote/http/curb.rb +79 -0
  100. data/lib/selenium/webdriver/remote/http/default.rb +139 -0
  101. data/lib/selenium/webdriver/remote/http/persistent.rb +38 -0
  102. data/lib/selenium/webdriver/remote/response.rb +97 -0
  103. data/lib/selenium/webdriver/remote/server_error.rb +17 -0
  104. data/lib/selenium/webdriver/safari.rb +46 -0
  105. data/lib/selenium/webdriver/safari/bridge.rb +110 -0
  106. data/lib/selenium/webdriver/safari/browser.rb +20 -0
  107. data/lib/selenium/webdriver/safari/extension.rb +120 -0
  108. data/lib/selenium/webdriver/safari/server.rb +145 -0
  109. data/lib/selenium/webdriver/support.rb +5 -0
  110. data/lib/selenium/webdriver/support/abstract_event_listener.rb +28 -0
  111. data/lib/selenium/webdriver/support/block_event_listener.rb +17 -0
  112. data/lib/selenium/webdriver/support/color.rb +110 -0
  113. data/lib/selenium/webdriver/support/event_firing_bridge.rb +112 -0
  114. data/lib/selenium/webdriver/support/select.rb +293 -0
  115. data/ruby.iml +13 -0
  116. data/spec/integration/selenium/client/api/backward_compatible_api_spec.rb +22 -0
  117. data/spec/integration/selenium/client/api/browser_xpath_library_spec.rb +17 -0
  118. data/spec/integration/selenium/client/api/click_spec.rb +39 -0
  119. data/spec/integration/selenium/client/api/cookie_spec.rb +39 -0
  120. data/spec/integration/selenium/client/api/element_spec.rb +14 -0
  121. data/spec/integration/selenium/client/api/highlight_located_element_spec.rb +19 -0
  122. data/spec/integration/selenium/client/api/retrieve_last_remote_control_logs_spec.rb +33 -0
  123. data/spec/integration/selenium/client/api/screenshot_spec.rb +31 -0
  124. data/spec/integration/selenium/client/api/select_window_spec.rb +46 -0
  125. data/spec/integration/selenium/client/api/start_stop_spec.rb +9 -0
  126. data/spec/integration/selenium/client/api/wait_for_ajax_spec.rb +27 -0
  127. data/spec/integration/selenium/client/api/wait_for_element_spec.rb +56 -0
  128. data/spec/integration/selenium/client/api/wait_for_field_value_spec.rb +52 -0
  129. data/spec/integration/selenium/client/api/wait_for_text_spec.rb +98 -0
  130. data/spec/integration/selenium/client/api/webdriver_backed_spec.rb +21 -0
  131. data/spec/integration/selenium/client/sample-app/public/jquery-1.3.2.js +4376 -0
  132. data/spec/integration/selenium/client/sample-app/public/jquery.html +55 -0
  133. data/spec/integration/selenium/client/sample-app/public/prototype-1.6.0.3.js +4320 -0
  134. data/spec/integration/selenium/client/sample-app/public/prototype.html +59 -0
  135. data/spec/integration/selenium/client/sample-app/sample_app.rb +32 -0
  136. data/spec/integration/selenium/client/spec_helper.rb +139 -0
  137. data/spec/integration/selenium/webdriver/app_cache_spec.rb +47 -0
  138. data/spec/integration/selenium/webdriver/browser_connection_spec.rb +20 -0
  139. data/spec/integration/selenium/webdriver/chrome/driver_spec.rb +28 -0
  140. data/spec/integration/selenium/webdriver/chrome/profile_spec.rb +63 -0
  141. data/spec/integration/selenium/webdriver/driver_spec.rb +266 -0
  142. data/spec/integration/selenium/webdriver/element_spec.rb +191 -0
  143. data/spec/integration/selenium/webdriver/error_spec.rb +30 -0
  144. data/spec/integration/selenium/webdriver/firefox/driver_spec.rb +21 -0
  145. data/spec/integration/selenium/webdriver/firefox/profile_spec.rb +141 -0
  146. data/spec/integration/selenium/webdriver/keyboard_spec.rb +57 -0
  147. data/spec/integration/selenium/webdriver/location_spec.rb +29 -0
  148. data/spec/integration/selenium/webdriver/mouse_spec.rb +57 -0
  149. data/spec/integration/selenium/webdriver/navigation_spec.rb +46 -0
  150. data/spec/integration/selenium/webdriver/opera/driver_spec.rb +47 -0
  151. data/spec/integration/selenium/webdriver/options_spec.rb +77 -0
  152. data/spec/integration/selenium/webdriver/remote/driver_spec.rb +19 -0
  153. data/spec/integration/selenium/webdriver/remote/element_spec.rb +26 -0
  154. data/spec/integration/selenium/webdriver/spec_helper.rb +36 -0
  155. data/spec/integration/selenium/webdriver/spec_support.rb +12 -0
  156. data/spec/integration/selenium/webdriver/spec_support/guards.rb +110 -0
  157. data/spec/integration/selenium/webdriver/spec_support/helpers.rb +51 -0
  158. data/spec/integration/selenium/webdriver/spec_support/rack_server.rb +123 -0
  159. data/spec/integration/selenium/webdriver/spec_support/test_environment.rb +239 -0
  160. data/spec/integration/selenium/webdriver/sql_database_spec.rb +59 -0
  161. data/spec/integration/selenium/webdriver/storage_spec.rb +96 -0
  162. data/spec/integration/selenium/webdriver/target_locator_spec.rb +186 -0
  163. data/spec/integration/selenium/webdriver/timeout_spec.rb +69 -0
  164. data/spec/integration/selenium/webdriver/touch_spec.rb +176 -0
  165. data/spec/integration/selenium/webdriver/window_spec.rb +70 -0
  166. data/spec/integration/selenium/webdriver/zipper_spec.rb +66 -0
  167. data/spec/unit/selenium/client/base_spec.rb +239 -0
  168. data/spec/unit/selenium/client/extensions_spec.rb +174 -0
  169. data/spec/unit/selenium/client/idiomatic_spec.rb +500 -0
  170. data/spec/unit/selenium/client/javascript_expression_builder_spec.rb +79 -0
  171. data/spec/unit/selenium/client/javascript_frameworks/jquery_spec.rb +10 -0
  172. data/spec/unit/selenium/client/javascript_frameworks/prototype_spec.rb +10 -0
  173. data/spec/unit/selenium/client/protocol_spec.rb +124 -0
  174. data/spec/unit/selenium/client/selenium_helper_spec.rb +56 -0
  175. data/spec/unit/selenium/client/spec_helper.rb +24 -0
  176. data/spec/unit/selenium/rake/task_spec.rb +79 -0
  177. data/spec/unit/selenium/server_spec.rb +150 -0
  178. data/spec/unit/selenium/webdriver/action_builder_spec.rb +97 -0
  179. data/spec/unit/selenium/webdriver/android/bridge_spec.rb +43 -0
  180. data/spec/unit/selenium/webdriver/chrome/bridge_spec.rb +137 -0
  181. data/spec/unit/selenium/webdriver/chrome/profile_spec.rb +57 -0
  182. data/spec/unit/selenium/webdriver/chrome/service_spec.rb +44 -0
  183. data/spec/unit/selenium/webdriver/error_spec.rb +41 -0
  184. data/spec/unit/selenium/webdriver/firefox/bridge_spec.rb +47 -0
  185. data/spec/unit/selenium/webdriver/ie/bridge_spec.rb +91 -0
  186. data/spec/unit/selenium/webdriver/iphone/bridge_spec.rb +42 -0
  187. data/spec/unit/selenium/webdriver/log_entry_spec.rb +11 -0
  188. data/spec/unit/selenium/webdriver/opera/bridge_spec.rb +44 -0
  189. data/spec/unit/selenium/webdriver/phantomjs/bridge_spec.rb +55 -0
  190. data/spec/unit/selenium/webdriver/proxy_spec.rb +106 -0
  191. data/spec/unit/selenium/webdriver/remote/bridge_spec.rb +16 -0
  192. data/spec/unit/selenium/webdriver/remote/capabilities_spec.rb +115 -0
  193. data/spec/unit/selenium/webdriver/remote/http/common_spec.rb +24 -0
  194. data/spec/unit/selenium/webdriver/remote/http/default_spec.rb +124 -0
  195. data/spec/unit/selenium/webdriver/search_context_spec.rb +61 -0
  196. data/spec/unit/selenium/webdriver/socket_poller_spec.rb +68 -0
  197. data/spec/unit/selenium/webdriver/spec_helper.rb +27 -0
  198. data/spec/unit/selenium/webdriver/support/color_spec.rb +119 -0
  199. data/spec/unit/selenium/webdriver/support/event_firing_spec.rb +111 -0
  200. data/spec/unit/selenium/webdriver/support/select_spec.rb +290 -0
  201. data/spec/unit/selenium/webdriver/wait_spec.rb +49 -0
  202. metadata +370 -0
@@ -0,0 +1,82 @@
1
+ require 'zip'
2
+ require 'tempfile'
3
+ require 'find'
4
+
5
+ module Selenium
6
+ module WebDriver
7
+ #
8
+ # @api private
9
+ #
10
+
11
+ module Zipper
12
+
13
+ EXTENSIONS = %w[.zip .xpi]
14
+
15
+ class << self
16
+
17
+ def unzip(path)
18
+ destination = Dir.mktmpdir("webdriver-unzip")
19
+ FileReaper << destination
20
+
21
+ Zip::File.open(path) do |zip|
22
+ zip.each do |entry|
23
+ to = File.join(destination, entry.name)
24
+ dirname = File.dirname(to)
25
+
26
+ FileUtils.mkdir_p dirname unless File.exist? dirname
27
+ zip.extract(entry, to)
28
+ end
29
+ end
30
+
31
+ destination
32
+ end
33
+
34
+ def zip(path)
35
+ with_tmp_zip do |zip|
36
+ ::Find.find(path) do |file|
37
+ unless File.directory?(file)
38
+ add_zip_entry zip, file, file.sub("#{path}/", '')
39
+ end
40
+ end
41
+
42
+ zip.commit
43
+ File.open(zip.name, "rb") { |io| Base64.strict_encode64 io.read }
44
+ end
45
+ end
46
+
47
+ def zip_file(path)
48
+ with_tmp_zip do |zip|
49
+ add_zip_entry zip, path, File.basename(path)
50
+
51
+ zip.commit
52
+ File.open(zip.name, "rb") { |io| Base64.strict_encode64 io.read }
53
+ end
54
+ end
55
+
56
+ private
57
+
58
+ def with_tmp_zip(&blk)
59
+ # can't use Tempfile here since it doesn't support File::BINARY mode on 1.8
60
+ # can't use Dir.mktmpdir(&blk) because of http://jira.codehaus.org/browse/JRUBY-4082
61
+ tmp_dir = Dir.mktmpdir
62
+ zip_path = File.join(tmp_dir, "webdriver-zip")
63
+
64
+ begin
65
+ Zip::File.open(zip_path, Zip::File::CREATE, &blk)
66
+ ensure
67
+ FileUtils.rm_rf tmp_dir
68
+ FileUtils.rm_rf zip_path
69
+ end
70
+ end
71
+
72
+ def add_zip_entry(zip, file, entry_name)
73
+ entry = Zip::Entry.new(zip.name, entry_name)
74
+ entry.follow_symlinks = true
75
+
76
+ zip.add entry, file
77
+ end
78
+
79
+ end
80
+ end # Zipper
81
+ end # WebDriver
82
+ end # Selenium
@@ -0,0 +1,37 @@
1
+ require 'timeout'
2
+ require 'socket'
3
+ require 'rexml/document'
4
+
5
+ require 'selenium/webdriver/firefox/util'
6
+ require 'selenium/webdriver/firefox/extension'
7
+ require 'selenium/webdriver/firefox/socket_lock'
8
+ require 'selenium/webdriver/firefox/binary'
9
+ require 'selenium/webdriver/firefox/profiles_ini'
10
+ require 'selenium/webdriver/firefox/profile'
11
+ require 'selenium/webdriver/firefox/launcher'
12
+ require 'selenium/webdriver/firefox/bridge'
13
+
14
+ module Selenium
15
+ module WebDriver
16
+ module Firefox
17
+
18
+ DEFAULT_PORT = 7055
19
+ DEFAULT_ENABLE_NATIVE_EVENTS = Platform.os == :windows
20
+ DEFAULT_SECURE_SSL = false
21
+ DEFAULT_ASSUME_UNTRUSTED_ISSUER = true
22
+ DEFAULT_LOAD_NO_FOCUS_LIB = false
23
+
24
+ def self.path=(path)
25
+ Binary.path = path
26
+ end
27
+
28
+ end
29
+ end
30
+ end
31
+
32
+
33
+ # SocketError was added in Ruby 1.8.7.
34
+ # If it's not defined, we add it here so it can be used in rescues.
35
+ unless defined? SocketError
36
+ class SocketError < IOError; end
37
+ end
@@ -0,0 +1,158 @@
1
+ module Selenium
2
+ module WebDriver
3
+ module Firefox
4
+
5
+ # @api private
6
+ class Binary
7
+
8
+ NO_FOCUS_LIBRARY_NAME = "x_ignore_nofocus.so"
9
+ NO_FOCUS_LIBRARIES = [
10
+ ["#{WebDriver.root}/selenium/webdriver/firefox/native/linux/amd64/#{NO_FOCUS_LIBRARY_NAME}", "amd64/#{NO_FOCUS_LIBRARY_NAME}"],
11
+ ["#{WebDriver.root}/selenium/webdriver/firefox/native/linux/x86/#{NO_FOCUS_LIBRARY_NAME}", "x86/#{NO_FOCUS_LIBRARY_NAME}"],
12
+ ]
13
+
14
+ WAIT_TIMEOUT = 90
15
+ QUIT_TIMEOUT = 5
16
+
17
+ def start_with(profile, profile_path, *args)
18
+ if Platform.cygwin?
19
+ profile_path = Platform.cygwin_path(profile_path, :windows => true)
20
+ elsif Platform.windows?
21
+ profile_path = profile_path.gsub("/", "\\")
22
+ end
23
+
24
+ ENV['XRE_CONSOLE_LOG'] = profile.log_file if profile.log_file
25
+ ENV['XRE_PROFILE_PATH'] = profile_path
26
+ ENV['MOZ_NO_REMOTE'] = '1' # able to launch multiple instances
27
+ ENV['MOZ_CRASHREPORTER_DISABLE'] = '1' # disable breakpad
28
+ ENV['NO_EM_RESTART'] = '1' # prevent the binary from detaching from the console
29
+
30
+ if Platform.linux? && (profile.native_events? || profile.load_no_focus_lib?)
31
+ modify_link_library_path profile_path
32
+ end
33
+
34
+ execute(*args)
35
+ cope_with_mac_strangeness(args) if Platform.mac?
36
+ end
37
+
38
+ def quit
39
+ return unless @process
40
+ @process.poll_for_exit QUIT_TIMEOUT
41
+ rescue ChildProcess::TimeoutError
42
+ # ok, force quit
43
+ @process.stop QUIT_TIMEOUT
44
+ end
45
+
46
+ def wait
47
+ @process.poll_for_exit(WAIT_TIMEOUT) if @process
48
+ end
49
+
50
+ private
51
+
52
+ def execute(*extra_args)
53
+ args = [self.class.path, "-no-remote"] + extra_args
54
+ @process = ChildProcess.build(*args)
55
+ @process.io.inherit! if $DEBUG
56
+ @process.start
57
+ end
58
+
59
+ def cope_with_mac_strangeness(args)
60
+ sleep 0.3
61
+
62
+ if @process.crashed?
63
+ # ok, trying a restart
64
+ sleep 7
65
+ execute(*args)
66
+ end
67
+
68
+ # ensure we're ok
69
+ sleep 0.3
70
+ if @process.crashed?
71
+ raise Error::WebDriverError, "unable to start Firefox cleanly, args: #{args.inspect}"
72
+ end
73
+ end
74
+
75
+ def modify_link_library_path(profile_path)
76
+ paths = []
77
+
78
+ NO_FOCUS_LIBRARIES.each do |from, to|
79
+ dest = File.join(profile_path, to)
80
+ FileUtils.mkdir_p File.dirname(dest)
81
+ FileUtils.cp from, dest
82
+
83
+ paths << File.expand_path(File.dirname(dest))
84
+ end
85
+
86
+ paths += ENV['LD_LIBRARY_PATH'].to_s.split(File::PATH_SEPARATOR)
87
+
88
+ ENV['LD_LIBRARY_PATH'] = paths.uniq.join(File::PATH_SEPARATOR)
89
+ ENV['LD_PRELOAD'] = NO_FOCUS_LIBRARY_NAME
90
+ end
91
+
92
+ class << self
93
+
94
+ #
95
+ # @api private
96
+ #
97
+ # @see Firefox.path=
98
+ #
99
+
100
+ def path=(path)
101
+ Platform.assert_executable(path)
102
+ @path = path
103
+ end
104
+
105
+ def path
106
+ @path ||= case Platform.os
107
+ when :macosx
108
+ macosx_path
109
+ when :windows
110
+ windows_path
111
+ when :linux, :unix
112
+ Platform.find_binary("firefox3", "firefox2", "firefox") || "/usr/bin/firefox"
113
+ else
114
+ raise Error::WebDriverError, "unknown platform: #{Platform.os}"
115
+ end
116
+
117
+ @path = Platform.cygwin_path(@path) if Platform.cygwin?
118
+
119
+ unless File.file?(@path.to_s)
120
+ raise Error::WebDriverError, "Could not find Firefox binary (os=#{Platform.os}). Make sure Firefox is installed or set the path manually with #{self}.path="
121
+ end
122
+
123
+ @path
124
+ end
125
+
126
+ private
127
+
128
+ def windows_path
129
+ windows_registry_path || Platform.find_in_program_files("\\Mozilla Firefox\\firefox.exe") || Platform.find_binary("firefox")
130
+ end
131
+
132
+ def macosx_path
133
+ path = "/Applications/Firefox.app/Contents/MacOS/firefox-bin"
134
+ path = Platform.find_binary("firefox-bin") unless File.exist?(path)
135
+
136
+ path
137
+ end
138
+
139
+ def windows_registry_path
140
+ require 'win32/registry'
141
+
142
+ lm = Win32::Registry::HKEY_LOCAL_MACHINE
143
+ lm.open("SOFTWARE\\Mozilla\\Mozilla Firefox") do |reg|
144
+ main = lm.open("SOFTWARE\\Mozilla\\Mozilla Firefox\\#{reg.keys[0]}\\Main")
145
+ if entry = main.find { |key, type, data| key =~ /pathtoexe/i }
146
+ return entry.last
147
+ end
148
+ end
149
+ rescue LoadError
150
+ # older JRuby or IronRuby does not have win32/registry
151
+ rescue Win32::Registry::Error
152
+ end
153
+ end # class << self
154
+
155
+ end # Binary
156
+ end # Firefox
157
+ end # WebDriver
158
+ end # Selenium
@@ -0,0 +1,70 @@
1
+ module Selenium
2
+ module WebDriver
3
+ module Firefox
4
+
5
+ # @api private
6
+ class Bridge < Remote::Bridge
7
+
8
+ def initialize(opts = {})
9
+ port = opts.delete(:port) || DEFAULT_PORT
10
+ profile = opts.delete(:profile)
11
+ http_client = opts.delete(:http_client)
12
+ proxy = opts.delete(:proxy)
13
+
14
+ caps = opts.delete(:desired_capabilities) do
15
+ Remote::Capabilities.firefox(:native_events => DEFAULT_ENABLE_NATIVE_EVENTS)
16
+ end
17
+
18
+ @launcher = create_launcher(port, profile)
19
+
20
+ unless opts.empty?
21
+ raise ArgumentError, "unknown option#{'s' if opts.size != 1}: #{opts.inspect}"
22
+ end
23
+
24
+ @launcher.launch
25
+
26
+ caps.proxy = proxy if proxy
27
+
28
+ remote_opts = {
29
+ :url => @launcher.url,
30
+ :desired_capabilities => caps
31
+ }
32
+
33
+ remote_opts.merge!(:http_client => http_client) if http_client
34
+
35
+ begin
36
+ super(remote_opts)
37
+ rescue
38
+ @launcher.quit
39
+ raise
40
+ end
41
+ end
42
+
43
+ def browser
44
+ :firefox
45
+ end
46
+
47
+ def driver_extensions
48
+ [
49
+ DriverExtensions::TakesScreenshot,
50
+ DriverExtensions::HasInputDevices
51
+ ]
52
+ end
53
+
54
+ def quit
55
+ super
56
+ nil
57
+ ensure
58
+ @launcher.quit
59
+ end
60
+
61
+ private
62
+
63
+ def create_launcher(port, profile)
64
+ Launcher.new Binary.new, port, profile
65
+ end
66
+
67
+ end # Bridge
68
+ end # Firefox
69
+ end # WebDriver
70
+ end # Selenium
@@ -0,0 +1,52 @@
1
+ module Selenium
2
+ module WebDriver
3
+ module Firefox
4
+
5
+ # @api private
6
+ class Extension
7
+ def initialize(path)
8
+ unless File.exist?(path)
9
+ raise Error::WebDriverError, "could not find extension at #{path.inspect}"
10
+ end
11
+
12
+ @path = path
13
+ @should_reap_root = false
14
+ end
15
+
16
+ def write_to(extensions_dir)
17
+ root_dir = create_root
18
+ ext_path = File.join extensions_dir, read_id_from_install_rdf(root_dir)
19
+
20
+ FileUtils.rm_rf ext_path
21
+ FileUtils.mkdir_p File.dirname(ext_path), :mode => 0700
22
+ FileUtils.cp_r root_dir, ext_path
23
+
24
+ FileReaper.reap(root_dir) if @should_reap_root
25
+ end
26
+
27
+ private
28
+
29
+ def create_root
30
+ if File.directory? @path
31
+ @path
32
+ else
33
+ unless Zipper::EXTENSIONS.include? File.extname(@path)
34
+ raise Error::WebDriverError, "expected #{Zipper::EXTENSIONS.join(" or ")}, got #{@path.inspect}"
35
+ end
36
+
37
+ @should_reap_root = true
38
+ Zipper.unzip(@path)
39
+ end
40
+ end
41
+
42
+ def read_id_from_install_rdf(directory)
43
+ rdf_path = File.join(directory, "install.rdf")
44
+ doc = REXML::Document.new(File.read(rdf_path))
45
+
46
+ REXML::XPath.first(doc, "//em:id").text
47
+ end
48
+
49
+ end # Extension
50
+ end # Firefox
51
+ end # WebDriver
52
+ end # Selenium
@@ -0,0 +1,106 @@
1
+ module Selenium
2
+ module WebDriver
3
+ module Firefox
4
+
5
+ # @api private
6
+ class Launcher
7
+
8
+ SOCKET_LOCK_TIMEOUT = 45
9
+ STABLE_CONNECTION_TIMEOUT = 60
10
+
11
+ def initialize(binary, port, profile = nil)
12
+ @binary = binary
13
+ @port = Integer(port)
14
+
15
+ raise Error::WebDriverError, "invalid port: #{@port}" if @port < 1
16
+
17
+ if profile.kind_of? Profile
18
+ @profile = profile
19
+ else
20
+ @profile_name = profile
21
+ @profile = nil
22
+ end
23
+
24
+ @host = "127.0.0.1"
25
+ end
26
+
27
+ def url
28
+ "http://#{@host}:#{@port}/hub"
29
+ end
30
+
31
+ def launch
32
+ socket_lock.locked do
33
+ find_free_port
34
+ create_profile
35
+ start_silent_and_wait
36
+ start
37
+ connect_until_stable
38
+ end
39
+
40
+ self
41
+ end
42
+
43
+ def quit
44
+ @binary.quit
45
+ FileReaper.reap(@profile_dir) if @profile_dir
46
+ end
47
+
48
+ def find_free_port
49
+ @port = PortProber.above @port
50
+ end
51
+
52
+ def create_profile
53
+ fetch_profile unless @profile
54
+
55
+ @profile.add_webdriver_extension
56
+ @profile.port = @port
57
+
58
+ @profile_dir = @profile.layout_on_disk
59
+ FileReaper << @profile_dir
60
+ end
61
+
62
+ def start
63
+ assert_profile
64
+ @binary.start_with @profile, @profile_dir, "-foreground"
65
+ end
66
+
67
+ def start_silent_and_wait
68
+ assert_profile
69
+
70
+ @binary.start_with @profile, @profile_dir, "-silent"
71
+ @binary.wait
72
+ end
73
+
74
+ def connect_until_stable
75
+ poller = SocketPoller.new(@host, @port, STABLE_CONNECTION_TIMEOUT)
76
+
77
+ unless poller.connected?
78
+ @binary.quit
79
+ raise Error::WebDriverError, "unable to obtain stable firefox connection in #{STABLE_CONNECTION_TIMEOUT} seconds (#{@host}:#{@port})"
80
+ end
81
+ end
82
+
83
+ def fetch_profile
84
+ if @profile_name
85
+ @profile = Profile.from_name @profile_name
86
+
87
+ unless @profile
88
+ raise Error::WebDriverError, "unable to find profile named: #{@profile_name.inspect}"
89
+ end
90
+ else
91
+ @profile = Profile.new
92
+ end
93
+ end
94
+
95
+ def assert_profile
96
+ raise Error::WebDriverError, "must create_profile first" unless @profile && @profile_dir
97
+ end
98
+
99
+ def socket_lock
100
+ @socket_lock ||= SocketLock.new(@port - 1, SOCKET_LOCK_TIMEOUT)
101
+ end
102
+
103
+ end # Launcher
104
+ end # Firefox
105
+ end # WebDriver
106
+ end # Selenium