selenium-webdriver 0.0.17 → 0.0.18
Sign up to get free protection for your applications and to get access to all the features.
- data/chrome/prebuilt/Win32/Release/npchromedriver.dll +0 -0
- data/chrome/prebuilt/x64/Release/npchromedriver.dll +0 -0
- data/chrome/src/extension/background.js +64 -48
- data/chrome/src/extension/content_script.js +253 -132
- data/chrome/src/extension/manifest-nonwin.json +1 -1
- data/chrome/src/extension/manifest-win.json +1 -1
- data/chrome/src/extension/utils.js +8 -8
- data/chrome/src/rb/lib/selenium/webdriver/chrome.rb +9 -0
- data/chrome/src/rb/lib/selenium/webdriver/chrome/bridge.rb +38 -280
- data/chrome/src/rb/lib/selenium/webdriver/chrome/command_executor.rb +119 -117
- data/chrome/src/rb/lib/selenium/webdriver/chrome/launcher.rb +36 -26
- data/common/src/js/abstractcommandprocessor.js +9 -11
- data/common/src/js/command.js +159 -83
- data/common/src/js/core/RemoteRunner.html +2 -2
- data/common/src/js/core/TestRunner-splash.html +3 -3
- data/common/src/js/core/TestRunner.html +5 -17
- data/common/src/js/core/scripts/htmlutils.js +4208 -2506
- data/common/src/js/core/scripts/selenium-api.js +2 -2
- data/common/src/js/core/scripts/selenium-browserbot.js +66 -58
- data/common/src/js/core/scripts/selenium-version.js +1 -1
- data/common/src/js/localcommandprocessor.js +5 -19
- data/common/src/js/testcase.js +2 -0
- data/common/src/js/webdriver.js +63 -93
- data/common/src/js/webelement.js +40 -42
- data/common/src/rb/lib/selenium/webdriver.rb +23 -14
- data/common/src/rb/lib/selenium/webdriver/bridge_helper.rb +8 -35
- data/common/src/rb/lib/selenium/webdriver/child_process.rb +2 -0
- data/common/src/rb/lib/selenium/webdriver/core_ext/dir.rb +1 -0
- data/common/src/rb/lib/selenium/webdriver/core_ext/string.rb +5 -0
- data/common/src/rb/lib/selenium/webdriver/driver.rb +20 -15
- data/common/src/rb/lib/selenium/webdriver/driver_extensions/takes_screenshot.rb +7 -2
- data/common/src/rb/lib/selenium/webdriver/element.rb +11 -2
- data/common/src/rb/lib/selenium/webdriver/error.rb +9 -5
- data/common/src/rb/lib/selenium/webdriver/keys.rb +1 -2
- data/common/src/rb/lib/selenium/webdriver/navigation.rb +16 -0
- data/common/src/rb/lib/selenium/webdriver/options.rb +32 -0
- data/common/src/rb/lib/selenium/webdriver/platform.rb +17 -1
- data/firefox/prebuilt/Win32/Release/webdriver-firefox.dll +0 -0
- data/firefox/src/extension/components/dispatcher.js +492 -0
- data/firefox/src/extension/components/driver-component.js +4 -1
- data/firefox/src/extension/components/errorcode.js +70 -0
- data/firefox/src/extension/components/firefoxDriver.js +173 -154
- data/firefox/src/extension/components/nsCommandProcessor.js +171 -132
- data/firefox/src/extension/components/promptService.js +5 -5
- data/firefox/src/extension/components/request.js +219 -0
- data/firefox/src/extension/components/response.js +276 -0
- data/firefox/src/extension/components/session.js +281 -0
- data/firefox/src/extension/components/sessionstore.js +226 -0
- data/firefox/src/extension/components/socketListener.js +350 -100
- data/firefox/src/extension/components/utils.js +166 -98
- data/firefox/src/extension/components/webdriverserver.js +9 -5
- data/firefox/src/extension/components/wrappedElement.js +189 -166
- data/firefox/src/extension/install.rdf +1 -1
- data/firefox/src/rb/lib/selenium/webdriver/firefox.rb +2 -0
- data/firefox/src/rb/lib/selenium/webdriver/firefox/binary.rb +39 -33
- data/firefox/src/rb/lib/selenium/webdriver/firefox/bridge.rb +7 -421
- data/firefox/src/rb/lib/selenium/webdriver/firefox/extension_connection.rb +7 -64
- data/firefox/src/rb/lib/selenium/webdriver/firefox/launcher.rb +2 -3
- data/firefox/src/rb/lib/selenium/webdriver/firefox/profile.rb +54 -10
- data/firefox/src/rb/lib/selenium/webdriver/firefox/profiles_ini.rb +2 -0
- data/firefox/src/rb/lib/selenium/webdriver/firefox/util.rb +6 -0
- data/jobbie/prebuilt/Win32/Release/InternetExplorerDriver.dll +0 -0
- data/jobbie/prebuilt/x64/Release/InternetExplorerDriver.dll +0 -0
- data/jobbie/src/rb/lib/selenium/webdriver/ie.rb +2 -0
- data/jobbie/src/rb/lib/selenium/webdriver/ie/bridge.rb +38 -13
- data/jobbie/src/rb/lib/selenium/webdriver/ie/lib.rb +9 -2
- data/jobbie/src/rb/lib/selenium/webdriver/ie/util.rb +5 -0
- data/remote/client/src/rb/lib/selenium/webdriver/remote.rb +2 -0
- data/remote/client/src/rb/lib/selenium/webdriver/remote/bridge.rb +42 -38
- data/remote/client/src/rb/lib/selenium/webdriver/remote/commands.rb +56 -47
- data/remote/client/src/rb/lib/selenium/webdriver/remote/default_http_client.rb +26 -26
- data/remote/client/src/rb/lib/selenium/webdriver/remote/patron_http_client.rb +58 -0
- data/remote/client/src/rb/lib/selenium/webdriver/remote/response.rb +10 -12
- data/remote/client/src/rb/lib/selenium/webdriver/remote/server_error.rb +2 -17
- metadata +44 -23
- data/common/src/js/context.js +0 -58
- data/firefox/src/extension/components/context.js +0 -37
@@ -7,19 +7,13 @@ module Selenium
|
|
7
7
|
#
|
8
8
|
# Low level bridge to the remote server, through which the rest of the API works.
|
9
9
|
#
|
10
|
-
# @
|
10
|
+
# @private
|
11
11
|
#
|
12
12
|
|
13
13
|
class Bridge
|
14
14
|
include Find
|
15
15
|
include BridgeHelper
|
16
16
|
|
17
|
-
DEFAULT_OPTIONS = {
|
18
|
-
:url => "http://localhost:4444/wd/hub",
|
19
|
-
:http_client => DefaultHttpClient,
|
20
|
-
:desired_capabilities => Capabilities.firefox
|
21
|
-
}
|
22
|
-
|
23
17
|
#
|
24
18
|
# Defines a wrapper method for a command, which ultimately calls #execute.
|
25
19
|
#
|
@@ -27,10 +21,7 @@ module Selenium
|
|
27
21
|
# name of the resulting method
|
28
22
|
# @param url [String]
|
29
23
|
# a URL template, which can include some arguments, much like the definitions on the server.
|
30
|
-
# the :session_id
|
31
|
-
# required method arguments.
|
32
|
-
# e.g., "session/:session_id/:context/element/:id/text" will define a method that takes id
|
33
|
-
# as it's first argument.
|
24
|
+
# the :session_id parameter is implicitly handled, but the remainder will become required method arguments.
|
34
25
|
# @param verb [Symbol]
|
35
26
|
# the appropriate http verb, such as :get, :post, or :delete
|
36
27
|
#
|
@@ -51,7 +42,7 @@ module Selenium
|
|
51
42
|
#
|
52
43
|
|
53
44
|
def initialize(opts = {})
|
54
|
-
opts =
|
45
|
+
opts = default_options.merge(opts)
|
55
46
|
http_client_class = opts.delete(:http_client)
|
56
47
|
desired_capabilities = opts.delete(:desired_capabilities)
|
57
48
|
url = opts.delete(:url)
|
@@ -71,7 +62,6 @@ module Selenium
|
|
71
62
|
uri = URI.parse(url)
|
72
63
|
uri.path += "/" unless uri.path =~ /\/$/
|
73
64
|
|
74
|
-
@context = "context"
|
75
65
|
@http = http_client_class.new uri
|
76
66
|
@capabilities = create_session(desired_capabilities)
|
77
67
|
end
|
@@ -92,17 +82,15 @@ module Selenium
|
|
92
82
|
@session_id || raise(Error::WebDriverError, "no current session exists")
|
93
83
|
end
|
94
84
|
|
95
|
-
|
96
85
|
def create_session(desired_capabilities)
|
97
|
-
resp = raw_execute :newSession, {}, desired_capabilities
|
86
|
+
resp = raw_execute :newSession, {}, :desiredCapabilities => desired_capabilities
|
98
87
|
@session_id = resp['sessionId'] || raise(Error::WebDriverError, 'no sessionId in returned payload')
|
99
|
-
@context = resp['context']
|
100
88
|
|
101
89
|
Capabilities.json_create resp['value']
|
102
90
|
end
|
103
91
|
|
104
92
|
def get(url)
|
105
|
-
execute :get, {}, url
|
93
|
+
execute :get, {}, :url => url
|
106
94
|
end
|
107
95
|
|
108
96
|
def goBack
|
@@ -134,15 +122,15 @@ module Selenium
|
|
134
122
|
end
|
135
123
|
|
136
124
|
def switchToWindow(name)
|
137
|
-
execute :switchToWindow, :name => name
|
125
|
+
execute :switchToWindow, {}, :name => name
|
138
126
|
end
|
139
127
|
|
140
128
|
def switchToFrame(id)
|
141
|
-
execute :switchToFrame, :id => id
|
129
|
+
execute :switchToFrame, {}, :id => id
|
142
130
|
end
|
143
131
|
|
144
132
|
def switchToDefaultContent
|
145
|
-
execute :switchToFrame, :id => nil
|
133
|
+
execute :switchToFrame, {}, :id => nil
|
146
134
|
end
|
147
135
|
|
148
136
|
def quit
|
@@ -166,7 +154,7 @@ module Selenium
|
|
166
154
|
end
|
167
155
|
|
168
156
|
def setSpeed(value)
|
169
|
-
execute :setSpeed, {}, value
|
157
|
+
execute :setSpeed, {}, :speed => value
|
170
158
|
end
|
171
159
|
|
172
160
|
def getSpeed
|
@@ -178,18 +166,16 @@ module Selenium
|
|
178
166
|
raise Error::UnsupportedOperationError, "underlying webdriver instance does not support javascript"
|
179
167
|
end
|
180
168
|
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
unwrap_script_argument response['value']
|
169
|
+
result = execute :executeScript, {}, :script => script, :args => args
|
170
|
+
unwrap_script_result result
|
185
171
|
end
|
186
172
|
|
187
173
|
def addCookie(cookie)
|
188
|
-
execute :addCookie, {}, cookie
|
174
|
+
execute :addCookie, {}, :cookie => cookie
|
189
175
|
end
|
190
176
|
|
191
177
|
def deleteCookie(name)
|
192
|
-
execute :
|
178
|
+
execute :deleteCookieNamed, :name => name
|
193
179
|
end
|
194
180
|
|
195
181
|
def getAllCookies
|
@@ -339,18 +325,20 @@ module Selenium
|
|
339
325
|
end
|
340
326
|
|
341
327
|
def dragElement(element, rigth_by, down_by)
|
342
|
-
|
343
|
-
|
328
|
+
execute :dragElement, {:id => element}, :x => rigth_by, :y => down_by
|
329
|
+
end
|
330
|
+
|
331
|
+
def getCapabilities
|
332
|
+
Capabilities.json_create execute(:getCapabilities)
|
344
333
|
end
|
345
334
|
|
346
335
|
private
|
347
336
|
|
348
337
|
def find_element_by(how, what, parent = nil)
|
349
338
|
if parent
|
350
|
-
|
351
|
-
id = execute :findChildElement, {:id => parent, :using => how}, {:using => how, :value => what}
|
339
|
+
id = execute :findChildElement, {:id => parent}, {:using => how, :value => what}
|
352
340
|
else
|
353
|
-
id = execute :findElement, {}, how, what
|
341
|
+
id = execute :findElement, {}, {:using => how, :value => what}
|
354
342
|
end
|
355
343
|
|
356
344
|
Element.new self, element_id_from(id)
|
@@ -359,9 +347,9 @@ module Selenium
|
|
359
347
|
def find_elements_by(how, what, parent = nil)
|
360
348
|
if parent
|
361
349
|
# TODO: why is how sent twice in the payload?
|
362
|
-
ids = execute :findChildElements, {:id => parent
|
350
|
+
ids = execute :findChildElements, {:id => parent}, {:using => how, :value => what}
|
363
351
|
else
|
364
|
-
ids = execute :findElements, {}, how, what
|
352
|
+
ids = execute :findElements, {}, {:using => how, :value => what}
|
365
353
|
end
|
366
354
|
|
367
355
|
ids.map { |id| Element.new self, element_id_from(id) }
|
@@ -385,21 +373,37 @@ module Selenium
|
|
385
373
|
# Returns a WebDriver::Remote::Response instance
|
386
374
|
#
|
387
375
|
|
388
|
-
def raw_execute(command, opts = {},
|
376
|
+
def raw_execute(command, opts = {}, command_hash = nil)
|
389
377
|
verb, path = COMMANDS[command] || raise("unknown command #{command.inspect}")
|
390
378
|
path = path.dup
|
391
379
|
|
392
380
|
path[':session_id'] = @session_id if path.include?(":session_id")
|
393
|
-
path[':context'] = @context if path.include?(":context")
|
394
381
|
|
395
382
|
begin
|
396
|
-
opts.each { |key, value| path[key.inspect] = URI.escape(value.to_s)
|
383
|
+
opts.each { |key, value| path[key.inspect] = URI.escape(value.to_s)}
|
397
384
|
rescue IndexError
|
398
385
|
raise ArgumentError, "#{opts.inspect} invalid for #{command.inspect}"
|
399
386
|
end
|
400
387
|
|
401
388
|
puts "-> #{verb.to_s.upcase} #{path}" if $DEBUG
|
402
|
-
http.call verb, path,
|
389
|
+
http.call verb, path, command_hash
|
390
|
+
end
|
391
|
+
|
392
|
+
def default_options
|
393
|
+
{
|
394
|
+
:url => "http://localhost:4444/wd/hub",
|
395
|
+
# TODO(jari): enable Patron when http://github.com/toland/patron/issues/issue/13 is fixed
|
396
|
+
:http_client => DefaultHttpClient,
|
397
|
+
:desired_capabilities => Capabilities.firefox
|
398
|
+
}
|
399
|
+
end
|
400
|
+
|
401
|
+
def http_client_class
|
402
|
+
require "selenium/webdriver/remote/patron_http_client"
|
403
|
+
PatronHttpClient
|
404
|
+
rescue LoadError
|
405
|
+
# patron not available
|
406
|
+
DefaultHttpClient
|
403
407
|
end
|
404
408
|
|
405
409
|
end # Bridge
|
@@ -1,53 +1,62 @@
|
|
1
|
+
# @private
|
1
2
|
class Selenium::WebDriver::Remote::Bridge
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
command :getCurrentUrl, :get, "session/:session_id/:context/url"
|
8
|
-
command :deleteAllCookies, :delete, "session/:session_id/:context/cookie"
|
9
|
-
command :deleteCookie, :delete, "session/:session_id/:context/cookie/:name"
|
10
|
-
command :dragElement, :post, "session/:session_id/:context/element/:id/drag"
|
11
|
-
command :elementEquals, :get, "session/:session_id/:context/element/:id/equals/:other"
|
12
|
-
command :executeScript, :post, "session/:session_id/:context/execute"
|
13
|
-
command :findElement, :post, "session/:session_id/:context/element"
|
14
|
-
command :findElements, :post, "session/:session_id/:context/elements"
|
15
|
-
command :findChildElement, :post, "session/:session_id/:context/element/:id/element/:using"
|
16
|
-
command :findChildElements, :post, "session/:session_id/:context/element/:id/elements/:using"
|
17
|
-
command :goForward, :post, "session/:session_id/:context/forward"
|
18
|
-
command :get, :post, "session/:session_id/:context/url"
|
19
|
-
command :getActiveElement, :post, "session/:session_id/:context/element/active"
|
20
|
-
command :getAllCookies, :get, "session/:session_id/:context/cookie"
|
21
|
-
# command :getCookie # TODO: getCookie
|
22
|
-
command :getCurrentWindowHandle, :get, "session/:session_id/:context/window_handle"
|
23
|
-
command :getElementAttribute, :get, "session/:session_id/:context/element/:id/attribute/:name"
|
24
|
-
command :getElementLocation, :get, "session/:session_id/:context/element/:id/location"
|
25
|
-
command :getElementSize, :get, "session/:session_id/:context/element/:id/size"
|
26
|
-
command :getElementText, :get, "session/:session_id/:context/element/:id/text"
|
27
|
-
command :getElementValue, :get, "session/:session_id/:context/element/:id/value"
|
28
|
-
command :getSpeed, :get, "session/:session_id/:context/speed"
|
29
|
-
command :getElementTagName, :get, "session/:session_id/:context/element/:id/name"
|
30
|
-
command :getTitle, :get, "session/:session_id/:context/title"
|
31
|
-
command :getElementValueOfCssProperty, :get, "session/:session_id/:context/element/:id/css/:property_name"
|
32
|
-
command :getVisible, :get, "session/:session_id/:context/visible"
|
33
|
-
command :getWindowHandles, :get, "session/:session_id/:context/window_handles"
|
34
|
-
command :hoverOverElement, :post, "session/:session_id/:context/element/:id/hover"
|
35
|
-
command :isElementDisplayed, :get, "session/:session_id/:context/element/:id/displayed"
|
36
|
-
command :isElementEnabled, :get, "session/:session_id/:context/element/:id/enabled"
|
37
|
-
command :isElementSelected, :get, "session/:session_id/:context/element/:id/selected"
|
3
|
+
|
4
|
+
#
|
5
|
+
# http://code.google.com/p/selenium/wiki/JsonWireProtocol#Command_Reference
|
6
|
+
#
|
7
|
+
|
38
8
|
command :newSession, :post, "session"
|
39
|
-
command :
|
9
|
+
command :getCapabilities, :get, "session/:session_id"
|
40
10
|
command :quit, :delete, "session/:session_id"
|
41
|
-
command :
|
42
|
-
command :
|
43
|
-
command :
|
44
|
-
command :
|
45
|
-
command :
|
46
|
-
command :
|
47
|
-
command :
|
48
|
-
command :
|
11
|
+
command :getCurrentWindowHandle, :get, "session/:session_id/window_handle"
|
12
|
+
command :getWindowHandles, :get, "session/:session_id/window_handles"
|
13
|
+
command :getCurrentUrl, :get, "session/:session_id/url"
|
14
|
+
command :get, :post, "session/:session_id/url"
|
15
|
+
command :goForward, :post, "session/:session_id/forward"
|
16
|
+
command :goBack, :post, "session/:session_id/back"
|
17
|
+
command :refresh, :post, "session/:session_id/refresh"
|
18
|
+
command :executeScript, :post, "session/:session_id/execute"
|
19
|
+
command :screenshot, :get, "session/:session_id/screenshot"
|
20
|
+
command :switchToFrame, :post, "session/:session_id/frame"
|
21
|
+
command :switchToWindow, :post, "session/:session_id/window"
|
22
|
+
command :getSpeed, :get, "session/:session_id/speed"
|
23
|
+
command :setSpeed, :post, "session/:session_id/speed"
|
24
|
+
command :getAllCookies, :get, "session/:session_id/cookie"
|
25
|
+
command :addCookie, :post, "session/:session_id/cookie"
|
26
|
+
command :deleteAllCookies, :delete, "session/:session_id/cookie"
|
27
|
+
command :deleteCookieNamed, :delete, "session/:session_id/cookie/:name"
|
28
|
+
command :getPageSource, :get, "session/:session_id/source"
|
29
|
+
command :getTitle, :get, "session/:session_id/title"
|
30
|
+
command :findElement, :post, "session/:session_id/element"
|
31
|
+
command :findElements, :post, "session/:session_id/elements"
|
32
|
+
command :getActiveElement, :post, "session/:session_id/element/active"
|
33
|
+
command :describeElement, :get, "session/:session_id/element/:id"
|
34
|
+
command :findChildElement, :post, "session/:session_id/element/:id/element"
|
35
|
+
command :findChildElements, :post, "session/:session_id/element/:id/elements"
|
36
|
+
command :clickElement, :post, "session/:session_id/element/:id/click"
|
37
|
+
command :submitElement, :post, "session/:session_id/element/:id/submit"
|
38
|
+
command :getElementValue, :get, "session/:session_id/element/:id/value"
|
39
|
+
command :sendKeysToElement, :post, "session/:session_id/element/:id/value"
|
40
|
+
command :getElementTagName, :get, "session/:session_id/element/:id/name"
|
41
|
+
command :clearElement, :post, "session/:session_id/element/:id/clear"
|
42
|
+
command :isElementSelected, :get, "session/:session_id/element/:id/selected"
|
43
|
+
command :setElementSelected, :post, "session/:session_id/element/:id/selected"
|
44
|
+
command :toggleElement, :post, "session/:session_id/element/:id/toggle"
|
45
|
+
command :isElementEnabled, :get, "session/:session_id/element/:id/enabled"
|
46
|
+
command :getElementAttribute, :get, "session/:session_id/element/:id/attribute/:name"
|
47
|
+
command :elementEquals, :get, "session/:session_id/element/:id/equals/:other"
|
48
|
+
command :isElementDisplayed, :get, "session/:session_id/element/:id/displayed"
|
49
|
+
command :getElementLocation, :get, "session/:session_id/element/:id/location"
|
50
|
+
command :getElementLocationInView, :get, "session/:session_id/element/:id/location_in_view"
|
51
|
+
command :getElementSize, :get, "session/:session_id/element/:id/size"
|
52
|
+
command :hoverOverElement, :post, "session/:session_id/element/:id/hover"
|
53
|
+
command :dragElement, :post, "session/:session_id/element/:id/drag"
|
54
|
+
command :getElementValueOfCssProperty, :get, "session/:session_id/element/:id/css/:property_name"
|
55
|
+
|
56
|
+
command :close, :delete, "session/:session_id/window"
|
57
|
+
command :getElementText, :get, "session/:session_id/element/:id/text"
|
58
|
+
command :getVisible, :get, "session/:session_id/visible"
|
59
|
+
command :setVisible, :post, "session/:session_id/visible"
|
49
60
|
# command :switchToFrameByIndex # TODO: switchToFrameByIndex
|
50
61
|
# command :switchToDefaultContent # TODO: switchToDefaultContent
|
51
|
-
command :switchToWindow, :post, "session/:session_id/:context/window/:name"
|
52
|
-
command :toggleElement, :post, "session/:session_id/:context/element/:id/toggle"
|
53
62
|
end
|
@@ -3,45 +3,33 @@ require "net/http"
|
|
3
3
|
module Selenium
|
4
4
|
module WebDriver
|
5
5
|
module Remote
|
6
|
+
|
7
|
+
# @private
|
6
8
|
class DefaultHttpClient
|
7
9
|
CONTENT_TYPE = "application/json"
|
8
|
-
DEFAULT_HEADERS = { "Accept" => CONTENT_TYPE }
|
9
|
-
|
10
|
-
class RetryException < StandardError; end
|
10
|
+
DEFAULT_HEADERS = { "Accept" => CONTENT_TYPE, "Content-Length" => "0" }
|
11
11
|
|
12
12
|
def initialize(url)
|
13
13
|
@server_url = url
|
14
14
|
end
|
15
15
|
|
16
|
-
def call(verb, url,
|
16
|
+
def call(verb, url, command_hash)
|
17
17
|
response = nil
|
18
18
|
url = @server_url.merge(url) unless url.kind_of?(URI)
|
19
19
|
headers = DEFAULT_HEADERS.dup
|
20
20
|
|
21
|
-
if
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
end
|
26
|
-
|
27
|
-
begin
|
28
|
-
request = Net::HTTP.const_get(verb.to_s.capitalize).new(url.path, headers)
|
21
|
+
if command_hash
|
22
|
+
payload = command_hash.to_json
|
23
|
+
headers["Content-Type"] = "#{CONTENT_TYPE}; charset=utf-8"
|
24
|
+
headers["Content-Length"] = payload.bytesize.to_s if [:post, :put].include?(verb)
|
29
25
|
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
verb, payload = :get, nil
|
34
|
-
url = URI.parse(res["Location"])
|
35
|
-
raise RetryException
|
36
|
-
else
|
37
|
-
response = create_response(res)
|
38
|
-
end
|
26
|
+
if $DEBUG
|
27
|
+
puts " >>> #{payload}"
|
28
|
+
puts " > #{headers.inspect}"
|
39
29
|
end
|
40
|
-
|
41
|
-
response
|
42
|
-
rescue RetryException
|
43
|
-
retry
|
44
30
|
end
|
31
|
+
|
32
|
+
request verb, url, headers, payload
|
45
33
|
end
|
46
34
|
|
47
35
|
private
|
@@ -51,6 +39,18 @@ module Selenium
|
|
51
39
|
@http ||= Net::HTTP.new @server_url.host, @server_url.port
|
52
40
|
end
|
53
41
|
|
42
|
+
def request(verb, url, headers, payload)
|
43
|
+
request = Net::HTTP.const_get(verb.to_s.capitalize).new(url.path, headers)
|
44
|
+
response = http.request(request, payload)
|
45
|
+
|
46
|
+
# TODO: should be checking against a maximum redirect count
|
47
|
+
if response.kind_of? Net::HTTPRedirection
|
48
|
+
request(:get, URI.parse(response['Location']), DEFAULT_HEADERS.dup, nil)
|
49
|
+
else
|
50
|
+
create_response response
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
54
|
def create_response(res)
|
55
55
|
puts "<- #{res.body}\n" if $DEBUG
|
56
56
|
if res.content_type == CONTENT_TYPE
|
@@ -68,4 +68,4 @@ module Selenium
|
|
68
68
|
end # DefaultHttpClient
|
69
69
|
end # Remote
|
70
70
|
end # WebDriver
|
71
|
-
end # Selenium
|
71
|
+
end # Selenium
|
@@ -0,0 +1,58 @@
|
|
1
|
+
require "patron"
|
2
|
+
|
3
|
+
module Selenium
|
4
|
+
module WebDriver
|
5
|
+
module Remote
|
6
|
+
|
7
|
+
# @private
|
8
|
+
class PatronHttpClient
|
9
|
+
CONTENT_TYPE = "application/json"
|
10
|
+
DEFAULT_HEADERS = { "Accept" => CONTENT_TYPE, "Content-Length" => "0" }
|
11
|
+
|
12
|
+
def initialize(url)
|
13
|
+
@session = Patron::Session.new
|
14
|
+
@session.base_url = url
|
15
|
+
end
|
16
|
+
|
17
|
+
def call(verb, url, command_hash)
|
18
|
+
DEFAULT_HEADERS.each do |key, val|
|
19
|
+
@session.headers[key] = val
|
20
|
+
end
|
21
|
+
|
22
|
+
if command_hash
|
23
|
+
payload = command_hash.to_json
|
24
|
+
@session.headers['Content-Type'] = "#{CONTENT_TYPE}; charset=utf-8;"
|
25
|
+
@session.headers['Content-Length'] = payload.bytesize.to_s if [:post, :put].include?(verb)
|
26
|
+
if $DEBUG
|
27
|
+
puts " >>> #{payload}"
|
28
|
+
puts " > #{@session.headers.inspect}"
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
if [:post, :put].include?(verb)
|
33
|
+
create_response @session.send(verb, url, payload || '')
|
34
|
+
else
|
35
|
+
create_response @session.send(verb, url)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
private
|
40
|
+
|
41
|
+
def create_response(res)
|
42
|
+
puts "<- #{res.body}\n" if $DEBUG
|
43
|
+
if res.headers['Content-Type'].include? CONTENT_TYPE
|
44
|
+
Response.new do |r|
|
45
|
+
r.code = res.status.to_i
|
46
|
+
r.payload = JSON.parse(res.body.strip)
|
47
|
+
end
|
48
|
+
elsif res.status == '204'
|
49
|
+
Response.new { |r| r.code = res.code.to_i }
|
50
|
+
else
|
51
|
+
raise "Unexpected content type: #{res.headers.inspect} (#{res.status})\n#{res.body}"
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
end # PatronHttpClient
|
56
|
+
end # Remote
|
57
|
+
end # WebDriver
|
58
|
+
end # Selenium
|
@@ -1,6 +1,8 @@
|
|
1
1
|
module Selenium
|
2
2
|
module WebDriver
|
3
3
|
module Remote
|
4
|
+
|
5
|
+
# @private
|
4
6
|
class Response
|
5
7
|
|
6
8
|
attr_accessor :code
|
@@ -12,12 +14,11 @@ module Selenium
|
|
12
14
|
end
|
13
15
|
|
14
16
|
def error
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
end
|
17
|
+
Error.for_code(payload['status'])
|
18
|
+
end
|
19
|
+
|
20
|
+
def error_message
|
21
|
+
payload['value']['message']
|
21
22
|
end
|
22
23
|
|
23
24
|
def [](key)
|
@@ -31,14 +32,11 @@ module Selenium
|
|
31
32
|
private
|
32
33
|
|
33
34
|
def assert_ok
|
34
|
-
if @code.nil? || @code
|
35
|
+
if @code.nil? || @code >= 400
|
35
36
|
if e = error()
|
36
|
-
raise(
|
37
|
-
Error.for_remote_class(e['class']),
|
38
|
-
e['message'] || self
|
39
|
-
)
|
37
|
+
raise(e, error_message)
|
40
38
|
else
|
41
|
-
raise ServerError, self
|
39
|
+
raise Error::ServerError, self
|
42
40
|
end
|
43
41
|
end
|
44
42
|
end
|