selenium-webdriver 3.6.0 → 4.0.0-alpha.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.
- package/CHANGES.md +181 -0
- package/README.md +25 -27
- package/chrome.js +113 -127
- package/edge.js +42 -117
- package/example/chrome_android.js +8 -8
- package/example/chrome_mobile_emulation.js +8 -8
- package/example/firefox_channels.js +22 -18
- package/example/google_search_test.js +39 -26
- package/example/logging.js +39 -6
- package/firefox.js +769 -0
- package/http/index.js +41 -4
- package/http/util.js +11 -6
- package/ie.js +56 -97
- package/index.js +178 -114
- package/jasmine.json +11 -0
- package/lib/actions.js +68 -63
- package/lib/by.js +1 -1
- package/lib/capabilities.js +255 -192
- package/lib/command.js +26 -50
- package/lib/error.js +85 -44
- package/lib/http.js +133 -110
- package/lib/input.js +1044 -8
- package/lib/promise.js +222 -3323
- package/lib/proxy.js +134 -39
- package/lib/test/bootstrap_jasmine.js +28 -0
- package/lib/test/data/actions/click.html +24 -0
- package/lib/test/data/actions/drag.html +77 -0
- package/lib/test/data/actions/record_click.html +21 -0
- package/lib/test/data/chrome/download.html +2 -0
- package/lib/test/data/inputs.html +42 -0
- package/lib/test/data/selectPage.html +12 -0
- package/lib/test/data/simpleTest.html +5 -0
- package/lib/test/data/upload_invisible.html +45 -0
- package/lib/test/fileserver.js +23 -19
- package/lib/test/index.js +30 -212
- package/lib/test/resources.js +0 -1
- package/lib/webdriver.js +675 -936
- package/net/index.js +21 -25
- package/net/portprober.js +51 -68
- package/package.json +5 -3
- package/remote/index.js +5 -19
- package/safari.js +41 -128
- package/test/actions_test.js +173 -18
- package/test/{session_test.js → builder_test.js} +44 -37
- package/test/chrome/devtools_test.js +93 -0
- package/test/chrome/options_test.js +48 -154
- package/test/chrome/service_test.js +7 -7
- package/test/cookie_test.js +77 -63
- package/test/element_finding_test.js +206 -201
- package/test/execute_script_test.js +115 -114
- package/test/fingerprint_test.js +16 -15
- package/test/firefox_test.js +251 -0
- package/test/http/http_test.js +0 -1
- package/test/http/util_test.js +2 -2
- package/test/io/zip_test.js +6 -7
- package/test/lib/error_test.js +34 -7
- package/test/lib/http_test.js +8 -128
- package/test/lib/input_test.js +1379 -0
- package/test/lib/promise_test.js +473 -908
- package/test/lib/webdriver_test.js +296 -868
- package/test/logging_test.js +37 -43
- package/test/page_loading_test.js +71 -81
- package/test/proxy_test.js +64 -72
- package/test/rect_test.js +14 -25
- package/test/remote_test.js +10 -29
- package/test/safari_test.js +7 -71
- package/test/stale_element_test.js +20 -23
- package/test/tag_name_test.js +10 -9
- package/test/upload_test.js +27 -35
- package/test/window_test.js +72 -85
- package/testing/index.js +386 -314
- package/.npmignore +0 -2
- package/example/async_await_test.js +0 -69
- package/example/google_search_generator.js +0 -47
- package/example/parallel_flows.js +0 -51
- package/firefox/binary.js +0 -347
- package/firefox/extension.js +0 -224
- package/firefox/index.js +0 -576
- package/firefox/profile.js +0 -311
- package/lib/events.js +0 -210
- package/lib/test/data/firefox/jetpack-sample.xpi +0 -0
- package/lib/test/data/firefox/sample.xpi +0 -0
- package/lib/test/promise.js +0 -79
- package/opera.js +0 -405
- package/phantomjs.js +0 -282
- package/test/firefox/extension_test.js +0 -120
- package/test/firefox/firefox_test.js +0 -244
- package/test/firefox/profile_test.js +0 -140
- package/test/lib/events_test.js +0 -177
- package/test/lib/promise_aplus_test.js +0 -78
- package/test/lib/promise_error_test.js +0 -884
- package/test/lib/promise_flow_test.js +0 -2288
- package/test/lib/promise_generator_test.js +0 -310
- package/test/phantomjs/execute_phantomjs_test.js +0 -59
- package/test/testing/assert_test.js +0 -373
- package/test/testing/index_test.js +0 -224
- package/testing/assert.js +0 -378
package/lib/http.js
CHANGED
|
@@ -29,8 +29,8 @@ const cmd = require('./command');
|
|
|
29
29
|
const error = require('./error');
|
|
30
30
|
const logging = require('./logging');
|
|
31
31
|
const promise = require('./promise');
|
|
32
|
-
const Session = require('./session')
|
|
33
|
-
const WebElement = require('./webdriver')
|
|
32
|
+
const {Session} = require('./session');
|
|
33
|
+
const {WebElement} = require('./webdriver');
|
|
34
34
|
|
|
35
35
|
const {getAttribute, isDisplayed} = /** @suppress {undefinedVars|uselessCode} */(function() {
|
|
36
36
|
try {
|
|
@@ -145,7 +145,7 @@ function resource(method, path) { return {method: method, path: path}; }
|
|
|
145
145
|
var CommandSpec;
|
|
146
146
|
|
|
147
147
|
|
|
148
|
-
/** @typedef {function(!cmd.Command): !
|
|
148
|
+
/** @typedef {function(!cmd.Command): !cmd.Command} */
|
|
149
149
|
var CommandTransformer;
|
|
150
150
|
|
|
151
151
|
|
|
@@ -155,21 +155,17 @@ class InternalTypeError extends TypeError {}
|
|
|
155
155
|
/**
|
|
156
156
|
* @param {!cmd.Command} command The initial command.
|
|
157
157
|
* @param {Atom} atom The name of the atom to execute.
|
|
158
|
-
* @return {!
|
|
158
|
+
* @return {!cmd.Command} The transformed command to execute.
|
|
159
159
|
*/
|
|
160
160
|
function toExecuteAtomCommand(command, atom, ...params) {
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
return;
|
|
165
|
-
}
|
|
161
|
+
if (typeof atom !== 'function') {
|
|
162
|
+
throw new InternalTypeError('atom is not a function: ' + typeof atom);
|
|
163
|
+
}
|
|
166
164
|
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
resolve(newCmd);
|
|
172
|
-
});
|
|
165
|
+
return new cmd.Command(cmd.Name.EXECUTE_SCRIPT)
|
|
166
|
+
.setParameter('sessionId', command.getParameter('sessionId'))
|
|
167
|
+
.setParameter('script', `return (${atom}).apply(null, arguments)`)
|
|
168
|
+
.setParameter('args', params.map(param => command.getParameter(param)));
|
|
173
169
|
}
|
|
174
170
|
|
|
175
171
|
|
|
@@ -179,7 +175,6 @@ const COMMAND_MAP = new Map([
|
|
|
179
175
|
[cmd.Name.GET_SERVER_STATUS, get('/status')],
|
|
180
176
|
[cmd.Name.NEW_SESSION, post('/session')],
|
|
181
177
|
[cmd.Name.GET_SESSIONS, get('/sessions')],
|
|
182
|
-
[cmd.Name.DESCRIBE_SESSION, get('/session/:sessionId')],
|
|
183
178
|
[cmd.Name.QUIT, del('/session/:sessionId')],
|
|
184
179
|
[cmd.Name.CLOSE, del('/session/:sessionId/window')],
|
|
185
180
|
[cmd.Name.GET_CURRENT_WINDOW_HANDLE, get('/session/:sessionId/window_handle')],
|
|
@@ -211,7 +206,6 @@ const COMMAND_MAP = new Map([
|
|
|
211
206
|
[cmd.Name.GET_ELEMENT_SIZE, get('/session/:sessionId/element/:id/size')],
|
|
212
207
|
[cmd.Name.GET_ELEMENT_ATTRIBUTE, get('/session/:sessionId/element/:id/attribute/:name')],
|
|
213
208
|
[cmd.Name.GET_ELEMENT_VALUE_OF_CSS_PROPERTY, get('/session/:sessionId/element/:id/css/:propertyName')],
|
|
214
|
-
[cmd.Name.ELEMENT_EQUALS, get('/session/:sessionId/element/:id/equals/:other')],
|
|
215
209
|
[cmd.Name.TAKE_ELEMENT_SCREENSHOT, get('/session/:sessionId/element/:id/screenshot')],
|
|
216
210
|
[cmd.Name.SWITCH_TO_WINDOW, post('/session/:sessionId/window')],
|
|
217
211
|
[cmd.Name.MAXIMIZE_WINDOW, post('/session/:sessionId/window/current/maximize')],
|
|
@@ -227,57 +221,103 @@ const COMMAND_MAP = new Map([
|
|
|
227
221
|
[cmd.Name.SCREENSHOT, get('/session/:sessionId/screenshot')],
|
|
228
222
|
[cmd.Name.GET_TIMEOUT, get('/session/:sessionId/timeouts')],
|
|
229
223
|
[cmd.Name.SET_TIMEOUT, post('/session/:sessionId/timeouts')],
|
|
230
|
-
[cmd.Name.MOVE_TO, post('/session/:sessionId/moveto')],
|
|
231
|
-
[cmd.Name.CLICK, post('/session/:sessionId/click')],
|
|
232
|
-
[cmd.Name.DOUBLE_CLICK, post('/session/:sessionId/doubleclick')],
|
|
233
|
-
[cmd.Name.MOUSE_DOWN, post('/session/:sessionId/buttondown')],
|
|
234
|
-
[cmd.Name.MOUSE_UP, post('/session/:sessionId/buttonup')],
|
|
235
|
-
[cmd.Name.MOVE_TO, post('/session/:sessionId/moveto')],
|
|
236
|
-
[cmd.Name.SEND_KEYS_TO_ACTIVE_ELEMENT, post('/session/:sessionId/keys')],
|
|
237
|
-
[cmd.Name.TOUCH_SINGLE_TAP, post('/session/:sessionId/touch/click')],
|
|
238
|
-
[cmd.Name.TOUCH_DOUBLE_TAP, post('/session/:sessionId/touch/doubleclick')],
|
|
239
|
-
[cmd.Name.TOUCH_DOWN, post('/session/:sessionId/touch/down')],
|
|
240
|
-
[cmd.Name.TOUCH_UP, post('/session/:sessionId/touch/up')],
|
|
241
|
-
[cmd.Name.TOUCH_MOVE, post('/session/:sessionId/touch/move')],
|
|
242
|
-
[cmd.Name.TOUCH_SCROLL, post('/session/:sessionId/touch/scroll')],
|
|
243
|
-
[cmd.Name.TOUCH_LONG_PRESS, post('/session/:sessionId/touch/longclick')],
|
|
244
|
-
[cmd.Name.TOUCH_FLICK, post('/session/:sessionId/touch/flick')],
|
|
245
224
|
[cmd.Name.ACCEPT_ALERT, post('/session/:sessionId/accept_alert')],
|
|
246
225
|
[cmd.Name.DISMISS_ALERT, post('/session/:sessionId/dismiss_alert')],
|
|
247
226
|
[cmd.Name.GET_ALERT_TEXT, get('/session/:sessionId/alert_text')],
|
|
248
227
|
[cmd.Name.SET_ALERT_TEXT, post('/session/:sessionId/alert_text')],
|
|
249
|
-
[cmd.Name.SET_ALERT_CREDENTIALS, post('/session/:sessionId/alert/credentials')],
|
|
250
228
|
[cmd.Name.GET_LOG, post('/session/:sessionId/log')],
|
|
251
229
|
[cmd.Name.GET_AVAILABLE_LOG_TYPES, get('/session/:sessionId/log/types')],
|
|
252
230
|
[cmd.Name.GET_SESSION_LOGS, post('/logs')],
|
|
253
231
|
[cmd.Name.UPLOAD_FILE, post('/session/:sessionId/file')],
|
|
232
|
+
[cmd.Name.LEGACY_ACTION_CLICK, post('/session/:sessionId/click')],
|
|
233
|
+
[cmd.Name.LEGACY_ACTION_DOUBLE_CLICK, post('/session/:sessionId/doubleclick')],
|
|
234
|
+
[cmd.Name.LEGACY_ACTION_MOUSE_DOWN, post('/session/:sessionId/buttondown')],
|
|
235
|
+
[cmd.Name.LEGACY_ACTION_MOUSE_UP, post('/session/:sessionId/buttonup')],
|
|
236
|
+
[cmd.Name.LEGACY_ACTION_MOUSE_MOVE, post('/session/:sessionId/moveto')],
|
|
237
|
+
[cmd.Name.LEGACY_ACTION_SEND_KEYS, post('/session/:sessionId/keys')],
|
|
238
|
+
[cmd.Name.LEGACY_ACTION_TOUCH_DOWN, post('/session/:sessionId/touch/down')],
|
|
239
|
+
[cmd.Name.LEGACY_ACTION_TOUCH_UP, post('/session/:sessionId/touch/up')],
|
|
240
|
+
[cmd.Name.LEGACY_ACTION_TOUCH_MOVE, post('/session/:sessionId/touch/move')],
|
|
241
|
+
[cmd.Name.LEGACY_ACTION_TOUCH_SCROLL, post('/session/:sessionId/touch/scroll')],
|
|
242
|
+
[cmd.Name.LEGACY_ACTION_TOUCH_LONG_PRESS, post('/session/:sessionId/touch/longclick')],
|
|
243
|
+
[cmd.Name.LEGACY_ACTION_TOUCH_FLICK, post('/session/:sessionId/touch/flick')],
|
|
244
|
+
[cmd.Name.LEGACY_ACTION_TOUCH_SINGLE_TAP, post('/session/:sessionId/touch/click')],
|
|
245
|
+
[cmd.Name.LEGACY_ACTION_TOUCH_DOUBLE_TAP, post('/session/:sessionId/touch/doubleclick')],
|
|
254
246
|
]);
|
|
255
247
|
|
|
256
248
|
|
|
257
249
|
/** @const {!Map<string, (CommandSpec|CommandTransformer)>} */
|
|
258
250
|
const W3C_COMMAND_MAP = new Map([
|
|
251
|
+
// Server status.
|
|
252
|
+
[cmd.Name.GET_SERVER_STATUS, get('/status')],
|
|
253
|
+
// Session management.
|
|
254
|
+
[cmd.Name.NEW_SESSION, post('/session')],
|
|
255
|
+
[cmd.Name.QUIT, del('/session/:sessionId')],
|
|
256
|
+
[cmd.Name.GET_TIMEOUT, get('/session/:sessionId/timeouts')],
|
|
257
|
+
[cmd.Name.SET_TIMEOUT, post('/session/:sessionId/timeouts')],
|
|
258
|
+
// Navigation.
|
|
259
|
+
[cmd.Name.GET_CURRENT_URL, get('/session/:sessionId/url')],
|
|
260
|
+
[cmd.Name.GET, post('/session/:sessionId/url')],
|
|
261
|
+
[cmd.Name.GO_BACK, post('/session/:sessionId/back')],
|
|
262
|
+
[cmd.Name.GO_FORWARD, post('/session/:sessionId/forward')],
|
|
263
|
+
[cmd.Name.REFRESH, post('/session/:sessionId/refresh')],
|
|
264
|
+
// Page inspection.
|
|
265
|
+
[cmd.Name.GET_PAGE_SOURCE, get('/session/:sessionId/source')],
|
|
266
|
+
[cmd.Name.GET_TITLE, get('/session/:sessionId/title')],
|
|
267
|
+
// Script execution.
|
|
268
|
+
[cmd.Name.EXECUTE_SCRIPT, post('/session/:sessionId/execute/sync')],
|
|
269
|
+
[cmd.Name.EXECUTE_ASYNC_SCRIPT, post('/session/:sessionId/execute/async')],
|
|
270
|
+
// Frame selection.
|
|
271
|
+
[cmd.Name.SWITCH_TO_FRAME, post('/session/:sessionId/frame')],
|
|
272
|
+
[cmd.Name.SWITCH_TO_FRAME_PARENT, post('/session/:sessionId/frame/parent')],
|
|
273
|
+
// Window management.
|
|
274
|
+
[cmd.Name.GET_CURRENT_WINDOW_HANDLE, get('/session/:sessionId/window')],
|
|
275
|
+
[cmd.Name.CLOSE, del('/session/:sessionId/window')],
|
|
276
|
+
[cmd.Name.SWITCH_TO_WINDOW, post('/session/:sessionId/window')],
|
|
277
|
+
[cmd.Name.GET_WINDOW_HANDLES, get('/session/:sessionId/window/handles')],
|
|
278
|
+
[cmd.Name.GET_WINDOW_RECT, get('/session/:sessionId/window/rect')],
|
|
279
|
+
[cmd.Name.SET_WINDOW_RECT, post('/session/:sessionId/window/rect')],
|
|
280
|
+
[cmd.Name.MAXIMIZE_WINDOW, post('/session/:sessionId/window/maximize')],
|
|
281
|
+
[cmd.Name.MINIMIZE_WINDOW, post('/session/:sessionId/window/minimize')],
|
|
282
|
+
[cmd.Name.FULLSCREEN_WINDOW, post('/session/:sessionId/window/fullscreen')],
|
|
283
|
+
// Actions.
|
|
284
|
+
[cmd.Name.ACTIONS, post('/session/:sessionId/actions')],
|
|
285
|
+
[cmd.Name.CLEAR_ACTIONS, del('/session/:sessionId/actions')],
|
|
286
|
+
// Locating elements.
|
|
259
287
|
[cmd.Name.GET_ACTIVE_ELEMENT, get('/session/:sessionId/element/active')],
|
|
260
|
-
[cmd.Name.
|
|
261
|
-
[cmd.Name.
|
|
262
|
-
[cmd.Name.
|
|
263
|
-
[cmd.Name.
|
|
288
|
+
[cmd.Name.FIND_ELEMENT, post('/session/:sessionId/element')],
|
|
289
|
+
[cmd.Name.FIND_ELEMENTS, post('/session/:sessionId/elements')],
|
|
290
|
+
[cmd.Name.FIND_CHILD_ELEMENT, post('/session/:sessionId/element/:id/element')],
|
|
291
|
+
[cmd.Name.FIND_CHILD_ELEMENTS, post('/session/:sessionId/element/:id/elements')],
|
|
292
|
+
// Element interaction.
|
|
293
|
+
[cmd.Name.GET_ELEMENT_TAG_NAME, get('/session/:sessionId/element/:id/name')],
|
|
294
|
+
[cmd.Name.GET_ELEMENT_VALUE_OF_CSS_PROPERTY, get('/session/:sessionId/element/:id/css/:propertyName')],
|
|
295
|
+
[cmd.Name.GET_ELEMENT_RECT, get('/session/:sessionId/element/:id/rect')],
|
|
296
|
+
[cmd.Name.CLEAR_ELEMENT, post('/session/:sessionId/element/:id/clear')],
|
|
297
|
+
[cmd.Name.CLICK_ELEMENT, post('/session/:sessionId/element/:id/click')],
|
|
298
|
+
[cmd.Name.SEND_KEYS_TO_ELEMENT, post('/session/:sessionId/element/:id/value')],
|
|
299
|
+
[cmd.Name.GET_ELEMENT_TEXT, get('/session/:sessionId/element/:id/text')],
|
|
300
|
+
[cmd.Name.IS_ELEMENT_ENABLED, get('/session/:sessionId/element/:id/enabled')],
|
|
264
301
|
[cmd.Name.GET_ELEMENT_ATTRIBUTE, (cmd) => {
|
|
265
302
|
return toExecuteAtomCommand(cmd, Atom.GET_ATTRIBUTE, 'id', 'name');
|
|
266
303
|
}],
|
|
267
|
-
[cmd.Name.GET_ELEMENT_LOCATION, get('/session/:sessionId/element/:id/rect')],
|
|
268
|
-
[cmd.Name.GET_ELEMENT_SIZE, get('/session/:sessionId/element/:id/rect')],
|
|
269
304
|
[cmd.Name.IS_ELEMENT_DISPLAYED, (cmd) => {
|
|
270
305
|
return toExecuteAtomCommand(cmd, Atom.IS_DISPLAYED, 'id');
|
|
271
306
|
}],
|
|
272
|
-
|
|
273
|
-
[cmd.Name.
|
|
274
|
-
[cmd.Name.
|
|
275
|
-
[cmd.Name.
|
|
276
|
-
[cmd.Name.
|
|
277
|
-
[cmd.Name.
|
|
278
|
-
|
|
279
|
-
[cmd.Name.
|
|
280
|
-
[cmd.Name.
|
|
307
|
+
// Cookie management.
|
|
308
|
+
[cmd.Name.GET_ALL_COOKIES, get('/session/:sessionId/cookie')],
|
|
309
|
+
[cmd.Name.ADD_COOKIE, post('/session/:sessionId/cookie')],
|
|
310
|
+
[cmd.Name.DELETE_ALL_COOKIES, del('/session/:sessionId/cookie')],
|
|
311
|
+
[cmd.Name.GET_COOKIE, get('/session/:sessionId/cookie/:name')],
|
|
312
|
+
[cmd.Name.DELETE_COOKIE, del('/session/:sessionId/cookie/:name')],
|
|
313
|
+
// Alert management.
|
|
314
|
+
[cmd.Name.ACCEPT_ALERT, post('/session/:sessionId/alert/accept')],
|
|
315
|
+
[cmd.Name.DISMISS_ALERT, post('/session/:sessionId/alert/dismiss')],
|
|
316
|
+
[cmd.Name.GET_ALERT_TEXT, get('/session/:sessionId/alert/text')],
|
|
317
|
+
[cmd.Name.SET_ALERT_TEXT, post('/session/:sessionId/alert/text')],
|
|
318
|
+
// Screenshots.
|
|
319
|
+
[cmd.Name.SCREENSHOT, get('/session/:sessionId/screenshot')],
|
|
320
|
+
[cmd.Name.TAKE_ELEMENT_SCREENSHOT, get('/session/:sessionId/element/:id/screenshot')],
|
|
281
321
|
]);
|
|
282
322
|
|
|
283
323
|
|
|
@@ -301,35 +341,13 @@ class Client {
|
|
|
301
341
|
}
|
|
302
342
|
|
|
303
343
|
|
|
304
|
-
const CLIENTS =
|
|
305
|
-
/** !WeakMap<!Executor, !(Client|IThenable<!Client>)> */new WeakMap;
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
/**
|
|
309
|
-
* Sends a request using the given executor.
|
|
310
|
-
* @param {!Executor} executor
|
|
311
|
-
* @param {!Request} request
|
|
312
|
-
* @return {!Promise<Response>}
|
|
313
|
-
*/
|
|
314
|
-
function doSend(executor, request) {
|
|
315
|
-
const client = CLIENTS.get(executor);
|
|
316
|
-
if (promise.isPromise(client)) {
|
|
317
|
-
return client.then(client => {
|
|
318
|
-
CLIENTS.set(executor, client);
|
|
319
|
-
return client.send(request);
|
|
320
|
-
});
|
|
321
|
-
} else {
|
|
322
|
-
return client.send(request);
|
|
323
|
-
}
|
|
324
|
-
}
|
|
325
|
-
|
|
326
344
|
|
|
327
345
|
/**
|
|
328
346
|
* @param {Map<string, CommandSpec>} customCommands
|
|
329
347
|
* A map of custom command definitions.
|
|
330
348
|
* @param {boolean} w3c Whether to use W3C command mappings.
|
|
331
349
|
* @param {!cmd.Command} command The command to resolve.
|
|
332
|
-
* @return {!
|
|
350
|
+
* @return {!Request} A promise that will resolve with the
|
|
333
351
|
* command to execute.
|
|
334
352
|
*/
|
|
335
353
|
function buildRequest(customCommands, w3c, command) {
|
|
@@ -343,8 +361,8 @@ function buildRequest(customCommands, w3c, command) {
|
|
|
343
361
|
spec = W3C_COMMAND_MAP.get(command.getName());
|
|
344
362
|
if (typeof spec === 'function') {
|
|
345
363
|
LOG.finest(() => `Transforming command for W3C: ${command.getName()}`);
|
|
346
|
-
|
|
347
|
-
|
|
364
|
+
let newCommand = spec(command);
|
|
365
|
+
return buildRequest(customCommands, w3c, newCommand);
|
|
348
366
|
} else if (spec) {
|
|
349
367
|
return toHttpRequest(spec);
|
|
350
368
|
}
|
|
@@ -354,23 +372,26 @@ function buildRequest(customCommands, w3c, command) {
|
|
|
354
372
|
if (spec) {
|
|
355
373
|
return toHttpRequest(spec);
|
|
356
374
|
}
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
'Unrecognized command: ' + command.getName()));
|
|
375
|
+
throw new error.UnknownCommandError(
|
|
376
|
+
'Unrecognized command: ' + command.getName());
|
|
360
377
|
|
|
361
378
|
/**
|
|
362
379
|
* @param {CommandSpec} resource
|
|
363
|
-
* @return {!
|
|
380
|
+
* @return {!Request}
|
|
364
381
|
*/
|
|
365
382
|
function toHttpRequest(resource) {
|
|
366
383
|
LOG.finest(() => `Building HTTP request: ${JSON.stringify(resource)}`);
|
|
367
384
|
let parameters = command.getParameters();
|
|
368
385
|
let path = buildPath(resource.path, parameters);
|
|
369
|
-
return
|
|
386
|
+
return new Request(resource.method, path, parameters);
|
|
370
387
|
}
|
|
371
388
|
}
|
|
372
389
|
|
|
373
390
|
|
|
391
|
+
const CLIENTS =
|
|
392
|
+
/** !WeakMap<!Executor, !(Client|IThenable<!Client>)> */new WeakMap;
|
|
393
|
+
|
|
394
|
+
|
|
374
395
|
/**
|
|
375
396
|
* A command executor that communicates with the server using JSON over HTTP.
|
|
376
397
|
*
|
|
@@ -430,38 +451,41 @@ class Executor {
|
|
|
430
451
|
}
|
|
431
452
|
|
|
432
453
|
/** @override */
|
|
433
|
-
execute(command) {
|
|
454
|
+
async execute(command) {
|
|
434
455
|
let request = buildRequest(this.customCommands_, this.w3c, command);
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
456
|
+
this.log_.finer(() => `>>> ${request.method} ${request.path}`);
|
|
457
|
+
|
|
458
|
+
let client = CLIENTS.get(this);
|
|
459
|
+
if (promise.isPromise(client)) {
|
|
460
|
+
client = await client;
|
|
461
|
+
CLIENTS.set(this, client);
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
let response = await client.send(request);
|
|
465
|
+
this.log_.finer(() => `>>>\n${request}\n<<<\n${response}`);
|
|
466
|
+
|
|
467
|
+
let httpResponse = /** @type {!Response} */(response);
|
|
468
|
+
let {isW3C, value} = parseHttpResponse(command, httpResponse);
|
|
469
|
+
|
|
470
|
+
if (command.getName() === cmd.Name.NEW_SESSION) {
|
|
471
|
+
if (!value || !value.sessionId) {
|
|
472
|
+
throw new error.WebDriverError(
|
|
473
|
+
`Unable to parse new session response: ${response.body}`);
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
// The remote end is a W3C compliant server if there is no `status`
|
|
477
|
+
// field in the response.
|
|
478
|
+
if (command.getName() === cmd.Name.NEW_SESSION) {
|
|
479
|
+
this.w3c = this.w3c || isW3C;
|
|
480
|
+
}
|
|
481
|
+
|
|
482
|
+
// No implementations use the `capabilities` key yet...
|
|
483
|
+
let capabilities = value.capabilities || value.value;
|
|
484
|
+
return new Session(
|
|
485
|
+
/** @type {{sessionId: string}} */(value).sessionId, capabilities);
|
|
486
|
+
}
|
|
461
487
|
|
|
462
|
-
|
|
463
|
-
});
|
|
464
|
-
});
|
|
488
|
+
return typeof value === 'undefined' ? null : value;
|
|
465
489
|
}
|
|
466
490
|
}
|
|
467
491
|
|
|
@@ -510,8 +534,7 @@ function parseHttpResponse(command, httpResponse) {
|
|
|
510
534
|
|
|
511
535
|
// Adjust legacy new session responses to look like W3C to simplify
|
|
512
536
|
// later processing.
|
|
513
|
-
if (command.getName() === cmd.Name.NEW_SESSION
|
|
514
|
-
|| command.getName() == cmd.Name.DESCRIBE_SESSION) {
|
|
537
|
+
if (command.getName() === cmd.Name.NEW_SESSION) {
|
|
515
538
|
value = parsed;
|
|
516
539
|
}
|
|
517
540
|
|