bbc-selenium-webdriver 1.17.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.
Files changed (168) hide show
  1. data/CHANGES +473 -0
  2. data/README +31 -0
  3. data/lib/selenium-client.rb +2 -0
  4. data/lib/selenium-webdriver.rb +1 -0
  5. data/lib/selenium/client.rb +37 -0
  6. data/lib/selenium/client/base.rb +118 -0
  7. data/lib/selenium/client/driver.rb +10 -0
  8. data/lib/selenium/client/errors.rb +9 -0
  9. data/lib/selenium/client/extensions.rb +118 -0
  10. data/lib/selenium/client/idiomatic.rb +488 -0
  11. data/lib/selenium/client/javascript_expression_builder.rb +116 -0
  12. data/lib/selenium/client/javascript_frameworks/jquery.rb +13 -0
  13. data/lib/selenium/client/javascript_frameworks/prototype.rb +13 -0
  14. data/lib/selenium/client/legacy_driver.rb +1720 -0
  15. data/lib/selenium/client/protocol.rb +104 -0
  16. data/lib/selenium/client/selenium_helper.rb +34 -0
  17. data/lib/selenium/rake/server_task.rb +157 -0
  18. data/lib/selenium/server.rb +223 -0
  19. data/lib/selenium/webdriver.rb +64 -0
  20. data/lib/selenium/webdriver/android.rb +9 -0
  21. data/lib/selenium/webdriver/android/bridge.rb +51 -0
  22. data/lib/selenium/webdriver/chrome.rb +26 -0
  23. data/lib/selenium/webdriver/chrome/bridge.rb +106 -0
  24. data/lib/selenium/webdriver/chrome/profile.rb +83 -0
  25. data/lib/selenium/webdriver/chrome/service.rb +74 -0
  26. data/lib/selenium/webdriver/common.rb +30 -0
  27. data/lib/selenium/webdriver/common/action_builder.rb +352 -0
  28. data/lib/selenium/webdriver/common/alert.rb +26 -0
  29. data/lib/selenium/webdriver/common/bridge_helper.rb +67 -0
  30. data/lib/selenium/webdriver/common/core_ext/base64.rb +9 -0
  31. data/lib/selenium/webdriver/common/core_ext/dir.rb +42 -0
  32. data/lib/selenium/webdriver/common/core_ext/string.rb +5 -0
  33. data/lib/selenium/webdriver/common/driver.rb +301 -0
  34. data/lib/selenium/webdriver/common/driver_extensions/has_input_devices.rb +39 -0
  35. data/lib/selenium/webdriver/common/driver_extensions/rotatable.rb +44 -0
  36. data/lib/selenium/webdriver/common/driver_extensions/takes_screenshot.rb +43 -0
  37. data/lib/selenium/webdriver/common/driver_extensions/uploads_files.rb +46 -0
  38. data/lib/selenium/webdriver/common/element.rb +262 -0
  39. data/lib/selenium/webdriver/common/error.rb +212 -0
  40. data/lib/selenium/webdriver/common/file_reaper.rb +47 -0
  41. data/lib/selenium/webdriver/common/keyboard.rb +52 -0
  42. data/lib/selenium/webdriver/common/keys.rb +109 -0
  43. data/lib/selenium/webdriver/common/mouse.rb +65 -0
  44. data/lib/selenium/webdriver/common/navigation.rb +43 -0
  45. data/lib/selenium/webdriver/common/options.rb +128 -0
  46. data/lib/selenium/webdriver/common/platform.rb +166 -0
  47. data/lib/selenium/webdriver/common/port_prober.rb +25 -0
  48. data/lib/selenium/webdriver/common/profile_helper.rb +67 -0
  49. data/lib/selenium/webdriver/common/proxy.rb +120 -0
  50. data/lib/selenium/webdriver/common/search_context.rb +92 -0
  51. data/lib/selenium/webdriver/common/socket_poller.rb +100 -0
  52. data/lib/selenium/webdriver/common/target_locator.rb +81 -0
  53. data/lib/selenium/webdriver/common/timeouts.rb +29 -0
  54. data/lib/selenium/webdriver/common/wait.rb +60 -0
  55. data/lib/selenium/webdriver/common/window.rb +96 -0
  56. data/lib/selenium/webdriver/common/zipper.rb +82 -0
  57. data/lib/selenium/webdriver/firefox.rb +37 -0
  58. data/lib/selenium/webdriver/firefox/binary.rb +161 -0
  59. data/lib/selenium/webdriver/firefox/bridge.rb +58 -0
  60. data/lib/selenium/webdriver/firefox/extension.rb +52 -0
  61. data/lib/selenium/webdriver/firefox/extension/webdriver.xpi +0 -0
  62. data/lib/selenium/webdriver/firefox/launcher.rb +104 -0
  63. data/lib/selenium/webdriver/firefox/native/linux/amd64/x_ignore_nofocus.so +0 -0
  64. data/lib/selenium/webdriver/firefox/native/linux/x86/x_ignore_nofocus.so +0 -0
  65. data/lib/selenium/webdriver/firefox/profile.rb +315 -0
  66. data/lib/selenium/webdriver/firefox/profiles_ini.rb +62 -0
  67. data/lib/selenium/webdriver/firefox/socket_lock.rb +61 -0
  68. data/lib/selenium/webdriver/firefox/util.rb +29 -0
  69. data/lib/selenium/webdriver/ie.rb +19 -0
  70. data/lib/selenium/webdriver/ie/bridge.rb +60 -0
  71. data/lib/selenium/webdriver/ie/native/win32/IEDriver.dll +0 -0
  72. data/lib/selenium/webdriver/ie/native/x64/IEDriver.dll +0 -0
  73. data/lib/selenium/webdriver/ie/server.rb +64 -0
  74. data/lib/selenium/webdriver/iphone.rb +9 -0
  75. data/lib/selenium/webdriver/iphone/bridge.rb +50 -0
  76. data/lib/selenium/webdriver/opera.rb +24 -0
  77. data/lib/selenium/webdriver/opera/bridge.rb +113 -0
  78. data/lib/selenium/webdriver/opera/service.rb +49 -0
  79. data/lib/selenium/webdriver/remote.rb +21 -0
  80. data/lib/selenium/webdriver/remote/bridge.rb +473 -0
  81. data/lib/selenium/webdriver/remote/capabilities.rb +241 -0
  82. data/lib/selenium/webdriver/remote/commands.rb +181 -0
  83. data/lib/selenium/webdriver/remote/http/common.rb +74 -0
  84. data/lib/selenium/webdriver/remote/http/curb.rb +79 -0
  85. data/lib/selenium/webdriver/remote/http/default.rb +102 -0
  86. data/lib/selenium/webdriver/remote/http/persistent.rb +38 -0
  87. data/lib/selenium/webdriver/remote/response.rb +99 -0
  88. data/lib/selenium/webdriver/remote/server_error.rb +17 -0
  89. data/lib/selenium/webdriver/support.rb +4 -0
  90. data/lib/selenium/webdriver/support/abstract_event_listener.rb +28 -0
  91. data/lib/selenium/webdriver/support/block_event_listener.rb +17 -0
  92. data/lib/selenium/webdriver/support/event_firing_bridge.rb +112 -0
  93. data/lib/selenium/webdriver/support/select.rb +293 -0
  94. data/spec/integration/selenium/client/api/backward_compatible_api_spec.rb +22 -0
  95. data/spec/integration/selenium/client/api/browser_xpath_library_spec.rb +17 -0
  96. data/spec/integration/selenium/client/api/click_spec.rb +39 -0
  97. data/spec/integration/selenium/client/api/cookie_spec.rb +39 -0
  98. data/spec/integration/selenium/client/api/element_spec.rb +14 -0
  99. data/spec/integration/selenium/client/api/highlight_located_element_spec.rb +19 -0
  100. data/spec/integration/selenium/client/api/retrieve_last_remote_control_logs_spec.rb +33 -0
  101. data/spec/integration/selenium/client/api/screenshot_spec.rb +29 -0
  102. data/spec/integration/selenium/client/api/select_window_spec.rb +46 -0
  103. data/spec/integration/selenium/client/api/start_stop_spec.rb +9 -0
  104. data/spec/integration/selenium/client/api/wait_for_ajax_spec.rb +27 -0
  105. data/spec/integration/selenium/client/api/wait_for_element_spec.rb +56 -0
  106. data/spec/integration/selenium/client/api/wait_for_field_value_spec.rb +52 -0
  107. data/spec/integration/selenium/client/api/wait_for_text_spec.rb +98 -0
  108. data/spec/integration/selenium/client/sample-app/public/jquery-1.3.2.js +4376 -0
  109. data/spec/integration/selenium/client/sample-app/public/jquery.html +55 -0
  110. data/spec/integration/selenium/client/sample-app/public/prototype-1.6.0.3.js +4320 -0
  111. data/spec/integration/selenium/client/sample-app/public/prototype.html +59 -0
  112. data/spec/integration/selenium/client/sample-app/sample_app.rb +32 -0
  113. data/spec/integration/selenium/client/spec_helper.rb +125 -0
  114. data/spec/integration/selenium/webdriver/chrome/driver_spec.rb +28 -0
  115. data/spec/integration/selenium/webdriver/chrome/profile_spec.rb +42 -0
  116. data/spec/integration/selenium/webdriver/driver_spec.rb +253 -0
  117. data/spec/integration/selenium/webdriver/element_spec.rb +185 -0
  118. data/spec/integration/selenium/webdriver/error_spec.rb +30 -0
  119. data/spec/integration/selenium/webdriver/firefox/driver_spec.rb +21 -0
  120. data/spec/integration/selenium/webdriver/firefox/profile_spec.rb +141 -0
  121. data/spec/integration/selenium/webdriver/keyboard_spec.rb +57 -0
  122. data/spec/integration/selenium/webdriver/mouse_spec.rb +55 -0
  123. data/spec/integration/selenium/webdriver/navigation_spec.rb +44 -0
  124. data/spec/integration/selenium/webdriver/opera/driver_spec.rb +47 -0
  125. data/spec/integration/selenium/webdriver/options_spec.rb +49 -0
  126. data/spec/integration/selenium/webdriver/remote/element_spec.rb +24 -0
  127. data/spec/integration/selenium/webdriver/spec_helper.rb +44 -0
  128. data/spec/integration/selenium/webdriver/spec_support.rb +13 -0
  129. data/spec/integration/selenium/webdriver/spec_support/guards.rb +86 -0
  130. data/spec/integration/selenium/webdriver/spec_support/helpers.rb +46 -0
  131. data/spec/integration/selenium/webdriver/spec_support/jruby_test_environment.rb +29 -0
  132. data/spec/integration/selenium/webdriver/spec_support/rack_server.rb +123 -0
  133. data/spec/integration/selenium/webdriver/spec_support/test_environment.rb +199 -0
  134. data/spec/integration/selenium/webdriver/target_locator_spec.rb +170 -0
  135. data/spec/integration/selenium/webdriver/timeout_spec.rb +56 -0
  136. data/spec/integration/selenium/webdriver/window_spec.rb +56 -0
  137. data/spec/integration/selenium/webdriver/zipper_spec.rb +66 -0
  138. data/spec/unit/selenium/client/base_spec.rb +239 -0
  139. data/spec/unit/selenium/client/extensions_spec.rb +174 -0
  140. data/spec/unit/selenium/client/idiomatic_spec.rb +500 -0
  141. data/spec/unit/selenium/client/javascript_expression_builder_spec.rb +79 -0
  142. data/spec/unit/selenium/client/javascript_frameworks/jquery_spec.rb +10 -0
  143. data/spec/unit/selenium/client/javascript_frameworks/prototype_spec.rb +10 -0
  144. data/spec/unit/selenium/client/protocol_spec.rb +124 -0
  145. data/spec/unit/selenium/client/selenium_helper_spec.rb +56 -0
  146. data/spec/unit/selenium/client/spec_helper.rb +24 -0
  147. data/spec/unit/selenium/rake/task_spec.rb +79 -0
  148. data/spec/unit/selenium/server_spec.rb +131 -0
  149. data/spec/unit/selenium/webdriver/action_builder_spec.rb +90 -0
  150. data/spec/unit/selenium/webdriver/android/bridge_spec.rb +31 -0
  151. data/spec/unit/selenium/webdriver/chrome/bridge_spec.rb +94 -0
  152. data/spec/unit/selenium/webdriver/chrome/profile_spec.rb +57 -0
  153. data/spec/unit/selenium/webdriver/chrome/service_spec.rb +44 -0
  154. data/spec/unit/selenium/webdriver/error_spec.rb +41 -0
  155. data/spec/unit/selenium/webdriver/firefox/bridge_spec.rb +17 -0
  156. data/spec/unit/selenium/webdriver/iphone/bridge_spec.rb +30 -0
  157. data/spec/unit/selenium/webdriver/proxy_spec.rb +87 -0
  158. data/spec/unit/selenium/webdriver/remote/bridge_spec.rb +16 -0
  159. data/spec/unit/selenium/webdriver/remote/capabilities_spec.rb +111 -0
  160. data/spec/unit/selenium/webdriver/remote/http/common_spec.rb +24 -0
  161. data/spec/unit/selenium/webdriver/remote/http/default_spec.rb +46 -0
  162. data/spec/unit/selenium/webdriver/search_context_spec.rb +61 -0
  163. data/spec/unit/selenium/webdriver/socket_poller_spec.rb +68 -0
  164. data/spec/unit/selenium/webdriver/spec_helper.rb +6 -0
  165. data/spec/unit/selenium/webdriver/support/event_firing_spec.rb +111 -0
  166. data/spec/unit/selenium/webdriver/support/select_spec.rb +290 -0
  167. data/spec/unit/selenium/webdriver/wait_spec.rb +40 -0
  168. metadata +215 -0
@@ -0,0 +1,64 @@
1
+ require 'childprocess'
2
+ require 'tmpdir'
3
+ require 'fileutils'
4
+ require 'date'
5
+
6
+ require 'multi_json'
7
+ require 'selenium/webdriver/common'
8
+
9
+ module Selenium
10
+ module WebDriver
11
+ Point = Struct.new(:x, :y)
12
+ Dimension = Struct.new(:width, :height)
13
+
14
+ autoload :Android, 'selenium/webdriver/android'
15
+ autoload :Chrome, 'selenium/webdriver/chrome'
16
+ autoload :Firefox, 'selenium/webdriver/firefox'
17
+ autoload :IE, 'selenium/webdriver/ie'
18
+ autoload :IPhone, 'selenium/webdriver/iphone'
19
+ autoload :Opera, 'selenium/webdriver/opera'
20
+ autoload :Remote, 'selenium/webdriver/remote'
21
+ autoload :Support, 'selenium/webdriver/support'
22
+
23
+ # @api private
24
+
25
+ def self.root
26
+ @root ||= File.expand_path("../..", __FILE__)
27
+ end
28
+
29
+ #
30
+ # Create a new Driver instance with the correct bridge for the given browser
31
+ #
32
+ # @param browser [:ie, :internet_explorer, :remote, :chrome, :firefox, :ff, :android, :iphone, :opera]
33
+ # the driver type to use
34
+ # @param *rest
35
+ # arguments passed to Bridge.new
36
+ #
37
+ # @return [Driver]
38
+ #
39
+ # @see Selenium::WebDriver::Remote::Bridge
40
+ # @see Selenium::WebDriver::Firefox::Bridge
41
+ # @see Selenium::WebDriver::IE::Bridge
42
+ # @see Selenium::WebDriver::Chrome::Bridge
43
+ # @see Selenium::WebDriver::Android::Bridge
44
+ # @see Selenium::WebDriver::IPhone::Bridge
45
+ # @see Selenium::WebDriver::Opera::Bridge
46
+ #
47
+ # @example
48
+ #
49
+ # WebDriver.for :firefox, :profile => "some-profile"
50
+ # WebDriver.for :firefox, :profile => Profile.new
51
+ # WebDriver.for :remote, :url => "http://localhost:4444/wd/hub", :desired_capabilities => caps
52
+ #
53
+ # One special argument is not passed on to the bridges, :listener. You can pass a listener for this option
54
+ # to get notified of WebDriver events. The passed object must respond to #call or implement the methods from AbstractEventListener.
55
+ #
56
+ # @see Selenium::WebDriver::Support::AbstractEventListener
57
+ #
58
+
59
+ def self.for(*args)
60
+ WebDriver::Driver.for(*args)
61
+ end
62
+
63
+ end # WebDriver
64
+ end # Selenium
@@ -0,0 +1,9 @@
1
+ module Selenium
2
+ module WebDriver
3
+ module Android
4
+
5
+ end # Android
6
+ end # WebDriver
7
+ end # Selenium
8
+
9
+ require 'selenium/webdriver/android/bridge'
@@ -0,0 +1,51 @@
1
+ module Selenium
2
+ module WebDriver
3
+ module Android
4
+
5
+ #
6
+ # @api private
7
+ #
8
+
9
+ class Bridge < Remote::Bridge
10
+
11
+ DEFAULT_URL = "http://#{Platform.localhost}:8080/wd/hub/"
12
+
13
+ def initialize(opts = {})
14
+ remote_opts = {
15
+ :url => opts.fetch(:url, DEFAULT_URL),
16
+ :desired_capabilities => opts.fetch(:desired_capabilities, capabilities),
17
+ }
18
+
19
+ remote_opts[:http_client] = opts[:http_client] if opts.has_key?(:http_client)
20
+
21
+ super remote_opts
22
+ end
23
+
24
+ def browser
25
+ :android
26
+ end
27
+
28
+ def driver_extensions
29
+ [
30
+ DriverExtensions::TakesScreenshot,
31
+ DriverExtensions::Rotatable,
32
+ DriverExtensions::HasInputDevices
33
+ ]
34
+ end
35
+
36
+ def setScreenOrientation(orientation)
37
+ execute :setScreenOrientation, {}, :orientation => orientation
38
+ end
39
+
40
+ def getScreenOrientation
41
+ execute :getScreenOrientation
42
+ end
43
+
44
+ def capabilities
45
+ @capabilities ||= Remote::Capabilities.android
46
+ end
47
+
48
+ end # Bridge
49
+ end # Android
50
+ end # WebDriver
51
+ end # Selenium
@@ -0,0 +1,26 @@
1
+ require 'net/http'
2
+
3
+ require 'selenium/webdriver/chrome/service'
4
+ require 'selenium/webdriver/chrome/bridge'
5
+ require 'selenium/webdriver/chrome/profile'
6
+
7
+ module Selenium
8
+ module WebDriver
9
+
10
+ module Chrome
11
+ def self.driver_path=(path)
12
+ Service.executable_path = path
13
+ end
14
+
15
+ def self.path=(path)
16
+ Platform.assert_executable path
17
+ @path = path
18
+ end
19
+
20
+ def self.path
21
+ @path ||= nil
22
+ end
23
+
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,106 @@
1
+ module Selenium
2
+ module WebDriver
3
+ module Chrome
4
+
5
+ # @api private
6
+ class Bridge < Remote::Bridge
7
+
8
+ def initialize(opts = {})
9
+ http_client = opts.delete(:http_client)
10
+
11
+ if opts.has_key?(:url)
12
+ url = opts.delete(:url)
13
+ else
14
+ @service = Service.default_service
15
+ @service.start
16
+
17
+ url = @service.uri
18
+ end
19
+
20
+ caps = create_capabilities(opts)
21
+
22
+ remote_opts = {
23
+ :url => url,
24
+ :desired_capabilities => caps
25
+ }
26
+
27
+ remote_opts.merge!(:http_client => http_client) if http_client
28
+
29
+ super(remote_opts)
30
+ end
31
+
32
+ def browser
33
+ :chrome
34
+ end
35
+
36
+ def driver_extensions
37
+ [
38
+ DriverExtensions::TakesScreenshot,
39
+ DriverExtensions::HasInputDevices
40
+ ]
41
+ end
42
+
43
+ def capabilities
44
+ @capabilities ||= Remote::Capabilities.chrome
45
+ end
46
+
47
+ def quit
48
+ super
49
+ ensure
50
+ @service.stop if @service
51
+ end
52
+
53
+ private
54
+
55
+ def create_capabilities(opts)
56
+ args = opts.delete(:args) || opts.delete(:switches)
57
+ native_events = opts.delete(:native_events)
58
+ verbose = opts.delete(:verbose)
59
+ profile = opts.delete(:profile)
60
+ detach = opts.delete(:detach)
61
+ proxy = opts.delete(:proxy)
62
+
63
+ unless opts.empty?
64
+ raise ArgumentError, "unknown option#{'s' if opts.size != 1}: #{opts.inspect}"
65
+ end
66
+
67
+ chrome_options = {}
68
+
69
+ if args
70
+ unless args.kind_of? Array
71
+ raise ArgumentError, ":args must be an Array of Strings"
72
+ end
73
+
74
+ chrome_options['args'] = args.map { |e| e.to_s }
75
+ end
76
+
77
+ if profile
78
+ data = profile.as_json
79
+
80
+ chrome_options.merge! 'profile' => data['zip'],
81
+ 'extensions' => data['extensions']
82
+ end
83
+
84
+
85
+ chrome_options['binary'] = Chrome.path if Chrome.path
86
+ chrome_options['nativeEvents'] = true if native_events
87
+ chrome_options['verbose'] = true if verbose
88
+ chrome_options['detach'] = detach.nil? || !!detach
89
+
90
+ caps = Remote::Capabilities.chrome
91
+ caps['chromeOptions'] = chrome_options
92
+ caps['proxy'] = proxy if proxy
93
+
94
+ # legacy options - for chromedriver < 17.0.963.0
95
+ caps["chrome.switches"] = chrome_options['args'] if chrome_options.member?('args')
96
+ %w[binary detach extensions nativeEvents profile verbose].each do |key|
97
+ caps["chrome.#{key}"] = chrome_options[key] if chrome_options.member?(key)
98
+ end
99
+
100
+ caps
101
+ end
102
+
103
+ end # Bridge
104
+ end # Chrome
105
+ end # WebDriver
106
+ end # Selenium
@@ -0,0 +1,83 @@
1
+ module Selenium
2
+ module WebDriver
3
+ module Chrome
4
+
5
+ #
6
+ # @private
7
+ #
8
+
9
+ class Profile
10
+ include ProfileHelper
11
+
12
+ def initialize(model = nil)
13
+ @model = verify_model(model)
14
+ @extensions = []
15
+ end
16
+
17
+ def add_extension(path)
18
+ unless File.file?(path)
19
+ raise Error::WebDriverError, "could not find extension at #{path.inspect}"
20
+ end
21
+
22
+ @extensions << path
23
+ end
24
+
25
+ #
26
+ # Set a preference in the profile.
27
+ #
28
+ # See http://codesearch.google.com/codesearch#OAMlx_jo-ck/src/chrome/common/pref_names.cc&exact_package=chromium
29
+ #
30
+
31
+ def []=(key, value)
32
+ parts = key.split(".")
33
+ parts[0..-2].inject(prefs) { |pr, k| pr[k] ||= {} }[parts.last] = value
34
+ end
35
+
36
+ def [](key)
37
+ parts = key.split(".")
38
+ parts.inject(prefs) { |pr, k| pr.fetch(k) }
39
+ end
40
+
41
+ def layout_on_disk
42
+ dir = @model ? create_tmp_copy(@model) : Dir.mktmpdir("webdriver-chrome-profile")
43
+ FileReaper << dir
44
+
45
+ write_prefs_to dir
46
+
47
+ dir
48
+ end
49
+
50
+ def as_json(opts = nil)
51
+ extensions = @extensions.map do |crx_path|
52
+ Base64.strict_encode64 File.read(crx_path)
53
+ end
54
+
55
+ super.merge('extensions' => extensions)
56
+ end
57
+
58
+ private
59
+
60
+ def write_prefs_to(dir)
61
+ prefs_file = prefs_file_for(dir)
62
+
63
+ FileUtils.mkdir_p File.dirname(prefs_file)
64
+ File.open(prefs_file, "w") { |file| file << MultiJson.encode(prefs) }
65
+ end
66
+
67
+ def prefs
68
+ @prefs ||= read_model_prefs
69
+ end
70
+
71
+ def read_model_prefs
72
+ return {} unless @model
73
+ MultiJson.decode File.read(prefs_file_for(@model))
74
+ end
75
+
76
+ def prefs_file_for(dir)
77
+ File.join dir, 'Default', 'Preferences'
78
+ end
79
+ end # Profile
80
+
81
+ end # Chrome
82
+ end # WebDriver
83
+ end # Selenium
@@ -0,0 +1,74 @@
1
+ module Selenium
2
+ module WebDriver
3
+ module Chrome
4
+
5
+ #
6
+ # @api private
7
+ #
8
+
9
+ class Service
10
+ START_TIMEOUT = 20
11
+ STOP_TIMEOUT = 5
12
+ MISSING_TEXT = "Unable to find the chromedriver executable. Please download the server from http://code.google.com/p/chromium/downloads/list and place it somewhere on your PATH. More info at http://code.google.com/p/selenium/wiki/ChromeDriver."
13
+
14
+ attr_reader :uri
15
+
16
+ def self.executable_path
17
+ @executable_path ||= (
18
+ path = Platform.find_binary "chromedriver"
19
+ path or raise Error::WebDriverError, MISSING_TEXT
20
+ Platform.assert_executable path
21
+
22
+ path
23
+ )
24
+ end
25
+
26
+ def self.executable_path=(path)
27
+ Platform.assert_executable path
28
+ @executable_path = path
29
+ end
30
+
31
+ def self.default_service
32
+ new executable_path, PortProber.random
33
+ end
34
+
35
+ def initialize(executable_path, port)
36
+ @uri = URI.parse "http://#{Platform.localhost}:#{port}"
37
+ server_command = [executable_path, "--port=#{port}"]
38
+
39
+ @process = ChildProcess.build(*server_command)
40
+ @socket_poller = SocketPoller.new Platform.localhost, port, START_TIMEOUT
41
+
42
+ @process.io.inherit! if $DEBUG == true
43
+ end
44
+
45
+ def start
46
+ @process.start
47
+
48
+ unless @socket_poller.connected?
49
+ raise Error::WebDriverError, "unable to connect to chromedriver #{@uri}"
50
+ end
51
+
52
+ Platform.exit_hook { stop } # make sure we don't leave the server running
53
+ end
54
+
55
+ def stop
56
+ return if @process.nil? || @process.exited?
57
+
58
+ Net::HTTP.start(uri.host, uri.port) do |http|
59
+ http.open_timeout = STOP_TIMEOUT / 2
60
+ http.read_timeout = STOP_TIMEOUT / 2
61
+
62
+ http.head("/shutdown")
63
+ end
64
+
65
+ @process.poll_for_exit STOP_TIMEOUT
66
+ rescue ChildProcess::TimeoutError
67
+ # ok, force quit
68
+ @process.stop STOP_TIMEOUT
69
+ end
70
+ end # Service
71
+
72
+ end # Chrome
73
+ end # WebDriver
74
+ end # Service
@@ -0,0 +1,30 @@
1
+ require 'selenium/webdriver/common/core_ext/dir'
2
+ require 'selenium/webdriver/common/core_ext/string'
3
+ require 'selenium/webdriver/common/core_ext/base64'
4
+ require 'selenium/webdriver/common/error'
5
+ require 'selenium/webdriver/common/platform'
6
+ require 'selenium/webdriver/common/proxy'
7
+ require 'selenium/webdriver/common/file_reaper'
8
+ require 'selenium/webdriver/common/socket_poller'
9
+ require 'selenium/webdriver/common/port_prober'
10
+ require 'selenium/webdriver/common/zipper'
11
+ require 'selenium/webdriver/common/wait'
12
+ require 'selenium/webdriver/common/alert'
13
+ require 'selenium/webdriver/common/mouse'
14
+ require 'selenium/webdriver/common/keyboard'
15
+ require 'selenium/webdriver/common/target_locator'
16
+ require 'selenium/webdriver/common/navigation'
17
+ require 'selenium/webdriver/common/timeouts'
18
+ require 'selenium/webdriver/common/window'
19
+ require 'selenium/webdriver/common/options'
20
+ require 'selenium/webdriver/common/search_context'
21
+ require 'selenium/webdriver/common/action_builder'
22
+ require 'selenium/webdriver/common/driver_extensions/takes_screenshot'
23
+ require 'selenium/webdriver/common/driver_extensions/rotatable'
24
+ require 'selenium/webdriver/common/driver_extensions/has_input_devices'
25
+ require 'selenium/webdriver/common/driver_extensions/uploads_files'
26
+ require 'selenium/webdriver/common/keys'
27
+ require 'selenium/webdriver/common/bridge_helper'
28
+ require 'selenium/webdriver/common/profile_helper'
29
+ require 'selenium/webdriver/common/driver'
30
+ require 'selenium/webdriver/common/element'