Skip to content

Commit 60dff38

Browse files
committed
Merge pull request #25 from institutional/release/v0.9.0
API Usage & More Unit Tests
2 parents b74bde0 + ee17643 commit 60dff38

File tree

9 files changed

+402
-133
lines changed

9 files changed

+402
-133
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
.*
22
!.gitignore
33
node_modules
4+
coverage

README.md

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
[Fiveby](http://en.wikipedia.org/wiki/Five_by_five)
1+
[Fiveby](http://en.wikipedia.org/wiki/Five_by_five) [![Build Status](http://djin-jenkins01.dowjones.net/job/fiveby/badge/icon)](http://djin-jenkins01.dowjones.net/job/fiveby/)
22
========
33

44
makes it easier to write automated tests/suites. Here's the idea: don't worry about selenium (or it's config), don't worry about selenium JS api oddities, don't worry about mocha, just use fiveby:
@@ -19,3 +19,19 @@ new fiveby(function (browser) { //browser is driver if you are looking at seleni
1919
});
2020
```
2121
See [docs](https://github.dowjones.net/institutional/fiveby/docs) for more details and use [gulp-fiveby](https://github.dowjones.net/institutional/gulp-fiveby) as a scaffold project. [Live Help](https://dowjones.slack.com/messages/fiveby/)
22+
23+
###Configuration - fiveby-config.json
24+
25+
```json
26+
{
27+
"implicitWait": 5000,
28+
"hubUrl": null,
29+
"browsers": {
30+
"chrome": 1
31+
},
32+
"disableBrowsers": false
33+
}
34+
```
35+
disableBrowsers is optional, defaults to false
36+
37+
hubUrl is optional, if not provided (and disableBrowsers = false) it will spin up a selenium server *requires java*

gulpfile.js

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
var gulp = require('gulp');
2+
var istanbul = require('gulp-istanbul');
3+
var mocha = require('gulp-mocha');
4+
5+
gulp.task('test', function (cb) {
6+
gulp.src(['lib/fiveby.js', 'index.js'])
7+
.pipe(istanbul())
8+
.on('finish', function () {
9+
gulp.src(['test/*.js'])
10+
.pipe(mocha())
11+
.pipe(istanbul.writeReports())
12+
.on('end', cb);
13+
});
14+
});

index.js

Lines changed: 18 additions & 112 deletions
Original file line numberDiff line numberDiff line change
@@ -1,142 +1,48 @@
1-
var webdriver = require('selenium-webdriver');
2-
var Hook = require('mocha').Hook;
1+
var fiveby = require('./lib/fiveby');
32
var path = require('path');
43
var fs = require('fs');
54
var _ = require('lodash');
6-
var tb = require('traceback');
75
var Properties = require('./lib/properties');
86
require('should');
97

10-
module.exports = fiveby;
11-
12-
//simplify webdriver usage
13-
global.by = webdriver.By;
14-
global.key = webdriver.Key;
15-
global.promise = webdriver.promise;
16-
global.bot = webdriver.error;
17-
188
//get project configuration if one exists
199
if (!global.fivebyConfig) {
2010

21-
if (process.env.fivebyopts) {
22-
global.fivebyConfig = JSON.parse(process.env.fivebyopts);
23-
} else {
24-
var configPath = path.resolve('fiveby-config.json');
25-
try {
11+
try {
12+
if (process.env.fivebyopts) {
13+
global.fivebyConfig = JSON.parse(process.env.fivebyopts);
14+
} else {
15+
var configPath = path.resolve('fiveby-config.json');
2616
global.fivebyConfig = JSON.parse(fs.readFileSync(configPath, {encoding: 'utf-8'}));
27-
} catch (e) {
28-
console.error('No global config loaded %s', e);
29-
process.exit(1);
3017
}
18+
} catch (e) {
19+
console.error('No global config loaded %s', e);
20+
return process.exit(1);
3121
}
3222

3323
//prep properties
3424
global.propertyService = new Properties(global.fivebyConfig.environment||'local');
3525
var props = global.propertyService.getProperties('default');
3626
props.setMany(global.fivebyConfig.properties||{});
3727

38-
global.testPromise = webdriver.promise.fulfilled();
39-
console.info('Configuration complete');
40-
41-
}
42-
43-
//spin up local selenium server if none provided
44-
if (!global.fivebyConfig.hubUrl) {
45-
console.info("No server defined, spinning one up ...");
46-
SeleniumServer = require('selenium-webdriver/remote').SeleniumServer;
47-
var server = new SeleniumServer('./node_modules/fiveby/selenium-server-standalone-2.42.2.jar', { port: 4444 });
48-
server.start();
49-
global.fivebyConfig.hubUrl = server.address();
5028
}
5129

5230
//main test driver
53-
function fiveby(params, test) {
31+
module.exports = function (params, test) {
5432

55-
var file = tb()[1].path;
33+
var config = _.cloneDeep(global.fivebyConfig); //seperate config for merge
5634

5735
if (arguments.length === 1) {//switch params for 1 arg
5836
test = params;
5937
} else {
60-
_.merge(global.fivebyConfig, params); //merge test params with global
38+
_.merge(config, params); //merge test params with config
6139
}
6240

63-
//ensure minimal configuration is provided
64-
if (!global.fivebyConfig.browsers) {
65-
return console.warn('No browsers provided, must provide at least one');
66-
}
67-
68-
//for each browser in the configuration
69-
Object.keys(global.fivebyConfig.browsers).forEach(function (elem) {
70-
71-
//check if specific browser is valid in selenium
72-
if (!webdriver.Capabilities[elem]) {
73-
return console.warn('No such browser: %s', elem);
74-
}
75-
76-
var lastPromise = global.testPromise;
77-
var testComplete = webdriver.promise.defer();
78-
global.testPromise = testComplete.promise;
79-
80-
//create a control flow and driver per test file
81-
lastPromise.then(function() {
82-
83-
// set options for current browser
84-
var capabilities = webdriver.Capabilities[elem]();
85-
86-
if (elem === 'chrome') {
87-
capabilities.set('chromeOptions', {
88-
args: ['--disable-extensions']
89-
});
90-
}
91-
92-
//build driver
93-
var driver = new webdriver.Builder()
94-
.usingServer(global.fivebyConfig.hubUrl)
95-
.withCapabilities(capabilities)
96-
.build();
97-
driver.name = elem;
98-
driver.manage().timeouts().implicitlyWait(global.fivebyConfig.implicitWait);
99-
100-
//register tests with mocha
101-
var describe = test(driver);
102-
103-
//register hooks with mocha
104-
registerHook('fiveby error handling', describe, "beforeEach", function () {
105-
this.currentTest.parent.file = this.currentTest.file = file;
106-
webdriver.promise.controlFlow().on('uncaughtException', function (e) {
107-
if(this.currentTest) {
108-
this.currentTest.callback(e);
109-
} else {
110-
console.error("Failed in setup or teardown, test result may not be valid for this file");
111-
throw(e);
112-
}
113-
});
114-
});
115-
116-
registerHook('fiveby cleanup', describe, "afterAll", function () {
117-
testComplete.fulfill();
118-
if (driver.session_) { //in case the tests already killed the session
119-
return driver.quit();
120-
}
121-
});
122-
123-
});
124-
});
125-
}
126-
127-
function registerHook(name, suite, hookarr, func) {
128-
var hook = new Hook(name, func);
129-
hook.parent = suite;
130-
if (suite && suite.ctx) {
131-
hook.ctx = suite.ctx;
132-
} else {
133-
console.error("Please return test suite (describe) in the fiveby constructor callback.");
134-
process.exit(2);
135-
}
136-
hook.timeout(5000);
137-
if(hookarr.indexOf("before") > -1){
138-
suite["_" + hookarr].unshift(hook);
41+
if(global.fivebyConfig.disableBrowsers){
42+
test();
13943
} else {
140-
suite["_" + hookarr].push(hook);
44+
var fb = new fiveby(config);
45+
fb.runSuiteInBrowsers(test);
14146
}
142-
}
47+
48+
};

lib/fiveby.js

Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
var webdriver = require('selenium-webdriver');
2+
var Hook = require('mocha').Hook;
3+
var tb = require('traceback');
4+
5+
//simplify webdriver usage
6+
global.by = webdriver.By;
7+
global.key = webdriver.Key;
8+
global.promise = webdriver.promise;
9+
global.bot = webdriver.error;
10+
11+
if(!global.testPromise){
12+
global.testPromise = webdriver.promise.fulfilled();
13+
}
14+
15+
module.exports = fiveby;
16+
17+
function fiveby(config) {
18+
this.config = config;
19+
//spin up local selenium server if none provided
20+
if (!global.fivebyConfig.hubUrl && !config.hubUrl) {
21+
console.info("No server defined, spinning one up ...");
22+
SeleniumServer = require('selenium-webdriver/remote').SeleniumServer;
23+
var server = new SeleniumServer('./node_modules/fiveby/selenium-server-standalone-2.44.0.jar', { port: 4444 });
24+
server.start();
25+
global.fivebyConfig.hubUrl = config.hubUrl = server.address();
26+
}
27+
}
28+
29+
fiveby.prototype.runSuiteInBrowsers = function (test) {
30+
31+
if(test.length === 0){ //bail if they don't want a browser
32+
return test();
33+
}
34+
35+
var self = this;
36+
//ensure minimal configuration is provided
37+
if (!this.config.browsers) {
38+
return console.warn('No browsers provided, must provide at least one');
39+
}
40+
41+
var file = tb()[2].path;
42+
43+
//for each browser in the configuration
44+
Object.keys(this.config.browsers).forEach(function (elem) {
45+
46+
//check if specific browser is valid in selenium
47+
if (!webdriver.Capabilities[elem]) {
48+
return console.warn('No such browser: %s', elem);
49+
}
50+
51+
var lastPromise = global.testPromise;
52+
var testComplete = webdriver.promise.defer();
53+
global.testPromise = testComplete.promise;
54+
55+
//create a control flow and driver per test file
56+
lastPromise.then(function() {
57+
58+
// set options for current browser
59+
var capabilities = webdriver.Capabilities[elem]();
60+
61+
if (elem === 'chrome') {
62+
capabilities.set('chromeOptions', {
63+
args: ['--disable-extensions']
64+
});
65+
}
66+
67+
//build driver
68+
var driver = new webdriver.Builder()
69+
.usingServer(self.config.hubUrl)
70+
.withCapabilities(capabilities)
71+
.build();
72+
driver.name = elem;
73+
driver.manage().timeouts().implicitlyWait(self.config.implicitWait);
74+
75+
//register tests with mocha
76+
var describe = test(driver);
77+
78+
//register hooks with mocha
79+
self.registerHook('fiveby error handling', describe, "beforeEach", function () {
80+
this.currentTest.parent.file = this.currentTest.file = file;
81+
webdriver.promise.controlFlow().on('uncaughtException', function (e) {
82+
if(this.currentTest) {
83+
this.currentTest.callback(e);
84+
} else {
85+
console.error("Failed in setup or teardown, test result may not be valid for this file");
86+
throw(e);
87+
}
88+
});
89+
});
90+
91+
self.registerHook('fiveby cleanup', describe, "afterAll", function () {
92+
testComplete.fulfill();
93+
if (driver.session_) { //in case the tests already killed the session
94+
return driver.quit();
95+
}
96+
});
97+
98+
});
99+
});
100+
};
101+
102+
fiveby.prototype.registerHook = function (name, suite, hookarr, func) {
103+
var hook = new Hook(name, func);
104+
hook.parent = suite;
105+
if (suite && suite.ctx) {
106+
hook.ctx = suite.ctx;
107+
} else {
108+
console.error("Please return test suite (describe) in the fiveby constructor callback.");
109+
return process.exit(2);
110+
}
111+
hook.timeout(5000);
112+
if(hookarr.indexOf("before") > -1){
113+
suite["_" + hookarr].unshift(hook);
114+
} else {
115+
suite["_" + hookarr].push(hook);
116+
}
117+
};

package.json

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,27 @@
11
{
22
"name": "fiveby",
3-
"version": "0.8.0",
3+
"version": "0.9.0",
44
"description": "Package up testing options, levels, apis, and dependencies into one simple lib",
55
"scripts": {
6-
"test": "mocha"
6+
"test": "gulp test"
77
},
88
"author": "Scott Rahner",
99
"repository": {
1010
"type": "git",
1111
"url": "https://github.dowjones.net/institutional/fiveby.git"
1212
},
1313
"dependencies": {
14-
"selenium-webdriver": "2.42.0",
15-
"should": "^4.0.4",
16-
"mocha": "^1.21.4",
1714
"lodash": "^2.4.1",
18-
"traceback": "^0.3.1",
19-
"tesla.lib.cache": "^0.1.1"
15+
"mocha": "^1.21.4",
16+
"selenium-webdriver": "2.44.0",
17+
"tesla.lib.cache": "^0.1.1",
18+
"traceback": "^0.3.1"
19+
},
20+
"devDependencies": {
21+
"gulp": "^3.8.9",
22+
"gulp-istanbul": "^0.3.1",
23+
"gulp-mocha": "^1.1.1",
24+
"should": "^4.0.4",
25+
"proxyquire": "^1.0.1"
2026
}
2127
}

0 commit comments

Comments
 (0)