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 9add3984d6
commit 6a0999f644
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); this.regexper = new Regexper(this.root);
spyOn(this.regexper, '_setHash'); spyOn(this.regexper, '_setHash');
spyOn(this.regexper, '_getHash'); spyOn(this.regexper, '_getHash');
spyOn(window._gaq, 'push');
}); });
describe('#keypressListener', function() { describe('#keypressListener', function() {
@ -193,7 +192,7 @@ describe('regexper.js', function() {
it('tracks the event', function() { it('tracks the event', function() {
this.regexper.hashchangeListener(); 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() { it('tracks the beginning of the render', function() {
this.regexper.renderRegexp('example expression'); 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() { 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) { it('tracks the parse error', function(done) {
this.regexper.renderRegexp('example expression') this.regexper.renderRegexp('example expression')
.then(() => { .then(() => {
expect(window._gaq.push).toHaveBeenCalledWith(['_trackEvent', 'visualization', 'parse error']); expect(util.track).toHaveBeenCalledWith('send', 'event', 'visualization', 'parse error');
done(); done();
}); });
}); });
@ -489,7 +488,7 @@ describe('regexper.js', function() {
it('tracks the complete render', function(done) { it('tracks the complete render', function(done) {
this.regexper.renderRegexp('example expression') this.regexper.renderRegexp('example expression')
.then(() => { .then(() => {
expect(window._gaq.push).toHaveBeenCalledWith(['_trackEvent', 'visualization', 'complete']); expect(util.track).toHaveBeenCalledWith('send', 'event', 'visualization', 'complete');
done(); done();
}); });
}); });
@ -505,7 +504,7 @@ describe('regexper.js', function() {
it('tracks the total rendering time', function(done) { it('tracks the total rendering time', function(done) {
this.regexper.renderRegexp('example expression') this.regexper.renderRegexp('example expression')
.then(() => { .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(); done();
}); });
}); });
@ -531,7 +530,7 @@ describe('regexper.js', function() {
it('tracks the cancelled render', function(done) { it('tracks the cancelled render', function(done) {
this.regexper.renderRegexp('example expression') this.regexper.renderRegexp('example expression')
.then(() => { .then(() => {
expect(window._gaq.push).toHaveBeenCalledWith(['_trackEvent', 'visualization', 'cancelled']); expect(util.track).toHaveBeenCalledWith('send', 'event', 'visualization', 'cancelled');
done(); done();
}); });
}); });

View File

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

View File

@ -10,33 +10,17 @@ import Regexper from './regexper.js';
import Parser from './parser/javascript.js'; import Parser from './parser/javascript.js';
import _ from 'lodash'; 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() { (function() {
// Global error handler that will send unhandled JavaScript exceptions and // Global error handler that will send unhandled JavaScript exceptions and
// stack-traces to Google Analytics. This data can be used to find errors in // stack-traces to Google Analytics. This data can be used to find errors in
// code that were not found during testing. // code that were not found during testing.
window.addEventListener('error', function(error) { window.addEventListener('error', function(error) {
if (error.lineno !== 0) { if (error.lineno !== 0) {
_gaq.push([ util.track('send', 'event', 'global', 'exception',
'_trackEvent', `${error.filename}(${error.lineno},${error.colno}): ${error.message}`);
'global',
'exception',
`${error.filename}(${error.lineno},${error.colno}): ${error.message}`
]);
if (typeof error.error !== 'undefined' && typeof error.error.stack !== 'undefined') { if (typeof error.error !== 'undefined' && typeof error.error.stack !== 'undefined') {
_gaq.push([ util.track('send', 'event', 'global', 'stack trace', error.error.stack);
'_trackEvent',
'global',
'stack trace',
error.error.stack
]);
} }
} }
}); });

View File

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

View File

@ -124,10 +124,22 @@ function exposeError(error) {
}, 0); }, 0);
} }
// Renders an SVG icon.
//
// - __selector__ - Selector to the SVG icon to render.
function icon(selector) { 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>`; 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 { export default {
customEvent, customEvent,
normalizeBBox, normalizeBBox,
@ -136,5 +148,6 @@ export default {
wait, wait,
tick, tick,
exposeError, exposeError,
icon icon,
track
}; };