From e0289321186cb08f5863077d02357dc67c715bde Mon Sep 17 00:00:00 2001 From: Jason Leyba Date: Fri, 12 Sep 2014 10:22:56 -0700 Subject: [PATCH] JS: Address flakiness with setting copying a Firefox profile The third-party package used to copy a template Firefox profile would somtimes fail to copy all of the files in a directory. This would yield an incomplete profile causing the FirefoxDriver to fail to initialize properly (up to 10% failrue rate on OS X 10.9.4 with node 0.10.x). This change removes the problematic dependency infavor of a simple, synchronous, recursive copy. At some point I will revisit this change to support fully asynchronous copying. --- javascript/node/selenium-webdriver/CHANGES.md | 5 ++ .../node/selenium-webdriver/io/index.js | 55 +++++++++++-------- .../node/selenium-webdriver/package.json | 3 +- 3 files changed, 37 insertions(+), 26 deletions(-) diff --git a/javascript/node/selenium-webdriver/CHANGES.md b/javascript/node/selenium-webdriver/CHANGES.md index d9511d32babe9..504a5676e88df 100644 --- a/javascript/node/selenium-webdriver/CHANGES.md +++ b/javascript/node/selenium-webdriver/CHANGES.md @@ -1,3 +1,8 @@ +## v2.43.1 + +* Fixed an issue with flakiness when setting up the Firefox profile that could + prevent the driver from initializing properly. + ## v2.43.0 * Added native support for Firefox - the Java Selenium server is no longer diff --git a/javascript/node/selenium-webdriver/io/index.js b/javascript/node/selenium-webdriver/io/index.js index ffe39c844fb04..a356ef6d386c5 100644 --- a/javascript/node/selenium-webdriver/io/index.js +++ b/javascript/node/selenium-webdriver/io/index.js @@ -14,7 +14,6 @@ // limitations under the License. var fs = require('fs'), - ncp = require('ncp').ncp, path = require('path'), tmp = require('tmp'); @@ -24,25 +23,6 @@ var promise = require('..').promise; var PATH_SEPARATOR = process.platform === 'win32' ? ';' : ':'; -/** - * Creates the specified directory and any necessary parent directories. No - * action is taken if the directory already exists. - * @param {string} dir The directory to create. - * @param {function(Error)} callback Callback function; accepts a single error - * or {@code null}. - */ -function createDirectories(dir, callback) { - fs.mkdir(dir, function(err) { - if (!err || err.code === 'EEXIST') { - callback(); - } else { - createDirectories(path.dirname(dir), function(err) { - err && callback(err) || fs.mkdir(dir, callback); - }); - } - }); -}; - // PUBLIC API @@ -89,11 +69,38 @@ exports.copyDir = function(src, dst, opt_exclude) { }; } - var copied = promise.defer(); - ncp(src, dst, {filter: predicate}, function(err) { - err && copied.reject(err) || copied.fulfill(dst); + // TODO(jleyba): Make this function completely async. + if (!fs.existsSync(dst)) { + fs.mkdirSync(dst); + } + + var files = fs.readdirSync(src); + files = files.map(function(file) { + return path.join(src, file); + }); + + if (predicate) { + files = files.filter(predicate); + } + + var results = []; + files.forEach(function(file) { + var stats = fs.statSync(file); + var target = path.join(dst, path.basename(file)); + + if (stats.isDirectory()) { + if (!fs.existsSync(target)) { + fs.mkdirSync(target, stats.mode); + } + results.push(exports.copyDir(file, target, predicate)); + } else { + results.push(exports.copy(file, target)); + } + }); + + return promise.all(results).then(function() { + return dst; }); - return copied.promise; }; diff --git a/javascript/node/selenium-webdriver/package.json b/javascript/node/selenium-webdriver/package.json index 79240ef338ea4..b52eb57d9d93a 100644 --- a/javascript/node/selenium-webdriver/package.json +++ b/javascript/node/selenium-webdriver/package.json @@ -1,6 +1,6 @@ { "name": "selenium-webdriver", - "version": "2.43.0", + "version": "2.43.1", "description": "The official WebDriver JavaScript bindings from the Selenium project", "keywords": [ "automation", @@ -23,7 +23,6 @@ }, "dependencies": { "adm-zip": "0.4.4", - "ncp": "0.6.0", "tmp": "0.0.24", "xml2js": "0.4.4" },