Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: pass command line opts through to browser #530

Closed
Closed
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
15 changes: 14 additions & 1 deletion lib/cli.js
Original file line number Diff line number Diff line change
@@ -56,6 +56,17 @@ var processArgs = function(argv, options) {
return options;
};

var parseClientArgs = function(argv) {
// extract any args after '--' as clientArgs
var clientArgs = [];
argv = argv.slice(2);
var idx = argv.indexOf('--');
if (idx !== -1) {
clientArgs = argv.slice(idx + 1);
}
return clientArgs;
};


var describeShared = function() {
optimist
@@ -65,7 +76,7 @@ var describeShared = function() {
'Commands:\n' +
' start [<configFile>] [<options>] Start the server / do single run.\n' +
' init [<configFile>] Initialize a config file.\n' +
' run [<options>] Trigger a test run.\n\n' +
' run [<options>] [ -- <clientArgs>] Trigger a test run.\n\n' +
'Run --help with particular command to see its description and available options.')
.describe('help', 'Print usage and options.')
.describe('version', 'Print current version.');
@@ -136,6 +147,7 @@ exports.process = function() {

case 'run':
describeRun();
options.clientArgs = parseClientArgs(process.argv);
break;

case 'init':
@@ -159,3 +171,4 @@ exports.process = function() {

// just for testing
exports.processArgs = processArgs;
exports.parseClientArgs = parseClientArgs;
2 changes: 2 additions & 0 deletions lib/runner.js
Original file line number Diff line number Diff line change
@@ -50,4 +50,6 @@ exports.run = function(config, done) {
socket.on('close', function() {
done(exitCode);
});

socket.write(JSON.stringify({args: config.clientArgs}) + '\0');
};
68 changes: 41 additions & 27 deletions lib/server.js
Original file line number Diff line number Diff line change
@@ -67,6 +67,7 @@ var start = function(injector, config, launcher, globalEmitter, preprocess, file
var executionScheduled = false;
var pendingCount = 0;
var runningBrowsers;
var clientConfig = {args: config.clientArgs};

globalEmitter.on('browsers_change', function() {
// TODO(vojta): send only to interested browsers
@@ -100,7 +101,7 @@ var start = function(injector, config, launcher, globalEmitter, preprocess, file
pendingCount = capturedBrowsers.length;
runningBrowsers = capturedBrowsers.clone();
globalEmitter.emit('run_start', runningBrowsers);
socketServer.sockets.emit('execute', {});
socketServer.sockets.emit('execute', clientConfig);
return true;
} else {
log.info('Delaying execution, these browsers are not ready: ' + nonReady.join(', '));
@@ -139,34 +140,47 @@ var start = function(injector, config, launcher, globalEmitter, preprocess, file

// listen on port, waiting for runner
var runnerServer = net.createServer(function (socket) {
log.debug('Execution (fired by runner)');

if (!capturedBrowsers.length) {
var url = 'http://' + config.hostname + ':' + config.port + config.urlRoot;

log.warn('No captured browser, open ' + url);
socket.end('No captured browser, open ' + url + '\n');
return;
}

if (!capturedBrowsers.areAllReady([])) {
socket.write('Waiting for previous execution...\n');
}

globalEmitter.once('run_start', function() {
var socketWrite = socket.write.bind(socket);

resultReporter.addAdapter(socketWrite);

// clean up, close runner socket
globalEmitter.once('run_complete', function(browsers, results) {
resultReporter.removeAdapter(socketWrite);
socket.end(constant.EXIT_CODE + results.exitCode);
var buf = '';
socket.on('data', function(data) {
buf += data;

// data is followed by a NUL byte, so keep buffering until that's present
if (buf[buf.length - 1] !== '\0') {
return;
}

// strip the NUL byte and parse
clientConfig = JSON.parse(buf.substr(0, buf.length - 1));
buf = '';
log.debug('Execution (fired by runner)');

if (!capturedBrowsers.length) {
var url = 'http://' + config.hostname + ':' + config.port + config.urlRoot;

log.warn('No captured browser, open ' + url);
socket.end('No captured browser, open ' + url + '\n');
return;
}

if (!capturedBrowsers.areAllReady([])) {
socket.write('Waiting for previous execution...\n');
}

globalEmitter.once('run_start', function() {
var socketWrite = socket.write.bind(socket);

resultReporter.addAdapter(socketWrite);

// clean up, close runner socket
globalEmitter.once('run_complete', function(browsers, results) {
resultReporter.removeAdapter(socketWrite);
socket.end(constant.EXIT_CODE + results.exitCode);
});
});
});

log.debug('Refreshing all the files / patterns');
fileList.refresh();
log.debug('Refreshing all the files / patterns');
fileList.refresh();
});
});

runnerServer.on('error', function(e) {
6 changes: 3 additions & 3 deletions static/karma.src.js
Original file line number Diff line number Diff line change
@@ -46,12 +46,12 @@ var instanceOf = function(value, constructorName) {

/* jshint unused: false */
var Karma = function(socket, context, navigator, location) {
var config;
var hasError = false;
var store = {};
var self = this;

this.VERSION = VERSION;
this.config = {};

this.setupContext = function(contextWindow) {
if (hasError) {
@@ -210,7 +210,7 @@ var Karma = function(socket, context, navigator, location) {
this.loaded = function() {
// has error -> cancel
if (!hasError) {
this.start(config);
this.start(this.config);
}

// remove reference to child iframe
@@ -240,7 +240,7 @@ var Karma = function(socket, context, navigator, location) {
socket.on('execute', function(cfg) {
// reset hasError and reload the iframe
hasError = false;
config = cfg;
self.config = cfg;
context.src = CONTEXT_URL;

// clear the console before run
35 changes: 34 additions & 1 deletion tasks/test.js
Original file line number Diff line number Diff line change
@@ -46,7 +46,9 @@ module.exports = function(grunt) {
'start', null, '--single-run', '--no-auto-watch'
];


var next = function(err, result, code) {
var testArgs = [];
if (processToKill) {
processToKill.kill();
}
@@ -64,7 +66,38 @@ module.exports = function(grunt) {
}, function() {});
}

spawnKarma(args, next);
if (args[1] === 'test/e2e/pass-opts/karma.conf.js') {
var serverArgs = args.slice();
serverArgs.splice(args.indexOf('--single-run'), 1);
var done = false;
var cont = function() {
if (!done) {
done = true;
next.apply(this, arguments);
}
};

processToKill = grunt.util.spawn({
cmd: node,
args: [cmd].concat(serverArgs),
opts: {stdio: [process.stdin, 'pipe', process.stderr]}
}, cont);

var onData = function(data) {
data = data.toString();
// wait for the browser to connect
if (/Connected on socket/.test(data)) {
processToKill.stdout.removeListener('data', onData);
spawnKarma(['run', 'runArg', '--','arg1','arg2','arg3'], cont);
} else {
console.log(data);
}
};

processToKill.stdout.on('data', onData);
} else {
spawnKarma(args.concat(testArgs), next);
}
} else {
specDone();
}
19 changes: 19 additions & 0 deletions test/e2e/pass-opts/karma.conf.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
module.exports = function(config) {
config.set({
frameworks: ['jasmine'],

files: [
'*.js'
],

browsers: [ process.env.TRAVIS ? 'Firefox' : 'Chrome' ],

reporters: ['dots'],

plugins: [
'karma-jasmine',
'karma-chrome-launcher',
'karma-firefox-launcher'
],
});
};
6 changes: 6 additions & 0 deletions test/e2e/pass-opts/test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
describe('config', function() {
it('should be passed through to the browser', function() {
expect(window.__karma__.config).toBeDefined();
expect(window.__karma__.config.args).toEqual(['arg1','arg2','arg3']);
});
});
14 changes: 12 additions & 2 deletions test/unit/cli.spec.coffee
Original file line number Diff line number Diff line change
@@ -8,9 +8,9 @@ describe 'cli', ->
CWD = process.cwd()
path = require 'path'

processArgs = (args) ->
processArgs = (args, opts) ->
argv = optimist.parse(args)
cli.processArgs argv, {}
cli.processArgs argv, opts || {}

describe 'processArgs', ->

@@ -80,3 +80,13 @@ describe 'cli', ->

options = processArgs ['--reporters', 'dots']
expect(options.reporters).to.deep.equal ['dots']


describe 'parseClientArgs', ->
it 'should return arguments after --', ->
args = cli.parseClientArgs(['node', 'karma.js', 'runArg', '--flag', '--', '--foo', '--bar', 'baz']);
expect(args).to.deep.equal ['--foo', '--bar', 'baz']

it 'should return empty args if -- is not present', ->
args = cli.parseClientArgs(['node', 'karma.js', 'runArg', '--flag', '--foo', '--bar', 'baz']);
expect(args).to.deep.equal []