selenium-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 (86) hide show
  1. data/chrome/prebuilt/Win32/Release/npchromedriver.dll +0 -0
  2. data/chrome/prebuilt/x64/Release/npchromedriver.dll +0 -0
  3. data/chrome/src/extension/background.html +9 -0
  4. data/chrome/src/extension/background.js +933 -0
  5. data/chrome/src/extension/content_script.js +1286 -0
  6. data/chrome/src/extension/manifest-nonwin.json +15 -0
  7. data/chrome/src/extension/manifest-win.json +16 -0
  8. data/chrome/src/extension/toolstrip.html +28 -0
  9. data/chrome/src/extension/utils.js +196 -0
  10. data/chrome/src/rb/lib/selenium/webdriver/chrome.rb +8 -0
  11. data/chrome/src/rb/lib/selenium/webdriver/chrome/bridge.rb +324 -0
  12. data/chrome/src/rb/lib/selenium/webdriver/chrome/command_executor.rb +70 -0
  13. data/chrome/src/rb/lib/selenium/webdriver/chrome/launcher.rb +119 -0
  14. data/common/src/js/abstractcommandprocessor.js +161 -0
  15. data/common/src/js/asserts.js +296 -0
  16. data/common/src/js/by.js +147 -0
  17. data/common/src/js/command.js +274 -0
  18. data/common/src/js/context.js +58 -0
  19. data/common/src/js/extension/README +2 -0
  20. data/common/src/js/extension/dommessenger.js +152 -0
  21. data/common/src/js/factory.js +55 -0
  22. data/common/src/js/future.js +118 -0
  23. data/common/src/js/key.js +117 -0
  24. data/common/src/js/localcommandprocessor.js +181 -0
  25. data/common/src/js/logging.js +249 -0
  26. data/common/src/js/testrunner.js +605 -0
  27. data/common/src/js/timing.js +89 -0
  28. data/common/src/js/wait.js +199 -0
  29. data/common/src/js/webdriver.js +853 -0
  30. data/common/src/js/webelement.js +683 -0
  31. data/common/src/rb/lib/selenium-webdriver.rb +1 -0
  32. data/common/src/rb/lib/selenium/webdriver.rb +52 -0
  33. data/common/src/rb/lib/selenium/webdriver/bridge_helper.rb +88 -0
  34. data/common/src/rb/lib/selenium/webdriver/child_process.rb +85 -0
  35. data/common/src/rb/lib/selenium/webdriver/core_ext/dir.rb +41 -0
  36. data/common/src/rb/lib/selenium/webdriver/driver.rb +128 -0
  37. data/common/src/rb/lib/selenium/webdriver/element.rb +126 -0
  38. data/common/src/rb/lib/selenium/webdriver/error.rb +68 -0
  39. data/common/src/rb/lib/selenium/webdriver/find.rb +69 -0
  40. data/common/src/rb/lib/selenium/webdriver/navigation.rb +23 -0
  41. data/common/src/rb/lib/selenium/webdriver/options.rb +50 -0
  42. data/common/src/rb/lib/selenium/webdriver/platform.rb +82 -0
  43. data/common/src/rb/lib/selenium/webdriver/target_locator.rb +23 -0
  44. data/firefox/prebuilt/nsICommandProcessor.xpt +0 -0
  45. data/firefox/prebuilt/nsINativeEvents.xpt +0 -0
  46. data/firefox/prebuilt/nsIResponseHandler.xpt +0 -0
  47. data/firefox/src/extension/chrome.manifest +3 -0
  48. data/firefox/src/extension/components/context.js +37 -0
  49. data/firefox/src/extension/components/driver-component.js +127 -0
  50. data/firefox/src/extension/components/firefoxDriver.js +706 -0
  51. data/firefox/src/extension/components/json2.js +273 -0
  52. data/firefox/src/extension/components/keytest.html +554 -0
  53. data/firefox/src/extension/components/nsCommandProcessor.js +586 -0
  54. data/firefox/src/extension/components/screenshooter.js +70 -0
  55. data/firefox/src/extension/components/socketListener.js +185 -0
  56. data/firefox/src/extension/components/utils.js +1200 -0
  57. data/firefox/src/extension/components/webLoadingListener.js +57 -0
  58. data/firefox/src/extension/components/webdriverserver.js +101 -0
  59. data/firefox/src/extension/components/wrappedElement.js +609 -0
  60. data/firefox/src/extension/content/fxdriver.xul +30 -0
  61. data/firefox/src/extension/content/server.js +95 -0
  62. data/firefox/src/extension/idl/nsICommandProcessor.idl +38 -0
  63. data/firefox/src/extension/idl/nsIResponseHandler.idl +34 -0
  64. data/firefox/src/extension/install.rdf +29 -0
  65. data/firefox/src/rb/lib/selenium/webdriver/firefox.rb +21 -0
  66. data/firefox/src/rb/lib/selenium/webdriver/firefox/binary.rb +86 -0
  67. data/firefox/src/rb/lib/selenium/webdriver/firefox/bridge.rb +426 -0
  68. data/firefox/src/rb/lib/selenium/webdriver/firefox/extension_connection.rb +82 -0
  69. data/firefox/src/rb/lib/selenium/webdriver/firefox/launcher.rb +132 -0
  70. data/firefox/src/rb/lib/selenium/webdriver/firefox/profile.rb +174 -0
  71. data/firefox/src/rb/lib/selenium/webdriver/firefox/profiles_ini.rb +60 -0
  72. data/firefox/src/rb/lib/selenium/webdriver/firefox/util.rb +23 -0
  73. data/jobbie/prebuilt/Win32/Release/InternetExplorerDriver.dll +0 -0
  74. data/jobbie/prebuilt/x64/Release/InternetExplorerDriver.dll +0 -0
  75. data/jobbie/src/rb/lib/selenium/webdriver/ie.rb +14 -0
  76. data/jobbie/src/rb/lib/selenium/webdriver/ie/bridge.rb +552 -0
  77. data/jobbie/src/rb/lib/selenium/webdriver/ie/lib.rb +94 -0
  78. data/jobbie/src/rb/lib/selenium/webdriver/ie/util.rb +147 -0
  79. data/remote/client/src/rb/lib/selenium/webdriver/remote.rb +16 -0
  80. data/remote/client/src/rb/lib/selenium/webdriver/remote/bridge.rb +374 -0
  81. data/remote/client/src/rb/lib/selenium/webdriver/remote/capabilities.rb +105 -0
  82. data/remote/client/src/rb/lib/selenium/webdriver/remote/commands.rb +53 -0
  83. data/remote/client/src/rb/lib/selenium/webdriver/remote/default_http_client.rb +71 -0
  84. data/remote/client/src/rb/lib/selenium/webdriver/remote/response.rb +43 -0
  85. data/remote/client/src/rb/lib/selenium/webdriver/remote/server_error.rb +32 -0
  86. metadata +182 -0
@@ -0,0 +1,15 @@
1
+ {
2
+ "name": "WebDriver",
3
+ "version": "0.3",
4
+ "description": "WebDriver extension for Chrome",
5
+ "toolstrips": ["toolstrip.html"],
6
+ "background_page": "background.html",
7
+ "content_scripts": [
8
+ {
9
+ "matches": ["http://*/*", "https://*/*", "file:///*"],
10
+ "js": ["utils.js", "content_script.js"],
11
+ "run_at": "document_start"
12
+ }
13
+ ],
14
+ "permissions": ["http://*/*", "tabs"]
15
+ }
@@ -0,0 +1,16 @@
1
+ {
2
+ "name": "WebDriver",
3
+ "version": "0.2",
4
+ "description": "WebDriver extension for Chrome",
5
+ "toolstrips": ["toolstrip.html"],
6
+ "background_page": "background.html",
7
+ "content_scripts": [
8
+ {
9
+ "matches": ["http://*/*", "https://*/*", "file:///*"],
10
+ "js": ["utils.js", "content_script.js"],
11
+ "run_at": "document_start"
12
+ }
13
+ ],
14
+ "plugins": [{"path": "npchromedriver.dll", "public": true}],
15
+ "permissions": ["http://*/*", "tabs"]
16
+ }
@@ -0,0 +1,28 @@
1
+ <html>
2
+ <head>
3
+ <script type="text/javascript">
4
+ function setWebdriverToolstripBusy() {
5
+ document.getElementById("toolstripText").className = "toolstripTextBusy";
6
+ }
7
+
8
+ function setWebdriverToolstripFree() {
9
+ document.getElementById("toolstripText").className = "toolstripTextFree";
10
+ }
11
+ </script>
12
+
13
+ <style type="text/css">
14
+ .toolstripTextBusy {
15
+ color: red;
16
+ }
17
+
18
+ .toolstripTextFree {
19
+ color: black;
20
+ }
21
+ </style>
22
+ </head>
23
+ <body>
24
+ <div>
25
+ <span id="toolstripText" class="toolstripTextFree">WebDriver</span>
26
+ </div>
27
+ </body>
28
+ </html>
@@ -0,0 +1,196 @@
1
+ //Very cut-down and slightly modified (generally to remove context) from
2
+ //$WEBDRIVER_HOME/firefox/src/extension/components/utils.js
3
+
4
+ function Utils() {
5
+ }
6
+
7
+ function getTextFromNode(node, toReturn, textSoFar, isPreformatted) {
8
+ if (node['tagName'] && node.tagName == "SCRIPT") {
9
+ return [toReturn, textSoFar];
10
+ } else if (node['tagName'] && node.tagName == "TITLE") {
11
+ return [textSoFar + node.text, ""];
12
+ }
13
+ var children = node.childNodes;
14
+
15
+ for (var i = 0; i < children.length; i++) {
16
+ var child = children[i];
17
+
18
+ // Do we need to collapse the text so far?
19
+ if (child["tagName"] && child.tagName == "PRE") {
20
+ toReturn += collapseWhitespace(textSoFar);
21
+ textSoFar = "";
22
+ var bits = getTextFromNode(child, toReturn, "", true);
23
+ toReturn += bits[1];
24
+ continue;
25
+ }
26
+
27
+ // Or is this just plain text?
28
+ if (child.nodeName == "#text") {
29
+ if (Utils.isDisplayed(child)) {
30
+ var textToAdd = child.nodeValue;
31
+ textToAdd = textToAdd.replace(new RegExp(String.fromCharCode(160), "gm"), " ");
32
+ textSoFar += textToAdd;
33
+ }
34
+ continue;
35
+ }
36
+
37
+ // Treat as another child node.
38
+ var bits = getTextFromNode(child, toReturn, textSoFar, false);
39
+ toReturn = bits[0];
40
+ textSoFar = bits[1];
41
+ }
42
+
43
+ if (isBlockLevel(node)) {
44
+ if (node["tagName"] && node.tagName != "PRE") {
45
+ toReturn += collapseWhitespace(textSoFar) + "\n";
46
+ textSoFar = "";
47
+ } else {
48
+ toReturn += "\n";
49
+ }
50
+ }
51
+ return [toReturn, textSoFar];
52
+ }
53
+ ;
54
+
55
+ function isBlockLevel(node) {
56
+ if (node["tagName"] && node.tagName == "BR")
57
+ return true;
58
+
59
+ try {
60
+ // Should we think about getting hold of the current document?
61
+ return "block" == Utils.getStyleProperty(node, "display");
62
+ } catch (e) {
63
+ return false;
64
+ }
65
+ };
66
+
67
+ Utils.isInHead = function(element) {
68
+ while (element) {
69
+ if (element.tagName && element.tagName.toLowerCase() == "head") {
70
+ return true;
71
+ }
72
+ try {
73
+ element = element.parentNode;
74
+ } catch (e) {
75
+ // Fine. the DOM has dispeared from underneath us
76
+ return false;
77
+ }
78
+ }
79
+
80
+ return false;
81
+ };
82
+
83
+ Utils.isDisplayed = function(element) {
84
+ // Ensure that we're dealing with an element.
85
+ var el = element;
86
+ while (el.nodeType != 1 && !(el.nodeType >= 9 && el.nodeType <= 11)) {
87
+ el = el.parentNode;
88
+ }
89
+
90
+ // Hidden input elements are, by definition, never displayed
91
+ if (el.tagName == "input" && el.type == "hidden") {
92
+ return false;
93
+ }
94
+
95
+ var visibility = Utils.getStyleProperty(el, "visibility");
96
+
97
+ var _isDisplayed = function(e) {
98
+ var display = e.ownerDocument.defaultView.getComputedStyle(e, null).getPropertyValue("display");
99
+ if (display == "none") return display;
100
+ if (e && e.parentNode && e.parentNode.style) {
101
+ return _isDisplayed(e.parentNode);
102
+ }
103
+ return undefined;
104
+ };
105
+
106
+ var displayed = _isDisplayed(el);
107
+
108
+ if (element.scrollIntoView && element.getBoundingClientRect &&
109
+ element.tagName.toLowerCase() != "option") {
110
+ //Option tags have 0-dimension bounding rects so ignore them
111
+ element.scrollIntoView(true);
112
+ var clientRect = element.getBoundingClientRect();
113
+ if (clientRect.width == 0 || clientRect.height == 0) {
114
+ return false;
115
+ }
116
+ }
117
+
118
+ return displayed != "none" && visibility != "hidden";
119
+ };
120
+
121
+ Utils.getStyleProperty = function(node, propertyName) {
122
+ if (!node)
123
+ return undefined;
124
+
125
+ var value = node.ownerDocument.defaultView.getComputedStyle(node, null).getPropertyValue(propertyName);
126
+
127
+ // Convert colours to hex if possible
128
+ var raw = /rgb\((\d{1,3}),\s(\d{1,3}),\s(\d{1,3})\)/.exec(value);
129
+ if (raw) {
130
+ var temp = value.substr(0, raw.index);
131
+
132
+ var hex = "#";
133
+ for (var i = 1; i <= 3; i++) {
134
+ var colour = (raw[i] - 0).toString(16);
135
+ if (colour.length == 1)
136
+ colour = "0" + colour;
137
+ hex += colour
138
+ }
139
+ hex = hex.toLowerCase();
140
+ value = temp + hex + value.substr(raw.index + raw[0].length);
141
+ }
142
+
143
+ if (value == "inherit" && element.parentNode.style) {
144
+ value = Utils.getStyleProperty(node.parentNode, propertyName);
145
+ }
146
+
147
+ return value;
148
+ };
149
+
150
+ function collapseWhitespace(textSoFar) {
151
+ return textSoFar.replace(/\s+/g, " ");
152
+ }
153
+ ;
154
+
155
+ function getPreformattedText(node) {
156
+ var textToAdd = "";
157
+ return getTextFromNode(node, "", textToAdd, true)[1];
158
+ }
159
+ ;
160
+
161
+ function isWhiteSpace(character) {
162
+ return character == '\n' || character == ' ' || character == '\t' || character == '\r';
163
+ }
164
+
165
+ Utils.getText = function(element) {
166
+ var bits = getTextFromNode(element, "", "", element.tagName == "PRE");
167
+ var text = bits[0] + collapseWhitespace(bits[1]);
168
+ var start = 0;
169
+ while (start < text.length && isWhiteSpace(text[start])) {
170
+ ++start;
171
+ }
172
+ var end = text.length;
173
+ while (end > start && isWhiteSpace(text[end - 1])) {
174
+ --end;
175
+ }
176
+ return text.slice(start, end);
177
+ };
178
+
179
+ Utils.fireHtmlEvent = function(element, eventName) {
180
+ var e = document.createEvent("HTMLEvents");
181
+ e.initEvent(eventName, true, true);
182
+ element.dispatchEvent(e);
183
+ };
184
+
185
+
186
+ Utils.fireMouseEventOn = function(element, eventName) {
187
+ Utils.triggerMouseEvent(element, eventName, 0, 0);
188
+ };
189
+
190
+ Utils.triggerMouseEvent = function(element, eventType, clientX, clientY) {
191
+ var event = element.ownerDocument.createEvent("MouseEvents");
192
+ var view = element.ownerDocument.defaultView;
193
+
194
+ event.initMouseEvent(eventType, true, true, view, 1, 0, 0, clientX, clientY, false, false, false, false, 0, element);
195
+ element.dispatchEvent(event);
196
+ };
@@ -0,0 +1,8 @@
1
+ require "selenium/webdriver/chrome/launcher"
2
+ require "selenium/webdriver/chrome/command_executor"
3
+ require "selenium/webdriver/chrome/bridge"
4
+
5
+ require "fileutils"
6
+ require "thread"
7
+ require "socket"
8
+
@@ -0,0 +1,324 @@
1
+ module Selenium
2
+ module WebDriver
3
+ module Chrome
4
+ class Bridge
5
+ include BridgeHelper
6
+
7
+ def initialize
8
+ @executor = CommandExecutor.new
9
+
10
+ @launcher = Launcher.launcher
11
+ @launcher.launch
12
+ # TODO: @launcher.kill
13
+ end
14
+
15
+ def browser
16
+ :chrome
17
+ end
18
+
19
+ def get(url)
20
+ execute :request => 'get',
21
+ :url => url
22
+ end
23
+
24
+ def goBack
25
+ execute :request => 'goBack'
26
+ end
27
+
28
+ def goForward
29
+ execute :request => 'goForward'
30
+ end
31
+
32
+ def getCurrentUrl
33
+ execute :request => 'getCurrentUrl'
34
+ end
35
+
36
+ def getTitle
37
+ execute :request => 'getTitle'
38
+ end
39
+
40
+ def getPageSource
41
+ execute :request => 'getPageSource'
42
+ end
43
+
44
+ def switchToWindow(name)
45
+ execute :request => 'switchToWindow',
46
+ :windowName => name
47
+ end
48
+
49
+ def switchToFrame(id)
50
+ execute :request => 'switchToFrameByName',
51
+ :name => id
52
+ end
53
+
54
+ def quit
55
+ @launcher.kill # FIXME: let chrome extension take care of this
56
+ execute :request => 'quit'
57
+ end
58
+
59
+ def close
60
+ execute :request => 'close'
61
+ end
62
+
63
+ def getWindowHandles
64
+ execute :request => 'getWindowHandles'
65
+ end
66
+
67
+ def getCurrentWindowHandle
68
+ execute :request => 'getCurrentWindowHandle'
69
+ end
70
+
71
+ def setSpeed(value)
72
+ @speed = value
73
+ end
74
+
75
+ def getSpeed
76
+ @speed
77
+ end
78
+
79
+ def executeScript(script, *args)
80
+ typed_args = args.map { |e| wrap_script_argument(e) }
81
+
82
+ resp = execute :request => 'executeScript',
83
+ :script => script,
84
+ :args => typed_args
85
+
86
+ unwrap_script_argument resp
87
+ end
88
+
89
+ def addCookie(cookie)
90
+ execute :request => 'addCookie',
91
+ :cookie => cookie
92
+ end
93
+
94
+ def deleteCookie(name)
95
+ execute :request => 'deleteCookie',
96
+ :name => name
97
+ end
98
+
99
+ def getAllCookies
100
+ execute :request => 'getCookies'
101
+ end
102
+
103
+ def deleteAllCookies
104
+ execute :request => 'deleteAllCookies'
105
+ end
106
+
107
+ def findElementByClassName(parent, class_name)
108
+ find_element_by 'class name', class_name, parent
109
+ end
110
+
111
+ def findElementsByClassName(parent, class_name)
112
+ find_elements_by 'class name', class_name, parent
113
+ end
114
+
115
+ def findElementById(parent, id)
116
+ find_element_by 'id', id, parent
117
+ end
118
+
119
+ def findElementsById(parent, id)
120
+ find_elements_by 'id', id, parent
121
+ end
122
+
123
+ def findElementByLinkText(parent, link_text)
124
+ find_element_by 'link text', link_text, parent
125
+ end
126
+
127
+ def findElementsByLinkText(parent, link_text)
128
+ find_elements_by 'link text', link_text, parent
129
+ end
130
+
131
+ def findElementByPartialLinkText(parent, link_text)
132
+ find_element_by 'partial link text', link_text, parent
133
+ end
134
+
135
+ def findElementsByPartialLinkText(parent, link_text)
136
+ find_elements_by 'partial link text', link_text, parent
137
+ end
138
+
139
+ def findElementByName(parent, name)
140
+ find_element_by 'name', name, parent
141
+ end
142
+
143
+ def findElementsByName(parent, name)
144
+ find_elements_by 'name', name, parent
145
+ end
146
+
147
+ def findElementByTagName(parent, tag_name)
148
+ find_element_by 'tag name', tag_name, parent
149
+ end
150
+
151
+ def findElementsByTagName(parent, tag_name)
152
+ find_elements_by 'tag name', tag_name, parent
153
+ end
154
+
155
+ def findElementByXpath(parent, xpath)
156
+ find_element_by 'xpath', xpath, parent
157
+ end
158
+
159
+ def findElementsByXpath(parent, xpath)
160
+ find_elements_by 'xpath', xpath, parent
161
+ end
162
+
163
+
164
+ #
165
+ # Element functions
166
+ #
167
+
168
+ def clickElement(element)
169
+ execute :request => 'clickElement',
170
+ :elementId => element
171
+ end
172
+
173
+ def getElementTagName(element)
174
+ execute :request => 'getElementTagName',
175
+ :elementId => element
176
+ end
177
+
178
+ def getElementAttribute(element, name)
179
+ execute :request => 'getElementAttribute',
180
+ :elementId => element,
181
+ :attribute => name
182
+ end
183
+
184
+ def getElementValue(element)
185
+ execute :request => 'getElementValue',
186
+ :elementId => element
187
+ end
188
+
189
+ def getElementText(element)
190
+ execute :request => 'getElementText',
191
+ :elementId => element
192
+ end
193
+
194
+ def getElementLocation(element)
195
+ data = execute :request => 'getElementLocation',
196
+ :elementId => element
197
+
198
+ Point.new data['x'], data['y']
199
+ end
200
+
201
+ def getElementSize(element)
202
+ execute :request => 'getElementSize',
203
+ :elementId => element
204
+ end
205
+
206
+ def sendKeysToElement(element, string)
207
+ execute :request => 'sendKeysToElement',
208
+ :elementId => element,
209
+ :keys => string.split(//u)
210
+ end
211
+
212
+ def clearElement(element)
213
+ execute :request => 'clearElement',
214
+ :elementId => element
215
+ end
216
+
217
+ def isElementEnabled(element)
218
+ execute :request => 'isElementEnabled',
219
+ :elementId => element
220
+ end
221
+
222
+ def isElementSelected(element)
223
+ execute :request => 'isElementSelected',
224
+ :elementId => element
225
+ end
226
+
227
+ def isElementDisplayed(element)
228
+ execute :request => 'isElementDisplayed',
229
+ :elementId => element
230
+ end
231
+
232
+ def submitElement(element)
233
+ execute :request => 'submitElement',
234
+ :elementId => element
235
+ end
236
+
237
+ def toggleElement(element)
238
+ execute :request => 'toggleElement',
239
+ :elementId => element
240
+ end
241
+
242
+ def setElementSelected(element)
243
+ execute :request => 'setElementSelected',
244
+ :elementId => element
245
+ end
246
+
247
+ def getElementValueOfCssProperty(element, prop)
248
+ execute :request => 'getElementValueOfCssProperty',
249
+ :elementId => element,
250
+ :css => prop
251
+ end
252
+
253
+ def getActiveElement
254
+ Element.new self, element_id_from(execute(:request => 'getActiveElement'))
255
+ end
256
+ alias_method :switchToActiveElement, :getActiveElement
257
+
258
+ def hoverOverElement
259
+ execute :request => 'hoverOverElement',
260
+ :elementId => element
261
+ end
262
+
263
+ def dragElement(element, rigth_by, down_by)
264
+ raise UnsupportedOperationError, "drag and drop unsupported in Chrome"
265
+ execute :drag_element, {:id => element}, element, rigth_by, down_by
266
+ end
267
+
268
+ private
269
+
270
+ def find_element_by(how, what, parent = nil)
271
+ if parent
272
+ id = execute :request => 'findChildElement',
273
+ :id => parent,
274
+ :using => how,
275
+ :value => what
276
+ else
277
+ id = execute :request => 'findElement',
278
+ :using => how,
279
+ :value => what
280
+ end
281
+
282
+ Element.new self, element_id_from(id)
283
+ end
284
+
285
+ def find_elements_by(how, what, parent = nil)
286
+ if parent
287
+ ids = execute :request => 'findChildElements',
288
+ :id => parent,
289
+ :using => how,
290
+ :value => what
291
+ else
292
+ ids = execute :request => 'findElements',
293
+ :using => how,
294
+ :value => what
295
+ end
296
+
297
+ ids.map { |id| Element.new self, element_id_from(id) }
298
+ end
299
+
300
+
301
+ private
302
+
303
+ def execute(command)
304
+ resp = raw_execute command
305
+ code = resp['statusCode']
306
+ if e = Error.for_code(code)
307
+ msg = resp['value']['message'] if resp['value']
308
+ msg ||= "unknown exception for #{command.inspect}"
309
+ msg << " (#{code})"
310
+
311
+ raise e, msg
312
+ end
313
+
314
+ resp['value']
315
+ end
316
+
317
+ def raw_execute(command)
318
+ @executor.execute command
319
+ end
320
+
321
+ end # Bridge
322
+ end # Chrome
323
+ end # WebDriver
324
+ end # Selenium