Skip to content

Commit

Permalink
[js] Fix atoms usage to remain platform agnostic
Browse files Browse the repository at this point in the history
  • Loading branch information
jleyba committed Nov 21, 2016
1 parent 3b95afa commit 5c82646
Show file tree
Hide file tree
Showing 6 changed files with 60 additions and 44 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
28 changes: 24 additions & 4 deletions Rakefile
Original file line number Diff line number Diff line change
Expand Up @@ -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" <<
Expand All @@ -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" <<
Expand Down
1 change: 1 addition & 0 deletions javascript/node/gendocs.js
Original file line number Diff line number Diff line change
Expand Up @@ -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'),
Expand Down
4 changes: 4 additions & 0 deletions javascript/node/selenium-webdriver/CHANGES.md
Original file line number Diff line number Diff line change
@@ -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
Expand Down
5 changes: 2 additions & 3 deletions javascript/node/selenium-webdriver/lib/README
Original file line number Diff line number Diff line change
@@ -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.
65 changes: 28 additions & 37 deletions javascript/node/selenium-webdriver/lib/http.js
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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<string, !Promise<string>> */new Map();
const LOG = logging.getLogger('webdriver.http');

/**
* @param {Atom} file The atom file to load.
* @return {!Promise<string>} 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<string> */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); }
Expand All @@ -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<!cmd.Command>} 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);
});
}

Expand Down

0 comments on commit 5c82646

Please sign in to comment.