2015-03-13 06:10:11 -04:00
|
|
|
import {
|
|
|
|
afterEach,
|
|
|
|
AsyncTestCompleter,
|
|
|
|
beforeEach,
|
|
|
|
ddescribe,
|
|
|
|
describe,
|
|
|
|
expect,
|
|
|
|
iit,
|
|
|
|
inject,
|
|
|
|
it,
|
|
|
|
xit,
|
|
|
|
} from 'angular2/test_lib';
|
2015-02-11 13:13:49 -05:00
|
|
|
|
|
|
|
import { ListWrapper } from 'angular2/src/facade/collection';
|
|
|
|
import { PromiseWrapper } from 'angular2/src/facade/async';
|
2015-02-25 20:43:33 -05:00
|
|
|
import { Json, isBlank } from 'angular2/src/facade/lang';
|
2015-02-11 13:13:49 -05:00
|
|
|
|
|
|
|
import {
|
|
|
|
WebDriverExtension, ChromeDriverExtension,
|
|
|
|
WebDriverAdapter, Injector, bind
|
2015-03-02 12:23:09 -05:00
|
|
|
} from 'benchpress/common';
|
2015-02-11 13:13:49 -05:00
|
|
|
|
2015-02-18 17:39:52 -05:00
|
|
|
import { TraceEventFactory } from '../trace_event_factory';
|
|
|
|
|
2015-02-11 13:13:49 -05:00
|
|
|
export function main() {
|
|
|
|
describe('chrome driver extension', () => {
|
|
|
|
var log;
|
|
|
|
var extension;
|
|
|
|
|
2015-02-18 17:39:52 -05:00
|
|
|
var blinkEvents = new TraceEventFactory('blink.console', 'pid0');
|
2015-03-04 12:59:18 -05:00
|
|
|
var v8Events = new TraceEventFactory('v8', 'pid0');
|
|
|
|
var v8EventsOtherProcess = new TraceEventFactory('v8', 'pid1');
|
2015-02-18 17:39:52 -05:00
|
|
|
var chromeTimelineEvents = new TraceEventFactory('disabled-by-default-devtools.timeline', 'pid0');
|
|
|
|
var normEvents = new TraceEventFactory('timeline', 'pid0');
|
|
|
|
|
2015-02-20 16:32:54 -05:00
|
|
|
function createExtension(perfRecords = null, messageMethod = 'Tracing.dataCollected') {
|
2015-02-11 13:13:49 -05:00
|
|
|
if (isBlank(perfRecords)) {
|
|
|
|
perfRecords = [];
|
|
|
|
}
|
|
|
|
log = [];
|
|
|
|
extension = new Injector([
|
|
|
|
ChromeDriverExtension.BINDINGS,
|
2015-02-20 16:32:54 -05:00
|
|
|
bind(WebDriverAdapter).toValue(new MockDriverAdapter(log, perfRecords, messageMethod))
|
|
|
|
]).get(ChromeDriverExtension);
|
2015-02-11 13:13:49 -05:00
|
|
|
return extension;
|
|
|
|
}
|
|
|
|
|
2015-03-13 06:10:11 -04:00
|
|
|
it('should force gc via window.gc()', inject([AsyncTestCompleter], (async) => {
|
2015-02-11 13:13:49 -05:00
|
|
|
createExtension().gc().then( (_) => {
|
|
|
|
expect(log).toEqual([['executeScript', 'window.gc()']]);
|
2015-03-13 06:10:11 -04:00
|
|
|
async.done();
|
2015-02-11 13:13:49 -05:00
|
|
|
});
|
2015-03-13 06:10:11 -04:00
|
|
|
}));
|
2015-02-11 13:13:49 -05:00
|
|
|
|
2015-03-13 06:10:11 -04:00
|
|
|
it('should mark the timeline via console.time()', inject([AsyncTestCompleter], (async) => {
|
2015-02-11 13:13:49 -05:00
|
|
|
createExtension().timeBegin('someName').then( (_) => {
|
2015-02-18 17:39:52 -05:00
|
|
|
expect(log).toEqual([['executeScript', `console.time('someName');`]]);
|
2015-03-13 06:10:11 -04:00
|
|
|
async.done();
|
2015-02-11 13:13:49 -05:00
|
|
|
});
|
2015-03-13 06:10:11 -04:00
|
|
|
}));
|
2015-02-11 13:13:49 -05:00
|
|
|
|
2015-03-13 06:10:11 -04:00
|
|
|
it('should mark the timeline via console.timeEnd()', inject([AsyncTestCompleter], (async) => {
|
2015-02-11 13:13:49 -05:00
|
|
|
createExtension().timeEnd('someName').then( (_) => {
|
2015-02-18 17:39:52 -05:00
|
|
|
expect(log).toEqual([['executeScript', `console.timeEnd('someName');`]]);
|
2015-03-13 06:10:11 -04:00
|
|
|
async.done();
|
2015-02-11 13:13:49 -05:00
|
|
|
});
|
2015-03-13 06:10:11 -04:00
|
|
|
}));
|
2015-02-11 13:13:49 -05:00
|
|
|
|
2015-03-13 06:10:11 -04:00
|
|
|
it('should mark the timeline via console.time() and console.timeEnd()', inject([AsyncTestCompleter], (async) => {
|
2015-02-11 13:13:49 -05:00
|
|
|
createExtension().timeEnd('name1', 'name2').then( (_) => {
|
2015-02-18 17:39:52 -05:00
|
|
|
expect(log).toEqual([['executeScript', `console.timeEnd('name1');console.time('name2');`]]);
|
2015-03-13 06:10:11 -04:00
|
|
|
async.done();
|
2015-02-11 13:13:49 -05:00
|
|
|
});
|
2015-03-13 06:10:11 -04:00
|
|
|
}));
|
2015-02-11 13:13:49 -05:00
|
|
|
|
|
|
|
describe('readPerfLog', () => {
|
|
|
|
|
2015-03-13 06:10:11 -04:00
|
|
|
it('should execute a dummy script before reading them', inject([AsyncTestCompleter], (async) => {
|
2015-02-11 13:13:49 -05:00
|
|
|
// TODO(tbosch): This seems to be a bug in ChromeDriver:
|
|
|
|
// Sometimes it does not report the newest events of the performance log
|
|
|
|
// to the WebDriver client unless a script is executed...
|
|
|
|
createExtension([]).readPerfLog().then( (_) => {
|
|
|
|
expect(log).toEqual([ [ 'executeScript', '1+1' ], [ 'logs', 'performance' ] ]);
|
2015-03-13 06:10:11 -04:00
|
|
|
async.done();
|
2015-02-11 13:13:49 -05:00
|
|
|
});
|
2015-03-13 06:10:11 -04:00
|
|
|
}));
|
2015-02-11 13:13:49 -05:00
|
|
|
|
2015-03-13 06:10:11 -04:00
|
|
|
it('should normalize times to ms and forward ph and pid event properties', inject([AsyncTestCompleter], (async) => {
|
2015-02-11 13:13:49 -05:00
|
|
|
createExtension([
|
2015-02-18 17:39:52 -05:00
|
|
|
chromeTimelineEvents.complete('FunctionCall', 1100, 5500, null)
|
2015-02-11 13:13:49 -05:00
|
|
|
]).readPerfLog().then( (events) => {
|
|
|
|
expect(events).toEqual([
|
2015-02-18 17:39:52 -05:00
|
|
|
normEvents.complete('script', 1.1, 5.5, null),
|
2015-02-24 19:37:45 -05:00
|
|
|
]);
|
2015-03-13 06:10:11 -04:00
|
|
|
async.done();
|
2015-02-24 19:37:45 -05:00
|
|
|
});
|
2015-03-13 06:10:11 -04:00
|
|
|
}));
|
2015-02-24 19:37:45 -05:00
|
|
|
|
2015-03-13 06:10:11 -04:00
|
|
|
it('should normalize "tdur" to "dur"', inject([AsyncTestCompleter], (async) => {
|
2015-02-24 19:37:45 -05:00
|
|
|
var event = chromeTimelineEvents.create('X', 'FunctionCall', 1100, null);
|
|
|
|
event['tdur'] = 5500;
|
|
|
|
createExtension([event]).readPerfLog().then( (events) => {
|
|
|
|
expect(events).toEqual([
|
|
|
|
normEvents.complete('script', 1.1, 5.5, null),
|
2015-02-18 17:39:52 -05:00
|
|
|
]);
|
2015-03-13 06:10:11 -04:00
|
|
|
async.done();
|
2015-02-18 17:39:52 -05:00
|
|
|
});
|
2015-03-13 06:10:11 -04:00
|
|
|
}));
|
2015-02-18 17:39:52 -05:00
|
|
|
|
2015-03-13 06:10:11 -04:00
|
|
|
it('should report FunctionCall events as "script"', inject([AsyncTestCompleter], (async) => {
|
2015-02-18 17:39:52 -05:00
|
|
|
createExtension([
|
|
|
|
chromeTimelineEvents.start('FunctionCall', 0)
|
|
|
|
]).readPerfLog().then( (events) => {
|
|
|
|
expect(events).toEqual([
|
|
|
|
normEvents.start('script', 0),
|
2015-02-11 13:13:49 -05:00
|
|
|
]);
|
2015-03-13 06:10:11 -04:00
|
|
|
async.done();
|
2015-02-11 13:13:49 -05:00
|
|
|
});
|
2015-03-13 06:10:11 -04:00
|
|
|
}));
|
2015-02-11 13:13:49 -05:00
|
|
|
|
2015-03-13 06:10:11 -04:00
|
|
|
it('should ignore FunctionCalls from webdriver', inject([AsyncTestCompleter], (async) => {
|
2015-02-11 13:13:49 -05:00
|
|
|
createExtension([
|
2015-02-18 17:39:52 -05:00
|
|
|
chromeTimelineEvents.start('FunctionCall', 0, {'data': {'scriptName': 'InjectedScript'}})
|
2015-02-11 13:13:49 -05:00
|
|
|
]).readPerfLog().then( (events) => {
|
|
|
|
expect(events).toEqual([]);
|
2015-03-13 06:10:11 -04:00
|
|
|
async.done();
|
2015-02-11 13:13:49 -05:00
|
|
|
});
|
2015-03-13 06:10:11 -04:00
|
|
|
}));
|
2015-02-11 13:13:49 -05:00
|
|
|
|
2015-03-13 06:10:11 -04:00
|
|
|
it('should report begin timestamps', inject([AsyncTestCompleter], (async) => {
|
2015-02-11 13:13:49 -05:00
|
|
|
createExtension([
|
2015-02-18 17:39:52 -05:00
|
|
|
blinkEvents.create('S', 'someName', 1000)
|
2015-02-11 13:13:49 -05:00
|
|
|
]).readPerfLog().then( (events) => {
|
|
|
|
expect(events).toEqual([
|
2015-02-18 17:39:52 -05:00
|
|
|
normEvents.markStart('someName', 1.0)
|
2015-02-11 13:13:49 -05:00
|
|
|
]);
|
2015-03-13 06:10:11 -04:00
|
|
|
async.done();
|
2015-02-11 13:13:49 -05:00
|
|
|
});
|
2015-03-13 06:10:11 -04:00
|
|
|
}));
|
2015-02-11 13:13:49 -05:00
|
|
|
|
2015-03-13 06:10:11 -04:00
|
|
|
it('should report end timestamps', inject([AsyncTestCompleter], (async) => {
|
2015-02-11 13:13:49 -05:00
|
|
|
createExtension([
|
2015-02-18 17:39:52 -05:00
|
|
|
blinkEvents.create('F', 'someName', 1000)
|
2015-02-11 13:13:49 -05:00
|
|
|
]).readPerfLog().then( (events) => {
|
|
|
|
expect(events).toEqual([
|
2015-02-18 17:39:52 -05:00
|
|
|
normEvents.markEnd('someName', 1.0)
|
2015-02-11 13:13:49 -05:00
|
|
|
]);
|
2015-03-13 06:10:11 -04:00
|
|
|
async.done();
|
2015-02-11 13:13:49 -05:00
|
|
|
});
|
2015-03-13 06:10:11 -04:00
|
|
|
}));
|
2015-02-11 13:13:49 -05:00
|
|
|
|
2015-03-13 06:10:11 -04:00
|
|
|
it('should report gc', inject([AsyncTestCompleter], (async) => {
|
2015-02-11 13:13:49 -05:00
|
|
|
createExtension([
|
2015-02-18 17:39:52 -05:00
|
|
|
chromeTimelineEvents.start('GCEvent', 1000, {'usedHeapSizeBefore': 1000}),
|
|
|
|
chromeTimelineEvents.end('GCEvent', 2000, {'usedHeapSizeAfter': 0}),
|
2015-02-11 13:13:49 -05:00
|
|
|
]).readPerfLog().then( (events) => {
|
|
|
|
expect(events).toEqual([
|
2015-02-18 17:39:52 -05:00
|
|
|
normEvents.start('gc', 1.0, {'usedHeapSize': 1000}),
|
2015-03-04 12:59:18 -05:00
|
|
|
normEvents.end('gc', 2.0, {'usedHeapSize': 0, 'majorGc': false}),
|
|
|
|
]);
|
2015-03-13 06:10:11 -04:00
|
|
|
async.done();
|
2015-03-04 12:59:18 -05:00
|
|
|
});
|
2015-03-13 06:10:11 -04:00
|
|
|
}));
|
2015-03-04 12:59:18 -05:00
|
|
|
|
2015-03-13 06:10:11 -04:00
|
|
|
it('should report major gc', inject([AsyncTestCompleter], (async) => {
|
2015-03-04 12:59:18 -05:00
|
|
|
createExtension([
|
|
|
|
chromeTimelineEvents.start('GCEvent', 1000, {'usedHeapSizeBefore': 1000}),
|
|
|
|
v8EventsOtherProcess.start('majorGC', 1100, null),
|
|
|
|
v8EventsOtherProcess.end('majorGC', 1200, null),
|
|
|
|
chromeTimelineEvents.end('GCEvent', 2000, {'usedHeapSizeAfter': 0}),
|
|
|
|
]).readPerfLog().then( (events) => {
|
|
|
|
expect(events).toEqual([
|
|
|
|
normEvents.start('gc', 1.0, {'usedHeapSize': 1000}),
|
|
|
|
normEvents.end('gc', 2.0, {'usedHeapSize': 0, 'majorGc': false}),
|
|
|
|
]);
|
2015-03-13 06:10:11 -04:00
|
|
|
async.done();
|
2015-03-04 12:59:18 -05:00
|
|
|
});
|
2015-03-13 06:10:11 -04:00
|
|
|
}));
|
2015-03-04 12:59:18 -05:00
|
|
|
|
2015-03-13 06:10:11 -04:00
|
|
|
it('should ignore major gc from different processes', inject([AsyncTestCompleter], (async) => {
|
2015-03-04 12:59:18 -05:00
|
|
|
createExtension([
|
|
|
|
chromeTimelineEvents.start('GCEvent', 1000, {'usedHeapSizeBefore': 1000}),
|
|
|
|
v8Events.start('majorGC', 1100, null),
|
|
|
|
v8Events.end('majorGC', 1200, null),
|
|
|
|
chromeTimelineEvents.end('GCEvent', 2000, {'usedHeapSizeAfter': 0}),
|
|
|
|
]).readPerfLog().then( (events) => {
|
|
|
|
expect(events).toEqual([
|
|
|
|
normEvents.start('gc', 1.0, {'usedHeapSize': 1000}),
|
|
|
|
normEvents.end('gc', 2.0, {'usedHeapSize': 0, 'majorGc': true}),
|
2015-02-11 13:13:49 -05:00
|
|
|
]);
|
2015-03-13 06:10:11 -04:00
|
|
|
async.done();
|
2015-02-11 13:13:49 -05:00
|
|
|
});
|
2015-03-13 06:10:11 -04:00
|
|
|
}));
|
2015-02-11 13:13:49 -05:00
|
|
|
|
|
|
|
['RecalculateStyles', 'Layout', 'UpdateLayerTree', 'Paint', 'Rasterize', 'CompositeLayers'].forEach( (recordType) => {
|
2015-03-13 06:10:11 -04:00
|
|
|
it(`should report ${recordType} as "render"`, inject([AsyncTestCompleter], (async) => {
|
2015-02-11 13:13:49 -05:00
|
|
|
createExtension([
|
2015-02-18 17:39:52 -05:00
|
|
|
chromeTimelineEvents.start(recordType, 1234),
|
|
|
|
chromeTimelineEvents.end(recordType, 2345)
|
2015-02-11 13:13:49 -05:00
|
|
|
]).readPerfLog().then( (events) => {
|
|
|
|
expect(events).toEqual([
|
2015-02-18 17:39:52 -05:00
|
|
|
normEvents.start('render', 1.234),
|
|
|
|
normEvents.end('render', 2.345),
|
2015-02-11 13:13:49 -05:00
|
|
|
]);
|
2015-03-13 06:10:11 -04:00
|
|
|
async.done();
|
2015-02-11 13:13:49 -05:00
|
|
|
});
|
2015-03-13 06:10:11 -04:00
|
|
|
}));
|
2015-02-11 13:13:49 -05:00
|
|
|
});
|
|
|
|
|
2015-03-13 06:10:11 -04:00
|
|
|
it('should throw an error on buffer overflow', inject([AsyncTestCompleter], (async) => {
|
2015-02-25 20:43:33 -05:00
|
|
|
PromiseWrapper.catchError(createExtension([
|
|
|
|
chromeTimelineEvents.start('FunctionCall', 1234),
|
|
|
|
], 'Tracing.bufferUsage').readPerfLog(), (err) => {
|
|
|
|
expect( () => {
|
|
|
|
throw err;
|
|
|
|
}).toThrowError('The DevTools trace buffer filled during the test!');
|
2015-03-13 06:10:11 -04:00
|
|
|
async.done();
|
2015-02-20 16:32:54 -05:00
|
|
|
});
|
2015-03-13 06:10:11 -04:00
|
|
|
}));
|
2015-02-20 16:32:54 -05:00
|
|
|
|
|
|
|
it('should match chrome browsers', () => {
|
|
|
|
expect(createExtension().supports({
|
|
|
|
'browserName': 'chrome'
|
|
|
|
})).toBe(true);
|
|
|
|
|
|
|
|
expect(createExtension().supports({
|
|
|
|
'browserName': 'Chrome'
|
|
|
|
})).toBe(true);
|
|
|
|
});
|
|
|
|
|
2015-02-11 13:13:49 -05:00
|
|
|
});
|
|
|
|
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
class MockDriverAdapter extends WebDriverAdapter {
|
|
|
|
_log:List;
|
2015-02-18 17:39:52 -05:00
|
|
|
_events:List;
|
2015-02-20 16:32:54 -05:00
|
|
|
_messageMethod:string;
|
|
|
|
constructor(log, events, messageMethod) {
|
2015-02-11 13:13:49 -05:00
|
|
|
super();
|
|
|
|
this._log = log;
|
2015-02-18 17:39:52 -05:00
|
|
|
this._events = events;
|
2015-02-20 16:32:54 -05:00
|
|
|
this._messageMethod = messageMethod;
|
2015-02-11 13:13:49 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
executeScript(script) {
|
|
|
|
ListWrapper.push(this._log, ['executeScript', script]);
|
|
|
|
return PromiseWrapper.resolve(null);
|
|
|
|
}
|
|
|
|
|
|
|
|
logs(type) {
|
|
|
|
ListWrapper.push(this._log, ['logs', type]);
|
|
|
|
if (type === 'performance') {
|
2015-02-20 16:32:54 -05:00
|
|
|
return PromiseWrapper.resolve(this._events.map( (event) => {
|
2015-02-11 13:13:49 -05:00
|
|
|
return {
|
|
|
|
'message': Json.stringify({
|
|
|
|
'message': {
|
2015-02-20 16:32:54 -05:00
|
|
|
'method': this._messageMethod,
|
2015-02-18 17:39:52 -05:00
|
|
|
'params': event
|
2015-02-11 13:13:49 -05:00
|
|
|
}
|
|
|
|
})
|
|
|
|
};
|
|
|
|
}));
|
|
|
|
} else {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|