parent
79f564be46
commit
b390f441a1
|
@ -9,6 +9,7 @@
|
|||
"license": "<%= packageJson.license %>",
|
||||
"dependencies": {
|
||||
"angular2": "<%= packageJson.version %>",
|
||||
"firefox-profile": "<%= packageJson.dependencies['firefox-profile'] %>",
|
||||
"rtts_assert": "<%= packageJson.version %>",
|
||||
"traceur": "<%= packageJson.dependencies.traceur %>",
|
||||
"selenium-webdriver": "<%= packageJson.dependencies['selenium-webdriver'] %>"
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
*.xpi
|
||||
addon-sdk*
|
|
@ -0,0 +1,12 @@
|
|||
exportFunction(function() {
|
||||
self.port.emit('startProfiler');
|
||||
}, unsafeWindow, {defineAs: "startProfiler"});
|
||||
|
||||
exportFunction(function(filePath) {
|
||||
self.port.emit('stopAndRecord', filePath);
|
||||
}, unsafeWindow, {defineAs: "stopAndRecord"});
|
||||
|
||||
exportFunction(function() {
|
||||
self.port.emit('forceGC');
|
||||
}, unsafeWindow, {defineAs: "forceGC"});
|
||||
|
|
@ -0,0 +1,61 @@
|
|||
var file = require('sdk/io/file');
|
||||
var {Cc,Ci,Cu} = require("chrome");
|
||||
|
||||
function Profiler() {
|
||||
this._profiler = Cc["@mozilla.org/tools/profiler;1"].getService(Ci.nsIProfiler);
|
||||
};
|
||||
|
||||
Profiler.prototype = {
|
||||
start: function(entries, interval, features) {
|
||||
this._profiler.StartProfiler(entries, interval, features, features.length);
|
||||
},
|
||||
stop: function(cb) {
|
||||
this._profiler.StopProfiler();
|
||||
// this.gcStats.clear();
|
||||
},
|
||||
getProfileData: function() {
|
||||
return this._profiler.getProfileData();
|
||||
}
|
||||
};
|
||||
|
||||
function saveToFile(savePath, str) {
|
||||
var textWriter = file.open(savePath, 'w');
|
||||
textWriter.write(str);
|
||||
textWriter.close();
|
||||
}
|
||||
|
||||
function forceGC() {
|
||||
Cu.forceGC();
|
||||
var os = Cc["@mozilla.org/observer-service;1"]
|
||||
.getService(Ci.nsIObserverService);
|
||||
os.notifyObservers(null, "child-gc-request", null);
|
||||
}
|
||||
|
||||
var profiler = new Profiler();
|
||||
function startProfiler() {
|
||||
profiler.start(/* = profiler memory */ 10000000, 1, ['leaf', 'js', "stackwalk", 'gc']);
|
||||
};
|
||||
function stopAndRecord(filePath) {
|
||||
var profileData = profiler.getProfileData();
|
||||
profiler.stop();
|
||||
saveToFile(filePath, JSON.stringify(profileData, null, 2));
|
||||
};
|
||||
|
||||
|
||||
var mod = require("sdk/page-mod");
|
||||
var data = require("sdk/self").data;
|
||||
mod.PageMod({
|
||||
include: ['*'],
|
||||
contentScriptFile: data.url("installed_script.js"),
|
||||
onAttach: function(worker) {
|
||||
worker.port.on('startProfiler', function() {
|
||||
startProfiler();
|
||||
});
|
||||
worker.port.on('stopAndRecord', function(filePath) {
|
||||
stopAndRecord(filePath);
|
||||
});
|
||||
worker.port.on('forceGC', function() {
|
||||
forceGC();
|
||||
});
|
||||
}
|
||||
});
|
|
@ -0,0 +1,47 @@
|
|||
var q = require('q');
|
||||
var FirefoxProfile = require('firefox-profile');
|
||||
var jpm = require('jpm/lib/xpi');
|
||||
var pathUtil = require('path');
|
||||
|
||||
var PERF_ADDON_PACKAGE_JSON_DIR = '..';
|
||||
|
||||
exports.getAbsolutePath = function(path) {
|
||||
var normalizedPath = pathUtil.normalize(path);
|
||||
if (pathUtil.resolve(normalizedPath) == normalizedPath) {
|
||||
// Already absolute path
|
||||
return normalizedPath;
|
||||
} else {
|
||||
return pathUtil.join(__dirname, normalizedPath);
|
||||
}
|
||||
};
|
||||
|
||||
exports.getFirefoxProfile = function(extensionPath) {
|
||||
var deferred = q.defer();
|
||||
|
||||
var firefoxProfile = new FirefoxProfile();
|
||||
firefoxProfile.addExtensions([extensionPath], function() {
|
||||
firefoxProfile.encoded(function(encodedProfile) {
|
||||
var multiCapabilities = [{
|
||||
browserName: 'firefox',
|
||||
firefox_profile : encodedProfile
|
||||
}];
|
||||
deferred.resolve(multiCapabilities);
|
||||
});
|
||||
});
|
||||
|
||||
return deferred.promise;
|
||||
};
|
||||
|
||||
exports.getFirefoxProfileWithExtension = function() {
|
||||
var absPackageJsonDir = pathUtil.join(__dirname, PERF_ADDON_PACKAGE_JSON_DIR);
|
||||
var packageJson = require(pathUtil.join(absPackageJsonDir, 'package.json'));
|
||||
|
||||
var savedCwd = process.cwd();
|
||||
process.chdir(absPackageJsonDir);
|
||||
|
||||
return jpm(packageJson).then(function(xpiPath) {
|
||||
process.chdir(savedCwd);
|
||||
return exports.getFirefoxProfile(xpiPath);
|
||||
});
|
||||
};
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"version": "0.0.1",
|
||||
"main": "lib/main.js",
|
||||
"name": "ffperf-addon"
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
var testHelper = require('../../src/firefox_extension/lib/test_helper.js');
|
||||
|
||||
// Where to save profile results (parent folder must exist)
|
||||
var PROFILE_SAVE_PATH = './perfProfile.json';
|
||||
|
||||
exports.config = {
|
||||
seleniumAddress: 'http://127.0.0.1:4444/wd/hub',
|
||||
|
||||
specs: ['spec.js'],
|
||||
|
||||
getMultiCapabilities: function() {
|
||||
return testHelper.getFirefoxProfileWithExtension();
|
||||
},
|
||||
|
||||
params: {
|
||||
profileSavePath: testHelper.getAbsolutePath(PROFILE_SAVE_PATH)
|
||||
}
|
||||
};
|
|
@ -0,0 +1,50 @@
|
|||
var fs = require('fs');
|
||||
|
||||
var validateFile = function() {
|
||||
try {
|
||||
var content = fs.readFileSync(browser.params.profileSavePath, 'utf8');
|
||||
// TODO(hankduan): This check not very useful. Ideally we want to validate
|
||||
// that the file contains all the events that we are looking for. Pending
|
||||
// on data transformer.
|
||||
expect(content).toContain('forceGC');
|
||||
// Delete file
|
||||
fs.unlinkSync(browser.params.profileSavePath);
|
||||
} catch (err) {
|
||||
if (err.code === 'ENOENT') {
|
||||
// If files doesn't exist
|
||||
console.error('Error: firefox extension did not save profile JSON');
|
||||
} else {
|
||||
console.error('Error: ' + err);
|
||||
}
|
||||
throw err;
|
||||
}
|
||||
};
|
||||
|
||||
describe('firefox extension', function() {
|
||||
it ('should measure performance', function() {
|
||||
browser.sleep(3000); // wait for extension to load
|
||||
|
||||
browser.driver.get('http://www.angularjs.org');
|
||||
|
||||
browser.executeScript('window.startProfiler()').then(function() {
|
||||
console.log('started measuring perf');
|
||||
});
|
||||
|
||||
browser.executeScript('window.forceGC()');
|
||||
|
||||
// Run some commands
|
||||
element(by.model('yourName')).sendKeys('Hank');
|
||||
expect(element(by.binding('yourName')).getText()).toEqual('Hello Hank!');
|
||||
|
||||
browser.executeScript('window.forceGC()');
|
||||
|
||||
var script =
|
||||
'window.stopAndRecord("' + browser.params.profileSavePath + '")';
|
||||
browser.executeScript(script).then(function() {
|
||||
console.log('stopped measuring perf');
|
||||
});
|
||||
|
||||
// wait for it to finish, then validate file.
|
||||
browser.sleep(3000).then(validateFile);
|
||||
})
|
||||
});
|
|
@ -25,6 +25,7 @@
|
|||
},
|
||||
"dependencies": {
|
||||
"es6-module-loader": "^0.9.2",
|
||||
"firefox-profile": "0.3.4",
|
||||
"googleapis": "1.0.x",
|
||||
"gulp-insert": "^0.4.0",
|
||||
"gulp-modify": "0.0.5",
|
||||
|
|
Loading…
Reference in New Issue