Skip to content

Commit d7753d8

Browse files
committed
Refactored testing to use Karma
All tests are now run using Karma and can be run on a combination of local browsers, (including a headless PhantomJS) and remote browsers via BrowserStack. To run the full test suite locally: `make test` - This will run every test suite, (each file in test/*.test.js) using PhantomJS and a Mocha reporter. Output will be printed to stdout so you never have to leave the terminal. To run the full test suite remotely: `BROWSER_STACK_USERNAME=<username> BROWSER_STACK_ACCESS_KEY=<key> make test_ci` This will run all of the tests on the following browsers: - IE 8 - Latest IE, Chrome, Firefox, Opera, Safari The operating system and version are not specified. To run a single test locally: `grunt test:shim --browsers=Chrome` - This will run the shim.test.js test suite in a real Chrome browser on your local machine. To debug a test locally: `grunt test:shim --browser=Chrome --singleRun=false` - This will run the test suite but leave the browser window open for you to debug using the Chrome dev tools. Some other useful testing commands: - Run a single test locally and remotely `BROWSER_STACK_USERNAME=<username> BROWSER_STACK_ACCESS_KEY=<key> grunt test:json --browsers=Safari,bs_latest_ie` - Run a single test on the oldest IE and FF browsers `BROWSER_STACK_USERNAME=<username> BROWSER_STACK_ACCESS_KEY=<key> grunt test:json --browsers=bs_ie_oldest,bs_firefox_oldest` See browserstack.browsers.js for more options for which browsers you can use.
1 parent 835b528 commit d7753d8

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

70 files changed

+5388
-19043
lines changed

Gruntfile.js

+142-184
Original file line numberDiff line numberDiff line change
@@ -1,167 +1,91 @@
1-
/* jshint node: true */
2-
3-
"use strict";
1+
'use strict';
42

3+
var glob = require('glob');
4+
var path = require('path');
5+
var pkg = require('./package.json');
56
var webpackConfig = require('./webpack.config.js');
7+
var browserStackBrowsers = require('./browserstack.browsers');
8+
9+
10+
function findTests() {
11+
var files = glob.sync('test/**/*.test.js');
12+
var mapping = {};
613

7-
var testFiles;
8-
9-
if (process.env.TEST) {
10-
testFiles= ['http://localhost:3000/' + process.env.TEST];
11-
} else {
12-
testFiles = ['http://localhost:3000/test/util.html',
13-
'http://localhost:3000/test/json.html',
14-
'http://localhost:3000/test/xhr.html',
15-
'http://localhost:3000/test/notifier.html',
16-
'http://localhost:3000/test/notifier.ratelimit.html',
17-
'http://localhost:3000/test/rollbar.html',
18-
'http://localhost:3000/test/shim.html',
19-
'http://localhost:3000/test/shimalias.html',
20-
'http://localhost:3000/test/integrations/mootools.html',
21-
'http://localhost:3000/test/integrations/browserify.html',
22-
'http://localhost:3000/test/plugins/jquery.html',
23-
'http://localhost:3000/test/integrations/requirejs.html'
24-
];
14+
files.forEach(function(file) {
15+
var testName = path.basename(file, '.test.js');
16+
mapping[testName] = file;
17+
});
18+
19+
return mapping;
2520
}
2621

27-
module.exports = function(grunt) {
28-
var pkg = grunt.file.readJSON('package.json');
29-
require('time-grunt')(grunt);
3022

31-
grunt.initConfig({
32-
pkg: pkg,
33-
webpack: {
34-
options: webpackConfig,
35-
build: {}
36-
},
37-
jshint: {
38-
options: {
39-
globals: {
40-
console: true,
41-
window: true,
42-
require: true,
43-
module: true
44-
},
45-
browser: true,
46-
curly: true,
47-
eqeqeq: true,
48-
es3: true,
49-
forin: true,
50-
freeze: true,
51-
futurehostile: true,
52-
globalstrict: true,
53-
noarg: true,
54-
nocomma: true,
55-
nonbsp: true,
56-
nonew: true,
57-
strict: true,
58-
undef: true
59-
},
23+
function buildGruntKarmaConfig(singleRun, browsers, tests, reporters) {
24+
var config = {
25+
options: {
26+
configFile: './karma.conf.js',
27+
singleRun: singleRun,
6028
files: [
61-
'Gruntfile.js',
62-
'src/error_parser.js',
63-
'src/globalnotifier.js',
64-
'src/notifier.js',
65-
'src/shim.js',
66-
'src/snippet_callback.js',
67-
'src/util.js',
68-
'src/xhr.js',
69-
'src/shimload.js',
70-
'src/bundles/rollbar.snippet.js',
71-
'src/bundles/rollbar.js'
72-
]
73-
},
74-
mocha_phantomjs: {
75-
test: {
76-
options: {
77-
'--web-security' : false,
78-
'--local-to-remote-url-access' : true,
79-
run: true,
80-
log: true,
81-
urls: testFiles
82-
}
83-
}
84-
},
85-
/* Serves up responses to requests from the notifier */
86-
express: {
87-
test: {
88-
options: {
89-
server: './test/express',
90-
port: 3000
91-
}
92-
}
93-
},
94-
/* Serves up the static test .html files */
95-
connect: {
96-
test: {
97-
options: {
98-
base: '.',
99-
port: 3000
100-
}
101-
}
102-
},
103-
bumpup: ['package.json', 'bower.json'],
104-
tagrelease: {
105-
file: 'package.json',
106-
prefix: 'v',
107-
commit: false
108-
},
109-
'saucelabs-mocha': {
110-
all: {
111-
options: {
112-
urls: ['http://localhost:3000/test/rollbar.html'],
113-
//'http://localhost:3000/test/shim.html',
114-
//'http://localhost:3000/test/notifier.html',
115-
//'http://localhost:3000/test/components.html'],
116-
tunnelTimeout: 5,
117-
build: process.env.TRAVIS_JOB_ID,
118-
concurrency: 3,
119-
browsers: browsers,
120-
testname: "mocha tests",
121-
username: process.env.SAUCE_USERNAME,
122-
key: process.env.SAUCE_ACCESS_KEY
29+
// Files that the tests will load
30+
{
31+
pattern: 'dist/**/*.js',
32+
included: false,
33+
served: true,
34+
watched: false
35+
},
36+
{
37+
pattern: 'src/**/*.js',
38+
included: false,
39+
served: true,
40+
watched: false
12341
}
124-
}
42+
]
12543
}
126-
});
44+
};
12745

128-
grunt.loadNpmTasks('grunt-mocha-phantomjs');
129-
grunt.loadNpmTasks('grunt-express');
130-
grunt.loadNpmTasks('grunt-contrib-connect');
131-
grunt.loadNpmTasks('grunt-contrib-watch');
132-
grunt.loadNpmTasks('grunt-contrib-concat');
133-
grunt.loadNpmTasks('grunt-bumpup');
134-
grunt.loadNpmTasks('grunt-tagrelease');
135-
grunt.loadNpmTasks('grunt-saucelabs');
136-
grunt.loadNpmTasks('grunt-webpack');
46+
if (browsers && browsers.length) {
47+
config.options.browsers = browsers;
48+
}
13749

138-
grunt.registerTask('build', ['webpack']);
139-
grunt.registerTask('release', ['build', 'copyrelease']);
50+
if (reporters && reporters.length) {
51+
config.options.reporters = reporters;
52+
}
53+
54+
for (var testName in tests) {
55+
var testFile = tests[testName];
56+
var testConfig = config[testName] = {};
57+
58+
// Special case for testing requirejs integration.
59+
// Include the requirejs module as a framework so
60+
// Karma will inclue it in the web page.
61+
if (testName === 'requirejs') {
62+
testConfig.files = [
63+
{src: './test/requirejs-loader.js'},
64+
{src: './test/requirejs.test.js', included: false},
65+
{src: './dist/rollbar.umd.js', included: false}
66+
];
67+
// NOTE: requirejs should go first in case the subsequent libraries
68+
// check for the existence of `define()`
69+
testConfig.frameworks = ['requirejs', 'expect', 'mocha'];
70+
} else {
71+
testConfig.files = [{src: [testFile]}];
72+
}
14073

141-
var testjobs = ['webpack', 'express'];
142-
if (typeof process.env.SAUCE_ACCESS_KEY !== 'undefined'){
143-
testjobs.push('saucelabs-mocha');
144-
} else {
145-
testjobs.push('mocha_phantomjs');
74+
// Special config for BrowserStack IE tests
75+
if (testName.slice(0, 3) === 'bs' && testName.indexOf('ie_') >= 0) {
76+
// Long timeout since IE 6/7/8 is slow
77+
testConfig.captureTimeout = 60000 * 10;
78+
}
14679
}
147-
grunt.registerTask('test', testjobs);
148-
149-
// This will allow you to run "grunt test-debug" and then open your
150-
// browser to http://localhost:3000/test/XXX.html to run tests.
151-
grunt.registerTask('test-browser', function() {
152-
console.log('Open your browser to http://localhost:3000/test/rollbar.html');
153-
grunt.task.run('express');
154-
grunt.task.run('express-keepalive');
155-
});
15680

157-
grunt.registerTask('default', ['build']);
81+
return config;
82+
}
15883

159-
grunt.registerTask('bumpversion', function(type) {
160-
type = type ? type : 'patch';
161-
grunt.task.run('bumpup:' + type);
162-
});
16384

164-
grunt.registerTask('copyrelease', function() {
85+
module.exports = function(grunt) {
86+
require('time-grunt')(grunt);
87+
88+
function createRelease() {
16589
var version = pkg.version;
16690
var builds = ['', '.nojson', '.umd', '.umd.nojson'];
16791

@@ -175,43 +99,77 @@ module.exports = function(grunt) {
17599
grunt.file.copy(js, releaseJs);
176100
grunt.file.copy(minJs, releaseMinJs);
177101
});
178-
});
179-
};
102+
}
180103

104+
var tests = findTests();
105+
var browsers = grunt.option('browsers');
106+
if (browsers) {
107+
browsers = browsers.split(',');
108+
109+
var expandedBrowserNames = [];
110+
var browserStackAliases = [];
111+
var nonBrowserStackAliases = [];
112+
browsers.forEach(function(browserName) {
113+
if (browserName.slice(0, 3) === 'bs_') {
114+
browserStackAliases.push(browserName);
115+
} else {
116+
nonBrowserStackAliases.push(browserName);
117+
}
118+
});
119+
120+
var expandedBrowsers = browserStackBrowsers.filter.apply(null, browserStackAliases);
121+
var expandedBrowserNames = [];
122+
expandedBrowsers.forEach(function(browser) {
123+
expandedBrowserNames.push(browser._alias);
124+
});
125+
browsers = nonBrowserStackAliases.concat(expandedBrowserNames);
126+
}
181127

182-
var browsers = [
183-
{
184-
browserName: 'firefox',
185-
version: '19',
186-
platform: 'XP'
187-
},
188-
{
189-
browserName: 'chrome',
190-
platform: 'XP'
191-
},
192-
{
193-
browserName: 'chrome',
194-
platform: 'linux'
195-
},
196-
{
197-
browserName: 'internet explorer',
198-
platform: 'WIN8',
199-
version: '10'
200-
},
201-
{
202-
browserName: 'internet explorer',
203-
platform: 'VISTA',
204-
version: '9'
205-
},
206-
{
207-
browserName: 'internet explorer',
208-
platform: 'XP',
209-
version: '8'
210-
},
211-
{
212-
browserName: 'opera',
213-
platform: 'Windows 2008',
214-
version: '12'
128+
var singleRun = grunt.option('singleRun');
129+
if (singleRun === undefined) {
130+
singleRun = true;
215131
}
216-
];
132+
133+
var reporters = grunt.option('reporters');
134+
if (reporters !== undefined) {
135+
reporters = reporters.split(',');
136+
}
137+
138+
grunt.loadNpmTasks('grunt-express');
139+
grunt.loadNpmTasks('grunt-karma');
140+
grunt.loadNpmTasks('grunt-webpack');
141+
142+
grunt.initConfig({
143+
pkg: pkg,
144+
webpack: webpackConfig,
145+
karma: buildGruntKarmaConfig(singleRun, browsers, tests, reporters),
146+
147+
// Serves up responses to requests from the tests
148+
express: {
149+
defaults: {
150+
options: {
151+
server: './test/express',
152+
port: 3000
153+
}
154+
}
155+
},
156+
157+
// Stores a reference to all of the tests for the
158+
// "test" multi task below to iterate over
159+
//test: tests,
160+
161+
// TODO: Upload assets to CDN
162+
});
163+
164+
grunt.registerTask('build', ['webpack']);
165+
grunt.registerTask('default', ['build']);
166+
grunt.registerTask('test', ['express', 'karma']);
167+
grunt.registerTask('release', ['build', createRelease]);
168+
169+
grunt.registerTask('test', function(target) {
170+
var karmaTask = 'karma' + (target ? ':' + target : '');
171+
var tasks = ['express', karmaTask];
172+
grunt.task.run.apply(grunt.task, tasks);
173+
});
174+
};
217175

Makefile

+8-3
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,15 @@ TESTS = test/index.html
22
REPORTER = dot
33

44
build:
5-
@./node_modules/.bin/grunt
5+
@npm run build
6+
@echo ""
67

78
test:
8-
@./node_modules/.bin/grunt test
9+
@npm run test
10+
@echo ""
11+
12+
test_ci:
13+
@npm run test_ci
914
@echo ""
1015

11-
.PHONY: test
16+
.PHONY: test test_ci

0 commit comments

Comments
 (0)