From 5c82646648881c104b28c9fb24621284b437172c Mon Sep 17 00:00:00 2001 From: Jason Leyba Date: Mon, 21 Nov 2016 12:02:38 -0800 Subject: [PATCH] [js] Fix atoms usage to remain platform agnostic Fixes #3121 --- .gitignore | 1 + Rakefile | 28 ++++++-- javascript/node/gendocs.js | 1 + javascript/node/selenium-webdriver/CHANGES.md | 4 ++ javascript/node/selenium-webdriver/lib/README | 5 +- .../node/selenium-webdriver/lib/http.js | 65 ++++++++----------- 6 files changed, 60 insertions(+), 44 deletions(-) diff --git a/.gitignore b/.gitignore index 4c25509cbc45d..1c14cf6c0158d 100644 --- a/.gitignore +++ b/.gitignore @@ -16,6 +16,7 @@ common/build cpp/iedriver/IEReturnTypes.h java/client/src/org/openqa/selenium/ie/IeReturnTypes.java javascript/deps.js +javascript/node/selenium-webdriver/lib/atoms/ javascript/node/selenium-webdriver/node_modules/ javascript/safari-driver/node_modules/ .idea/vcs.xml diff --git a/Rakefile b/Rakefile index d5024400238b6..9e9171c3b44d2 100644 --- a/Rakefile +++ b/Rakefile @@ -557,12 +557,34 @@ task :release_ide => [:ide] do end namespace :node do + task :atoms => [ + "//javascript/atoms/fragments:is-displayed", + "//javascript/webdriver/atoms:getAttribute", + ] do + baseDir = "javascript/node/selenium-webdriver/lib/atoms" + mkdir_p baseDir + + [ + Rake::Task["//javascript/atoms/fragments:is-displayed"].out, + Rake::Task["//javascript/webdriver/atoms:getAttribute"].out, + ].each do |atom| + name = File.basename(atom) + + puts "Generating #{atom} as #{name}" + File.open(File.join(baseDir, name), "w") do |f| + f << "// GENERATED CODE - DO NOT EDIT\n" + f << "module.exports = " + f << IO.read(atom).strip + f << ";\n" + end + end + end + task :deploy => [ + "node:atoms", "//cpp:noblur", "//cpp:noblur64", - "//javascript/atoms/fragments:is-displayed", "//javascript/firefox-driver:webdriver", - "//javascript/webdriver/atoms:getAttribute", ] do cmd = "node javascript/node/deploy.js" << " --output=build/javascript/node/selenium-webdriver" << @@ -572,8 +594,6 @@ namespace :node do " --resource=build/cpp/amd64/libnoblur64.so:firefox/amd64/libnoblur64.so" << " --resource=build/cpp/i386/libnoblur.so:firefox/i386/libnoblur.so" << " --resource=build/javascript/firefox-driver/webdriver.xpi:firefox/webdriver.xpi" << - " --resource=buck-out/gen/javascript/webdriver/atoms/getAttribute.js:atoms/getAttribute.js" << - " --resource=buck-out/gen/javascript/atoms/fragments/is-displayed.js:atoms/isDisplayed.js" << " --resource=common/src/web/:test/data/" << " --exclude_resource=common/src/web/Bin" << " --exclude_resource=.gitignore" << diff --git a/javascript/node/gendocs.js b/javascript/node/gendocs.js index 413c75ac60c59..881da8fa9e516 100644 --- a/javascript/node/gendocs.js +++ b/javascript/node/gendocs.js @@ -111,6 +111,7 @@ function getModules() { console.log('Scanning sources...'); const excludeDirs = [ path.join(__dirname, 'selenium-webdriver/example'), + path.join(__dirname, 'selenium-webdriver/lib/atoms'), path.join(__dirname, 'selenium-webdriver/lib/firefox'), path.join(__dirname, 'selenium-webdriver/lib/safari'), path.join(__dirname, 'selenium-webdriver/lib/test'), diff --git a/javascript/node/selenium-webdriver/CHANGES.md b/javascript/node/selenium-webdriver/CHANGES.md index b9ac5fd229ea9..34527fbb5ab11 100644 --- a/javascript/node/selenium-webdriver/CHANGES.md +++ b/javascript/node/selenium-webdriver/CHANGES.md @@ -1,3 +1,7 @@ +## v.next + +* The `lib` package is once again platform agnostic (excluding `lib/devmode`). + ## v3.0.1 * More API adjustments to align with native Promises diff --git a/javascript/node/selenium-webdriver/lib/README b/javascript/node/selenium-webdriver/lib/README index 583293864a1a2..c39abbece1348 100644 --- a/javascript/node/selenium-webdriver/lib/README +++ b/javascript/node/selenium-webdriver/lib/README @@ -1,6 +1,5 @@ This directory contains modules internal to selenium-webdriver that are not intended for general consumption. They may change at any time. -With the exception of the test/ directory, all files under this directory -may only depend on built-in JavaScript features and other modules in the -directory. +All files in this directory and the atoms/ subdirectory may only depend on +built-in JavaScript features and other modules in this directory. diff --git a/javascript/node/selenium-webdriver/lib/http.js b/javascript/node/selenium-webdriver/lib/http.js index 68bc43213c0a9..7413d74edea3c 100644 --- a/javascript/node/selenium-webdriver/lib/http.js +++ b/javascript/node/selenium-webdriver/lib/http.js @@ -25,17 +25,27 @@ '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() { + const load = path => /** @type {!Function} */(require(path)); + try { + return { + getAttribute: load('./atoms/getAttribute.js'), + isDisplayed: load('./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 +126,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 +150,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); }); }