I am attempting to run automated tests for my Google Analytics interactions using Headless Chrome in combination with Puppeteer, Mocha, and Sinon. However, I am unable to access the dataLayer property for Sinon to monitor its actions. Below is my current implementation, but I’ve encountered an issue where the ‘window’ object is always undefined. ‘test’ is a class that serves as a proxy to forward Puppeteer calls to the browser instance.
const { test } = require('../browser');
const sinon = require('sinon');
const layerName = 'dataLayer';
const assert = sinon.assert;
describe('Analytics Tests', () => {
let spy;
it('track homepage analytics', test(async (browser, options) => {
const pageInstance = await browser.newPage();
await pageInstance.goto(`${options.appUrl}`);
spy = sinon.spy(window.dataLayer, 'push');
assert.called(spy);
assert.calledWith(spy, [
'error scenario',
]);
spy.restore();
}));
});
Here is the code for the Browser class:
const puppeteer = require('puppeteer');
class Browser {
initialize(done) {
const puppeteerConfig = this.settings && this.settings.puppeteer ?
this.settings.puppeteer :
{};
puppeteer.launch(puppeteerConfig).then(async (browserInstance) => {
this.assignBrowser(browserInstance);
done();
});
}
assignBrowser(instance) {
this.browser = instance;
const originalNewPage = this.browser.newPage.bind(this.browser);
this.browser.newPage = async function () {
const pageInstance = await originalNewPage();
this.latestPage = pageInstance;
return pageInstance;
};
}
configureOptions(settings) {
this.settings = settings;
}
runTest(promise) {
return (done) => {
promise(this.browser, this.settings)
.then(() => done()).catch(done);
};
}
}
module.exports = new Proxy(new Browser(), {
get(target, property) {
return property in target ? target[property].bind(target) : target.browser[property];
},
});