Skip to content
This repository was archived by the owner on Jul 29, 2024. It is now read-only.
Closed
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
14 changes: 13 additions & 1 deletion docs/referenceConf.js
Original file line number Diff line number Diff line change
Expand Up @@ -125,15 +125,27 @@ exports.config = {
specs: ['spec/chromeOnlySpec.js'],

// Spec files to be excluded on this capability only.
exclude: ['spec/doNotRunInChromeSpec.js']
exclude: ['spec/doNotRunInChromeSpec.js'],

// Optional: override global seleniumAddress on this capability only.
seleniumAddress: null
},

// If you would like to run more than one instance of WebDriver on the same
// tests, use multiCapabilities, which takes an array of capabilities.
// If this is specified, capabilities will be ignored.
multiCapabilities: [],

// If you need to resolve multiCapabilities asynchronously (i.e. wait for
// server/proxy, set firefox profile, etc), you can specify a function here
// which will return either `multiCapabilities` or a promise to
// `multiCapabilities`.
// If this returns a promise, it is resolved immediately after
// `beforeLaunch` is run, and before any driver is set up.
// If this is specified, both capabilities and multiCapabilities will be
// ignored.
getMultiCapabilities: null,

// Maximum number of total browser sessions to run. Tests are queued in
// sequence if number of browser sessions is limited by this parameter.
// Use a number less than 1 to denote unlimited. Default is unlimited.
Expand Down
15 changes: 3 additions & 12 deletions lib/driverProviders/hosted.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,18 +21,9 @@ util.inherits(HostedDriverProvider, DriverProvider);
* ready to test.
*/
HostedDriverProvider.prototype.setupEnv = function() {
var config = this.config_,
seleniumAddress = config.seleniumAddress;

if (q.isPromiseAlike(seleniumAddress)) {
return q.when(seleniumAddress).then(function(resolvedAddress) {
config.seleniumAddress = resolvedAddress;
log.puts('Using the selenium server at ' + config.seleniumAddress);
});
} else {
log.puts('Using the selenium server at ' + this.config_.seleniumAddress);
return q.fcall(function() {});
}
log.puts('Using the selenium server at ' +
this.config_.seleniumAddress);
return q.fcall(function() {});
};

// new instance w/ each include
Expand Down
91 changes: 65 additions & 26 deletions lib/launcher.js
Original file line number Diff line number Diff line change
Expand Up @@ -114,34 +114,73 @@ var init = function(configFile, additionalConfig) {
log.debug('Running with --troubleshoot');
log.debug('Protractor version: ' + require('../package.json').version);
log.debug('Your base url for tests is ' + config.baseUrl);
var scheduler = new TaskScheduler(config);

process.on('exit', function(code) {
if (code) {
log_('Process exited with error code ' + code);
} else if (scheduler.numTasksOutstanding() > 0) {
log_('BUG: launcher exited with ' +
scheduler.numTasksOutstanding() + ' tasks remaining');
process.exit(RUNNERS_FAILED_EXIT_CODE);
}
});

var cleanUpAndExit = function(exitCode) {
return helper.runFilenameOrFn_(
config.configDir, config.afterLaunch, [exitCode]).
then(function(returned) {
if (typeof returned === 'number') {
process.exit(returned);
} else {
process.exit(exitCode);
}
}, function(err) {
log_('Error:', err);
process.exit(1);
});
};

// Run beforeLaunch
helper.runFilenameOrFn_(config.configDir, config.beforeLaunch).then(function() {

// Set `multicapabilities` using `capabilities`, `multicapabilites`,
// `getMultiCapabilities()`, or default
return q.promise(function(resolve) {
if (config.getMultiCapabilities &&
typeof config.getMultiCapabilities === 'function') {
if (config.multiCapabilities.length || config.capabilities) {
log.warn('getMultiCapabilities() will override both capabilites ' +
'and multiCapabilities');
}
// If getMultiCapabilities is defined and a function, use this.
q.when(config.getMultiCapabilities(), function(multiCapabilities) {
config.multiCapabilities = multiCapabilities;
config.capabilities = null;
}).then(resolve);
} else {
resolve();
}
}).then(function() {
if (config.capabilities) {
if (config.multiCapabilities.length) {
log.warn('You have specified both capabilites and ' +
'multiCapabilities. This will result in capabilities being ' +
'ignored');
} else {
// Use capabilities if multiCapabilities is empty.
config.multiCapabilities = [config.capabilities];
}
} else if (!config.multiCapabilities.length) {
// Default to chrome if no capabilities given
config.multiCapabilities = [{
browserName: 'chrome'
}];
}
});
}).then(function() {
var scheduler = new TaskScheduler(config);

process.on('exit', function(code) {
if (code) {
log_('Process exited with error code ' + code);
} else if (scheduler.numTasksOutstanding() > 0) {
log_('BUG: launcher exited with ' +
scheduler.numTasksOutstanding() + ' tasks remaining');
process.exit(RUNNERS_FAILED_EXIT_CODE);
}
});

// Run afterlaunch and exit
var cleanUpAndExit = function(exitCode) {
return helper.runFilenameOrFn_(
config.configDir, config.afterLaunch, [exitCode]).
then(function(returned) {
if (typeof returned === 'number') {
process.exit(returned);
} else {
process.exit(exitCode);
}
}, function(err) {
log_('Error:', err);
process.exit(1);
});
};

var totalTasks = scheduler.numTasksOutstanding();
var forkProcess = false;
if (totalTasks > 1) { // Start new processes only if there are >1 tasks.
Expand Down
8 changes: 3 additions & 5 deletions lib/runner.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,9 @@ var Runner = function(config) {
flow.timeout(1000, 'waiting for debugger to attach');
}

if (config.capabilities && config.capabilities.seleniumAddress) {
config.seleniumAddress = config.capabilities.seleniumAddress;
}
this.loadDriverProvider_(config);
this.setTestPreparer(config.onPrepare);
};
Expand Down Expand Up @@ -250,12 +253,7 @@ Runner.prototype.run = function() {
// 1) Setup environment
//noinspection JSValidateTypes
return this.driverprovider_.setupEnv().then(function() {
// Resolve capabilities first, so it can be a promise
return q(self.config_.capabilities).then(function(capabilities) {
self.config_.capabilities = capabilities;
});
// 2) Create a browser and setup globals
}).then(function() {
var browser = self.createBrowser();
self.setupGlobals_(browser);
return browser.getSession().then(function(session) {
Expand Down
21 changes: 3 additions & 18 deletions lib/taskScheduler.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
'use strict';

var ConfigParser = require('./configParser');
var log = require('./logger.js');

// A queue of specs for a particular capacity
var TaskQueue = function(capabilities, specLists) {
Expand All @@ -19,8 +18,10 @@ var TaskQueue = function(capabilities, specLists) {
/**
* A scheduler to keep track of specs that need running and their associated
* capabilities. It will suggest a task (combination of capabilities and spec)
* to run while observing the following config rules: capabilities,
* to run while observing the following config rules:
* multiCapabilities, shardTestFiles, and maxInstance.
* Precondition: multiCapabilities is a non-empty array
* (capabilities and getCapabilities will both be ignored)
*
* @constructor
* @param {Object} config parsed from the config file
Expand All @@ -32,22 +33,6 @@ var TaskScheduler = function(config) {
return excludes.indexOf(path) < 0;
});

if (config.capabilities) {
if (config.multiCapabilities.length) {
log.warn('You have specified both capabilites and ' +
'multiCapabilities. This will result in capabilities being ' +
'ignored');
} else {
// Use capabilities if multiCapabilities is empty.
config.multiCapabilities = [config.capabilities];
}
} else if (!config.multiCapabilities.length) {
// Default to chrome if no capabilities given
config.multiCapabilities = [{
browserName: 'chrome'
}];
}

var taskQueues = [];
config.multiCapabilities.forEach(function(capabilities) {
var capabilitiesSpecs = allSpecs;
Expand Down
3 changes: 2 additions & 1 deletion scripts/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@ var passingTests = [
'node lib/cli.js spec/pluginsFullConf.js',
'node lib/cli.js spec/ngHintSuccessConfig.js',
'node lib/cli.js spec/interactionConf.js',
'node lib/cli.js spec/directConnectConf.js'
'node lib/cli.js spec/directConnectConf.js',
'node lib/cli.js spec/getCapabilitiesConf.js'
];

passingTests.push(
Expand Down
26 changes: 26 additions & 0 deletions spec/getCapabilitiesConf.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
var env = require('./environment.js');
var q = require('q');

exports.config = {
seleniumAddress: env.seleniumAddress,

// Spec patterns are relative to this directory.
specs: [
'basic/mock*',
],

framework: 'debugprint',
getMultiCapabilities: function() {
var deferred = q.defer();
// Wait for a server to be ready or get capabilities asynchronously.
setTimeout(function() {
deferred.resolve([{
'browserName': 'firefox'
}]);
}, 1000);
return deferred.promise;
},

baseUrl: env.baseUrl
};

23 changes: 0 additions & 23 deletions spec/unit/runner_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,29 +30,6 @@ describe('the Protractor runner', function() {
});
});

it('should wait for promise capabilities to resolve', function(done) {
var config = {
mockSelenium: true,
specs: ['*.js'],
framework: 'debugprint',
capabilities: q.when({
'browserName': 'customfortest'
})
};
var exitCode;
Runner.prototype.exit_ = function(exit) {
exitCode = exit;
};
var runner = new Runner(config);

runner.run().then(function() {
expect(runner.getConfig().capabilities.browserName).
toEqual('customfortest');
expect(exitCode).toEqual(0);
done();
});
});

it('should fail with no specs', function() {
var config = {
mockSelenium: true,
Expand Down
34 changes: 8 additions & 26 deletions spec/unit/taskScheduler_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ describe('the task scheduler', function() {
'spec/unit/data/fakespecA.js',
'spec/unit/data/fakespecB.js'
],
capabilities: {
multiCapabilities: [{
browserName: 'chrome'
}
}]
};
var config = new ConfigParser().addConfig(toAdd).getConfig();
var scheduler = new TaskScheduler(config);
Expand All @@ -30,11 +30,11 @@ describe('the task scheduler', function() {
'spec/unit/data/fakespecA.js',
'spec/unit/data/fakespecB.js'
],
capabilities: {
multiCapabilities: [{
shardTestFiles: true,
maxInstances: 2,
browserName: 'chrome'
}
}]
};
var config = new ConfigParser().addConfig(toAdd).getConfig();
var scheduler = new TaskScheduler(config);
Expand All @@ -58,10 +58,10 @@ describe('the task scheduler', function() {
'spec/unit/data/fakespecA.js',
'spec/unit/data/fakespecB.js'
],
capabilities: {
multiCapabilities: [{
count: 2,
browserName: 'chrome'
}
}]
};
var config = new ConfigParser().addConfig(toAdd).getConfig();
var scheduler = new TaskScheduler(config);
Expand Down Expand Up @@ -113,11 +113,11 @@ describe('the task scheduler', function() {
'spec/unit/data/fakespecA.js',
'spec/unit/data/fakespecB.js'
],
capabilities: {
multiCapabilities: [{
shardTestFiles: true,
maxInstances: 1,
browserName: 'chrome'
}
}]
};
var config = new ConfigParser().addConfig(toAdd).getConfig();
var scheduler = new TaskScheduler(config);
Expand Down Expand Up @@ -215,24 +215,6 @@ describe('the task scheduler', function() {
expect(scheduler.numTasksOutstanding()).toEqual(0);
});

it('should default to chrome when no capability is defined', function() {
var toAdd = {
specs: [
'spec/unit/data/fakespecA.js',
'spec/unit/data/fakespecB.js'
]
};
var config = new ConfigParser().addConfig(toAdd).getConfig();
var scheduler = new TaskScheduler(config);

var task = scheduler.nextTask();
expect(task.capabilities.browserName).toEqual('chrome');
expect(task.specs.length).toEqual(2);

task.done();
expect(scheduler.numTasksOutstanding()).toEqual(0);
});

it('should exclude capability-specific specs', function() {
var toAdd = {
specs: [
Expand Down