Installation

Getting the library

To get started, add the repository to your project:

npm install git+https://git@github.com/philsawicki/GoogleAnalytics-WebTester.git

Installing Protractor

Using npm, install Protractor globally using:

npm install -g protractor

This will install two command-line tools: protractor and webdriver-manager, a helper tool to get an instance of a running Selenium Server. Use it to download the necessary binaries with:

webdriver-manager update

The Selenium Server can be started with:

webdriver-manager start

Protractor tests will send requests to this server to control a local browser. Information about the status of the server can be found at http://localhost:4444/wd/hub.

For detailed installation and configuration instructions, refer to Protractor's tutorial.

Configuring Protractor

In order to intercept calls to Analytics' ga() function, some custom JavaScript code must be injected into each page at the beginning of a test. In your protractor.conf.js file, simply add the following to the onPrepare callback.

// protractor.conf.js

exports.config = {
   // ...

   // Base URL for the application under test. Calls to "protractor.get()"
   // with relative paths will be prepended with this.
   // This may also be a directory on a local system, prefixed with "file://".
   baseUrl: 'http://localhost:8000/',

   // Test files to execute (relative to the location of this config).
   specs: [
      // ...
      'jumbotronSpec.js'
   ],

   // ...

   // The params object will be passed directly to the Protractor instance,
   // and can be accessed from the tests. It is an arbitrary object and can
   // contain anything needed for tests.
   // This can be changed via the command line as:
   //   --params.login.user 'Joe'
   params: {
      GoogleAnalyticsWebTester: {
          // Submit test data to Google Analytics? "false" will not actually send the data to "ga()" 
          // in order to avoid skew results by recording test data.
         submitToGA: false
      }
   },

   // A callback function called once Protractor is ready and available, and
   // before the specs are executed.
   // You can specify a file containing code to run by setting onPrepare to
   // the filename string.
   onPrepare: function () {
      // Load the Web Tester (the path may vary depending on your setup):
      var GoogleAnalyticsWebTester = require('GoogleAnalytics-WebTester/lib/GoogleAnalyticsWebTester');

      // Initialize the Web Tester:
      GoogleAnalyticsWebTester.initialize({
         browserParams: browser.params, // Browser params (from Protractor's "browser.params").
         browserDriver: browser.driver  // A reference to Protractor's WebDriver (i.e. the actual browser instance).
      });
   }
}

The configuration tells Protractor where the test files are located, and use the default values for all other configuration options. For a list of available options and their default values, check the reference configuration file.

Writing a Test

Tests can now be created using Protractor specification files. As an example, here is how the a Custom Event can be tracked, when clicking on a CTA button:

// jumbotronSpec.js

describe('The Google Analytics "click" tracking', function () {

   // Before each test: 
   //   1. Navigate to the "index.html" page.
   //   2. Register the Analytics Data Interceptor.
   beforeEach(function () {
      // Load the page to test:
      browser.get('index.html');

      // Register the Google Analytics Event Data Interceptor:
      browser.driver.registerGoogleAnalyticsEventDataInterceptor();
   });
   
   // Execute a test:
   //   1. Click on the button with ID "jumbotronCTA".
   //   2. Get the last event recorded by the Analytics Data Interceptor.
   //   3. Validate that the last event data matches the expected values.
   it('should fire an Event when clicking on the Jumbotron CTA', function (done) {
      // Click on the "Jumbotron" CTA:
      element( by.css('#jumbotronCTA') ).click();
 
      // Get the "LastEvent" object back from the browser:
      browser.driver.executeScript(function () {
         return window.GAWebTester.getLastEvent();
      })
      .then(
         // Validate the content of the "LastData" object:
         function successCallback (LastData) {
            expect( LastData ).toEqual( ['send', 'event', 'Button', 'Click', 'Jumbotron CTA'] );
         },
         // If there was an error getting back the "LastData" object from the browser, fail the test:
         function errorCallback (error) {
            fail('Should not have received Error: ' + JSON.stringify(error));
         }
      )
      .then(done);
   });
});

The describe and it syntax come from the Jasmine framework. browser is a global object created by Proctractor, which is used for browser-level commands such as navigating to a page (by calling browser.get).

Running the Test

Assuming everything is set up correctly, you should now be able to launch Protractor to execute the test suite:

protractor protractor.conf.js

A Chrome browser window should open up and navigate to the "index.html" page of the configured server, then close itself (this might be very fast!).

If the "index.html" page of your website contains a DOMElement with ID "jumbotronCTA" which calls ga('send', 'event', 'Button', 'Click', 'Jumbotron CTA'); when clicked, Proctractor should report the following:

1 test, 1 assertions, 0 failures

Congratulations!