Skip to content

Commit

Permalink
Include unit tests for Closure-based js code with selenium-webdriver …
Browse files Browse the repository at this point in the history
…package.
  • Loading branch information
jleyba committed Jul 16, 2014
1 parent 6f810c4 commit c1b1b2a
Show file tree
Hide file tree
Showing 5 changed files with 203 additions and 58 deletions.
1 change: 1 addition & 0 deletions javascript/node/build.desc
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ node_module(
deps = [
"//javascript/webdriver:asserts_lib",
"//javascript/webdriver:webdriver_lib",
"//javascript/webdriver:unit_test_lib",
],
content_roots = [
"javascript",
Expand Down
58 changes: 40 additions & 18 deletions javascript/node/deploy.js
Original file line number Diff line number Diff line change
Expand Up @@ -199,12 +199,17 @@ function copyLibraries(outputDirPath, filePaths) {
var seenFiles = {};
var symbols = [];
var providedSymbols = [];
var rootFiles = [];
filePaths.filter(function(path) {
return !fs.statSync(path).isDirectory();
}).forEach(function(path) {
if (!FILE_INFO[path].provides.length) {
rootFiles.push(path);
}
providedSymbols = providedSymbols.concat(FILE_INFO[path].provides);
symbols = symbols.concat(FILE_INFO[path].requires);
});
rootFiles.forEach(processFile);
providedSymbols.forEach(resolveDeps);
symbols.forEach(resolveDeps);

Expand All @@ -220,7 +225,10 @@ function copyLibraries(outputDirPath, filePaths) {
'; required in\n ' + UNPROVIDED[symbol].join('\n '));
}

var file = PROVIDERS[symbol];
processFile(PROVIDERS[symbol]);
}

function processFile(file) {
if (seenFiles[file]) return;
seenFiles[file] = true;

Expand Down Expand Up @@ -321,40 +329,55 @@ function copyResources(outputDirPath, resources, exclusions) {
}


function generateDocs(outputDir) {
function generateDocs(outputDir, callback) {
var libDir = path.join(outputDir, 'lib');
var excludedDirs = [
path.join(outputDir, 'example'),
path.join(libDir, 'test'),
path.join(libDir, 'webdriver/test'),
path.join(outputDir, 'test')
];

var excludedFiles = [
path.join(libDir, 'webdriver/testing/client.js'),
path.join(libDir, 'webdriver/testing/flowtester.js'),
path.join(libDir, 'webdriver/testing/jsunit.js'),
path.join(libDir, 'webdriver/testing/window.js'),
];

var endsWith = function(str, suffix) {
var l = str.length - suffix.length;
return l >= 0 && str.indexOf(suffix, l) == l;
};

var getFiles = function(dir) {
return fs.readdirSync(dir).map(function(file) {
return path.join(dir, file);
}).filter(function(file) {
if (fs.statSync(file).isDirectory()) {
return excludedDirs.indexOf(file) == -1;
var files = [];
fs.readdirSync(dir).forEach(function(file) {
file = path.join(dir, file);
if (fs.statSync(file).isDirectory() &&
excludedDirs.indexOf(file) == -1) {
files = files.concat(getFiles(file));
} else if (endsWith(path.basename(file), '.js') &&
excludedFiles.indexOf(file) == -1) {
files.push(file);
}
return endsWith(path.basename(file), '.js');
});
return files;
};

var sourceFiles = getFiles(libDir);
var moduleFiles = getFiles(outputDir).filter(function(file) {
return sourceFiles.indexOf(file) == -1;
});

var config = {
'output': path.join(outputDir, 'docs'),
'closureLibraryDir': path.join(outputDir, 'lib', 'goog'),
'license': path.join(outputDir, 'COPYING'),
'readme': path.join(outputDir, 'README.md'),
'language': 'ES5',
'sources': getFiles(libDir),
'modules': getFiles(outputDir).filter(function(file) {
return file != libDir;
})
'sources': sourceFiles,
'modules': moduleFiles
};

var configFile = outputDir + '-docs.json';
Expand All @@ -365,9 +388,7 @@ function generateDocs(outputDir) {
__dirname, '../../third_party/java/dossier/dossier-0.3.0.jar'),
'-c', configFile
].join(' ');
child_process.exec(command, function(error) {
if (error) throw error;
});
child_process.exec(command, callback);
}


Expand Down Expand Up @@ -423,9 +444,10 @@ function main() {
console.log('Copying resource files...');
copyResources(options.output, options.resource, options.exclude_resource);
console.log('Generating documentation...');
generateDocs(options.output);

console.log('ALL DONE');
generateDocs(options.output, function(e) {
if (e) throw e;
console.log('ALL DONE');
});
}


Expand Down
90 changes: 52 additions & 38 deletions javascript/node/selenium-webdriver/_base.js
Original file line number Diff line number Diff line change
Expand Up @@ -74,46 +74,59 @@ var DEPS_FILE_PATH = (function() {
})();



/**
* Synchronously loads a script into the protected Closure context.
* @param {string} src Path to the file to load.
* Maintains a unique context for Closure library-based code.
* @param {boolean=} opt_configureForTesting Whether to configure a fake DOM
* for Closure-testing code that (incorrectly) assumes a DOM is always
* present.
* @constructor
*/
function loadScript(src) {
src = path.normalize(src);
var contents = fs.readFileSync(src, 'utf8');
vm.runInContext(contents, closure, src);
function Context(opt_configureForTesting) {
var closure = this.closure = vm.createContext({
console: console,
setTimeout: setTimeout,
setInterval: setInterval,
clearTimeout: clearTimeout,
clearInterval: clearInterval,
process: process,
require: require,
Buffer: Buffer,
Error: Error,
CLOSURE_BASE_PATH: path.dirname(CLOSURE_BASE_FILE_PATH) + '/',
CLOSURE_IMPORT_SCRIPT: function(src) {
loadScript(src);
return true;
},
CLOSURE_NO_DEPS: !isDevMode(),
goog: {}
});
closure.window = closure.top = closure;

if (opt_configureForTesting) {
closure.document = {
body: {},
createElement: function() { return {}; },
getElementsByTagName: function() { return []; }
};
closure.document.body.ownerDocument = closure.document;
}

loadScript(CLOSURE_BASE_FILE_PATH);
loadScript(DEPS_FILE_PATH);

/**
* Synchronously loads a script into the protected Closure context.
* @param {string} src Path to the file to load.
*/
function loadScript(src) {
src = path.normalize(src);
var contents = fs.readFileSync(src, 'utf8');
vm.runInContext(contents, closure, src);
}
}


/**
* The protected context to host the Closure library.
* @type {!Object}
* @const
*/
var closure = vm.createContext({
console: console,
setTimeout: setTimeout,
setInterval: setInterval,
clearTimeout: clearTimeout,
clearInterval: clearInterval,
process: process,
require: require,
Buffer: Buffer,
Error: Error,
CLOSURE_BASE_PATH: path.dirname(CLOSURE_BASE_FILE_PATH) + '/',
CLOSURE_IMPORT_SCRIPT: function(src) {
loadScript(src);
return true;
},
CLOSURE_NO_DEPS: !isDevMode(),
goog: {}
});
closure.window = closure;


loadScript(CLOSURE_BASE_FILE_PATH);
loadScript(DEPS_FILE_PATH);
var context = new Context();


/**
Expand All @@ -123,8 +136,8 @@ loadScript(DEPS_FILE_PATH);
* @throws {Error} If the symbol has not been defined.
*/
function closureRequire(symbol) {
closure.goog.require(symbol);
return closure.goog.getObjectByName(symbol);
context.closure.goog.require(symbol);
return context.closure.goog.getObjectByName(symbol);
}


Expand Down Expand Up @@ -159,7 +172,8 @@ exports.exportPublicApi = function(symbol) {


if (isDevMode()) {
exports.closure = closure;
exports.closure = context.closure;
}
exports.Context = Context;
exports.isDevMode = isDevMode;
exports.require = closureRequire;
97 changes: 97 additions & 0 deletions javascript/node/selenium-webdriver/test/_base_test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
// Copyright 2014 Software Freedom Conservancy. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

var assert = require('assert'),
fs = require('fs'),
path = require('path');

var base = require('../_base');

describe('Context', function() {
it('does not pollute the global scope', function() {
assert.equal('undefined', typeof goog);

var context = new base.Context();
assert.equal('undefined', typeof goog);
assert.equal('object', typeof context.closure.goog);

context.closure.goog.require('goog.array');
assert.equal('undefined', typeof goog);
assert.equal('object', typeof context.closure.goog.array);
});
});


function runClosureTest(file) {
var name = path.basename(file);
name = name.substring(0, name.length - '.js'.length);

describe(name, function() {
var context = new base.Context(true);
context.closure.document.title = name;
// Null out console so everything loads silently.
context.closure.console = null;
context.closure.CLOSURE_IMPORT_SCRIPT(file);

var tc = context.closure.G_testRunner.testCase;
if (!tc) {
tc = new context.closure.goog.testing.TestCase(name);
tc.autoDiscoverTests();
}
// Reset console for running tests.
context.closure.console = console;

var allTests = tc.getTests();
allTests.forEach(function(test) {
it(test.name, function(done) {
tc.setTests([test]);
tc.setCompletedCallback(function() {
if (tc.isSuccess()) {
return done();
}
var results = tc.getTestResults();
done(Error('\n' + Object.keys(results).map(function(name) {
var msg = [name + ': ' + (results[name].length ? 'FAILED' : 'PASSED')];
if (results[name].length) {
msg = msg.concat(results[name]);
}
return msg.join('\n');
}).join('\n')));
});
tc.runTests();
});
});
});
}


function findTests(dir) {
fs.readdirSync(dir).forEach(function(name) {
var file = path.join(dir, name);

var stat = fs.statSync(file);
if (stat.isDirectory() && name !== 'atoms' && name !== 'e2e') {
findTests(file);
return;
}

var l = file.length - '_test.js'.length;
if (l >= 0 && file.indexOf('_test.js', l) == l) {
runClosureTest(file);
}
});
}

findTests(path.join(
__dirname, base.isDevMode() ? '../../..' : '../lib', 'webdriver/test'));
15 changes: 13 additions & 2 deletions javascript/webdriver/build.desc
Original file line number Diff line number Diff line change
Expand Up @@ -32,14 +32,25 @@ js_library(name = "asserts_lib",
srcs = ["testing/asserts.js"],
deps = [":webdriver_lib"])

js_library(name = "test_lib",
js_library(name = "test_support_lib",
srcs = [
"testing/*.js",
],
deps = [
":webdriver_lib"
])

js_library(name = "unit_test_lib",
srcs = [
"test/*.js",
"test/http/*.js",
"test/testing/*.js",
],
deps = [
":webdriver_lib",
":test_support_lib",
])

js_deps(name = "deps",
srcs = [
"*.js",
Expand Down Expand Up @@ -96,7 +107,7 @@ js_test(name = "test",
"test/**/*_test.html",
],
deps = [
":test_lib",
":test_support_lib",
"//java/client/test/org/openqa/selenium/javascript",
"//java/server/test/org/openqa/selenium:server-with-tests:uber",
])

0 comments on commit c1b1b2a

Please sign in to comment.