From 82f2b76e25a4a67e01ec67e5ebe39d14ad771ea8 Mon Sep 17 00:00:00 2001 From: Florian Dold Date: Thu, 20 Apr 2017 03:09:25 +0200 Subject: Reorganize module loading. We now use webpack instead of SystemJS, effectively bundling modules into one file (plus commons chunks) for every entry point. This results in a much smaller extension size (almost half). Furthermore we use yarn/npm even for extension run-time dependencies. This relieves us from manually vendoring and building dependencies. It's also easier to understand for new developers familiar with node. --- node_modules/selenium-webdriver/lib/http.js | 102 +++++++++++++++------------- 1 file changed, 54 insertions(+), 48 deletions(-) (limited to 'node_modules/selenium-webdriver/lib/http.js') diff --git a/node_modules/selenium-webdriver/lib/http.js b/node_modules/selenium-webdriver/lib/http.js index 68bc43213..136a48e63 100644 --- a/node_modules/selenium-webdriver/lib/http.js +++ b/node_modules/selenium-webdriver/lib/http.js @@ -25,17 +25,26 @@ 'use strict'; -const fs = require('fs'); -const path = require('path'); - const cmd = require('./command'); -const devmode = require('./devmode'); const error = require('./error'); const logging = require('./logging'); const promise = require('./promise'); const Session = require('./session').Session; const WebElement = require('./webdriver').WebElement; +const {getAttribute, isDisplayed} = (function() { + try { + return { + getAttribute: require('./atoms/getAttribute.js'), + isDisplayed: require('./atoms/is-displayed.js') + }; + } catch (ex) { + throw Error( + 'Failed to import atoms modules. If running in devmode, you need to run' + + ' `./go node:atoms` from the project root: ' + ex); + } +})(); + /** * Converts a headers map to a HTTP header block string. @@ -116,43 +125,15 @@ class Response { const DEV_ROOT = '../../../../buck-out/gen/javascript/'; -/** @enum {string} */ +/** @enum {!Function} */ const Atom = { - GET_ATTRIBUTE: devmode - ? path.join(__dirname, DEV_ROOT, 'webdriver/atoms/getAttribute.js') - : path.join(__dirname, 'atoms/getAttribute.js'), - IS_DISPLAYED: devmode - ? path.join(__dirname, DEV_ROOT, 'atoms/fragments/is-displayed.js') - : path.join(__dirname, 'atoms/isDisplayed.js'), + GET_ATTRIBUTE: getAttribute, + IS_DISPLAYED: isDisplayed }; -const ATOMS = /** !Map> */new Map(); const LOG = logging.getLogger('webdriver.http'); -/** - * @param {Atom} file The atom file to load. - * @return {!Promise} A promise that will resolve to the contents of the - * file. - */ -function loadAtom(file) { - if (ATOMS.has(file)) { - return ATOMS.get(file); - } - let contents = /** !Promise */new Promise((resolve, reject) => { - LOG.finest(() => `Loading atom ${file}`); - fs.readFile(file, 'utf8', function(err, data) { - if (err) { - reject(err); - } else { - resolve(data); - } - }); - }); - ATOMS.set(file, contents); - return contents; -} - function post(path) { return resource('POST', path); } function del(path) { return resource('DELETE', path); } @@ -168,17 +149,26 @@ var CommandSpec; var CommandTransformer; +class InternalTypeError extends TypeError {} + + /** * @param {!cmd.Command} command The initial command. * @param {Atom} atom The name of the atom to execute. * @return {!Promise} The transformed command to execute. */ function toExecuteAtomCommand(command, atom, ...params) { - return loadAtom(atom).then(atom => { - return new cmd.Command(cmd.Name.EXECUTE_SCRIPT) + return new Promise((resolve, reject) => { + if (typeof atom !== 'function') { + reject(new InternalTypeError('atom is not a function: ' + typeof atom)); + return; + } + + let newCmd = new cmd.Command(cmd.Name.EXECUTE_SCRIPT) .setParameter('sessionId', command.getParameter('sessionId')) .setParameter('script', `return (${atom}).apply(null, arguments)`) .setParameter('args', params.map(param => command.getParameter(param))); + resolve(newCmd); }); } @@ -269,6 +259,8 @@ const W3C_COMMAND_MAP = new Map([ [cmd.Name.GET_ELEMENT_ATTRIBUTE, (cmd) => { return toExecuteAtomCommand(cmd, Atom.GET_ATTRIBUTE, 'id', 'name'); }], + [cmd.Name.GET_ELEMENT_LOCATION, get('/session/:sessionId/element/:id/rect')], + [cmd.Name.GET_ELEMENT_SIZE, get('/session/:sessionId/element/:id/rect')], [cmd.Name.IS_ELEMENT_DISPLAYED, (cmd) => { return toExecuteAtomCommand(cmd, Atom.IS_DISPLAYED, 'id'); }], @@ -437,7 +429,8 @@ class Executor { this.log_.finer(() => `>>>\n${request}\n<<<\n${response}`); let parsed = - parseHttpResponse(/** @type {!Response} */ (response), this.w3c); + parseHttpResponse( + command, /** @type {!Response} */ (response), this.w3c); if (command.getName() === cmd.Name.NEW_SESSION || command.getName() === cmd.Name.DESCRIBE_SESSION) { @@ -447,7 +440,7 @@ class Executor { } // The remote end is a W3C compliant server if there is no `status` - // field in the response. This is not appliable for the DESCRIBE_SESSION + // field in the response. This is not applicable for the DESCRIBE_SESSION // command, which is not defined in the W3C spec. if (command.getName() === cmd.Name.NEW_SESSION) { this.w3c = this.w3c || !('status' in parsed); @@ -485,29 +478,42 @@ function tryParse(str) { /** * Callback used to parse {@link Response} objects from a * {@link HttpClient}. + * + * @param {!cmd.Command} command The command the response is for. * @param {!Response} httpResponse The HTTP response to parse. * @param {boolean} w3c Whether the response should be processed using the * W3C wire protocol. * @return {?} The parsed response. * @throws {WebDriverError} If the HTTP response is an error. */ -function parseHttpResponse(httpResponse, w3c) { +function parseHttpResponse(command, httpResponse, w3c) { let parsed = tryParse(httpResponse.body); if (parsed !== undefined) { + if (httpResponse.status < 200) { + // This should never happen, but throw the raw response so + // users report it. + throw new error.WebDriverError( + `Unexpected HTTP response:\n${httpResponse}`); + } + if (w3c) { if (httpResponse.status > 399) { error.throwDecodedError(parsed); } + return parsed; + } - if (httpResponse.status < 200) { - // This should never happen, but throw the raw response so - // users report it. - throw new error.WebDriverError( - `Unexpected HTTP response:\n${httpResponse}`); - } - } else { - error.checkLegacyResponse(parsed); + // If this is a new session command, we need to check for a W3C compliant + // error object. This is necessary since a successful new session command + // is what puts the executor into W3C mode. + if (httpResponse.status > 399 + && (command.getName() == cmd.Name.NEW_SESSION + || command.getName() === cmd.Name.DESCRIBE_SESSION) + && error.isErrorResponse(parsed)) { + error.throwDecodedError(parsed); } + + error.checkLegacyResponse(parsed); return parsed; } -- cgit v1.2.3