Skip to content
This repository was archived by the owner on Jul 29, 2024. It is now read-only.
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
7 changes: 6 additions & 1 deletion lib/config.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import {PluginConfig} from './plugins';

export type SpecScheduler = () => (specs: Array<string>, capabilities: any) => Array<Array<string>>;

export interface Config {
[key: string]: any;

Expand Down Expand Up @@ -340,9 +342,12 @@ export interface Config {
/**
* If this is set to be true, specs will be sharded by file (i.e. all
* files to be run by this set of capabilities will run in parallel).
* By default each test file will run in separeted browser instance.
* Default is false.
* You can also provide custom spec scheduler function
* that can change default behaviour and run many specs in one browser instance.
*/
shardTestFiles?: boolean;
shardTestFiles: boolean | SpecScheduler;

/**
* Maximum number of browser instances that can run in parallel for this
Expand Down
22 changes: 12 additions & 10 deletions lib/taskScheduler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,17 +63,19 @@ export class TaskScheduler {
});
}

let specLists: Array<Array<string>> = [];
// If we shard, we return an array of one element arrays, each containing
// the spec file. If we don't shard, we return an one element array
// containing an array of all the spec files
if (capabilities.shardTestFiles) {
capabilitiesSpecs.forEach((spec) => {
specLists.push([spec]);
});
} else {
specLists.push(capabilitiesSpecs);
let shardScheduler = capabilities.shardTestFiles;
if (typeof shardScheduler !== 'function') {
// If we shard, we return an array of one element arrays, each containing
// the spec file. If we don't shard, we return an one element array
// containing an array of all the spec files
shardScheduler = function(specs: Array<string>, capabilities: any): Array<Array<string>> {
if (capabilities.shardTestFiles) {
return specs.map(spec => [spec]);
}
return [specs];
};
}
const specLists = shardScheduler(capabilitiesSpecs, capabilities);

capabilities.count = capabilities.count || 1;

Expand Down
48 changes: 48 additions & 0 deletions spec/unit/taskScheduler_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -258,4 +258,52 @@ describe('the task scheduler', function() {
expect(scheduler.numTasksOutstanding()).toEqual(0);
});

it('should use custom shard scheduler when provided', function() {
var toAdd = {
specs: [
'spec/unit/data/fakespecA.js',
'spec/unit/data/fakespecB.js',
'spec/unit/data/fakespecC.js'
],
multiCapabilities: [{
shardTestFiles: shardScheduler,
browserName: 'chrome',
maxInstances: 2,
}]
};
var config = new ConfigParser().addConfig(toAdd).getConfig();
var scheduler = new TaskScheduler(config);

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

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

task1.done();
task2.done();
expect(scheduler.numTasksOutstanding()).toEqual(0);
});

function shardScheduler(specs, capabilities) {
const numberOfShards = capabilities.maxInstances;
if(numberOfShards > 1) {
const bucketSize = Math.ceil(specs.length/numberOfShards);
const shards = [];
let start = 0;
while (start < specs.length) {
let end = start + bucketSize;
if ( end > specs.length) {
end = specs.length;
}
shards.push(specs.slice(start,end));
start = end;
}
return shards;
}
return [specs];
}

});