feat(bench press): allow multiple reporters, metrics and driver extensions.
This commit is contained in:
parent
987a5fdf56
commit
1d4ffd986d
|
@ -14,5 +14,7 @@ export { IOsDriverExtension } from './src/webdriver/ios_driver_extension';
|
||||||
export { Runner } from './src/runner';
|
export { Runner } from './src/runner';
|
||||||
export { Options } from './src/sample_options';
|
export { Options } from './src/sample_options';
|
||||||
export { MeasureValues } from './src/measure_values';
|
export { MeasureValues } from './src/measure_values';
|
||||||
|
export { MultiMetric } from './src/metric/multi_metric';
|
||||||
|
export { MultiReporter } from './src/reporter/multi_reporter';
|
||||||
|
|
||||||
export { bind, Injector, OpaqueToken } from 'angular2/di';
|
export { bind, Injector, OpaqueToken } from 'angular2/di';
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import { bind } from 'angular2/di';
|
||||||
import {
|
import {
|
||||||
Promise, PromiseWrapper
|
Promise, PromiseWrapper
|
||||||
} from 'angular2/src/facade/async';
|
} from 'angular2/src/facade/async';
|
||||||
|
@ -11,6 +12,14 @@ import { StringMap } from 'angular2/src/facade/collection';
|
||||||
*/
|
*/
|
||||||
@ABSTRACT()
|
@ABSTRACT()
|
||||||
export class Metric {
|
export class Metric {
|
||||||
|
static bindTo(delegateToken) {
|
||||||
|
return [
|
||||||
|
bind(Metric).toFactory(
|
||||||
|
(delegate) => delegate, [delegateToken]
|
||||||
|
)
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Starts measuring
|
* Starts measuring
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -0,0 +1,69 @@
|
||||||
|
import { bind, Injector, OpaqueToken } from 'angular2/di';
|
||||||
|
import { List, ListWrapper, StringMapWrapper, StringMap } from 'angular2/src/facade/collection';
|
||||||
|
import { Promise, PromiseWrapper } from 'angular2/src/facade/async';
|
||||||
|
|
||||||
|
import { Metric } from '../metric';
|
||||||
|
|
||||||
|
export class MultiMetric extends Metric {
|
||||||
|
static createBindings(childTokens) {
|
||||||
|
return [
|
||||||
|
bind(_CHILDREN).toAsyncFactory(
|
||||||
|
(injector) => PromiseWrapper.all(ListWrapper.map(childTokens, (token) => injector.asyncGet(token) )),
|
||||||
|
[Injector]
|
||||||
|
),
|
||||||
|
bind(MultiMetric).toFactory(
|
||||||
|
(children) => new MultiMetric(children),
|
||||||
|
[_CHILDREN]
|
||||||
|
)
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
_metrics:List;
|
||||||
|
|
||||||
|
constructor(metrics) {
|
||||||
|
super();
|
||||||
|
this._metrics = metrics;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Starts measuring
|
||||||
|
*/
|
||||||
|
beginMeasure():Promise {
|
||||||
|
return PromiseWrapper.all(ListWrapper.map(
|
||||||
|
this._metrics, (metric) => metric.beginMeasure()
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ends measuring and reports the data
|
||||||
|
* since the begin call.
|
||||||
|
* @param restart: Whether to restart right after this.
|
||||||
|
*/
|
||||||
|
endMeasure(restart:boolean):Promise<StringMap> {
|
||||||
|
return PromiseWrapper.all(ListWrapper.map(
|
||||||
|
this._metrics, (metric) => metric.endMeasure(restart)
|
||||||
|
)).then( (values) => {
|
||||||
|
return mergeStringMaps(values);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Describes the metrics provided by this metric implementation.
|
||||||
|
* (e.g. units, ...)
|
||||||
|
*/
|
||||||
|
describe():StringMap {
|
||||||
|
return mergeStringMaps(this._metrics.map( (metric) => metric.describe() ));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function mergeStringMaps(maps) {
|
||||||
|
var result = {};
|
||||||
|
ListWrapper.forEach(maps, (map) => {
|
||||||
|
StringMapWrapper.forEach(map, (value, prop) => {
|
||||||
|
result[prop] = value;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
var _CHILDREN = new OpaqueToken('MultiMetric.children');
|
|
@ -155,7 +155,7 @@ var _MAX_RETRY_COUNT = 20;
|
||||||
var _MARK_NAME_PREFIX = 'benchpress';
|
var _MARK_NAME_PREFIX = 'benchpress';
|
||||||
var _SET_TIMEOUT = new OpaqueToken('PerflogMetric.setTimeout');
|
var _SET_TIMEOUT = new OpaqueToken('PerflogMetric.setTimeout');
|
||||||
var _BINDINGS = [
|
var _BINDINGS = [
|
||||||
bind(Metric).toFactory(
|
bind(PerflogMetric).toFactory(
|
||||||
(driverExtension, setTimeout) => new PerflogMetric(driverExtension, setTimeout),
|
(driverExtension, setTimeout) => new PerflogMetric(driverExtension, setTimeout),
|
||||||
[WebDriverExtension, _SET_TIMEOUT]
|
[WebDriverExtension, _SET_TIMEOUT]
|
||||||
),
|
),
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import { bind } from 'angular2/di';
|
||||||
import {
|
import {
|
||||||
Promise, PromiseWrapper
|
Promise, PromiseWrapper
|
||||||
} from 'angular2/src/facade/async';
|
} from 'angular2/src/facade/async';
|
||||||
|
@ -12,6 +13,14 @@ import { MeasureValues } from './measure_values';
|
||||||
*/
|
*/
|
||||||
@ABSTRACT()
|
@ABSTRACT()
|
||||||
export class Reporter {
|
export class Reporter {
|
||||||
|
static bindTo(delegateToken) {
|
||||||
|
return [
|
||||||
|
bind(Reporter).toFactory(
|
||||||
|
(delegate) => delegate, [delegateToken]
|
||||||
|
)
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
reportMeasureValues(values:MeasureValues):Promise {
|
reportMeasureValues(values:MeasureValues):Promise {
|
||||||
throw new BaseException('NYI');
|
throw new BaseException('NYI');
|
||||||
}
|
}
|
||||||
|
|
|
@ -109,7 +109,7 @@ export class ConsoleReporter extends Reporter {
|
||||||
var _PRINT = new OpaqueToken('ConsoleReporter.print');
|
var _PRINT = new OpaqueToken('ConsoleReporter.print');
|
||||||
var _COLUMN_WIDTH = new OpaqueToken('ConsoleReporter.columnWidht');
|
var _COLUMN_WIDTH = new OpaqueToken('ConsoleReporter.columnWidht');
|
||||||
var _BINDINGS = [
|
var _BINDINGS = [
|
||||||
bind(Reporter).toFactory(
|
bind(ConsoleReporter).toFactory(
|
||||||
(columnWidth, sampleDescription, print) => new ConsoleReporter(columnWidth, sampleDescription, print),
|
(columnWidth, sampleDescription, print) => new ConsoleReporter(columnWidth, sampleDescription, print),
|
||||||
[_COLUMN_WIDTH, SampleDescription, _PRINT]
|
[_COLUMN_WIDTH, SampleDescription, _PRINT]
|
||||||
),
|
),
|
||||||
|
|
|
@ -0,0 +1,42 @@
|
||||||
|
import { bind, Injector, OpaqueToken } from 'angular2/di';
|
||||||
|
import { List, ListWrapper } from 'angular2/src/facade/collection';
|
||||||
|
import { Promise, PromiseWrapper } from 'angular2/src/facade/async';
|
||||||
|
|
||||||
|
import { MeasureValues } from '../measure_values';
|
||||||
|
import { Reporter } from '../reporter';
|
||||||
|
|
||||||
|
export class MultiReporter extends Reporter {
|
||||||
|
static createBindings(childTokens) {
|
||||||
|
return [
|
||||||
|
bind(_CHILDREN).toAsyncFactory(
|
||||||
|
(injector) => PromiseWrapper.all(ListWrapper.map(childTokens, (token) => injector.asyncGet(token) )),
|
||||||
|
[Injector]
|
||||||
|
),
|
||||||
|
bind(MultiReporter).toFactory(
|
||||||
|
(children) => new MultiReporter(children),
|
||||||
|
[_CHILDREN]
|
||||||
|
)
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
_reporters:List;
|
||||||
|
|
||||||
|
constructor(reporters) {
|
||||||
|
super();
|
||||||
|
this._reporters = reporters;
|
||||||
|
}
|
||||||
|
|
||||||
|
reportMeasureValues(values:MeasureValues):Promise {
|
||||||
|
return PromiseWrapper.all(ListWrapper.map(
|
||||||
|
this._reporters, (reporter) => reporter.reportMeasureValues(values)
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
reportSample(completeSample:List<MeasureValues>, validSample:List<MeasureValues>):Promise {
|
||||||
|
return PromiseWrapper.all(ListWrapper.map(
|
||||||
|
this._reporters, (reporter) => reporter.reportSample(completeSample, validSample)
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var _CHILDREN = new OpaqueToken('MultiReporter.children');
|
|
@ -5,11 +5,19 @@ import { Promise } from 'angular2/src/facade/async';
|
||||||
|
|
||||||
import { Sampler, SampleState } from './sampler';
|
import { Sampler, SampleState } from './sampler';
|
||||||
import { ConsoleReporter } from './reporter/console_reporter';
|
import { ConsoleReporter } from './reporter/console_reporter';
|
||||||
|
import { MultiReporter } from './reporter/multi_reporter';
|
||||||
import { RegressionSlopeValidator } from './validator/regression_slope_validator';
|
import { RegressionSlopeValidator } from './validator/regression_slope_validator';
|
||||||
|
import { SizeValidator } from './validator/size_validator';
|
||||||
|
import { Validator } from './validator';
|
||||||
import { PerflogMetric } from './metric/perflog_metric';
|
import { PerflogMetric } from './metric/perflog_metric';
|
||||||
|
import { MultiMetric } from './metric/multi_metric';
|
||||||
import { ChromeDriverExtension } from './webdriver/chrome_driver_extension';
|
import { ChromeDriverExtension } from './webdriver/chrome_driver_extension';
|
||||||
|
import { IOsDriverExtension } from './webdriver/ios_driver_extension';
|
||||||
|
import { WebDriverExtension } from './web_driver_extension';
|
||||||
import { SampleDescription } from './sample_description';
|
import { SampleDescription } from './sample_description';
|
||||||
|
import { WebDriverAdapter } from './web_driver_adapter';
|
||||||
|
import { Reporter } from './reporter';
|
||||||
|
import { Metric } from './metric';
|
||||||
import { Options } from './sample_options';
|
import { Options } from './sample_options';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -48,7 +56,23 @@ var _DEFAULT_BINDINGS = [
|
||||||
Sampler.BINDINGS,
|
Sampler.BINDINGS,
|
||||||
ConsoleReporter.BINDINGS,
|
ConsoleReporter.BINDINGS,
|
||||||
RegressionSlopeValidator.BINDINGS,
|
RegressionSlopeValidator.BINDINGS,
|
||||||
|
SizeValidator.BINDINGS,
|
||||||
ChromeDriverExtension.BINDINGS,
|
ChromeDriverExtension.BINDINGS,
|
||||||
|
IOsDriverExtension.BINDINGS,
|
||||||
PerflogMetric.BINDINGS,
|
PerflogMetric.BINDINGS,
|
||||||
SampleDescription.BINDINGS
|
SampleDescription.BINDINGS,
|
||||||
|
MultiReporter.createBindings([ConsoleReporter]),
|
||||||
|
MultiMetric.createBindings([PerflogMetric]),
|
||||||
|
|
||||||
|
Reporter.bindTo(MultiReporter),
|
||||||
|
Validator.bindTo(RegressionSlopeValidator),
|
||||||
|
WebDriverExtension.bindTo([ChromeDriverExtension, IOsDriverExtension]),
|
||||||
|
Metric.bindTo(MultiMetric),
|
||||||
|
|
||||||
|
bind(Options.CAPABILITIES).toAsyncFactory(
|
||||||
|
(adapter) => adapter.capabilities(), [WebDriverAdapter]
|
||||||
|
),
|
||||||
|
bind(Options.USER_AGENT).toAsyncFactory(
|
||||||
|
(adapter) => adapter.executeScript('return window.navigator.userAgent;'), [WebDriverAdapter]
|
||||||
|
)
|
||||||
];
|
];
|
||||||
|
|
|
@ -27,15 +27,18 @@ export class SampleDescription {
|
||||||
|
|
||||||
var _BINDINGS = [
|
var _BINDINGS = [
|
||||||
bind(SampleDescription).toFactory(
|
bind(SampleDescription).toFactory(
|
||||||
(metric, id, forceGc, validator, defaultDesc, userDesc) => new SampleDescription(id,
|
(metric, id, forceGc, userAgent, validator, defaultDesc, userDesc) => new SampleDescription(id,
|
||||||
[
|
[
|
||||||
{'forceGc': forceGc},
|
{'forceGc': forceGc, 'userAgent': userAgent},
|
||||||
validator.describe(),
|
validator.describe(),
|
||||||
defaultDesc,
|
defaultDesc,
|
||||||
userDesc
|
userDesc
|
||||||
],
|
],
|
||||||
metric.describe()),
|
metric.describe()),
|
||||||
[Metric, Options.SAMPLE_ID, Options.FORCE_GC, Validator, Options.DEFAULT_DESCRIPTION, Options.SAMPLE_DESCRIPTION]
|
[
|
||||||
|
Metric, Options.SAMPLE_ID, Options.FORCE_GC, Options.USER_AGENT,
|
||||||
|
Validator, Options.DEFAULT_DESCRIPTION, Options.SAMPLE_DESCRIPTION
|
||||||
|
]
|
||||||
),
|
),
|
||||||
bind(Options.DEFAULT_DESCRIPTION).toValue({}),
|
bind(Options.DEFAULT_DESCRIPTION).toValue({}),
|
||||||
bind(Options.SAMPLE_DESCRIPTION).toValue({})
|
bind(Options.SAMPLE_DESCRIPTION).toValue({})
|
||||||
|
|
|
@ -13,11 +13,17 @@ export class Options {
|
||||||
static get PREPARE() { return _PREPARE; }
|
static get PREPARE() { return _PREPARE; }
|
||||||
// TODO(tbosch): use static initializer when our transpiler supports it
|
// TODO(tbosch): use static initializer when our transpiler supports it
|
||||||
static get EXECUTE() { return _EXECUTE; }
|
static get EXECUTE() { return _EXECUTE; }
|
||||||
|
// TODO(tbosch): use static initializer when our transpiler supports it
|
||||||
|
static get CAPABILITIES() { return _CAPABILITIES; }
|
||||||
|
// TODO(tbosch): use static initializer when our transpiler supports it
|
||||||
|
static get USER_AGENT() { return _USER_AGENT; }
|
||||||
}
|
}
|
||||||
|
|
||||||
var _SAMPLE_ID = new OpaqueToken('SampleDescription.sampleId');
|
var _SAMPLE_ID = new OpaqueToken('Options.sampleId');
|
||||||
var _DEFAULT_DESCRIPTION = new OpaqueToken('SampleDescription.defaultDescription');
|
var _DEFAULT_DESCRIPTION = new OpaqueToken('Options.defaultDescription');
|
||||||
var _SAMPLE_DESCRIPTION = new OpaqueToken('SampleDescription.sampleDescription');
|
var _SAMPLE_DESCRIPTION = new OpaqueToken('Options.sampleDescription');
|
||||||
var _FORCE_GC = new OpaqueToken('Sampler.forceGc');
|
var _FORCE_GC = new OpaqueToken('Options.forceGc');
|
||||||
var _PREPARE = new OpaqueToken('Sampler.prepare');
|
var _PREPARE = new OpaqueToken('Options.prepare');
|
||||||
var _EXECUTE = new OpaqueToken('Sampler.execute');
|
var _EXECUTE = new OpaqueToken('Options.execute');
|
||||||
|
var _CAPABILITIES = new OpaqueToken('Options.capabilities');
|
||||||
|
var _USER_AGENT = new OpaqueToken('Options.userAgent');
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import { bind } from 'angular2/di';
|
||||||
import { List, StringMap } from 'angular2/src/facade/collection';
|
import { List, StringMap } from 'angular2/src/facade/collection';
|
||||||
import {
|
import {
|
||||||
ABSTRACT, BaseException
|
ABSTRACT, BaseException
|
||||||
|
@ -12,6 +13,14 @@ import { MeasureValues } from './measure_values';
|
||||||
*/
|
*/
|
||||||
@ABSTRACT()
|
@ABSTRACT()
|
||||||
export class Validator {
|
export class Validator {
|
||||||
|
static bindTo(delegateToken) {
|
||||||
|
return [
|
||||||
|
bind(Validator).toFactory(
|
||||||
|
(delegate) => delegate, [delegateToken]
|
||||||
|
)
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Calculates a valid sample out of the complete sample
|
* Calculates a valid sample out of the complete sample
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -60,7 +60,7 @@ export class RegressionSlopeValidator extends Validator {
|
||||||
var _SAMPLE_SIZE = new OpaqueToken('RegressionSlopeValidator.sampleSize');
|
var _SAMPLE_SIZE = new OpaqueToken('RegressionSlopeValidator.sampleSize');
|
||||||
var _METRIC = new OpaqueToken('RegressionSlopeValidator.metric');
|
var _METRIC = new OpaqueToken('RegressionSlopeValidator.metric');
|
||||||
var _BINDINGS = [
|
var _BINDINGS = [
|
||||||
bind(Validator).toFactory(
|
bind(RegressionSlopeValidator).toFactory(
|
||||||
(sampleSize, metric) => new RegressionSlopeValidator(sampleSize, metric),
|
(sampleSize, metric) => new RegressionSlopeValidator(sampleSize, metric),
|
||||||
[_SAMPLE_SIZE, _METRIC]
|
[_SAMPLE_SIZE, _METRIC]
|
||||||
),
|
),
|
||||||
|
|
|
@ -38,7 +38,7 @@ export class SizeValidator extends Validator {
|
||||||
|
|
||||||
var _SAMPLE_SIZE = new OpaqueToken('SizeValidator.sampleSize');
|
var _SAMPLE_SIZE = new OpaqueToken('SizeValidator.sampleSize');
|
||||||
var _BINDINGS = [
|
var _BINDINGS = [
|
||||||
bind(Validator).toFactory(
|
bind(SizeValidator).toFactory(
|
||||||
(size) => new SizeValidator(size),
|
(size) => new SizeValidator(size),
|
||||||
[_SAMPLE_SIZE]
|
[_SAMPLE_SIZE]
|
||||||
),
|
),
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
|
import { bind } from 'angular2/di';
|
||||||
import { Promise } from 'angular2/src/facade/async';
|
import { Promise } from 'angular2/src/facade/async';
|
||||||
import { BaseException, ABSTRACT } from 'angular2/src/facade/lang';
|
import { BaseException, ABSTRACT } from 'angular2/src/facade/lang';
|
||||||
|
import { List, Map } from 'angular2/src/facade/collection';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A WebDriverAdapter bridges API differences between different WebDriver clients,
|
* A WebDriverAdapter bridges API differences between different WebDriver clients,
|
||||||
|
@ -8,16 +10,24 @@ import { BaseException, ABSTRACT } from 'angular2/src/facade/lang';
|
||||||
*/
|
*/
|
||||||
@ABSTRACT()
|
@ABSTRACT()
|
||||||
export class WebDriverAdapter {
|
export class WebDriverAdapter {
|
||||||
|
static bindTo(delegateToken) {
|
||||||
|
return [
|
||||||
|
bind(WebDriverAdapter).toFactory(
|
||||||
|
(delegate) => delegate, [delegateToken]
|
||||||
|
)
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
waitFor(callback:Function):Promise {
|
waitFor(callback:Function):Promise {
|
||||||
throw new BaseException('NYI');
|
throw new BaseException('NYI');
|
||||||
}
|
}
|
||||||
executeScript(script:string):Promise {
|
executeScript(script:string):Promise {
|
||||||
throw new BaseException('NYI');
|
throw new BaseException('NYI');
|
||||||
}
|
}
|
||||||
capabilities():Promise {
|
capabilities():Promise<Map> {
|
||||||
throw new BaseException('NYI');
|
throw new BaseException('NYI');
|
||||||
}
|
}
|
||||||
logs(type:string):Promise {
|
logs(type:string):Promise<List> {
|
||||||
throw new BaseException('NYI');
|
throw new BaseException('NYI');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,10 @@
|
||||||
import { BaseException, ABSTRACT } from 'angular2/src/facade/lang';
|
import { bind, Injector, OpaqueToken } from 'angular2/di';
|
||||||
import { Promise } from 'angular2/src/facade/async';
|
|
||||||
import { List } from 'angular2/src/facade/collection';
|
import { BaseException, ABSTRACT, isBlank } from 'angular2/src/facade/lang';
|
||||||
|
import { Promise, PromiseWrapper } from 'angular2/src/facade/async';
|
||||||
|
import { List, ListWrapper, StringMap } from 'angular2/src/facade/collection';
|
||||||
|
|
||||||
|
import { Options } from './sample_options';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A WebDriverExtension implements extended commands of the webdriver protocol
|
* A WebDriverExtension implements extended commands of the webdriver protocol
|
||||||
|
@ -9,6 +13,30 @@ import { List } from 'angular2/src/facade/collection';
|
||||||
*/
|
*/
|
||||||
@ABSTRACT()
|
@ABSTRACT()
|
||||||
export class WebDriverExtension {
|
export class WebDriverExtension {
|
||||||
|
static bindTo(childTokens) {
|
||||||
|
return [
|
||||||
|
bind(_CHILDREN).toAsyncFactory(
|
||||||
|
(injector) => PromiseWrapper.all(ListWrapper.map(childTokens, (token) => injector.asyncGet(token) )),
|
||||||
|
[Injector]
|
||||||
|
),
|
||||||
|
bind(WebDriverExtension).toFactory(
|
||||||
|
(children, capabilities) => {
|
||||||
|
var delegate;
|
||||||
|
ListWrapper.forEach(children, (extension) => {
|
||||||
|
if (extension.supports(capabilities)) {
|
||||||
|
delegate = extension;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (isBlank(delegate)) {
|
||||||
|
throw new BaseException('Could not find a delegate for given capabilities!');
|
||||||
|
}
|
||||||
|
return delegate;
|
||||||
|
},
|
||||||
|
[_CHILDREN, Options.CAPABILITIES]
|
||||||
|
)
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
gc():Promise {
|
gc():Promise {
|
||||||
throw new BaseException('NYI');
|
throw new BaseException('NYI');
|
||||||
}
|
}
|
||||||
|
@ -35,4 +63,10 @@ export class WebDriverExtension {
|
||||||
readPerfLog():Promise<List> {
|
readPerfLog():Promise<List> {
|
||||||
throw new BaseException('NYI');
|
throw new BaseException('NYI');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
supports(capabilities:StringMap):boolean {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var _CHILDREN = new OpaqueToken('WebDriverExtension.children');
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { bind } from 'angular2/di';
|
import { bind } from 'angular2/di';
|
||||||
import { ListWrapper, StringMapWrapper } from 'angular2/src/facade/collection';
|
import { ListWrapper, StringMapWrapper, StringMap } from 'angular2/src/facade/collection';
|
||||||
import {
|
import {
|
||||||
Json, isPresent, isBlank, RegExpWrapper, StringWrapper, BaseException, NumberWrapper
|
Json, isPresent, isBlank, RegExpWrapper, StringWrapper, BaseException, NumberWrapper
|
||||||
} from 'angular2/src/facade/lang';
|
} from 'angular2/src/facade/lang';
|
||||||
|
@ -36,6 +36,7 @@ export class ChromeDriverExtension extends WebDriverExtension {
|
||||||
return this._driver.executeScript(script);
|
return this._driver.executeScript(script);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// See [Chrome Trace Event Format](https://docs.google.com/document/d/1CvAClvFfyA5R-PhYUmn5OOQtYMH4h6I0nSsKchNAySU/edit)
|
||||||
readPerfLog() {
|
readPerfLog() {
|
||||||
// TODO(tbosch): Bug in ChromeDriver: Need to execute at least one command
|
// TODO(tbosch): Bug in ChromeDriver: Need to execute at least one command
|
||||||
// so that the browser logs can be read out!
|
// so that the browser logs can be read out!
|
||||||
|
@ -95,6 +96,10 @@ export class ChromeDriverExtension extends WebDriverExtension {
|
||||||
});
|
});
|
||||||
return normalizedEvents;
|
return normalizedEvents;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
supports(capabilities:StringMap):boolean {
|
||||||
|
return StringWrapper.equals(capabilities['browserName'].toLowerCase(), 'chrome');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function normalizeEvent(chromeEvent, data) {
|
function normalizeEvent(chromeEvent, data) {
|
||||||
|
@ -120,7 +125,7 @@ function normalizeEvent(chromeEvent, data) {
|
||||||
}
|
}
|
||||||
|
|
||||||
var _BINDINGS = [
|
var _BINDINGS = [
|
||||||
bind(WebDriverExtension).toFactory(
|
bind(ChromeDriverExtension).toFactory(
|
||||||
(driver) => new ChromeDriverExtension(driver),
|
(driver) => new ChromeDriverExtension(driver),
|
||||||
[WebDriverAdapter]
|
[WebDriverAdapter]
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { bind } from 'angular2/di';
|
import { bind } from 'angular2/di';
|
||||||
import { ListWrapper } from 'angular2/src/facade/collection';
|
import { ListWrapper, StringMap } from 'angular2/src/facade/collection';
|
||||||
import {
|
import {
|
||||||
Json, isPresent, isBlank, RegExpWrapper, StringWrapper
|
Json, isPresent, isBlank, RegExpWrapper, StringWrapper
|
||||||
} from 'angular2/src/facade/lang';
|
} from 'angular2/src/facade/lang';
|
||||||
|
@ -36,6 +36,7 @@ export class IOsDriverExtension extends WebDriverExtension {
|
||||||
return this._driver.executeScript(script);
|
return this._driver.executeScript(script);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// See https://github.com/WebKit/webkit/tree/master/Source/WebInspectorUI/Versions
|
||||||
readPerfLog() {
|
readPerfLog() {
|
||||||
// TODO(tbosch): Bug in IOsDriver: Need to execute at least one command
|
// TODO(tbosch): Bug in IOsDriver: Need to execute at least one command
|
||||||
// so that the browser logs can be read out!
|
// so that the browser logs can be read out!
|
||||||
|
@ -97,6 +98,10 @@ export class IOsDriverExtension extends WebDriverExtension {
|
||||||
});
|
});
|
||||||
return events;
|
return events;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
supports(capabilities:StringMap):boolean {
|
||||||
|
return StringWrapper.equals(capabilities['browserName'].toLowerCase(), 'safari');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function createEvent(ph, name, time, args = null) {
|
function createEvent(ph, name, time, args = null) {
|
||||||
|
@ -132,7 +137,7 @@ function createMarkEndEvent(name, time) {
|
||||||
}
|
}
|
||||||
|
|
||||||
var _BINDINGS = [
|
var _BINDINGS = [
|
||||||
bind(WebDriverExtension).toFactory(
|
bind(IOsDriverExtension).toFactory(
|
||||||
(driver) => new IOsDriverExtension(driver),
|
(driver) => new IOsDriverExtension(driver),
|
||||||
[WebDriverAdapter]
|
[WebDriverAdapter]
|
||||||
)
|
)
|
||||||
|
|
|
@ -17,7 +17,13 @@ export class SeleniumWebDriverAdapter extends WebDriverAdapter {
|
||||||
|
|
||||||
_convertPromise(thenable) {
|
_convertPromise(thenable) {
|
||||||
var completer = PromiseWrapper.completer();
|
var completer = PromiseWrapper.completer();
|
||||||
thenable.then(completer.complete, completer.reject);
|
thenable.then(
|
||||||
|
// selenium-webdriver uses an own Node.js context,
|
||||||
|
// so we need to convert data into objects of this context.
|
||||||
|
// (e.g. otherwise instanceof checks of rtts_assert would fail)
|
||||||
|
(data) => completer.complete(convertToLocalProcess(data)),
|
||||||
|
completer.reject
|
||||||
|
);
|
||||||
return completer.promise;
|
return completer.promise;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -30,7 +36,9 @@ export class SeleniumWebDriverAdapter extends WebDriverAdapter {
|
||||||
}
|
}
|
||||||
|
|
||||||
capabilities():Promise {
|
capabilities():Promise {
|
||||||
return this._convertPromise(this._driver.getCapabilities());
|
return this._convertPromise(
|
||||||
|
this._driver.getCapabilities().then( (capsObject) => capsObject.toJSON() )
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
logs(type:string):Promise {
|
logs(type:string):Promise {
|
||||||
|
@ -39,11 +47,15 @@ export class SeleniumWebDriverAdapter extends WebDriverAdapter {
|
||||||
return this._convertPromise(this._driver.schedule(
|
return this._convertPromise(this._driver.schedule(
|
||||||
new webdriver.Command(webdriver.CommandName.GET_LOG).
|
new webdriver.Command(webdriver.CommandName.GET_LOG).
|
||||||
setParameter('type', type),
|
setParameter('type', type),
|
||||||
'WebDriver.manage().logs().get(' + type + ')').then( (logs) => {
|
'WebDriver.manage().logs().get(' + type + ')'));
|
||||||
// Need to convert the Array into an instance of an Array
|
|
||||||
// as selenium-webdriver uses an own Node.js context!
|
|
||||||
return [].slice.call(logs);
|
|
||||||
}));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function convertToLocalProcess(data) {
|
||||||
|
var serialized = JSON.stringify(data);
|
||||||
|
if (''+serialized === 'undefined') {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
return JSON.parse(serialized);
|
||||||
|
}
|
|
@ -0,0 +1,80 @@
|
||||||
|
import {ddescribe, describe, it, iit, xit, expect, beforeEach, afterEach} from 'angular2/test_lib';
|
||||||
|
|
||||||
|
import { List, ListWrapper, StringMap } from 'angular2/src/facade/collection';
|
||||||
|
import { PromiseWrapper, Promise } from 'angular2/src/facade/async';
|
||||||
|
|
||||||
|
import { Metric, MultiMetric, bind, Injector } from 'benchpress/benchpress';
|
||||||
|
|
||||||
|
export function main() {
|
||||||
|
function createMetric(ids) {
|
||||||
|
return new Injector([
|
||||||
|
ListWrapper.map(ids, (id) => bind(id).toValue(new MockMetric(id)) ),
|
||||||
|
MultiMetric.createBindings(ids)
|
||||||
|
]).asyncGet(MultiMetric);
|
||||||
|
}
|
||||||
|
|
||||||
|
describe('multi metric', () => {
|
||||||
|
|
||||||
|
it('should merge descriptions', (done) => {
|
||||||
|
createMetric(['m1', 'm2']).then( (m) => {
|
||||||
|
expect(m.describe()).toEqual({
|
||||||
|
'm1': 'describe', 'm2': 'describe'
|
||||||
|
});
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should merge all beginMeasure calls', (done) => {
|
||||||
|
createMetric(['m1', 'm2'])
|
||||||
|
.then( (m) => m.beginMeasure() )
|
||||||
|
.then( (values) => {
|
||||||
|
expect(values).toEqual([
|
||||||
|
'm1_beginMeasure', 'm2_beginMeasure'
|
||||||
|
]);
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
[false, true].forEach( (restartFlag) => {
|
||||||
|
it(`should merge all endMeasure calls for restart=${restartFlag}`, (done) => {
|
||||||
|
createMetric(['m1', 'm2'])
|
||||||
|
.then( (m) => m.endMeasure(restartFlag) )
|
||||||
|
.then( (values) => {
|
||||||
|
expect(values).toEqual({
|
||||||
|
'm1': { 'restart': restartFlag },
|
||||||
|
'm2': { 'restart': restartFlag }
|
||||||
|
});
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
class MockMetric extends Metric {
|
||||||
|
_id:string;
|
||||||
|
|
||||||
|
constructor(id) {
|
||||||
|
super();
|
||||||
|
this._id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
beginMeasure():Promise {
|
||||||
|
return PromiseWrapper.resolve(`${this._id}_beginMeasure`);
|
||||||
|
}
|
||||||
|
|
||||||
|
endMeasure(restart:boolean):Promise<StringMap> {
|
||||||
|
var result = {};
|
||||||
|
result[this._id] = {
|
||||||
|
'restart': restart
|
||||||
|
};
|
||||||
|
return PromiseWrapper.resolve(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
describe():StringMap {
|
||||||
|
var result = {};
|
||||||
|
result[this._id] = 'describe';
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
|
@ -20,7 +20,7 @@ export function main() {
|
||||||
fn();
|
fn();
|
||||||
}),
|
}),
|
||||||
bind(WebDriverExtension).toValue(new MockDriverExtension(perfLogs, commandLog))
|
bind(WebDriverExtension).toValue(new MockDriverExtension(perfLogs, commandLog))
|
||||||
]).get(Metric);
|
]).get(PerflogMetric);
|
||||||
}
|
}
|
||||||
|
|
||||||
describe('perflog metric', () => {
|
describe('perflog metric', () => {
|
||||||
|
|
|
@ -29,7 +29,7 @@ export function main() {
|
||||||
if (isPresent(columnWidth)) {
|
if (isPresent(columnWidth)) {
|
||||||
ListWrapper.push(bindings, bind(ConsoleReporter.COLUMN_WIDTH).toValue(columnWidth));
|
ListWrapper.push(bindings, bind(ConsoleReporter.COLUMN_WIDTH).toValue(columnWidth));
|
||||||
}
|
}
|
||||||
reporter = new Injector(bindings).get(Reporter);
|
reporter = new Injector(bindings).get(ConsoleReporter);
|
||||||
}
|
}
|
||||||
|
|
||||||
it('should print the sample id, description and table header', () => {
|
it('should print the sample id, description and table header', () => {
|
||||||
|
|
|
@ -0,0 +1,78 @@
|
||||||
|
import {ddescribe, describe, it, iit, xit, expect, beforeEach, afterEach} from 'angular2/test_lib';
|
||||||
|
|
||||||
|
import { List, ListWrapper, StringMap } from 'angular2/src/facade/collection';
|
||||||
|
import { PromiseWrapper, Promise } from 'angular2/src/facade/async';
|
||||||
|
import { DateWrapper } from 'angular2/src/facade/lang';
|
||||||
|
|
||||||
|
import { Reporter, MultiReporter, bind, Injector, MeasureValues } from 'benchpress/benchpress';
|
||||||
|
|
||||||
|
export function main() {
|
||||||
|
function createReporters(ids) {
|
||||||
|
return new Injector([
|
||||||
|
ListWrapper.map(ids, (id) => bind(id).toValue(new MockReporter(id)) ),
|
||||||
|
MultiReporter.createBindings(ids)
|
||||||
|
]).asyncGet(MultiReporter);
|
||||||
|
}
|
||||||
|
|
||||||
|
describe('multi reporter', () => {
|
||||||
|
|
||||||
|
it('should reportMeasureValues to all', (done) => {
|
||||||
|
var mv = new MeasureValues(0, DateWrapper.now(), {});
|
||||||
|
createReporters(['m1', 'm2'])
|
||||||
|
.then( (r) => r.reportMeasureValues(mv) )
|
||||||
|
.then( (values) => {
|
||||||
|
|
||||||
|
expect(values).toEqual([
|
||||||
|
{'id': 'm1', 'values': mv},
|
||||||
|
{'id': 'm2', 'values': mv}
|
||||||
|
]);
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should reportSample to call', (done) => {
|
||||||
|
var completeSample = [
|
||||||
|
new MeasureValues(0, DateWrapper.now(), {}),
|
||||||
|
new MeasureValues(1, DateWrapper.now(), {})
|
||||||
|
];
|
||||||
|
var validSample = [completeSample[1]];
|
||||||
|
|
||||||
|
createReporters(['m1', 'm2'])
|
||||||
|
.then( (r) => r.reportSample(completeSample, validSample) )
|
||||||
|
.then( (values) => {
|
||||||
|
|
||||||
|
expect(values).toEqual([
|
||||||
|
{'id': 'm1', 'completeSample': completeSample, 'validSample': validSample},
|
||||||
|
{'id': 'm2', 'completeSample': completeSample, 'validSample': validSample}
|
||||||
|
]);
|
||||||
|
done();
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
class MockReporter extends Reporter {
|
||||||
|
_id:string;
|
||||||
|
|
||||||
|
constructor(id) {
|
||||||
|
super();
|
||||||
|
this._id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
reportMeasureValues(values:MeasureValues):Promise {
|
||||||
|
return PromiseWrapper.resolve({
|
||||||
|
'id': this._id,
|
||||||
|
'values': values
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
reportSample(completeSample:List<MeasureValues>, validSample:List<MeasureValues>):Promise {
|
||||||
|
return PromiseWrapper.resolve({
|
||||||
|
'id': this._id,
|
||||||
|
'completeSample': completeSample,
|
||||||
|
'validSample': validSample
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -2,7 +2,7 @@ import {describe, it, iit, xit, expect, beforeEach, afterEach} from 'angular2/te
|
||||||
import {
|
import {
|
||||||
Runner, Sampler, SampleDescription,
|
Runner, Sampler, SampleDescription,
|
||||||
Validator, bind, Injector, Metric,
|
Validator, bind, Injector, Metric,
|
||||||
Options
|
Options, WebDriverAdapter
|
||||||
} from 'benchpress/benchpress';
|
} from 'benchpress/benchpress';
|
||||||
import { isBlank } from 'angular2/src/facade/lang';
|
import { isBlank } from 'angular2/src/facade/lang';
|
||||||
import { Promise, PromiseWrapper } from 'angular2/src/facade/async';
|
import { Promise, PromiseWrapper } from 'angular2/src/facade/async';
|
||||||
|
@ -25,16 +25,19 @@ export function main() {
|
||||||
}, [Injector]
|
}, [Injector]
|
||||||
),
|
),
|
||||||
bind(Metric).toFactory( () => new MockMetric(), []),
|
bind(Metric).toFactory( () => new MockMetric(), []),
|
||||||
bind(Validator).toFactory( () => new MockValidator(), [])
|
bind(Validator).toFactory( () => new MockValidator(), []),
|
||||||
|
bind(WebDriverAdapter).toFactory( () => new MockWebDriverAdapter(), [])
|
||||||
]);
|
]);
|
||||||
return runner;
|
return runner;
|
||||||
}
|
}
|
||||||
|
|
||||||
it('should set SampleDescription.id', (done) => {
|
it('should set SampleDescription.id', (done) => {
|
||||||
createRunner().sample({id: 'someId'}).then( (_) => {
|
createRunner().sample({id: 'someId'})
|
||||||
expect(injector.get(SampleDescription).id).toBe('someId');
|
.then( (_) => injector.asyncGet(SampleDescription) )
|
||||||
done();
|
.then( (desc) => {
|
||||||
});
|
expect(desc.id).toBe('someId');
|
||||||
|
done();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should merge SampleDescription.description', (done) => {
|
it('should merge SampleDescription.description', (done) => {
|
||||||
|
@ -42,9 +45,12 @@ export function main() {
|
||||||
bind(Options.DEFAULT_DESCRIPTION).toValue({'a': 1})
|
bind(Options.DEFAULT_DESCRIPTION).toValue({'a': 1})
|
||||||
]).sample({id: 'someId', bindings: [
|
]).sample({id: 'someId', bindings: [
|
||||||
bind(Options.SAMPLE_DESCRIPTION).toValue({'b': 2})
|
bind(Options.SAMPLE_DESCRIPTION).toValue({'b': 2})
|
||||||
]}).then( (_) => {
|
]}).then( (_) => injector.asyncGet(SampleDescription) )
|
||||||
expect(injector.get(SampleDescription).description).toEqual({
|
.then( (desc) => {
|
||||||
|
|
||||||
|
expect(desc.description).toEqual({
|
||||||
'forceGc': false,
|
'forceGc': false,
|
||||||
|
'userAgent': 'someUserAgent',
|
||||||
'a': 1,
|
'a': 1,
|
||||||
'b': 2,
|
'b': 2,
|
||||||
'v': 11
|
'v': 11
|
||||||
|
@ -54,8 +60,11 @@ export function main() {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should fill SampleDescription.metrics from the Metric', (done) => {
|
it('should fill SampleDescription.metrics from the Metric', (done) => {
|
||||||
createRunner().sample({id: 'someId'}).then( (_) => {
|
createRunner().sample({id: 'someId'})
|
||||||
expect(injector.get(SampleDescription).metrics).toEqual({ 'm1': 'some metric' });
|
.then( (_) => injector.asyncGet(SampleDescription) )
|
||||||
|
.then( (desc) => {
|
||||||
|
|
||||||
|
expect(desc.metrics).toEqual({ 'm1': 'some metric' });
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -81,7 +90,9 @@ export function main() {
|
||||||
bind(Options.DEFAULT_DESCRIPTION).toValue({'a': 1}),
|
bind(Options.DEFAULT_DESCRIPTION).toValue({'a': 1}),
|
||||||
]).sample({id: 'someId', bindings: [
|
]).sample({id: 'someId', bindings: [
|
||||||
bind(Options.DEFAULT_DESCRIPTION).toValue({'a': 2}),
|
bind(Options.DEFAULT_DESCRIPTION).toValue({'a': 2}),
|
||||||
]}).then( (_) => {
|
]}).then( (_) => injector.asyncGet(SampleDescription) )
|
||||||
|
.then( (desc) => {
|
||||||
|
|
||||||
expect(injector.get(SampleDescription).description['a']).toBe(2);
|
expect(injector.get(SampleDescription).description['a']).toBe(2);
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
|
@ -91,6 +102,12 @@ export function main() {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class MockWebDriverAdapter extends WebDriverAdapter {
|
||||||
|
executeScript(script):Promise {
|
||||||
|
return PromiseWrapper.resolve('someUserAgent');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
class MockValidator extends Validator {
|
class MockValidator extends Validator {
|
||||||
constructor() {
|
constructor() {
|
||||||
super();
|
super();
|
||||||
|
|
|
@ -15,7 +15,7 @@ export function main() {
|
||||||
RegressionSlopeValidator.BINDINGS,
|
RegressionSlopeValidator.BINDINGS,
|
||||||
bind(RegressionSlopeValidator.METRIC).toValue(metric),
|
bind(RegressionSlopeValidator.METRIC).toValue(metric),
|
||||||
bind(RegressionSlopeValidator.SAMPLE_SIZE).toValue(size)
|
bind(RegressionSlopeValidator.SAMPLE_SIZE).toValue(size)
|
||||||
]).get(Validator);
|
]).get(RegressionSlopeValidator);
|
||||||
}
|
}
|
||||||
|
|
||||||
it('should return sampleSize and metric as description', () => {
|
it('should return sampleSize and metric as description', () => {
|
||||||
|
|
|
@ -14,7 +14,7 @@ export function main() {
|
||||||
validator = new Injector([
|
validator = new Injector([
|
||||||
SizeValidator.BINDINGS,
|
SizeValidator.BINDINGS,
|
||||||
bind(SizeValidator.SAMPLE_SIZE).toValue(size)
|
bind(SizeValidator.SAMPLE_SIZE).toValue(size)
|
||||||
]).get(Validator);
|
]).get(SizeValidator);
|
||||||
}
|
}
|
||||||
|
|
||||||
it('should return sampleSize as description', () => {
|
it('should return sampleSize as description', () => {
|
||||||
|
|
|
@ -0,0 +1,51 @@
|
||||||
|
import {ddescribe, describe, it, iit, xit, expect, beforeEach, afterEach} from 'angular2/test_lib';
|
||||||
|
|
||||||
|
import { StringMap, ListWrapper } from 'angular2/src/facade/collection';
|
||||||
|
import { isPresent, StringWrapper, isJsObject } from 'angular2/src/facade/lang';
|
||||||
|
|
||||||
|
import { WebDriverExtension, bind, Injector, Options } from 'benchpress/benchpress';
|
||||||
|
|
||||||
|
export function main() {
|
||||||
|
function createExtension(ids, caps) {
|
||||||
|
return new Injector([
|
||||||
|
ListWrapper.map(ids, (id) => bind(id).toValue(new MockExtension(id)) ),
|
||||||
|
bind(Options.CAPABILITIES).toValue(caps),
|
||||||
|
WebDriverExtension.bindTo(ids)
|
||||||
|
]).asyncGet(WebDriverExtension);
|
||||||
|
}
|
||||||
|
|
||||||
|
describe('WebDriverExtension.bindTo', () => {
|
||||||
|
|
||||||
|
it('should bind the extension that matches the capabilities', (done) => {
|
||||||
|
createExtension(['m1', 'm2', 'm3'], {'browser': 'm2'}).then( (m) => {
|
||||||
|
expect(m.id).toEqual('m2');
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// TODO(tbosch): In Dart, somehow we don't provide the error
|
||||||
|
// correctly in the promise result...
|
||||||
|
if (isJsObject({})) {
|
||||||
|
it('should throw if there is no match', (done) => {
|
||||||
|
createExtension(['m1'], {'browser': 'm2'}).then(null, (err) => {
|
||||||
|
expect(isPresent(err)).toBe(true);
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
class MockExtension extends WebDriverExtension {
|
||||||
|
id:string;
|
||||||
|
|
||||||
|
constructor(id) {
|
||||||
|
super();
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
supports(capabilities:StringMap):boolean {
|
||||||
|
return StringWrapper.equals(capabilities['browser'], this.id);
|
||||||
|
}
|
||||||
|
}
|
|
@ -2,7 +2,7 @@ import {describe, it, iit, xit, expect, beforeEach, afterEach} from 'angular2/te
|
||||||
|
|
||||||
import { ListWrapper } from 'angular2/src/facade/collection';
|
import { ListWrapper } from 'angular2/src/facade/collection';
|
||||||
import { PromiseWrapper } from 'angular2/src/facade/async';
|
import { PromiseWrapper } from 'angular2/src/facade/async';
|
||||||
import { Json, isBlank } from 'angular2/src/facade/lang';
|
import { Json, isBlank, isJsObject } from 'angular2/src/facade/lang';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
WebDriverExtension, ChromeDriverExtension,
|
WebDriverExtension, ChromeDriverExtension,
|
||||||
|
@ -20,15 +20,15 @@ export function main() {
|
||||||
var chromeTimelineEvents = new TraceEventFactory('disabled-by-default-devtools.timeline', 'pid0');
|
var chromeTimelineEvents = new TraceEventFactory('disabled-by-default-devtools.timeline', 'pid0');
|
||||||
var normEvents = new TraceEventFactory('timeline', 'pid0');
|
var normEvents = new TraceEventFactory('timeline', 'pid0');
|
||||||
|
|
||||||
function createExtension(perfRecords = null) {
|
function createExtension(perfRecords = null, messageMethod = 'Tracing.dataCollected') {
|
||||||
if (isBlank(perfRecords)) {
|
if (isBlank(perfRecords)) {
|
||||||
perfRecords = [];
|
perfRecords = [];
|
||||||
}
|
}
|
||||||
log = [];
|
log = [];
|
||||||
extension = new Injector([
|
extension = new Injector([
|
||||||
ChromeDriverExtension.BINDINGS,
|
ChromeDriverExtension.BINDINGS,
|
||||||
bind(WebDriverAdapter).toValue(new MockDriverAdapter(log, perfRecords))
|
bind(WebDriverAdapter).toValue(new MockDriverAdapter(log, perfRecords, messageMethod))
|
||||||
]).get(WebDriverExtension);
|
]).get(ChromeDriverExtension);
|
||||||
return extension;
|
return extension;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -153,6 +153,31 @@ export function main() {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// TODO(tbosch): In Dart, somehow we don't provide the error
|
||||||
|
// correctly in the promise result...
|
||||||
|
if (isJsObject({})) {
|
||||||
|
it('should throw an error on buffer overflow', (done) => {
|
||||||
|
createExtension([
|
||||||
|
chromeTimelineEvents.start('FunctionCall', 1234),
|
||||||
|
], 'Tracing.bufferUsage').readPerfLog().then(null, (err) => {
|
||||||
|
expect( () => {
|
||||||
|
throw err;
|
||||||
|
}).toThrowError('The DevTools trace buffer filled during the test!');
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
it('should match chrome browsers', () => {
|
||||||
|
expect(createExtension().supports({
|
||||||
|
'browserName': 'chrome'
|
||||||
|
})).toBe(true);
|
||||||
|
|
||||||
|
expect(createExtension().supports({
|
||||||
|
'browserName': 'Chrome'
|
||||||
|
})).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
@ -161,10 +186,12 @@ export function main() {
|
||||||
class MockDriverAdapter extends WebDriverAdapter {
|
class MockDriverAdapter extends WebDriverAdapter {
|
||||||
_log:List;
|
_log:List;
|
||||||
_events:List;
|
_events:List;
|
||||||
constructor(log, events) {
|
_messageMethod:string;
|
||||||
|
constructor(log, events, messageMethod) {
|
||||||
super();
|
super();
|
||||||
this._log = log;
|
this._log = log;
|
||||||
this._events = events;
|
this._events = events;
|
||||||
|
this._messageMethod = messageMethod;
|
||||||
}
|
}
|
||||||
|
|
||||||
executeScript(script) {
|
executeScript(script) {
|
||||||
|
@ -175,11 +202,11 @@ class MockDriverAdapter extends WebDriverAdapter {
|
||||||
logs(type) {
|
logs(type) {
|
||||||
ListWrapper.push(this._log, ['logs', type]);
|
ListWrapper.push(this._log, ['logs', type]);
|
||||||
if (type === 'performance') {
|
if (type === 'performance') {
|
||||||
return PromiseWrapper.resolve(this._events.map(function(event) {
|
return PromiseWrapper.resolve(this._events.map( (event) => {
|
||||||
return {
|
return {
|
||||||
'message': Json.stringify({
|
'message': Json.stringify({
|
||||||
'message': {
|
'message': {
|
||||||
'method': 'Tracing.dataCollected',
|
'method': this._messageMethod,
|
||||||
'params': event
|
'params': event
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
|
@ -26,7 +26,7 @@ export function main() {
|
||||||
extension = new Injector([
|
extension = new Injector([
|
||||||
IOsDriverExtension.BINDINGS,
|
IOsDriverExtension.BINDINGS,
|
||||||
bind(WebDriverAdapter).toValue(new MockDriverAdapter(log, perfRecords))
|
bind(WebDriverAdapter).toValue(new MockDriverAdapter(log, perfRecords))
|
||||||
]).get(WebDriverExtension);
|
]).get(IOsDriverExtension);
|
||||||
return extension;
|
return extension;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -155,6 +155,16 @@ export function main() {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should match safari browsers', () => {
|
||||||
|
expect(createExtension().supports({
|
||||||
|
'browserName': 'safari'
|
||||||
|
})).toBe(true);
|
||||||
|
|
||||||
|
expect(createExtension().supports({
|
||||||
|
'browserName': 'Safari'
|
||||||
|
})).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
|
@ -175,19 +175,13 @@ exports.createBenchpressRunner = function(options) {
|
||||||
benchpress.bind(benchpress.Options.DEFAULT_DESCRIPTION).toValue({
|
benchpress.bind(benchpress.Options.DEFAULT_DESCRIPTION).toValue({
|
||||||
'lang': options.lang,
|
'lang': options.lang,
|
||||||
'runId': runId
|
'runId': runId
|
||||||
}),
|
})
|
||||||
// TODO(tbosch): Make the ChromeDriverExtension configurable based on the
|
|
||||||
// capabilities. Should support the case where we test against
|
|
||||||
// ios and chrome at the same time!
|
|
||||||
benchpress.bind(benchpress.WebDriverExtension).toFactory(function(adapter) {
|
|
||||||
return new benchpress.ChromeDriverExtension(adapter);
|
|
||||||
}, [benchpress.WebDriverAdapter])
|
|
||||||
];
|
];
|
||||||
if (argv['benchmark']) {
|
if (argv['benchmark']) {
|
||||||
bindings.push(benchpress.RegressionSlopeValidator.BINDINGS);
|
bindings.push(benchpress.Validator.bindTo(benchpress.RegressionSlopeValidator));
|
||||||
bindings.push(benchpress.bind(benchpress.RegressionSlopeValidator.SAMPLE_SIZE).toValue(argv['sample-size']));
|
bindings.push(benchpress.bind(benchpress.RegressionSlopeValidator.SAMPLE_SIZE).toValue(argv['sample-size']));
|
||||||
} else {
|
} else {
|
||||||
bindings.push(benchpress.SizeValidator.BINDINGS);
|
bindings.push(benchpress.Validator.bindTo(benchpress.SizeValidator));
|
||||||
bindings.push(benchpress.bind(benchpress.SizeValidator.SAMPLE_SIZE).toValue(1));
|
bindings.push(benchpress.bind(benchpress.SizeValidator.SAMPLE_SIZE).toValue(1));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue