Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MWPW-147741 [Geo-Routing] Need to load modal after bootstrap in order to ensure Analytics fires #2399

Merged
merged 10 commits into from
Jun 6, 2024
13 changes: 12 additions & 1 deletion libs/blocks/modal/modal.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ export function findDetails(hash, el) {
return { id, path, isHash: hash === window.location.hash };
}

export function sendAnalytics(event) {
function fireAnalyticsEvent(event) {
// eslint-disable-next-line no-underscore-dangle
window._satellite?.track('event', {
xdm: {},
Expand All @@ -30,6 +30,17 @@ export function sendAnalytics(event) {
});
}

export function sendAnalytics(event) {
// eslint-disable-next-line no-underscore-dangle
if (window._satellite?.track) {
fireAnalyticsEvent(event);
} else {
window.addEventListener('alloy_sendEvent', () => {
fireAnalyticsEvent(event);
}, { once: true });
}
}

export function closeModal(modal) {
const { id } = modal;
const closeEvent = new Event('milo:modal:closed');
Expand Down
24 changes: 12 additions & 12 deletions libs/features/georoutingv2/georoutingv2.js
Original file line number Diff line number Diff line change
Expand Up @@ -102,18 +102,17 @@ function getGeoroutingOverride() {
return georouting === 'off';
}

function decorateForOnLinkClick(link, urlPrefix, localePrefix) {
function decorateForOnLinkClick(link, urlPrefix, localePrefix, eventType = 'Switch') {
const modCurrPrefix = localePrefix || 'us';
const modPrefix = urlPrefix || 'us';
const eventName = `${eventType}:${modPrefix.split('_')[0]}-${modCurrPrefix.split('_')[0]}|Geo_Routing_Modal`;
link.setAttribute('daa-ll', eventName);
link.addEventListener('click', () => {
const modPrefix = urlPrefix || 'us';
// set cookie so legacy code on adobecom still works properly.
const domain = window.location.host === 'adobe.com'
|| window.location.host.endsWith('.adobe.com') ? 'domain=adobe.com' : '';
document.cookie = `international=${modPrefix};path=/;${domain}`;
link.closest('.dialog-modal').dispatchEvent(new Event('closeModal'));
if (localePrefix !== undefined) {
const modCurrPrefix = localePrefix || 'us';
sendAnalyticsFunc(new Event(`Stay:${modPrefix.split('_')[0]}-${modCurrPrefix.split('_')[0]}|Geo_Routing_Modal`));
}
});
}

Expand Down Expand Up @@ -149,15 +148,15 @@ function removeOnClickOutsideElement(element, event, button) {
document.addEventListener('click', func);
}

function openPicker(button, locales, country, event, dir) {
function openPicker(button, locales, country, event, dir, currentPage) {
if (document.querySelector('.locale-modal-v2 .picker')) {
return;
}
const list = createTag('ul', { class: 'picker', dir });
locales.forEach((l) => {
const lang = config.locales[l.prefix]?.ietf ?? '';
const a = createTag('a', { lang, href: l.url }, `${country} - ${l.language}`);
decorateForOnLinkClick(a, l.prefix);
decorateForOnLinkClick(a, l.prefix, currentPage.prefix);
const li = createTag('li', {}, a);
list.appendChild(li);
});
Expand Down Expand Up @@ -208,15 +207,15 @@ function buildContent(currentPage, locale, geoData, locales) {
span.appendChild(downArrow);
mainAction.addEventListener('click', (e) => {
e.preventDefault();
openPicker(mainAction, locales, locale.button, e, dir);
openPicker(mainAction, locales, locale.button, e, dir, currentPage);
});
} else {
mainAction.href = locale.url;
decorateForOnLinkClick(mainAction, locale.prefix);
decorateForOnLinkClick(mainAction, locale.prefix, currentPage.prefix);
}

const altAction = createTag('a', { lang, href: currentPage.url }, currentPage.button);
decorateForOnLinkClick(altAction, currentPage.prefix, locale.prefix);
decorateForOnLinkClick(altAction, currentPage.prefix, locale.prefix, 'Stay');
const linkWrapper = createTag('div', { class: 'link-wrapper' }, mainAction);
linkWrapper.appendChild(altAction);
fragment.append(title, text, linkWrapper);
Expand Down Expand Up @@ -320,12 +319,13 @@ export default async function loadGeoRouting(

// Show modal when derived countries from url locale and akamai disagree
try {
const akamaiCode = await getAkamaiCode();
let akamaiCode = await getAkamaiCode();
if (akamaiCode && !getCodes(urlGeoData).includes(akamaiCode)) {
const localeMatches = getMatches(json.georouting.data, akamaiCode);
const details = await getDetails(urlGeoData, localeMatches, json.geos.data);
if (details) {
await showModal(details);
if (akamaiCode === 'gb') akamaiCode = 'uk';
sendAnalyticsFunc(
new Event(`Load:${urlLocale || 'us'}-${akamaiCode || 'us'}|Geo_Routing_Modal`),
);
Expand Down
18 changes: 11 additions & 7 deletions libs/utils/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -829,7 +829,11 @@ export async function loadIms() {
return imsLoaded;
}

export async function loadMartech({ persEnabled = false, persManifests = [] } = {}) {
export async function loadMartech({
persEnabled = false,
persManifests = [],
postLCP = false,
} = {}) {
// eslint-disable-next-line no-underscore-dangle
if (window.marketingtech?.adobe?.launch && window._satellite) {
return true;
Expand All @@ -844,7 +848,7 @@ export async function loadMartech({ persEnabled = false, persManifests = [] } =
loadIms().catch(() => {});

const { default: initMartech } = await import('../martech/martech.js');
await initMartech({ persEnabled, persManifests });
await initMartech({ persEnabled, persManifests, postLCP });

return true;
}
Expand Down Expand Up @@ -937,16 +941,16 @@ async function checkForPageMods() {
}

async function loadPostLCP(config) {
const georouting = getMetadata('georouting') || config.geoRouting;
if (georouting === 'on') {
const { default: loadGeoRouting } = await import('../features/georoutingv2/georoutingv2.js');
await loadGeoRouting(config, createTag, getMetadata, loadBlock, loadStyle);
}
if (config.mep?.targetEnabled === 'gnav') {
await loadMartech({ persEnabled: true, postLCP: true });
} else {
loadMartech();
}
const georouting = getMetadata('georouting') || config.geoRouting;
if (georouting === 'on') {
const { default: loadGeoRouting } = await import('../features/georoutingv2/georoutingv2.js');
await loadGeoRouting(config, createTag, getMetadata, loadBlock, loadStyle);
}
const header = document.querySelector('header');
if (header) {
header.classList.add('gnav-hide');
Expand Down
32 changes: 28 additions & 4 deletions test/blocks/modals/modals.test.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/* eslint-disable no-underscore-dangle */
import { readFile, sendKeys } from '@web/test-runner-commands';
import { expect } from '@esm-bundle/chai';
import sinon from 'sinon';
Expand All @@ -9,12 +10,14 @@ const {
getModal,
getHashParams,
delayedModal,
sendAnalytics,
} = await import('../../../libs/blocks/modal/modal.js');
const satellite = { track: sinon.spy() };

describe('Modals', () => {
beforeEach(() => {
// eslint-disable-next-line no-underscore-dangle
window._satellite = { track: sinon.spy() };
window._satellite = satellite;
window._satellite.track.called = false;
});

afterEach(() => {
Expand Down Expand Up @@ -208,7 +211,6 @@ describe('Modals', () => {
expect(modal).to.be.not.null;
expect(document.querySelector('#delayed-modal').classList.contains('delayed-modal'));
expect(window.sessionStorage.getItem('shown:#delayed-modal').includes(window.location.pathname)).to.be.true;
// eslint-disable-next-line no-underscore-dangle
expect(window._satellite.track.called).to.be.true;
window.sessionStorage.removeItem('shown:#delayed-modal');
modal.remove();
Expand All @@ -221,11 +223,33 @@ describe('Modals', () => {
window.sessionStorage.setItem('shown:#dm', window.location.pathname);
expect(delayedModal(el)).to.be.true;
await delay(1000);
// eslint-disable-next-line no-underscore-dangle
expect(window._satellite.track.called).to.be.false;
const modal = document.querySelector('#dm');
expect(modal).to.not.exist;
window.sessionStorage.removeItem('shown:#dm');
el.remove();
});
});

describe('sendAnalytics', () => {
afterEach(() => {
sinon.restore();
});

it('satellite event not set, so must use event listener', async () => {
window._satellite = false;
sendAnalytics({});
window._satellite = satellite;
window._satellite.track.called = false;
const martechEvent = new Event('alloy_sendEvent');
dispatchEvent(martechEvent);
expect(window._satellite.track.called).to.be.true;
});

it('satellite event set, so can fire load event immediately', async () => {
window._satellite = satellite;
window._satellite.track.called = false;
sendAnalytics({});
expect(window._satellite.track.called).to.be.true;
});
});
Loading