Skip to content

Commit

Permalink
Test getting GA4 client_id from GTAG API (mozilla#13898)
Browse files Browse the repository at this point in the history
* test getting GA4 id from GTMAPI
  • Loading branch information
stephaniehobson authored Jan 8, 2024
1 parent b9adaa9 commit ae79ff6
Show file tree
Hide file tree
Showing 2 changed files with 191 additions and 0 deletions.
108 changes: 108 additions & 0 deletions media/js/base/stub-attribution.js
Original file line number Diff line number Diff line change
Expand Up @@ -586,7 +586,115 @@ if (typeof window.Mozilla === 'undefined') {
}
}
});

// Wait for GTM to load the GTAG GET API so that we can pass along client and session ID
StubAttribution.waitForGTagAPI(function (data) {
var gtagData = data;

if (gtagData && StubAttribution.withinAttributionRate()) {
// GA4 - send an event indicating we did or did not get session ID from GTM
if (gtagData.client_id && gtagData.session_id) {
window.dataLayer.push({
event: 'stub_session_test',
label: 'session found'
});
} else {
window.dataLayer.push({
event: 'stub_session_test',
label: 'session not-found'
});
}
}
});
}
};

/**
* Attempts to retrieve the GA4 client and session ID from the dataLayer
* The GTAG GET API tag will write it to the dataLayer once GTM has loaded it
* https://www.simoahava.com/gtmtips/write-client-id-other-gtag-fields-datalayer/
*/
StubAttribution.getGtagData = function (dataLayer) {
dataLayer =
typeof dataLayer !== 'undefined' ? dataLayer : window.dataLayer;

var result = {
client_id: null,
session_id: null
};

var _findObject = function (name, obj) {
for (var key in obj) {
if (
typeof obj[key] === 'object' &&
Object.prototype.hasOwnProperty.call(obj, key)
) {
if (key === name) {
if (
typeof obj[key].client_id === 'string' &&
typeof obj[key].session_id === 'string'
) {
result = obj[key];
} else {
return result;
}
break;
} else {
_findObject(name, obj[key]);
}
}
}
};

try {
if (typeof dataLayer === 'object') {
dataLayer.forEach(function (layer) {
_findObject('gtagApiResult', layer);
});
}
} catch (error) {
// GA4
window.dataLayer.push({
event: 'stub_session_test',
label: 'error'
});
}

return result;
};

/**
* A crude check to see if GTAG GET API has been loaded by GTM. Periodically
* attempts to retrieve the client and session ID.
* @param {Function} callback
*/
StubAttribution.waitForGTagAPI = function (callback) {
var timeout;
var pollRetry = 0;
var interval = 100;
var limit = 20; // (100 x 20) / 1000 = 2 seconds

function _checkGtagAPI() {
clearTimeout(timeout);
var data = StubAttribution.getGtagData();

if (
typeof data === 'object' &&
typeof data.client_id === 'string' &&
typeof data.session_id === 'string'
) {
callback(data);
} else {
if (pollRetry <= limit) {
pollRetry += 1;
timeout = window.setTimeout(_checkGtagAPI, interval);
} else {
callback(false);
}
}
}

_checkGtagAPI();
};

window.Mozilla.StubAttribution = StubAttribution;
Expand Down
83 changes: 83 additions & 0 deletions tests/unit/spec/base/stub-attribution.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@

describe('stub-attribution.js', function () {
const GA_CLIENT_ID = '1456954538.1610960957';
const GA_SESSION_ID = '1668161374';
const STUB_SESSION_ID = '1234567890';
const DLSOURCE = 'mozorg';

Expand Down Expand Up @@ -1197,4 +1198,86 @@ describe('stub-attribution.js', function () {
expect(/^\d{10}$/.test(result)).toBeTruthy();
});
});

describe('getGtagData', function () {
it('should return a valid Google Analytics client ID and session ID', function () {
const dataLayer = [
{
event: 'page-id-loaded',
pageId: 'Homepage',
'gtm.uniqueEventId': 1
},
{
'gtm.start': 1678700450438,
event: 'gtm.js',
'gtm.uniqueEventId': 2
},
{
h: {
0: 'get',
1: 'G-YBFC8BJZW8',
2: 'client_id'
}
},
{
h: {
0: 'get',
1: 'G-YBFC8BJZW8',
2: 'session_id'
}
},
{
h: {
event: 'gtagApiGet',
gtagApiResult: {
client_id: GA_CLIENT_ID,
session_id: GA_SESSION_ID
},
'gtm.uniqueEventId': 11
}
},
{
event: 'gtm.dom',
'gtm.uniqueEventId': 12
},
{
event: 'gtm.load',
'gtm.uniqueEventId': 13
}
];

expect(Mozilla.StubAttribution.getGtagData(dataLayer)).toEqual({
client_id: GA_CLIENT_ID,
session_id: GA_SESSION_ID
});
});
});

it('should return null values if client ID and session ID are not found', function () {
const dataLayer = [
{
event: 'page-id-loaded',
pageId: 'Homepage',
'gtm.uniqueEventId': 1
},
{
'gtm.start': 1678700450438,
event: 'gtm.js',
'gtm.uniqueEventId': 2
},
{
event: 'gtm.dom',
'gtm.uniqueEventId': 12
},
{
event: 'gtm.load',
'gtm.uniqueEventId': 13
}
];

expect(Mozilla.StubAttribution.getGtagData(dataLayer)).toEqual({
client_id: null,
session_id: null
});
});
});

0 comments on commit ae79ff6

Please sign in to comment.