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.
- checksums.yaml +7 -0
- data/CHANGES +791 -0
- data/README.md +31 -0
- data/build.desc +334 -0
- data/lib/selenium-client.rb +2 -0
- data/lib/selenium-webdriver.rb +1 -0
- data/lib/selenium/client.rb +37 -0
- data/lib/selenium/client/base.rb +132 -0
- data/lib/selenium/client/driver.rb +10 -0
- data/lib/selenium/client/errors.rb +9 -0
- data/lib/selenium/client/extensions.rb +118 -0
- data/lib/selenium/client/idiomatic.rb +488 -0
- data/lib/selenium/client/javascript_expression_builder.rb +116 -0
- data/lib/selenium/client/javascript_frameworks/jquery.rb +13 -0
- data/lib/selenium/client/javascript_frameworks/prototype.rb +13 -0
- data/lib/selenium/client/legacy_driver.rb +1720 -0
- data/lib/selenium/client/protocol.rb +104 -0
- data/lib/selenium/client/selenium_helper.rb +34 -0
- data/lib/selenium/rake/server_task.rb +157 -0
- data/lib/selenium/server.rb +248 -0
- data/lib/selenium/webdriver.rb +71 -0
- data/lib/selenium/webdriver/android.rb +9 -0
- data/lib/selenium/webdriver/android/bridge.rb +47 -0
- data/lib/selenium/webdriver/chrome.rb +26 -0
- data/lib/selenium/webdriver/chrome/bridge.rb +120 -0
- data/lib/selenium/webdriver/chrome/profile.rb +90 -0
- data/lib/selenium/webdriver/chrome/service.rb +75 -0
- data/lib/selenium/webdriver/common.rb +44 -0
- data/lib/selenium/webdriver/common/action_builder.rb +352 -0
- data/lib/selenium/webdriver/common/alert.rb +30 -0
- data/lib/selenium/webdriver/common/bridge_helper.rb +67 -0
- data/lib/selenium/webdriver/common/core_ext/base64.rb +9 -0
- data/lib/selenium/webdriver/common/core_ext/dir.rb +42 -0
- data/lib/selenium/webdriver/common/core_ext/string.rb +5 -0
- data/lib/selenium/webdriver/common/driver.rb +301 -0
- data/lib/selenium/webdriver/common/driver_extensions/has_browser_connection.rb +17 -0
- data/lib/selenium/webdriver/common/driver_extensions/has_input_devices.rb +39 -0
- data/lib/selenium/webdriver/common/driver_extensions/has_location.rb +25 -0
- data/lib/selenium/webdriver/common/driver_extensions/has_remote_status.rb +13 -0
- data/lib/selenium/webdriver/common/driver_extensions/has_session_id.rb +22 -0
- data/lib/selenium/webdriver/common/driver_extensions/has_touch_screen.rb +19 -0
- data/lib/selenium/webdriver/common/driver_extensions/has_web_storage.rb +22 -0
- data/lib/selenium/webdriver/common/driver_extensions/rotatable.rb +45 -0
- data/lib/selenium/webdriver/common/driver_extensions/takes_screenshot.rb +43 -0
- data/lib/selenium/webdriver/common/driver_extensions/uploads_files.rb +46 -0
- data/lib/selenium/webdriver/common/element.rb +293 -0
- data/lib/selenium/webdriver/common/error.rb +207 -0
- data/lib/selenium/webdriver/common/file_reaper.rb +47 -0
- data/lib/selenium/webdriver/common/html5/local_storage.rb +42 -0
- data/lib/selenium/webdriver/common/html5/location.rb +0 -0
- data/lib/selenium/webdriver/common/html5/session_storage.rb +44 -0
- data/lib/selenium/webdriver/common/html5/shared_web_storage.rb +42 -0
- data/lib/selenium/webdriver/common/json_helper.rb +34 -0
- data/lib/selenium/webdriver/common/keyboard.rb +55 -0
- data/lib/selenium/webdriver/common/keys.rb +109 -0
- data/lib/selenium/webdriver/common/log_entry.rb +29 -0
- data/lib/selenium/webdriver/common/logs.rb +23 -0
- data/lib/selenium/webdriver/common/mouse.rb +72 -0
- data/lib/selenium/webdriver/common/navigation.rb +43 -0
- data/lib/selenium/webdriver/common/options.rb +136 -0
- data/lib/selenium/webdriver/common/platform.rb +218 -0
- data/lib/selenium/webdriver/common/port_prober.rb +42 -0
- data/lib/selenium/webdriver/common/profile_helper.rb +67 -0
- data/lib/selenium/webdriver/common/proxy.rb +149 -0
- data/lib/selenium/webdriver/common/search_context.rb +92 -0
- data/lib/selenium/webdriver/common/socket_poller.rb +105 -0
- data/lib/selenium/webdriver/common/target_locator.rb +81 -0
- data/lib/selenium/webdriver/common/timeouts.rb +38 -0
- data/lib/selenium/webdriver/common/touch_action_builder.rb +64 -0
- data/lib/selenium/webdriver/common/touch_screen.rb +105 -0
- data/lib/selenium/webdriver/common/wait.rb +63 -0
- data/lib/selenium/webdriver/common/window.rb +104 -0
- data/lib/selenium/webdriver/common/zipper.rb +82 -0
- data/lib/selenium/webdriver/firefox.rb +37 -0
- data/lib/selenium/webdriver/firefox/binary.rb +158 -0
- data/lib/selenium/webdriver/firefox/bridge.rb +70 -0
- data/lib/selenium/webdriver/firefox/extension.rb +52 -0
- data/lib/selenium/webdriver/firefox/launcher.rb +106 -0
- data/lib/selenium/webdriver/firefox/profile.rb +263 -0
- data/lib/selenium/webdriver/firefox/profiles_ini.rb +62 -0
- data/lib/selenium/webdriver/firefox/socket_lock.rb +61 -0
- data/lib/selenium/webdriver/firefox/util.rb +29 -0
- data/lib/selenium/webdriver/ie.rb +19 -0
- data/lib/selenium/webdriver/ie/bridge.rb +68 -0
- data/lib/selenium/webdriver/ie/server.rb +86 -0
- data/lib/selenium/webdriver/iphone.rb +9 -0
- data/lib/selenium/webdriver/iphone/bridge.rb +45 -0
- data/lib/selenium/webdriver/opera.rb +24 -0
- data/lib/selenium/webdriver/opera/bridge.rb +112 -0
- data/lib/selenium/webdriver/opera/service.rb +49 -0
- data/lib/selenium/webdriver/phantomjs.rb +22 -0
- data/lib/selenium/webdriver/phantomjs/bridge.rb +59 -0
- data/lib/selenium/webdriver/phantomjs/service.rb +90 -0
- data/lib/selenium/webdriver/remote.rb +22 -0
- data/lib/selenium/webdriver/remote/bridge.rb +644 -0
- data/lib/selenium/webdriver/remote/capabilities.rb +267 -0
- data/lib/selenium/webdriver/remote/commands.rb +193 -0
- data/lib/selenium/webdriver/remote/http/common.rb +74 -0
- data/lib/selenium/webdriver/remote/http/curb.rb +79 -0
- data/lib/selenium/webdriver/remote/http/default.rb +139 -0
- data/lib/selenium/webdriver/remote/http/persistent.rb +38 -0
- data/lib/selenium/webdriver/remote/response.rb +97 -0
- data/lib/selenium/webdriver/remote/server_error.rb +17 -0
- data/lib/selenium/webdriver/safari.rb +46 -0
- data/lib/selenium/webdriver/safari/bridge.rb +110 -0
- data/lib/selenium/webdriver/safari/browser.rb +20 -0
- data/lib/selenium/webdriver/safari/extension.rb +120 -0
- data/lib/selenium/webdriver/safari/server.rb +145 -0
- data/lib/selenium/webdriver/support.rb +5 -0
- data/lib/selenium/webdriver/support/abstract_event_listener.rb +28 -0
- data/lib/selenium/webdriver/support/block_event_listener.rb +17 -0
- data/lib/selenium/webdriver/support/color.rb +110 -0
- data/lib/selenium/webdriver/support/event_firing_bridge.rb +112 -0
- data/lib/selenium/webdriver/support/select.rb +293 -0
- data/ruby.iml +13 -0
- data/spec/integration/selenium/client/api/backward_compatible_api_spec.rb +22 -0
- data/spec/integration/selenium/client/api/browser_xpath_library_spec.rb +17 -0
- data/spec/integration/selenium/client/api/click_spec.rb +39 -0
- data/spec/integration/selenium/client/api/cookie_spec.rb +39 -0
- data/spec/integration/selenium/client/api/element_spec.rb +14 -0
- data/spec/integration/selenium/client/api/highlight_located_element_spec.rb +19 -0
- data/spec/integration/selenium/client/api/retrieve_last_remote_control_logs_spec.rb +33 -0
- data/spec/integration/selenium/client/api/screenshot_spec.rb +31 -0
- data/spec/integration/selenium/client/api/select_window_spec.rb +46 -0
- data/spec/integration/selenium/client/api/start_stop_spec.rb +9 -0
- data/spec/integration/selenium/client/api/wait_for_ajax_spec.rb +27 -0
- data/spec/integration/selenium/client/api/wait_for_element_spec.rb +56 -0
- data/spec/integration/selenium/client/api/wait_for_field_value_spec.rb +52 -0
- data/spec/integration/selenium/client/api/wait_for_text_spec.rb +98 -0
- data/spec/integration/selenium/client/api/webdriver_backed_spec.rb +21 -0
- data/spec/integration/selenium/client/sample-app/public/jquery-1.3.2.js +4376 -0
- data/spec/integration/selenium/client/sample-app/public/jquery.html +55 -0
- data/spec/integration/selenium/client/sample-app/public/prototype-1.6.0.3.js +4320 -0
- data/spec/integration/selenium/client/sample-app/public/prototype.html +59 -0
- data/spec/integration/selenium/client/sample-app/sample_app.rb +32 -0
- data/spec/integration/selenium/client/spec_helper.rb +139 -0
- data/spec/integration/selenium/webdriver/app_cache_spec.rb +47 -0
- data/spec/integration/selenium/webdriver/browser_connection_spec.rb +20 -0
- data/spec/integration/selenium/webdriver/chrome/driver_spec.rb +28 -0
- data/spec/integration/selenium/webdriver/chrome/profile_spec.rb +63 -0
- data/spec/integration/selenium/webdriver/driver_spec.rb +266 -0
- data/spec/integration/selenium/webdriver/element_spec.rb +191 -0
- data/spec/integration/selenium/webdriver/error_spec.rb +30 -0
- data/spec/integration/selenium/webdriver/firefox/driver_spec.rb +21 -0
- data/spec/integration/selenium/webdriver/firefox/profile_spec.rb +141 -0
- data/spec/integration/selenium/webdriver/keyboard_spec.rb +57 -0
- data/spec/integration/selenium/webdriver/location_spec.rb +29 -0
- data/spec/integration/selenium/webdriver/mouse_spec.rb +57 -0
- data/spec/integration/selenium/webdriver/navigation_spec.rb +46 -0
- data/spec/integration/selenium/webdriver/opera/driver_spec.rb +47 -0
- data/spec/integration/selenium/webdriver/options_spec.rb +77 -0
- data/spec/integration/selenium/webdriver/remote/driver_spec.rb +19 -0
- data/spec/integration/selenium/webdriver/remote/element_spec.rb +26 -0
- data/spec/integration/selenium/webdriver/spec_helper.rb +36 -0
- data/spec/integration/selenium/webdriver/spec_support.rb +12 -0
- data/spec/integration/selenium/webdriver/spec_support/guards.rb +110 -0
- data/spec/integration/selenium/webdriver/spec_support/helpers.rb +51 -0
- data/spec/integration/selenium/webdriver/spec_support/rack_server.rb +123 -0
- data/spec/integration/selenium/webdriver/spec_support/test_environment.rb +239 -0
- data/spec/integration/selenium/webdriver/sql_database_spec.rb +59 -0
- data/spec/integration/selenium/webdriver/storage_spec.rb +96 -0
- data/spec/integration/selenium/webdriver/target_locator_spec.rb +186 -0
- data/spec/integration/selenium/webdriver/timeout_spec.rb +69 -0
- data/spec/integration/selenium/webdriver/touch_spec.rb +176 -0
- data/spec/integration/selenium/webdriver/window_spec.rb +70 -0
- data/spec/integration/selenium/webdriver/zipper_spec.rb +66 -0
- data/spec/unit/selenium/client/base_spec.rb +239 -0
- data/spec/unit/selenium/client/extensions_spec.rb +174 -0
- data/spec/unit/selenium/client/idiomatic_spec.rb +500 -0
- data/spec/unit/selenium/client/javascript_expression_builder_spec.rb +79 -0
- data/spec/unit/selenium/client/javascript_frameworks/jquery_spec.rb +10 -0
- data/spec/unit/selenium/client/javascript_frameworks/prototype_spec.rb +10 -0
- data/spec/unit/selenium/client/protocol_spec.rb +124 -0
- data/spec/unit/selenium/client/selenium_helper_spec.rb +56 -0
- data/spec/unit/selenium/client/spec_helper.rb +24 -0
- data/spec/unit/selenium/rake/task_spec.rb +79 -0
- data/spec/unit/selenium/server_spec.rb +150 -0
- data/spec/unit/selenium/webdriver/action_builder_spec.rb +97 -0
- data/spec/unit/selenium/webdriver/android/bridge_spec.rb +43 -0
- data/spec/unit/selenium/webdriver/chrome/bridge_spec.rb +137 -0
- data/spec/unit/selenium/webdriver/chrome/profile_spec.rb +57 -0
- data/spec/unit/selenium/webdriver/chrome/service_spec.rb +44 -0
- data/spec/unit/selenium/webdriver/error_spec.rb +41 -0
- data/spec/unit/selenium/webdriver/firefox/bridge_spec.rb +47 -0
- data/spec/unit/selenium/webdriver/ie/bridge_spec.rb +91 -0
- data/spec/unit/selenium/webdriver/iphone/bridge_spec.rb +42 -0
- data/spec/unit/selenium/webdriver/log_entry_spec.rb +11 -0
- data/spec/unit/selenium/webdriver/opera/bridge_spec.rb +44 -0
- data/spec/unit/selenium/webdriver/phantomjs/bridge_spec.rb +55 -0
- data/spec/unit/selenium/webdriver/proxy_spec.rb +106 -0
- data/spec/unit/selenium/webdriver/remote/bridge_spec.rb +16 -0
- data/spec/unit/selenium/webdriver/remote/capabilities_spec.rb +115 -0
- data/spec/unit/selenium/webdriver/remote/http/common_spec.rb +24 -0
- data/spec/unit/selenium/webdriver/remote/http/default_spec.rb +124 -0
- data/spec/unit/selenium/webdriver/search_context_spec.rb +61 -0
- data/spec/unit/selenium/webdriver/socket_poller_spec.rb +68 -0
- data/spec/unit/selenium/webdriver/spec_helper.rb +27 -0
- data/spec/unit/selenium/webdriver/support/color_spec.rb +119 -0
- data/spec/unit/selenium/webdriver/support/event_firing_spec.rb +111 -0
- data/spec/unit/selenium/webdriver/support/select_spec.rb +290 -0
- data/spec/unit/selenium/webdriver/wait_spec.rb +49 -0
- 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,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
|