Skip to content

Commit

Permalink
Introducing Health service for Selenium IDE
Browse files Browse the repository at this point in the history
  • Loading branch information
samitbadle committed Sep 24, 2014
1 parent 01852d3 commit e9ec39a
Show file tree
Hide file tree
Showing 4 changed files with 229 additions and 0 deletions.
6 changes: 6 additions & 0 deletions ide/main/src/content/editor.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ function Editor(window) {
this.window = window;
window.editor = this;
var self = this;
this.health = new HealthService();
this.health.attach(window, 'editor');
this.health.addEvent('editor', 'initializing');
this.safeLastWindow = new LastWindow();
this.recordFrameTitle = false;
this.app = new Application();
Expand All @@ -46,6 +49,7 @@ function Editor(window) {
self.updateDeveloperTools(self.app.getBooleanOption('showDeveloperTools'));
self.updateExperimentalFeatures(self.app.getBooleanOption('enableExperimentalFeatures'));
self.updateVisualEye(self.app.getBooleanOption('visualEye'));
self.health.showAlerts(self.app.getBooleanOption('showHealthAlerts'));
},

testSuiteChanged: function (testSuite) {
Expand Down Expand Up @@ -145,6 +149,7 @@ function Editor(window) {
}
});

this.health.showAlerts(this.app.getBooleanOption('showHealthAlerts'));
this.document = document;
this.recordButton = document.getElementById("record-button");
this.recordMenuItem = document.getElementById("menu_record");
Expand Down Expand Up @@ -219,6 +224,7 @@ function Editor(window) {
}
this.log.info("Ready");
this.app.notify('initComplete');
this.health.addEvent('editor', 'initialized');
}

Editor.prototype.saveTC = function () {
Expand Down
221 changes: 221 additions & 0 deletions ide/main/src/content/health/health-service.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,221 @@
/*
* Health Service - provide a service to collect errors, events and statistics
*
* Copyright 2014 Samit Badle
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
function HealthService() {
this.startTime = Date.now();
this.diagProviders = {};
this.handlers = {};
this.key = 0;
this.alerts = true;

this.diags = {};
this.events = [];
this.metrics = {};
this.stats = {};
}

/**
* reset all collected data
*/
HealthService.prototype.reset = function() {
this.diags = {};
this.events = [];
this.metrics = {};
this.stats = {};
this.addEvent('HealthService', 'reset');
};

/**
* Add a diagnostic in a script at load time
* @param name the result of the diagnostic is stored with this name
* @param object needs a runDiagnostic fn
*/
HealthService.addDiagnostic = function(name, object) {
if (!this.diagProviders) {
this.diagProviders = {};
}
this.diagProviders[name] = object;
};

/**
* Add a diagnostic to an instance of this object
* @param name the result of the diagnostic is stored with this name
* @param object needs a runDiagnostic fn
*/
HealthService.prototype.addDiagnostic = function(name, object) {
this.diagProviders[name] = object;
};

/**
* Run all added diagnostics
*/
HealthService.prototype.runDiagnostics = function() {
// run those added to the instance
var results = this._runDiagnostics(this.diagProviders, {});
// run those added to the class
this.diags = this._runDiagnostics(HealthService.diagProviders, results);
};

HealthService.prototype._runDiagnostics = function(providers, results) {
if (providers) {
for (var k in providers) {
if (providers.hasOwnProperty(k)) {
try {
results[k] = providers[k].runDiagnostic();
} catch (e) {
results[k] = "Error: " + e;
}
}
}
}
return results;
};

/**
* Choose if any uncaught errors should be displayed
*/
HealthService.prototype.showAlerts = function(value) {
this.alerts = value ? true : false;
};

HealthService.prototype._newKey = function() {
return ++this.key;
};

/**
* Add health handlers
*/
HealthService.prototype.attach = function(win, component) {
if (win) {
var oldOnError = win.onerror;
win.__side_health_key = Date.now() + component + this._newKey();
this.handlers[win.__side_health_key] = {
component: component,
oldOnError: oldOnError
};
var self = this;
win.onerror = function SIDEErrorHandler(msg, url, line) {
self.addError(component, "UncaughtException", msg, url, line);
if (self.alerts) {
alert("Caught onerror. Msg: " + msg + ", url: " + url + ", line: " + line);
}
return oldOnError ? oldOnError(msg, url, line) : false;
};
this.addEvent('HealthService', 'attached: ' + component);
}
};

/**
* Remove the attached health handlers
*/
HealthService.prototype.detach = function(win) {
if (win && win.__side_health_key && this.handlers[win.__side_health_key]) {
var info = this.handlers[win.__side_health_key];
this.handlers[win.__side_health_key] = null;
win.onerror = info.oldOnError;
this.addEvent('HealthService', 'detached: ' + info.component);
}
};

/**
* Add an event for a component
*/
HealthService.prototype.addEvent = function(component, event) {
this.events.push({
at: Date.now(),
component: component,
type: 'Event',
event: event
});
};

/**
* Add an error for a component
*/
HealthService.prototype.addError = function(component, event, msg, url, line) {
this.events.push({
at: Date.now(),
component: component,
type: 'Error',
event: event,
msg: msg,
url: url,
line: line
});
};

/**
* Increase the counter in a component
*/
HealthService.prototype.increaseCounter = function(component, counter) {
if (!this.stats[component]) {
this.stats[component] = {};
this.stats[component][counter] = 0;
}
this.stats[component][counter]++;
};

/**
* Store a metric in a component
*/
HealthService.prototype.setMetric = function(component, metric, data) {
if (!this.metrics[component]) {
this.metrics[component] = {};
}
this.metrics[component][metric] = data;
};

/**
* Retrieve a metric in a component
*/
HealthService.prototype.getMetric = function(component, metric, defaultValue) {
if (this.metrics[component]) {
return this.metrics[component].hasOwnProperty(metric) ? this.metrics[component][metric] : defaultValue;
}
return defaultValue;
};

/**
* Return the collected data
*/
HealthService.prototype.getData = function() {
return {
startTime: this.startTime,
at: Date.now(),
diags: this.diags,
events: this.events,
metrics: this.metrics,
stats: this.stats
};
};

/**
* Return the collected data
*/
HealthService.prototype.getJSON = function() {
return JSON.stringify(this.getData());
};

/**
* Return the collected data so that it can be persisted to storage
* and reset all collected data so that memory consumption is contained
*/
HealthService.prototype.flush = function() {
var data = this.getJSON();
this.reset();
return data;
};
1 change: 1 addition & 0 deletions ide/main/src/content/preferences.js
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,7 @@ SeleniumIDE.Preferences.DEFAULT_OPTIONS = {
//Internal data
pluginsData: "[]",
currentVersion: "",
showHealthAlerts: "false",
lastSavedTestCase: "",
lastSavedTestSuite: ""
};
Expand Down
1 change: 1 addition & 0 deletions ide/main/src/content/selenium-ide-common.xul
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ limitations under the License.
<overlay id="selenium-ide-common" xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<script type="application/x-javascript" src="chrome://global/content/globalOverlay.js"/>
<script type="application/x-javascript" src="chrome://global/content/nsDragAndDrop.js"/>
<script type="application/x-javascript" src="chrome://selenium-ide/content/health/health-service.js"/>
<script type="application/x-javascript" src="chrome://selenium-ide/content/dnd-observers.js"/>
<script type="application/x-javascript" src="chrome://selenium-ide/content/preferences.js"/>
<!-- import misc.js before tools.js, because both declare a Log object -->
Expand Down

0 comments on commit e9ec39a

Please sign in to comment.