Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .eslintrc
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"eslint:recommended"
],
"parserOptions": {
"ecmaVersion": 6,
"ecmaVersion": 8,
"sourceType": "module"
},
"plugins": [
Expand Down
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# nemo-core CHANGELOG

## UNRELEASED (breaking)

- upgrade to selenium@4
- refactor away from callbacks (where required so far)
- remove the `selenium.version` feature

## v1.1.3

- Fix npm audit issues
Expand Down
26 changes: 3 additions & 23 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -479,20 +479,6 @@ Useful such functions are:

The nemo setup routine will prefer these "builder" properties over other abstracted properties above, if there is a conflict.

#### selenium.version (optional)

Since nemo requires a narrow range of versions of selenium-webdriver, you may have a need to upgrade selenium-webdriver (or downgrade) outside of the supported versions that nemo uses.
You can do that by using `selenium.version`. E.g.

```js
"driver": {
"browser": "firefox",
"selenium.version": "^2.53.1"
}
```

Nemo-core will upgrade its internal dependency to what is set in this property. The `npm install` will only run if the version specified is not already installed.

#### custom driver

You can also provide a module, which exports a function that returns a fully formed `WebDriver` object. To do so, follow
Expand Down Expand Up @@ -683,18 +669,12 @@ Because we NEed MOre automation testing!

## Unit Tests

* Unit tests run by default using headless browser [PhantomJS](http://phantomjs.org/). To run unit tests out of box, You must have PhantomJS installed on your system and must be present in the path
* Download PhantomJS from [here](http://phantomjs.org/download.html)
* On OSX, you can optionally use `brew` to install PhantomJS like `brew install phantomjs`
* PhantomJS installation detailed guide on Ubuntu can be found [here](https://gist.github.com/julionc/7476620)

* If you want to run unit tests on your local browser, like lets say Firefox/Chrome (make sure ChromeDriver is in current path), you need to update browser in unit test
configuration, for example the browser section under `test/config/config.json` like [here](https://github.com/paypal/nemo-core/blob/master/test/config/config.json#L19)
* Unit tests run by default using Chrome and Firefox.
* The `latest` versions of geckodriver and chromedriver binaries will be installed by default
* You'll need to ensure you have the proper versions of the two browsers installed locally per the driver versions.

* How to run unit tests?
* `npm test` will run unit tests as well as lint task
* `grunt simplemocha` will just run unit tests
* `grunt` - default grunt task will run linting as well as unit tests
* To run directly using mocha assuming its globally installed on your system `mocha -t 60s`
* Or a specific test, `mocha --grep @allArgs@ -t 60s`
* Or post `npm install` on nemo module, you can run `node_modules/.bin/mocha --grep @allArgs@ -t 60s`
45 changes: 24 additions & 21 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,11 @@
│ limitations under the License. │
\*───────────────────────────────────────────────────────────────────────────*/

const Promiz = require('./lib/promise');
const Configure = require('./lib/configure');
const Setup = require('./lib/setup');
const debug = require('debug');
const log = debug('nemo-core:log');
const error = debug('nemo-core:error');
const _ = require('lodash');
const path = require('path');

log.log = console.log.bind(console);
error.log = console.error.bind(console);
Expand All @@ -32,12 +29,15 @@ error.log = console.error.bind(console);
*
*/

module.exports = function Nemo(_basedir, _configOverride, _cb) {
module.exports = async function Nemo(_basedir, _configOverride, _cb) {
log('Nemo constructor begin');
//argument vars
var basedir, configOverride, cb, promiz;
var basedir, configOverride, cb;
var nemo = {};

//promise
let resolve, reject;
let prom;
//check for confit object as single parameter
if (arguments.length === 1 && arguments[0].get) {
return Setup(arguments[0]);
Expand All @@ -52,28 +52,31 @@ module.exports = function Nemo(_basedir, _configOverride, _cb) {
configOverride = configOverride || {};
if (!cb) {
log('returning promise');
promiz = Promiz();
prom = new Promise((yay, boo) => {
resolve = yay;
reject = boo;
});
cb = function (err, n) {
if (err) {
return promiz.reject(err);
return reject(err);
}
promiz.fulfill(n);
return resolve(n);
};
}
}
log('basedir', basedir);
log('configOverride', configOverride);
Configure(basedir, configOverride)
.then(function (config) {
log('Configure complete');
return Setup(config);
})
.then(function (_nemo) {
log('Setup complete');
_.merge(nemo, _nemo);
return cb(null, nemo);
})
.catch(cb);
return promiz && promiz.promise || nemo;
try {
let config = await Configure(basedir, configOverride);
let _nemo = await Setup(config);
log('Setup complete');
nemo = Object.assign({}, nemo, _nemo);
cb(null, nemo);
} catch(err) {
error(`error in Nemo constructor ${err}`)
cb(err);
}

return prom || nemo;
};

module.exports.Configure = Configure;
16 changes: 9 additions & 7 deletions lib/configure.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,9 @@ const log = debug('nemo-core:log');
const confit = require('confit');
const _ = require('lodash');
const path = require('path');
const Promiz = require('./promise');
const handlers = require('shortstop-handlers');
const yargs = require('yargs');
const error = debug('nemo-core:error');

log.log = console.log.bind(console);
error.log = console.error.bind(console);

Expand All @@ -20,10 +18,14 @@ module.exports = function Configure(_basedir, _configOverride) {
configOverride = !configOverride && arguments.length && arguments[1] && typeof arguments[1] === 'object' ? arguments[1] : configOverride;
configOverride = !configOverride ? {} : configOverride;

//promise
let resolve, reject;
let prom = new Promise((yay, boo) => {
resolve = yay;
reject = boo;
});
log('basedir %s, configOverride %o', basedir, configOverride);

let prom = Promiz();

//hack because confit doesn't JSON.parse environment variables before merging
//look into using shorstop handler or pseudo-handler in place of this
let envdata = envToJSON('data');
Expand Down Expand Up @@ -61,11 +63,11 @@ module.exports = function Configure(_basedir, _configOverride) {
envdriver.reset();
envplugins.reset();
if (err) {
return prom.reject(err);
return reject(err);
}
prom.fulfill(config);
resolve(config);
});
return prom.promise;
return prom;
};

let envToJSON = function (prop) {
Expand Down
19 changes: 8 additions & 11 deletions lib/plugin.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
const debug = require('debug');
const log = debug('nemo-core:log');
const error = debug('nemo-core:error');
const Promiz = require('./promise');

log.log = console.log.bind(console);
error.log = console.error.bind(console);
Expand All @@ -15,10 +14,9 @@ module.exports.compare = function (a, b) {
return ap - bp;
};

module.exports.registration = function (nemo, plugins) {
module.exports.registration = async function (nemo, plugins) {
log('plugin.registration start');
let promiz = Promiz(),
pluginError,
let pluginError,
registerFns = [];
let pluginErrored = Object.keys(plugins || {}).find(function pluginsKeys(key) {
let pluginConfig = plugins[key],
Expand All @@ -41,27 +39,26 @@ module.exports.registration = function (nemo, plugins) {
}

registerFns.push({
fn: pluginReg(nemo, pluginArgs, pluginModule),
fn: pluginReg(nemo, pluginArgs, pluginModule, key),
key: key,
priority: pluginConfig.priority || -1
});
return false;
});

if (pluginErrored) {
error(pluginError);
promiz.reject(pluginError);
error(`pluginError: ${pluginError}`);
throw pluginError;

} else {
log(`plugin.registration fulfill with ${registerFns.length} plugins.`);
promiz.fulfill(registerFns);
return Promise.resolve(registerFns);
}
return promiz.promise;
};

let pluginReg = function (_nemo, pluginArgs, pluginModule) {
let pluginReg = function (_nemo, pluginArgs, pluginModule, key) {
return function pluginReg(callback) {

log(`pluginReg for ${key}`)
pluginArgs.push(_nemo);
pluginArgs.push(callback);
try {
Expand Down
18 changes: 0 additions & 18 deletions lib/promise.js

This file was deleted.

92 changes: 46 additions & 46 deletions lib/setup.js
Original file line number Diff line number Diff line change
@@ -1,51 +1,56 @@
const Plugin = require('./plugin');
const wd = require('selenium-webdriver');
const Promiz = require('./promise');
const debug = require('debug');
const log = debug('nemo-core:log');
const error = debug('nemo-core:error');
const async = require('async');
const Driver = require('./driver');

log.log = console.log.bind(console);
error.log = console.error.bind(console);


let setup = function setup(config, cb) {
let setup = async function setup(config) {
let nemo = {
'data': config.get('data'),
'driver': {},
'_config': config
};
Plugin.registration(nemo, config.get('plugins'))
.then(function (registerFns) {
//add driver setup
registerFns.push({fn: driversetup(nemo), priority: 100});
registerFns = registerFns.sort(Plugin.compare).map(function (obj) {
return obj.fn;
});
registerFns.unshift(function setWebdriver(callback) {
nemo.wd = wd;
callback(null);
});
if (config.get('driver:selenium.version')) {
//install before driver setup
log('Requested install of selenium version %s', config.get('driver:selenium.version'));
var seleniumInstall = require('./install');
registerFns.unshift(seleniumInstall(config.get('driver:selenium.version')));
}
async.waterfall(registerFns, function waterfall(err) {
if (err) {
cb(err);
} else {
cb(null, nemo);
}
});
})
.catch(function (err) {
error(err);
cb(err);
let registerFns;
try {
registerFns = await Plugin.registration(nemo, config.get('plugins'));
//add driver setup
registerFns.push({fn: driversetup(nemo), priority: 100});
registerFns = registerFns.sort(Plugin.compare).map(function (obj) {
return obj.fn;
});
registerFns.unshift(function setWebdriver(callback) {
nemo.wd = wd;
callback(null);
});
if (config.get('driver:selenium.version')) {
//install before driver setup
log('Requested install of selenium version %s', config.get('driver:selenium.version'));
var seleniumInstall = require('./install');
registerFns.unshift(seleniumInstall(config.get('driver:selenium.version')));
}
for (let i = 0; i < registerFns.length; i++) {
await new Promise((resolve, reject) => {
registerFns[i]((err) => {
if (err) {
reject(err);
} else {
resolve(true);
}
});
});
}
} catch (err) {
if (nemo && nemo.driver && nemo.driver.quit) {
await nemo.driver.quit();
}
throw err;
}
return Promise.resolve(nemo)
};

var driversetup = function (_nemo) {
Expand All @@ -68,26 +73,21 @@ var driversetup = function (_nemo) {



module.exports = function (config) {
let promiz = Promiz();
module.exports = async function (config) {
if (config.get('driver') === undefined) {
var errorMessage = 'Nemo essential driver properties not found in configuration';
error(errorMessage);
var badDriverProps = new Error(errorMessage);
badDriverProps.name = 'nemoBadDriverProps';
process.nextTick(function () {
promiz.reject(badDriverProps);
});
return Promise.reject(badDriverProps);
} else {
setup(config, function (err, nemo) {
log('got called back');
if (err !== null) {
promiz.reject(err);
return;
}
promiz.fulfill(nemo);
});
let nemo;
try {
nemo = await setup(config);
} catch (err) {
error(err);
return Promise.reject(err);
}
return Promise.resolve(nemo);
}

return promiz.promise;
};
Loading