parent
8968b206b4
commit
989dea7083
|
@ -1,2 +0,0 @@
|
||||||
*.xpi
|
|
||||||
addon-sdk*
|
|
|
@ -1,38 +0,0 @@
|
||||||
/**
|
|
||||||
* @license
|
|
||||||
* Copyright Google Inc. All Rights Reserved.
|
|
||||||
*
|
|
||||||
* Use of this source code is governed by an MIT-style license that can be
|
|
||||||
* found in the LICENSE file at https://angular.io/license
|
|
||||||
*/
|
|
||||||
|
|
||||||
declare var exportFunction: any;
|
|
||||||
declare var unsafeWindow: any;
|
|
||||||
|
|
||||||
exportFunction(function() {
|
|
||||||
const curTime = unsafeWindow.performance.now();
|
|
||||||
(<any>self).port.emit('startProfiler', curTime);
|
|
||||||
}, unsafeWindow, {defineAs: 'startProfiler'});
|
|
||||||
|
|
||||||
exportFunction(function() {
|
|
||||||
(<any>self).port.emit('stopProfiler');
|
|
||||||
}, unsafeWindow, {defineAs: 'stopProfiler'});
|
|
||||||
|
|
||||||
exportFunction(function(cb: Function) {
|
|
||||||
(<any>self).port.once('perfProfile', cb);
|
|
||||||
(<any>self).port.emit('getProfile');
|
|
||||||
}, unsafeWindow, {defineAs: 'getProfile'});
|
|
||||||
|
|
||||||
exportFunction(function() {
|
|
||||||
(<any>self).port.emit('forceGC');
|
|
||||||
}, unsafeWindow, {defineAs: 'forceGC'});
|
|
||||||
|
|
||||||
exportFunction(function(name: string) {
|
|
||||||
const curTime = unsafeWindow.performance.now();
|
|
||||||
(<any>self).port.emit('markStart', name, curTime);
|
|
||||||
}, unsafeWindow, {defineAs: 'markStart'});
|
|
||||||
|
|
||||||
exportFunction(function(name: string) {
|
|
||||||
const curTime = unsafeWindow.performance.now();
|
|
||||||
(<any>self).port.emit('markEnd', name, curTime);
|
|
||||||
}, unsafeWindow, {defineAs: 'markEnd'});
|
|
|
@ -1,80 +0,0 @@
|
||||||
/**
|
|
||||||
* @license
|
|
||||||
* Copyright Google Inc. All Rights Reserved.
|
|
||||||
*
|
|
||||||
* Use of this source code is governed by an MIT-style license that can be
|
|
||||||
* found in the LICENSE file at https://angular.io/license
|
|
||||||
*/
|
|
||||||
|
|
||||||
const {Cc, Ci, Cu} = require('chrome');
|
|
||||||
const os = Cc['@mozilla.org/observer-service;1'].getService(Ci.nsIObserverService);
|
|
||||||
const ParserUtil = require('./parser_util');
|
|
||||||
|
|
||||||
class Profiler {
|
|
||||||
private _profiler: any;
|
|
||||||
// TODO(issue/24571): remove '!'.
|
|
||||||
private _markerEvents !: any[];
|
|
||||||
// TODO(issue/24571): remove '!'.
|
|
||||||
private _profilerStartTime !: number;
|
|
||||||
|
|
||||||
constructor() { this._profiler = Cc['@mozilla.org/tools/profiler;1'].getService(Ci.nsIProfiler); }
|
|
||||||
|
|
||||||
start(entries: any, interval: any, features: any, timeStarted: any) {
|
|
||||||
this._profiler.StartProfiler(entries, interval, features, features.length);
|
|
||||||
this._profilerStartTime = timeStarted;
|
|
||||||
this._markerEvents = [];
|
|
||||||
}
|
|
||||||
|
|
||||||
stop() { this._profiler.StopProfiler(); }
|
|
||||||
|
|
||||||
getProfilePerfEvents() {
|
|
||||||
const profileData = this._profiler.getProfileData();
|
|
||||||
let perfEvents = ParserUtil.convertPerfProfileToEvents(profileData);
|
|
||||||
perfEvents = this._mergeMarkerEvents(perfEvents);
|
|
||||||
perfEvents.sort(function(event1: any, event2: any) {
|
|
||||||
return event1.ts - event2.ts;
|
|
||||||
}); // Sort by ts
|
|
||||||
return perfEvents;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** @internal */
|
|
||||||
private _mergeMarkerEvents(perfEvents: any[]): any[] {
|
|
||||||
this._markerEvents.forEach(function(markerEvent) { perfEvents.push(markerEvent); });
|
|
||||||
return perfEvents;
|
|
||||||
}
|
|
||||||
|
|
||||||
addStartEvent(name: string, timeStarted: number) {
|
|
||||||
this._markerEvents.push({ph: 'B', ts: timeStarted - this._profilerStartTime, name: name});
|
|
||||||
}
|
|
||||||
|
|
||||||
addEndEvent(name: string, timeEnded: number) {
|
|
||||||
this._markerEvents.push({ph: 'E', ts: timeEnded - this._profilerStartTime, name: name});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function forceGC() {
|
|
||||||
Cu.forceGC();
|
|
||||||
os.notifyObservers(null, 'child-gc-request', null);
|
|
||||||
}
|
|
||||||
|
|
||||||
const mod = require('sdk/page-mod');
|
|
||||||
const data = require('sdk/self').data;
|
|
||||||
const profiler = new Profiler();
|
|
||||||
mod.PageMod({
|
|
||||||
include: ['*'],
|
|
||||||
contentScriptFile: data.url('installed_script.js'),
|
|
||||||
onAttach: (worker: any) => {
|
|
||||||
worker.port.on(
|
|
||||||
'startProfiler',
|
|
||||||
(timeStarted: any) => profiler.start(
|
|
||||||
/* = profiler memory */ 3000000, 0.1, ['leaf', 'js', 'stackwalk', 'gc'], timeStarted));
|
|
||||||
worker.port.on('stopProfiler', () => profiler.stop());
|
|
||||||
worker.port.on(
|
|
||||||
'getProfile', () => worker.port.emit('perfProfile', profiler.getProfilePerfEvents()));
|
|
||||||
worker.port.on('forceGC', forceGC);
|
|
||||||
worker.port.on(
|
|
||||||
'markStart', (name: string, timeStarted: any) => profiler.addStartEvent(name, timeStarted));
|
|
||||||
worker.port.on(
|
|
||||||
'markEnd', (name: string, timeEnded: any) => profiler.addEndEvent(name, timeEnded));
|
|
||||||
}
|
|
||||||
});
|
|
|
@ -1,92 +0,0 @@
|
||||||
/**
|
|
||||||
* @license
|
|
||||||
* Copyright Google Inc. All Rights Reserved.
|
|
||||||
*
|
|
||||||
* Use of this source code is governed by an MIT-style license that can be
|
|
||||||
* found in the LICENSE file at https://angular.io/license
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {Object} perfProfile The perf profile JSON object.
|
|
||||||
* @return {Object[]} An array of recognized events that are captured
|
|
||||||
* within the perf profile.
|
|
||||||
*/
|
|
||||||
export function convertPerfProfileToEvents(perfProfile: any): any[] {
|
|
||||||
const inProgressEvents = new Map(); // map from event name to start time
|
|
||||||
const finishedEvents: {[key: string]: any}[] = []; // Event[] finished events
|
|
||||||
const addFinishedEvent = function(eventName: string, startTime: number, endTime: number) {
|
|
||||||
const categorizedEventName = categorizeEvent(eventName);
|
|
||||||
let args: {[key: string]: any}|undefined = undefined;
|
|
||||||
if (categorizedEventName == 'gc') {
|
|
||||||
// TODO: We cannot measure heap size at the moment
|
|
||||||
args = {usedHeapSize: 0};
|
|
||||||
}
|
|
||||||
if (startTime == endTime) {
|
|
||||||
// Finished instantly
|
|
||||||
finishedEvents.push({ph: 'X', ts: startTime, name: categorizedEventName, args: args});
|
|
||||||
} else {
|
|
||||||
// Has duration
|
|
||||||
finishedEvents.push({ph: 'B', ts: startTime, name: categorizedEventName, args: args});
|
|
||||||
finishedEvents.push({ph: 'E', ts: endTime, name: categorizedEventName, args: args});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const samples = perfProfile.threads[0].samples;
|
|
||||||
// In perf profile, firefox samples all the frames in set time intervals. Here
|
|
||||||
// we go through all the samples and construct the start and end time for each
|
|
||||||
// event.
|
|
||||||
for (let i = 0; i < samples.length; ++i) {
|
|
||||||
const sample = samples[i];
|
|
||||||
const sampleTime = sample.time;
|
|
||||||
|
|
||||||
// Add all the frames into a set so it's easier/faster to find the set
|
|
||||||
// differences
|
|
||||||
const sampleFrames = new Set();
|
|
||||||
sample.frames.forEach(function(frame: {[key: string]: any}) {
|
|
||||||
sampleFrames.add(frame['location']);
|
|
||||||
});
|
|
||||||
|
|
||||||
// If an event is in the inProgressEvents map, but not in the current sample,
|
|
||||||
// then it must have just finished. We add this event to the finishedEvents
|
|
||||||
// array and remove it from the inProgressEvents map.
|
|
||||||
const previousSampleTime = (i == 0 ? /* not used */ -1 : samples[i - 1].time);
|
|
||||||
inProgressEvents.forEach(function(startTime, eventName) {
|
|
||||||
if (!(sampleFrames.has(eventName))) {
|
|
||||||
addFinishedEvent(eventName, startTime, previousSampleTime);
|
|
||||||
inProgressEvents.delete(eventName);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// If an event is in the current sample, but not in the inProgressEvents map,
|
|
||||||
// then it must have just started. We add this event to the inProgressEvents
|
|
||||||
// map.
|
|
||||||
sampleFrames.forEach(function(eventName) {
|
|
||||||
if (!(inProgressEvents.has(eventName))) {
|
|
||||||
inProgressEvents.set(eventName, sampleTime);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// If anything is still in progress, we need to included it as a finished event
|
|
||||||
// since recording ended.
|
|
||||||
const lastSampleTime = samples[samples.length - 1].time;
|
|
||||||
inProgressEvents.forEach(function(startTime, eventName) {
|
|
||||||
addFinishedEvent(eventName, startTime, lastSampleTime);
|
|
||||||
});
|
|
||||||
|
|
||||||
// Remove all the unknown categories.
|
|
||||||
return finishedEvents.filter(function(event) { return event['name'] != 'unknown'; });
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: this is most likely not exhaustive.
|
|
||||||
export function categorizeEvent(eventName: string): string {
|
|
||||||
if (eventName.indexOf('PresShell::Paint') > -1) {
|
|
||||||
return 'render';
|
|
||||||
} else if (eventName.indexOf('FirefoxDriver.prototype.executeScript') > -1) {
|
|
||||||
return 'script';
|
|
||||||
} else if (eventName.indexOf('forceGC') > -1) {
|
|
||||||
return 'gc';
|
|
||||||
} else {
|
|
||||||
return 'unknown';
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,51 +0,0 @@
|
||||||
/**
|
|
||||||
* @license
|
|
||||||
* Copyright Google Inc. All Rights Reserved.
|
|
||||||
*
|
|
||||||
* Use of this source code is governed by an MIT-style license that can be
|
|
||||||
* found in the LICENSE file at https://angular.io/license
|
|
||||||
*/
|
|
||||||
|
|
||||||
const q = require('q');
|
|
||||||
const FirefoxProfile = require('firefox-profile');
|
|
||||||
const jpm = require('jpm/lib/xpi');
|
|
||||||
const pathUtil = require('path');
|
|
||||||
|
|
||||||
const PERF_ADDON_PACKAGE_JSON_DIR = '..';
|
|
||||||
|
|
||||||
exports.getAbsolutePath = function(path: string) {
|
|
||||||
const normalizedPath = pathUtil.normalize(path);
|
|
||||||
if (pathUtil.resolve(normalizedPath) == normalizedPath) {
|
|
||||||
// Already absolute path
|
|
||||||
return normalizedPath;
|
|
||||||
} else {
|
|
||||||
return pathUtil.join(__dirname, normalizedPath);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
exports.getFirefoxProfile = function(extensionPath: string) {
|
|
||||||
const deferred = q.defer();
|
|
||||||
|
|
||||||
const firefoxProfile = new FirefoxProfile();
|
|
||||||
firefoxProfile.addExtensions([extensionPath], () => {
|
|
||||||
firefoxProfile.encoded((err: any, encodedProfile: string) => {
|
|
||||||
const multiCapabilities = [{browserName: 'firefox', firefox_profile: encodedProfile}];
|
|
||||||
deferred.resolve(multiCapabilities);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
return deferred.promise;
|
|
||||||
};
|
|
||||||
|
|
||||||
exports.getFirefoxProfileWithExtension = function() {
|
|
||||||
const absPackageJsonDir = pathUtil.join(__dirname, PERF_ADDON_PACKAGE_JSON_DIR);
|
|
||||||
const packageJson = require(pathUtil.join(absPackageJsonDir, 'package.json'));
|
|
||||||
|
|
||||||
const savedCwd = process.cwd();
|
|
||||||
process.chdir(absPackageJsonDir);
|
|
||||||
|
|
||||||
return jpm(packageJson).then((xpiPath: string) => {
|
|
||||||
process.chdir(savedCwd);
|
|
||||||
return exports.getFirefoxProfile(xpiPath);
|
|
||||||
});
|
|
||||||
};
|
|
|
@ -1 +0,0 @@
|
||||||
{ "version" : "0.0.1", "main" : "lib/main.js", "name" : "ffperf-addon" }
|
|
|
@ -1,21 +0,0 @@
|
||||||
/**
|
|
||||||
* @license
|
|
||||||
* Copyright Google Inc. All Rights Reserved.
|
|
||||||
*
|
|
||||||
* Use of this source code is governed by an MIT-style license that can be
|
|
||||||
* found in the LICENSE file at https://angular.io/license
|
|
||||||
*/
|
|
||||||
|
|
||||||
require('core-js');
|
|
||||||
require('reflect-metadata');
|
|
||||||
const testHelper = require('../../src/firefox_extension/lib/test_helper.js');
|
|
||||||
|
|
||||||
exports.config = {
|
|
||||||
specs: ['spec.js', 'sample_benchmark.js'],
|
|
||||||
|
|
||||||
framework: 'jasmine2',
|
|
||||||
|
|
||||||
jasmineNodeOpts: {showColors: true, defaultTimeoutInterval: 1200000},
|
|
||||||
|
|
||||||
getMultiCapabilities: function() { return testHelper.getFirefoxProfileWithExtension(); }
|
|
||||||
};
|
|
|
@ -1,100 +0,0 @@
|
||||||
/**
|
|
||||||
* @license
|
|
||||||
* Copyright Google Inc. All Rights Reserved.
|
|
||||||
*
|
|
||||||
* Use of this source code is governed by an MIT-style license that can be
|
|
||||||
* found in the LICENSE file at https://angular.io/license
|
|
||||||
*/
|
|
||||||
|
|
||||||
import {convertPerfProfileToEvents} from '../../src/firefox_extension/lib/parser_util';
|
|
||||||
|
|
||||||
function assertEventsEqual(actualEvents: any[], expectedEvents: any[]) {
|
|
||||||
expect(actualEvents.length == expectedEvents.length);
|
|
||||||
for (let i = 0; i < actualEvents.length; ++i) {
|
|
||||||
const actualEvent = actualEvents[i];
|
|
||||||
const expectedEvent = expectedEvents[i];
|
|
||||||
for (const key in actualEvent) {
|
|
||||||
expect(actualEvent[key]).toEqual(expectedEvent[key]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
describe('convertPerfProfileToEvents', function() {
|
|
||||||
it('should convert single instantaneous event', function() {
|
|
||||||
const profileData = {
|
|
||||||
threads: [
|
|
||||||
{samples: [{time: 1, frames: [{location: 'FirefoxDriver.prototype.executeScript'}]}]}
|
|
||||||
]
|
|
||||||
};
|
|
||||||
const perfEvents = convertPerfProfileToEvents(profileData);
|
|
||||||
assertEventsEqual(perfEvents, [{ph: 'X', ts: 1, name: 'script'}]);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should convert single non-instantaneous event', function() {
|
|
||||||
const profileData = {
|
|
||||||
threads: [{
|
|
||||||
samples: [
|
|
||||||
{time: 1, frames: [{location: 'FirefoxDriver.prototype.executeScript'}]},
|
|
||||||
{time: 2, frames: [{location: 'FirefoxDriver.prototype.executeScript'}]},
|
|
||||||
{time: 100, frames: [{location: 'FirefoxDriver.prototype.executeScript'}]}
|
|
||||||
]
|
|
||||||
}]
|
|
||||||
};
|
|
||||||
const perfEvents = convertPerfProfileToEvents(profileData);
|
|
||||||
assertEventsEqual(
|
|
||||||
perfEvents, [{ph: 'B', ts: 1, name: 'script'}, {ph: 'E', ts: 100, name: 'script'}]);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should convert multiple instantaneous events', function() {
|
|
||||||
const profileData = {
|
|
||||||
threads: [{
|
|
||||||
samples: [
|
|
||||||
{time: 1, frames: [{location: 'FirefoxDriver.prototype.executeScript'}]},
|
|
||||||
{time: 2, frames: [{location: 'PresShell::Paint'}]}
|
|
||||||
]
|
|
||||||
}]
|
|
||||||
};
|
|
||||||
const perfEvents = convertPerfProfileToEvents(profileData);
|
|
||||||
assertEventsEqual(
|
|
||||||
perfEvents, [{ph: 'X', ts: 1, name: 'script'}, {ph: 'X', ts: 2, name: 'render'}]);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should convert multiple mixed events', function() {
|
|
||||||
const profileData = {
|
|
||||||
threads: [{
|
|
||||||
samples: [
|
|
||||||
{time: 1, frames: [{location: 'FirefoxDriver.prototype.executeScript'}]},
|
|
||||||
{time: 2, frames: [{location: 'PresShell::Paint'}]},
|
|
||||||
{time: 5, frames: [{location: 'FirefoxDriver.prototype.executeScript'}]},
|
|
||||||
{time: 10, frames: [{location: 'FirefoxDriver.prototype.executeScript'}]}
|
|
||||||
]
|
|
||||||
}]
|
|
||||||
};
|
|
||||||
const perfEvents = convertPerfProfileToEvents(profileData);
|
|
||||||
assertEventsEqual(perfEvents, [
|
|
||||||
{ph: 'X', ts: 1, name: 'script'}, {ph: 'X', ts: 2, name: 'render'},
|
|
||||||
{ph: 'B', ts: 5, name: 'script'}, {ph: 'E', ts: 10, name: 'script'}
|
|
||||||
]);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should add args to gc events', function() {
|
|
||||||
const profileData = {threads: [{samples: [{time: 1, frames: [{location: 'forceGC'}]}]}]};
|
|
||||||
const perfEvents = convertPerfProfileToEvents(profileData);
|
|
||||||
assertEventsEqual(perfEvents, [{ph: 'X', ts: 1, name: 'gc', args: {usedHeapSize: 0}}]);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should skip unknown events', function() {
|
|
||||||
const profileData = {
|
|
||||||
threads: [{
|
|
||||||
samples: [
|
|
||||||
{time: 1, frames: [{location: 'FirefoxDriver.prototype.executeScript'}]},
|
|
||||||
{time: 2, frames: [{location: 'foo'}]}
|
|
||||||
]
|
|
||||||
}]
|
|
||||||
};
|
|
||||||
const perfEvents = convertPerfProfileToEvents(profileData);
|
|
||||||
assertEventsEqual(perfEvents, [{ph: 'X', ts: 1, name: 'script'}]);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
|
@ -1,45 +0,0 @@
|
||||||
/**
|
|
||||||
* @license
|
|
||||||
* Copyright Google Inc. All Rights Reserved.
|
|
||||||
*
|
|
||||||
* Use of this source code is governed by an MIT-style license that can be
|
|
||||||
* found in the LICENSE file at https://angular.io/license
|
|
||||||
*/
|
|
||||||
|
|
||||||
import {$, browser} from 'protractor';
|
|
||||||
|
|
||||||
const benchpress = require('../../index.js');
|
|
||||||
|
|
||||||
// TODO: this test is currnetly failing. it seems that it didn't run on the ci for a while
|
|
||||||
xdescribe('deep tree baseline', function() {
|
|
||||||
const runner = new benchpress.Runner([
|
|
||||||
// use protractor as Webdriver client
|
|
||||||
benchpress.SeleniumWebDriverAdapter.PROTRACTOR_PROVIDERS,
|
|
||||||
// use RegressionSlopeValidator to validate samples
|
|
||||||
benchpress.Validator.bind(benchpress.RegressionSlopeValidator),
|
|
||||||
// use 10 samples to calculate slope regression
|
|
||||||
benchpress.bind(benchpress.RegressionSlopeValidator.SAMPLE_SIZE).toValue(20),
|
|
||||||
// use the script metric to calculate slope regression
|
|
||||||
benchpress.bind(benchpress.RegressionSlopeValidator.METRIC).toValue('scriptTime'),
|
|
||||||
benchpress.bind(benchpress.Options.FORCE_GC).toValue(true)
|
|
||||||
]);
|
|
||||||
|
|
||||||
|
|
||||||
it('should be fast!', function(done) {
|
|
||||||
browser.ignoreSynchronization = true;
|
|
||||||
browser.get('http://localhost:8001/playground/src/benchpress/');
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Tell benchpress to click the buttons to destroy and re-create the tree for each sample.
|
|
||||||
* Benchpress will log the collected metrics after each sample is collected, and will stop
|
|
||||||
* sampling as soon as the calculated regression slope for last 20 samples is stable.
|
|
||||||
*/
|
|
||||||
runner
|
|
||||||
.sample({
|
|
||||||
id: 'baseline',
|
|
||||||
execute: function() { $('button').click(); },
|
|
||||||
providers: [benchpress.bind(benchpress.Options.SAMPLE_DESCRIPTION).toValue({depth: 9})]
|
|
||||||
})
|
|
||||||
.then(done, done.fail);
|
|
||||||
});
|
|
||||||
});
|
|
|
@ -1,45 +0,0 @@
|
||||||
/**
|
|
||||||
* @license
|
|
||||||
* Copyright Google Inc. All Rights Reserved.
|
|
||||||
*
|
|
||||||
* Use of this source code is governed by an MIT-style license that can be
|
|
||||||
* found in the LICENSE file at https://angular.io/license
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* tslint:disable:no-console */
|
|
||||||
import {browser} from 'protractor';
|
|
||||||
|
|
||||||
const assertEventsContainsName = function(events: any[], eventName: string) {
|
|
||||||
let found = false;
|
|
||||||
for (let i = 0; i < events.length; ++i) {
|
|
||||||
if (events[i].name == eventName) {
|
|
||||||
found = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
expect(found).toBeTruthy();
|
|
||||||
};
|
|
||||||
|
|
||||||
// TODO: this test is currnetly failing. it seems that it didn't run on the ci for a while
|
|
||||||
xdescribe('firefox extension', function() {
|
|
||||||
const TEST_URL = 'http://localhost:8001/playground/src/hello_world/index.html';
|
|
||||||
|
|
||||||
it('should measure performance', function() {
|
|
||||||
browser.sleep(3000); // wait for extension to load
|
|
||||||
|
|
||||||
browser.driver.get(TEST_URL);
|
|
||||||
|
|
||||||
browser.executeScript('window.startProfiler()').then(function() {
|
|
||||||
console.log('started measuring perf');
|
|
||||||
});
|
|
||||||
|
|
||||||
browser.executeAsyncScript('setTimeout(arguments[0], 1000);');
|
|
||||||
browser.executeScript('window.forceGC()');
|
|
||||||
|
|
||||||
browser.executeAsyncScript('var cb = arguments[0]; window.getProfile(cb);')
|
|
||||||
.then(function(profile: any) {
|
|
||||||
assertEventsContainsName(profile, 'gc');
|
|
||||||
assertEventsContainsName(profile, 'script');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
Loading…
Reference in New Issue