Skip to content

Commit

Permalink
Fix tracking a page view with a custom title sets the title for futur…
Browse files Browse the repository at this point in the history
…e page views as well (close #1332)

PR #1334
  • Loading branch information
matus-tomlein committed Jul 24, 2024
1 parent 57c68a7 commit 9fe9ee9
Show file tree
Hide file tree
Showing 4 changed files with 125 additions and 3 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"changes": [
{
"packageName": "@snowplow/browser-tracker-core",
"comment": "Fix tracking a page view with a custom title sets the title for future page views as well (#1332)",
"type": "none"
}
],
"packageName": "@snowplow/browser-tracker-core"
}
12 changes: 11 additions & 1 deletion libraries/browser-tracker-core/src/tracker/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,10 @@ export function Tracker(
lastDocumentTitle = document.title,
// Custom title
lastConfigTitle: string | null | undefined,
// Indicates that the lastConfigTitle was set from a trackPageView call
// Custom title configured this way has a shorter lifespan than when set using setDocumentTitle.
// It only lasts until the next trackPageView call.
lastConfigTitleFromTrackPageView: boolean = false,
// Controls whether activity tracking page ping event timers are reset on page view events
resetActivityTrackingOnPageView = trackerConfiguration.resetActivityTrackingOnPageView ?? true,
// Disallow hash tags in URL. TODO: Should this be set to true by default?
Expand Down Expand Up @@ -987,7 +991,12 @@ export function Tracker(

// So we know what document.title was at the time of trackPageView
lastDocumentTitle = document.title;
lastConfigTitle = title ?? lastConfigTitle;
if (title) {
lastConfigTitle = title;
lastConfigTitleFromTrackPageView = true;
} else if (lastConfigTitleFromTrackPageView) {
lastConfigTitle = null;
}

// Fixup page title
const pageTitle = fixupTitle(lastConfigTitle || lastDocumentTitle);
Expand Down Expand Up @@ -1227,6 +1236,7 @@ export function Tracker(
// So we know what document.title was at the time of trackPageView
lastDocumentTitle = document.title;
lastConfigTitle = title;
lastConfigTitleFromTrackPageView = false;
},

discardHashTag: function (enableFilter: boolean) {
Expand Down
103 changes: 103 additions & 0 deletions libraries/browser-tracker-core/test/tracker/page_view.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
/*
* Copyright (c) 2022 Snowplow Analytics Ltd, 2010 Anthon Pang
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

import { createTracker } from '../helpers';

describe('Tracker API: page views', () => {
beforeEach(() => {
jest.spyOn(document, 'title', 'get').mockReturnValue('Page title 1');
});

it('Uses custom page title for only a single page view', () => {
let titles: string[] = [];
const tracker = createTracker({
plugins: [
{
afterTrack: (payload) => {
titles.push(payload.page as string);
},
},
],
});

tracker?.trackPageView({
title: 'Title override',
});
tracker?.trackPageView();

expect(titles).toEqual(['Title override', 'Page title 1']);
});

it('Uses custom page title set using setDocumentTitle until overriden again', () => {
let titles: string[] = [];
const tracker = createTracker({
plugins: [
{
afterTrack: (payload) => {
titles.push(payload.page as string);
},
},
],
});

tracker?.setDocumentTitle('Title override');
tracker?.trackPageView();
tracker?.trackPageView();

jest.spyOn(document, 'title', 'get').mockReturnValue('Page title 2');
tracker?.trackPageView();

tracker?.setDocumentTitle('Title override 2');
tracker?.trackPageView();

expect(titles).toEqual(['Title override', 'Title override', 'Title override', 'Title override 2']);
});

it('Explicit title in trackPageView overrides setDocumentTitle', () => {
let titles: string[] = [];
const tracker = createTracker({
plugins: [
{
afterTrack: (payload) => {
titles.push(payload.page as string);
},
},
],
});

tracker?.setDocumentTitle('Title override');
tracker?.trackPageView({
title: 'Explicit title',
});
tracker?.trackPageView();

expect(titles).toEqual(['Explicit title', 'Page title 1']);
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -89,8 +89,7 @@ describe('Snowplow Micro integration', () => {
platform: 'mob',
app_id: `sp-${method}-${testIdentifier}`,
user_id: 'Malcolm',
// The title is not correctly set due to #1332
// page_title: 'Integration test page',
page_title: 'Integration test page',
},
})
).toBe(true);
Expand Down

0 comments on commit 9fe9ee9

Please sign in to comment.