Skip to content
This repository has been archived by the owner on Sep 11, 2024. It is now read-only.

Commit

Permalink
fix: page tracking
Browse files Browse the repository at this point in the history
closes #163
closes #150
  • Loading branch information
MatteoGabriele committed Jul 14, 2020
1 parent c360cd9 commit 93c17e1
Show file tree
Hide file tree
Showing 3 changed files with 97 additions and 83 deletions.
138 changes: 70 additions & 68 deletions __tests__/page-tracker.spec.js
Original file line number Diff line number Diff line change
@@ -1,149 +1,151 @@
import { warn } from "@/util";
import { getRouter, getOptions } from "@/install";
import pageTracker, * as tracker from "@/page-tracker";
import * as pageTracker from "@/page-tracker";
import pageview from "@/api/pageview";
import screenview from "@/api/screenview";
import * as util from "@/util";

jest.mock("@/install");
jest.mock("@/api/pageview");
jest.mock("@/api/screenview");
jest.mock("@/util");

const noop = () => {};
const toMock = { name: "about", path: "/about" };
const fromMock = { name: "home", path: "/" };

const to = {
name: "About",
path: "/about"
};
const updateLocationPath = href => {
global.window = Object.create(window);

const from = {
name: "Home",
path: "/"
Object.defineProperty(window, "location", {
value: {
href
}
});
};

describe("page-tracker", () => {
afterEach(() => {
beforeEach(() => {
jest.clearAllMocks();
});

it("should call config to track pageviews", () => {
getOptions.mockReturnValueOnce({
pageTrackerTemplate: noop
});

const url = "foo";
it("should track a pageview", () => {
updateLocationPath("http://localhost/about");

global.window = Object.create(window);
Object.defineProperty(window, "location", {
value: {
href: url
}
getOptions.mockReturnValue({
pageTrackerTemplate: () => null
});

tracker.trackPage(to, from);
pageTracker.trackPage({ to: toMock, from: fromMock });

expect(pageview).toHaveBeenCalledWith({
page_location: url,
page_location: "http://localhost/about",
page_path: "/about",
page_title: "About"
page_title: "about"
});

expect(screenview).not.toHaveBeenCalled();
});

it("should call screenview to track screenviews", () => {
getOptions.mockReturnValueOnce({
pageTrackerTemplate: noop,
it("should track a screenview", () => {
updateLocationPath("http://localhost/about");

getOptions.mockReturnValue({
pageTrackerScreenviewEnabled: true,
pageTrackerTemplate: () => null,
appName: "MyApp"
});

tracker.trackPage(to, from);
pageTracker.trackPage({ to: toMock, from: fromMock });

expect(screenview).toHaveBeenCalledWith({
app_name: "MyApp",
screen_name: "About"
screen_name: "about"
});
expect(pageview).not.toHaveBeenCalled();
});

it("should", () => {
const template = {
foo: "bar",
bar: "foo"
};
it("should not track when same path", () => {
const to = { name: "home", path: "/" };
const from = { name: "home", path: "/" };

getOptions.mockReturnValueOnce({
pageTrackerTemplate: () => template
});
updateLocationPath("http://localhost/about");

tracker.trackPage(to, from);
getOptions.mockReturnValue({});

expect(pageview).toHaveBeenCalledWith(template);
});

it("should not track when `to` and `from` routes are identical", () => {
tracker.trackPage({ path: "/foo" }, { path: "/foo" });
pageTracker.trackPage({ to, from });

expect(screenview).not.toHaveBeenCalled();
expect(pageview).not.toHaveBeenCalled();
});

it("should warn when using screenview without an appName", () => {
util.warn = jest.fn();

getOptions.mockReturnValueOnce({
pageTrackerTemplate: noop,
getOptions.mockReturnValue({
pageTrackerTemplate: () => null,
pageTrackerScreenviewEnabled: true
});

tracker.trackPage(to, from);
pageTracker.trackPage({ to: toMock, from: fromMock });

expect(util.warn).toHaveBeenCalledWith(
expect(warn).toHaveBeenCalledWith(
"To use the screenview, add the appName to the plugin options"
);

expect(screenview).not.toHaveBeenCalled();
});

it("should warn when using screenview without naming routes", () => {
util.warn = jest.fn();

getOptions.mockReturnValueOnce({
pageTrackerTemplate: noop,
getOptions.mockReturnValue({
pageTrackerTemplate: () => null,
pageTrackerScreenviewEnabled: true,
appName: "MyApp"
});

tracker.trackPage({ path: "/" }, { path: "/about" });
const to = { path: "/" };
const from = { path: "/about" };

pageTracker.trackPage({ to, from });

expect(util.warn).toHaveBeenCalledWith(
expect(warn).toHaveBeenCalledWith(
"To use the screenview, name your routes"
);

expect(screenview).not.toHaveBeenCalled();
});

it("should return a custom template", () => {
getOptions.mockReturnValue({
pageTrackerTemplate() {
return {
page_title: "foo",
page_path: "bar",
page_location: "/foo/bar"
};
}
});

pageTracker.trackPage({ to: toMock, from: fromMock });

expect(pageview).toHaveBeenCalledWith({
page_title: "foo",
page_path: "bar",
page_location: "/foo/bar"
});
});

it("should not trigger init without a Router instance", () => {
tracker.init = jest.fn();
pageTracker.startRouter = jest.fn();

pageTracker();
pageTracker.autotrack();

expect(tracker.init).not.toHaveBeenCalled();
expect(pageTracker.startRouter).not.toHaveBeenCalled();
});

it("should trigger init", () => {
const spy = jest.fn();

getOptions.mockReturnValueOnce({
onBeforeTrack: noop,
onAfterTrack: noop
onBeforeTrack: () => {},
onAfterTrack: () => {}
});

getRouter.mockReturnValueOnce({
onReady: spy
});

pageTracker();
pageTracker.autotrack();

expect(spy).toHaveBeenCalled();
});
Expand Down
8 changes: 4 additions & 4 deletions src/bootstrap.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { warn, isFn, loadScript } from "./util";
import config from "./api/config";
import api from "./api";
import { getRouter, getOptions } from "../src/install";
import optOut from "./api/opt-out";
import pageTracker from "./page-tracker";
Expand All @@ -13,7 +13,7 @@ export default function() {
enabled,
globalObjectName,
globalDataLayerName,
config: { id },
config,
pageTrackerEnabled,
onReady,
disableScriptLoad
Expand All @@ -38,15 +38,15 @@ export default function() {
if (isPageTrackerEnabled) {
pageTracker();
} else {
config();
api.config(config.params);
}

if (disableScriptLoad) {
return;
}

const domain = "https://www.googletagmanager.com";
const resource = `${domain}/gtag/js?id=${id}&l=${globalDataLayerName}`;
const resource = `${domain}/gtag/js?id=${config.id}&l=${globalDataLayerName}`;

return loadScript(resource, domain)
.then(() => {
Expand Down
34 changes: 23 additions & 11 deletions src/page-tracker.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { warn } from "./util";
import pageview from "./api/pageview";
import screenview from "./api/screenview";

export const trackPage = (to = {}, from = {}) => {
export const getPageviewTemplate = (to = {}, from = {}) => {
if (to.path === from.path) {
return;
}
Expand Down Expand Up @@ -32,50 +32,62 @@ export const trackPage = (to = {}, from = {}) => {
};
}

if (pageTrackerScreenviewEnabled && !template.app_name) {
return template;
};

export const trackPage = ({ to, from, params = {} } = {}) => {
const { pageTrackerScreenviewEnabled } = getOptions();
const newParams = {
...getPageviewTemplate(to, from),
...params
};

if (pageTrackerScreenviewEnabled && !newParams.app_name) {
warn("To use the screenview, add the appName to the plugin options");
return;
}

if (pageTrackerScreenviewEnabled && !template.screen_name) {
if (pageTrackerScreenviewEnabled && !newParams.screen_name) {
warn("To use the screenview, name your routes");
return;
}

if (pageTrackerScreenviewEnabled) {
screenview(template);
screenview(newParams);
return;
}

pageview(template);
pageview(newParams);
};

export const init = Router => {
export const startRouter = Router => {
const Vue = getVue();
const { onBeforeTrack, onAfterTrack } = getOptions();
const { onBeforeTrack, onAfterTrack, config } = getOptions();

/* istanbul ignore next */
Router.onReady(current => {
Vue.nextTick().then(() => {
trackPage(current);
trackPage({ to: current, params: config.params });
});

Router.afterEach((to, from) => {
Vue.nextTick().then(() => {
onBeforeTrack(to, from);
trackPage(to, from);
trackPage({ to, from });
onAfterTrack(to, from);
});
});
});
};

export default () => {
export const autotrack = () => {
const Router = getRouter();

if (!Router) {
return;
}

init(Router);
startRouter(Router);
};

export default autotrack;

0 comments on commit 93c17e1

Please sign in to comment.