browserstack-webdriver 0.0.1

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.
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,86 @@
1
+ module Selenium
2
+ module WebDriver
3
+ module IE
4
+ class Server
5
+
6
+ STOP_TIMEOUT = 5
7
+
8
+ def self.get
9
+ binary = IE.driver_path || Platform.find_binary("IEDriverServer")
10
+ if binary
11
+ new(binary)
12
+ else
13
+ raise Error::WebDriverError,
14
+ "Unable to find standalone executable. Please download the IEDriverServer from http://code.google.com/p/selenium/downloads/list and place the executable on your PATH."
15
+ end
16
+ end
17
+
18
+ attr_accessor :log_level, :log_file
19
+
20
+ def initialize(binary_path, opts = {})
21
+ Platform.assert_executable binary_path
22
+
23
+ @binary_path = binary_path
24
+ @process = nil
25
+
26
+ opts = opts.dup
27
+ @log_level = opts.delete(:log_level)
28
+ @log_file = opts.delete(:log_file)
29
+
30
+ unless opts.empty?
31
+ raise ArgumentError, "invalid option#{'s' if opts.size != 1}: #{opts.inspect}"
32
+ end
33
+
34
+ end
35
+
36
+ def start(port, timeout)
37
+ return @port if running?
38
+
39
+ @port = port
40
+
41
+ @process = ChildProcess.new(@binary_path, *server_args)
42
+ @process.io.inherit! if $DEBUG
43
+ @process.start
44
+
45
+ unless SocketPoller.new(Platform.localhost, @port, timeout).connected?
46
+ raise Error::WebDriverError, "unable to connect to IE server within #{timeout} seconds"
47
+ end
48
+
49
+ Platform.exit_hook { stop }
50
+
51
+ @port
52
+ end
53
+
54
+ def stop
55
+ if running?
56
+ @process.stop STOP_TIMEOUT
57
+ end
58
+ end
59
+
60
+ def port
61
+ @port
62
+ end
63
+
64
+ def uri
65
+ "http://#{Platform.localhost}:#{port}"
66
+ end
67
+
68
+ def running?
69
+ @process && @process.alive?
70
+ end
71
+
72
+ private
73
+
74
+ def server_args
75
+ args = ["--port=#{@port}"]
76
+
77
+ args << "--log-level=#{@log_level.to_s.upcase}" if @log_level
78
+ args << "--log-file=#{@log_file}" if @log_file
79
+
80
+ args
81
+ end
82
+
83
+ end
84
+ end
85
+ end
86
+ end
@@ -0,0 +1,9 @@
1
+ module Selenium
2
+ module WebDriver
3
+ module IPhone
4
+
5
+ end # IPhone
6
+ end # WebDriver
7
+ end # Selenium
8
+
9
+ require 'selenium/webdriver/iphone/bridge'
@@ -0,0 +1,45 @@
1
+ module Selenium
2
+ module WebDriver
3
+ module IPhone
4
+ #
5
+ # @api private
6
+ #
7
+
8
+ class Bridge < Remote::Bridge
9
+
10
+ DEFAULT_URL = "http://#{Platform.localhost}:3001/wd/hub/"
11
+
12
+ def initialize(opts = {})
13
+ warn 'The iPhone driver is reprecated - please use http://appium.io/ or http://ios-driver.github.io/ios-driver/ instead'
14
+
15
+ remote_opts = {
16
+ :url => opts.fetch(:url, DEFAULT_URL),
17
+ :desired_capabilities => opts.fetch(:desired_capabilities, capabilities),
18
+ }
19
+
20
+ remote_opts[:http_client] = opts[:http_client] if opts.has_key?(:http_client)
21
+
22
+ super remote_opts
23
+ end
24
+
25
+ def browser
26
+ :iphone
27
+ end
28
+
29
+ def driver_extensions
30
+ [
31
+ DriverExtensions::TakesScreenshot,
32
+ DriverExtensions::HasInputDevices,
33
+ DriverExtensions::HasWebStorage,
34
+ DriverExtensions::HasLocation
35
+ ]
36
+ end
37
+
38
+ def capabilities
39
+ @capabilities ||= Remote::Capabilities.iphone
40
+ end
41
+
42
+ end # Bridge
43
+ end # IPhone
44
+ end # WebDriver
45
+ end # Selenium
@@ -0,0 +1,24 @@
1
+ require 'selenium/server'
2
+ require 'selenium/webdriver/opera/service'
3
+ require 'selenium/webdriver/opera/bridge'
4
+
5
+ module Selenium
6
+ module WebDriver
7
+
8
+ module Opera
9
+ def self.driver_path=(path)
10
+ Service.selenium_server_jar = path
11
+ end
12
+
13
+ def self.path=(path)
14
+ Platform.assert_executable path
15
+ @path = path
16
+ end
17
+
18
+ def self.path
19
+ @path ||= nil
20
+ end
21
+ end
22
+
23
+ end
24
+ end
@@ -0,0 +1,112 @@
1
+ module Selenium
2
+ module WebDriver
3
+ module Opera
4
+
5
+ #
6
+ # @api private
7
+ #
8
+
9
+ LOGGING_LEVELS = [:severe, :warning, :info, :config, :fine, :finer, :finest, :all]
10
+
11
+ class Bridge < Remote::Bridge
12
+
13
+ def initialize(opts = {})
14
+ @service = Service.default_service :log => (opts[:logging_level] ? true : false)
15
+
16
+ http_client = opts.delete(:http_client)
17
+ caps = create_capabilities(opts)
18
+
19
+ @service.start
20
+
21
+ remote_opts = {
22
+ :url => @service.uri,
23
+ :desired_capabilities => caps
24
+ }
25
+
26
+ remote_opts.merge!(:http_client => http_client) if http_client
27
+
28
+ super(remote_opts)
29
+ end
30
+
31
+ def browser
32
+ :opera
33
+ end
34
+
35
+ def driver_extensions
36
+ [
37
+ DriverExtensions::HasInputDevices,
38
+ DriverExtensions::TakesScreenshot
39
+ ]
40
+ end
41
+
42
+ def capabilities
43
+ @capabilities ||= Remote::Capabilities.opera
44
+ end
45
+
46
+ def quit
47
+ super
48
+ ensure
49
+ @service.stop
50
+ end
51
+
52
+ private
53
+
54
+ def create_capabilities(opts)
55
+ original_opts = opts.dup
56
+
57
+ arguments = opts.delete(:arguments)
58
+ logging_level = opts.delete(:logging_level)
59
+ logging_file = opts.delete(:logging_file)
60
+ host = opts.delete(:host)
61
+ port = opts.delete(:port)
62
+ launcher = opts.delete(:launcher)
63
+ profile = opts.delete(:profile)
64
+ idle = opts.delete(:idle)
65
+ display = opts.delete(:display)
66
+ autostart = opts.delete(:autostart)
67
+ no_restart = opts.delete(:no_restart)
68
+ no_quit = opts.delete(:no_quit)
69
+ product = opts.delete(:product)
70
+ caps = opts.delete(:desired_capabilities) { Remote::Capabilities.opera }
71
+
72
+ unless opts.empty?
73
+ raise ArgumentError, "unknown option#{'s' if opts.size != 1}: #{opts.inspect}"
74
+ end
75
+
76
+ if arguments
77
+ unless arguments.kind_of? Array
78
+ raise ArgumentError, ':arguments must be an Array of Strings'
79
+ end
80
+
81
+ caps.merge! 'opera.arguments' => arguments.join(' ')
82
+ end
83
+
84
+ if logging_level
85
+ unless LOGGING_LEVELS.include?(logging_level)
86
+ raise ArgumentError,
87
+ "unknown logging level #{logging_level.inspect}, available levels: #{LOGGING_LEVELS.inspect}"
88
+ end
89
+
90
+ caps.merge! 'opera.logging.level' => logging_level.to_s.upcase
91
+ end
92
+
93
+ caps.merge! 'opera.logging.file' => logging_file if logging_file
94
+ caps.merge! 'opera.binary' => Opera.path if Opera.path
95
+ caps.merge! 'opera.host' => host if host
96
+ caps.merge! 'opera.port' => port.to_i if port
97
+ caps.merge! 'opera.launcher' => launcher if launcher
98
+ caps.merge! 'opera.profile' => profile if original_opts.has_key?(:profile)
99
+ caps.merge! 'opera.idle' => !!idle unless idle.nil?
100
+ caps.merge! 'opera.display' => display.to_i if display
101
+ caps.merge! 'opera.autostart' => !!autostart unless autostart.nil?
102
+ caps.merge! 'opera.no_restart' => !!no_restart unless no_restart.nil?
103
+ caps.merge! 'opera.no_quit' => !!no_quit unless no_quit.nil?
104
+ caps.merge! 'opera.product' => product if product
105
+
106
+ caps
107
+ end
108
+
109
+ end
110
+ end
111
+ end
112
+ end
@@ -0,0 +1,49 @@
1
+ module Selenium
2
+ module WebDriver
3
+ module Opera
4
+
5
+ #
6
+ # @api private
7
+ #
8
+
9
+ class Service
10
+ MISSING_TEXT = 'Unable to find the Selenium server jar. Please download the standalone server from http://code.google.com/p/selenium/downloads/list and set the SELENIUM_SERVER_JAR environmental variable to its location. More info at http://code.google.com/p/selenium/wiki/OperaDriver.'
11
+
12
+ def self.selenium_server_jar
13
+ @selenium_server_jar ||= (
14
+ ENV['SELENIUM_SERVER_JAR'] or raise Error::WebDriverError, MISSING_TEXT
15
+ )
16
+ end
17
+
18
+ def self.selenium_server_jar=(path)
19
+ Platform.assert_file path
20
+ @selenium_server_jar = path
21
+ end
22
+
23
+ def self.default_service(opts = {})
24
+ new selenium_server_jar, opts
25
+ end
26
+
27
+ def initialize(jar, opts = {})
28
+ opts.merge! :background => true, :port => PortProber.above(4444)
29
+ opts.merge! :log => !!$DEBUG if $DEBUG
30
+ @server = Selenium::Server.new File.expand_path(jar), opts
31
+ end
32
+
33
+ def uri
34
+ @server.webdriver_url
35
+ end
36
+
37
+ def start
38
+ @server.start
39
+ Platform.exit_hook { stop } # make sure we don't leave the server running
40
+ end
41
+
42
+ def stop
43
+ @server.stop
44
+ end
45
+ end
46
+
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,22 @@
1
+ require 'net/http'
2
+
3
+ require 'selenium/webdriver/phantomjs/service'
4
+ require 'selenium/webdriver/phantomjs/bridge'
5
+
6
+ module Selenium
7
+ module WebDriver
8
+
9
+ module PhantomJS
10
+
11
+ def self.path=(path)
12
+ Platform.assert_executable path
13
+ @path = path
14
+ end
15
+
16
+ def self.path
17
+ @path ||= Platform.find_binary("phantomjs")
18
+ end
19
+
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,59 @@
1
+ module Selenium
2
+ module WebDriver
3
+ module PhantomJS
4
+
5
+
6
+ # @api private
7
+ class Bridge < Remote::Bridge
8
+
9
+ def initialize(opts = {})
10
+ http_client = opts.delete(:http_client)
11
+ caps = opts.delete(:desired_capabilities) { Remote::Capabilities.phantomjs }
12
+
13
+ if opts.has_key?(:url)
14
+ url = opts.delete(:url)
15
+ else
16
+ args = opts.delete(:args) || caps['phantomjs.cli.args']
17
+ port = opts.delete(:port)
18
+
19
+ @service = Service.default_service(port)
20
+ @service.start(args)
21
+
22
+ url = @service.uri
23
+ end
24
+
25
+ remote_opts = {
26
+ :url => url,
27
+ :desired_capabilities => caps
28
+ }
29
+
30
+ remote_opts.merge!(:http_client => http_client) if http_client
31
+
32
+ super(remote_opts)
33
+ end
34
+
35
+ def browser
36
+ :phantomjs
37
+ end
38
+
39
+ def driver_extensions
40
+ [
41
+ DriverExtensions::TakesScreenshot,
42
+ DriverExtensions::HasInputDevices
43
+ ]
44
+ end
45
+
46
+ def capabilities
47
+ @capabilities ||= Remote::Capabilities.phantomjs
48
+ end
49
+
50
+ def quit
51
+ super
52
+ ensure
53
+ @service.stop if @service
54
+ end
55
+
56
+ end # Bridge
57
+ end # PhantomJS
58
+ end # WebDriver
59
+ end # Selenium
@@ -0,0 +1,90 @@
1
+ module Selenium
2
+ module WebDriver
3
+ module PhantomJS
4
+
5
+ #
6
+ # @api private
7
+ #
8
+
9
+ class Service
10
+ START_TIMEOUT = 20
11
+ STOP_TIMEOUT = 5
12
+ DEFAULT_PORT = 8910
13
+ MISSING_TEXT = "Unable to find phantomjs executable."
14
+
15
+ attr_reader :uri
16
+
17
+ def self.executable_path
18
+ @executable_path ||= (
19
+ path = PhantomJS.path
20
+ path or raise Error::WebDriverError, MISSING_TEXT
21
+ Platform.assert_executable path
22
+
23
+ path
24
+ )
25
+ end
26
+
27
+ def self.default_service(port = nil)
28
+ new executable_path, port || PortProber.above(DEFAULT_PORT)
29
+ end
30
+
31
+ def initialize(executable_path, port)
32
+ @uri = URI.parse "http://#{Platform.localhost}:#{port}"
33
+ @executable = executable_path
34
+ end
35
+
36
+ def start(args = [])
37
+ if @process && @process.alive?
38
+ raise "already started: #{@uri.inspect} #{@executable.inspect}"
39
+ end
40
+
41
+ @process = create_process(args)
42
+ @process.start
43
+
44
+ socket_poller = SocketPoller.new Platform.localhost, @uri.port, START_TIMEOUT
45
+
46
+ unless socket_poller.connected?
47
+ raise Error::WebDriverError, "unable to connect to phantomjs @ #{@uri} after #{START_TIMEOUT} seconds"
48
+ end
49
+
50
+ Platform.exit_hook { stop } # make sure we don't leave the server running
51
+ end
52
+
53
+ def stop
54
+ return if @process.nil? || @process.exited?
55
+
56
+ Net::HTTP.start(uri.host, uri.port) do |http|
57
+ http.open_timeout = STOP_TIMEOUT / 2
58
+ http.read_timeout = STOP_TIMEOUT / 2
59
+
60
+ http.get("/shutdown")
61
+ end
62
+
63
+ @process.poll_for_exit STOP_TIMEOUT
64
+ rescue ChildProcess::TimeoutError
65
+ # ok, force quit
66
+ @process.stop STOP_TIMEOUT
67
+
68
+ if Platform.jruby? && !$DEBUG
69
+ @process.io.close rescue nil
70
+ end
71
+ end
72
+
73
+ def create_process(args)
74
+ server_command = [@executable, "--webdriver=#{@uri.port}", *args]
75
+ process = ChildProcess.build(*server_command.compact)
76
+
77
+ if $DEBUG == true
78
+ process.io.inherit!
79
+ elsif Platform.jruby?
80
+ # apparently we need to read the output for phantomjs to work on jruby
81
+ process.io.stdout = process.io.stderr = File.new(Platform.null_device, 'w')
82
+ end
83
+
84
+ process
85
+ end
86
+
87
+ end # Service
88
+ end # PhantomJS
89
+ end # WebDriver
90
+ end # Service