diff --git a/.github/workflows/label-zero-impact.yaml b/.github/workflows/label-zero-impact.yaml index b6dd810c09..d0ce919246 100644 --- a/.github/workflows/label-zero-impact.yaml +++ b/.github/workflows/label-zero-impact.yaml @@ -1,7 +1,7 @@ name: Add or remove zero impact label on: - pull_request: + pull_request_target: types: [opened, synchronize, reopened, labeled, unlabeled] jobs: diff --git a/libs/blocks/merch-card/merch-card.js b/libs/blocks/merch-card/merch-card.js index cd71b33a6a..6a084c25af 100644 --- a/libs/blocks/merch-card/merch-card.js +++ b/libs/blocks/merch-card/merch-card.js @@ -47,7 +47,7 @@ const isHeadingTag = (tagName) => /^H[2-5]$/.test(tagName); const isParagraphTag = (tagName) => tagName === 'P'; const appendSlot = (slotEls, slotName, merchCard) => { - if (slotEls.length === 0 && merchCard.variant !== MINI_COMPARE_CHART) return; + if (slotEls.length === 0 || merchCard.variant !== MINI_COMPARE_CHART) return; const newEl = createTag( 'p', { slot: slotName, class: slotName }, diff --git a/libs/blocks/modal/modal.js b/libs/blocks/modal/modal.js index 5520cf04bc..586861c4df 100644 --- a/libs/blocks/modal/modal.js +++ b/libs/blocks/modal/modal.js @@ -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: {}, @@ -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'); diff --git a/libs/features/georoutingv2/georoutingv2.js b/libs/features/georoutingv2/georoutingv2.js index bc64153e99..5adadb6da2 100644 --- a/libs/features/georoutingv2/georoutingv2.js +++ b/libs/features/georoutingv2/georoutingv2.js @@ -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`)); - } }); } @@ -149,7 +148,7 @@ 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; } @@ -157,7 +156,7 @@ function openPicker(button, locales, country, event, 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); }); @@ -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); @@ -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`), ); diff --git a/libs/utils/utils.js b/libs/utils/utils.js index fc39d9017c..8c2103ca49 100644 --- a/libs/utils/utils.js +++ b/libs/utils/utils.js @@ -954,16 +954,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'); diff --git a/test/blocks/modals/modals.test.js b/test/blocks/modals/modals.test.js index 12671d4deb..54fd2c05a9 100644 --- a/test/blocks/modals/modals.test.js +++ b/test/blocks/modals/modals.test.js @@ -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'; @@ -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(() => { @@ -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(); @@ -221,7 +223,6 @@ 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; @@ -229,3 +230,26 @@ describe('Modals', () => { 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; + }); +});