Refactoring tracking code

This is to support the new Google Analytics setup
This commit is contained in:
Jeff Avallone 2016-05-23 21:10:50 -04:00
parent 1025fb0501
commit da8850e93b
5 changed files with 35 additions and 37 deletions

View File

@ -23,7 +23,6 @@ describe('regexper.js', function() {
this.regexper = new Regexper(this.root);
spyOn(this.regexper, '_setHash');
spyOn(this.regexper, '_getHash');
spyOn(window._gaq, 'push');
});
describe('#keypressListener', function() {
@ -193,7 +192,7 @@ describe('regexper.js', function() {
it('tracks the event', function() {
this.regexper.hashchangeListener();
expect(window._gaq.push).toHaveBeenCalledWith(['_trackEvent', 'visualization', 'malformed URL']);
expect(util.track).toHaveBeenCalledWith('send', 'event', 'visualization', 'malformed URL');
});
});
@ -391,7 +390,7 @@ describe('regexper.js', function() {
it('tracks the beginning of the render', function() {
this.regexper.renderRegexp('example expression');
expect(window._gaq.push).toHaveBeenCalledWith(['_trackEvent', 'visualization', 'start']);
expect(util.track).toHaveBeenCalledWith('send', 'event', 'visualization', 'start');
});
it('keeps a copy of the running property parser', function() {
@ -429,7 +428,7 @@ describe('regexper.js', function() {
it('tracks the parse error', function(done) {
this.regexper.renderRegexp('example expression')
.then(() => {
expect(window._gaq.push).toHaveBeenCalledWith(['_trackEvent', 'visualization', 'parse error']);
expect(util.track).toHaveBeenCalledWith('send', 'event', 'visualization', 'parse error');
done();
});
});
@ -489,7 +488,7 @@ describe('regexper.js', function() {
it('tracks the complete render', function(done) {
this.regexper.renderRegexp('example expression')
.then(() => {
expect(window._gaq.push).toHaveBeenCalledWith(['_trackEvent', 'visualization', 'complete']);
expect(util.track).toHaveBeenCalledWith('send', 'event', 'visualization', 'complete');
done();
});
});
@ -505,7 +504,7 @@ describe('regexper.js', function() {
it('tracks the total rendering time', function(done) {
this.regexper.renderRegexp('example expression')
.then(() => {
expect(window._gaq.push).toHaveBeenCalledWith(['_trackTiming', 'visualization', 'total time', jasmine.any(Number)]);
expect(util.track).toHaveBeenCalledWith('send', 'timing', 'visualization', 'total time', jasmine.any(Number));
done();
});
});
@ -531,7 +530,7 @@ describe('regexper.js', function() {
it('tracks the cancelled render', function(done) {
this.regexper.renderRegexp('example expression')
.then(() => {
expect(window._gaq.push).toHaveBeenCalledWith(['_trackEvent', 'visualization', 'cancelled']);
expect(util.track).toHaveBeenCalledWith('send', 'event', 'visualization', 'cancelled');
done();
});
});

View File

@ -1,3 +1,5 @@
import util from '../src/js/util.js';
// Setup (and teardown) SVG container template
beforeEach(function() {
var template = document.createElement('script');
@ -25,7 +27,7 @@ afterEach(function() {
document.body.removeChild(document.body.querySelector('#svg-container-base'));
});
// Spy on _gaq.push to prevent unnecessary logging
window._gaq = {
push() {}
}
// Spy on util.track to prevent unnecessary logging
beforeEach(function() {
spyOn(util, 'track');
});

View File

@ -10,33 +10,17 @@ import Regexper from './regexper.js';
import Parser from './parser/javascript.js';
import _ from 'lodash';
// Add a dummy version of `_gaq` (the Google Analytics global object). This
// dummy object will log out tracking commands that would otherwise be sent to
// Google Analytics.
window._gaq = (typeof _gaq !== 'undefined') ? _gaq : {
push: console.debug.bind(console)
};
(function() {
// Global error handler that will send unhandled JavaScript exceptions and
// stack-traces to Google Analytics. This data can be used to find errors in
// code that were not found during testing.
window.addEventListener('error', function(error) {
if (error.lineno !== 0) {
_gaq.push([
'_trackEvent',
'global',
'exception',
`${error.filename}(${error.lineno},${error.colno}): ${error.message}`
]);
util.track('send', 'event', 'global', 'exception',
`${error.filename}(${error.lineno},${error.colno}): ${error.message}`);
if (typeof error.error !== 'undefined' && typeof error.error.stack !== 'undefined') {
_gaq.push([
'_trackEvent',
'global',
'stack trace',
error.error.stack
]);
util.track('send', 'event', 'global', 'stack trace', error.error.stack);
}
}
});

View File

@ -68,7 +68,7 @@ export default class Regexper {
if (expr instanceof Error) {
this.state = 'has-error';
this.error.innerHTML = 'Malformed expression in URL';
window._gaq.push(['_trackEvent', 'visualization', 'malformed URL']);
util.track('send', 'event', 'visualization', 'malformed URL');
} else {
this.permalinkEnabled = true;
this.showExpression(expr);
@ -206,7 +206,7 @@ export default class Regexper {
}
this.state = 'is-loading';
window._gaq.push(['_trackEvent', 'visualization', 'start']);
util.track('send', 'event', 'visualization', 'start');
startTime = new Date().getTime();
this.running = new Parser(this.svgContainer);
@ -236,20 +236,20 @@ export default class Regexper {
this.state = 'has-results';
this.updateLinks();
this.displayWarnings(this.running.warnings);
window._gaq.push(['_trackEvent', 'visualization', 'complete']);
util.track('send', 'event', 'visualization', 'complete');
endTime = new Date().getTime();
window._gaq.push(['_trackTiming', 'visualization', 'total time', endTime - startTime]);
util.track('send', 'timing', 'visualization', 'total time', endTime - startTime);
})
// Handle any errors that happened during the rendering pipeline.
// Swallows parse errors and render cancellations. Any other exceptions
// are allowed to continue on to be tracked by the global error handler.
.catch(message => {
if (message === 'Render cancelled') {
window._gaq.push(['_trackEvent', 'visualization', 'cancelled']);
util.track('send', 'event', 'visualization', 'cancelled');
this.state = '';
} else if (parseError) {
window._gaq.push(['_trackEvent', 'visualization', 'parse error']);
util.track('send', 'event', 'visualization', 'parse error');
} else {
throw message;
}

View File

@ -124,10 +124,22 @@ function exposeError(error) {
}, 0);
}
// Renders an SVG icon.
//
// - __selector__ - Selector to the SVG icon to render.
function icon(selector) {
return `<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 8 8"><use xlink:href="${selector}" /></svg>`;
}
// Send tracking data.
function track() {
if (window.ga) {
ga.apply(ga, arguments);
} else {
console.debug.apply(console, arguments);
}
}
export default {
customEvent,
normalizeBBox,
@ -136,5 +148,6 @@ export default {
wait,
tick,
exposeError,
icon
icon,
track
};