Skip to content

Commit

Permalink
MWPW-156793 [MILO][Analytics] Change char limit for headers based on …
Browse files Browse the repository at this point in the history
…MD (#2765)

* Add charlimit for headers analytics

* Fix header for integer value only

* Update libs/martech/attributes.js

set header length to false for clarity

Co-authored-by: Vivian A Goodrich <[email protected]>

* Add tests

* Refacter str null check per suggestion

* Fix test coverage

---------

Co-authored-by: Vivian A Goodrich <[email protected]>
  • Loading branch information
markpadbe and vgoodric authored Sep 2, 2024
1 parent 6362c19 commit 42d51a0
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 5 deletions.
16 changes: 13 additions & 3 deletions libs/martech/attributes.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { getMetadata } from '../utils/utils.js';

const INVALID_CHARACTERS = /[^\u00C0-\u1FFF\u2C00-\uD7FF\w]+/g;
const LEAD_UNDERSCORES = /^_+|_+$/g;

Expand All @@ -11,6 +13,13 @@ export function processTrackingLabels(text, config, charLimit) {
return analyticsValue;
}

function getHeaderCharLimit(str) {
const defaultLimit = 20;
if (!str) return defaultLimit;
if (str === 'off') return false;
if (!Number.isNaN(Number(str))) return parseInt(str, 10);
return defaultLimit;
}
export function decorateDefaultLinkAnalytics(block, config) {
if (block.classList.length
&& !block.className.includes('metadata')
Expand All @@ -20,20 +29,21 @@ export function decorateDefaultLinkAnalytics(block, config) {
let header = '';
let linkCount = 1;

const headerCharLimit = getHeaderCharLimit(getMetadata('analytics-header-limit'));
const headerSelector = 'h1, h2, h3, h4, h5, h6';
let analyticsSelector = `${headerSelector}, .tracking-header`;
const headers = block.querySelectorAll(analyticsSelector);
if (!headers.length) analyticsSelector = `${analyticsSelector}, b, strong`;
block.querySelectorAll(`${analyticsSelector}, a:not(.video.link-block), button`).forEach((item) => {
if (item.nodeName === 'A' || item.nodeName === 'BUTTON') {
if (item.classList.contains('tracking-header')) {
header = processTrackingLabels(item.textContent, config, 20);
header = processTrackingLabels(item.textContent, config, headerCharLimit);
} else if (!header) {
const section = block.closest('.section');
if (section?.className.includes('-up') || section?.classList.contains('milo-card-section')) {
const previousHeader = section?.previousElementSibling?.querySelector(headerSelector);
if (previousHeader) {
header = processTrackingLabels(previousHeader.textContent, config, 20);
header = processTrackingLabels(previousHeader.textContent, config, headerCharLimit);
}
}
}
Expand All @@ -59,7 +69,7 @@ export function decorateDefaultLinkAnalytics(block, config) {
if (item.nodeName === 'STRONG' || item.nodeName === 'B') {
item.classList.add('tracking-header');
}
header = processTrackingLabels(item.textContent, config, 20);
header = processTrackingLabels(item.textContent, config, headerCharLimit);
}
});
}
Expand Down
52 changes: 52 additions & 0 deletions test/martech/attributes.test.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
import { readFile } from '@web/test-runner-commands';
import { expect } from '@esm-bundle/chai';
import { decorateSectionAnalytics, processTrackingLabels } from '../../libs/martech/attributes.js';
import { createTag } from '../../libs/utils/utils.js';

const expectedLinkValues = [
'already-has-1',
'Traditional Link-2--Second Traditional H',
'Title Only Link-3--Tracking Header',
'Traditional Link-5--Button Tracking Head',
'After bold-1--Bold text',
'After strong-2--Strong text',
];
Expand Down Expand Up @@ -44,6 +46,56 @@ describe('Analytics', async () => {
expect(link.getAttribute('daa-ll')).to.equal(expectedLinkValues[idx]);
});
});
it('should limit analytics header length to analytics-header-limit when this metadata value is set to a number', async () => {
document.body.outerHTML = await readFile({ path: './mocks/body.html' });
const analyticsHeaderLimit = 2;
const meta = createTag('meta', { name: 'analytics-header-limit', content: analyticsHeaderLimit });
document.querySelector('head')?.append(meta);
document.querySelectorAll('main > div').forEach((section, idx) => decorateSectionAnalytics(section, idx, { mep: { martech: '|smb|hp' } }));
const section = document.querySelector('main > div');
section.querySelectorAll('a').forEach((link) => {
const daall = link.getAttribute('daa-ll');
const linkHeaderValue = daall.includes('--') && daall.split('--')[1];
if (linkHeaderValue) {
expect(linkHeaderValue.length).to.be.at.most(analyticsHeaderLimit);
}
});
});
it('should not limit analytics header length when metadata analytics-header-limit value set to off', async () => {
document.body.outerHTML = await readFile({ path: './mocks/body.html' });
const analyticsHeaderLimit = 'off';
document.querySelector('meta[name="analytics-header-limit"]')?.setAttribute('content', analyticsHeaderLimit);
document.querySelectorAll('main > div').forEach((section, idx) => decorateSectionAnalytics(section, idx, { mep: { martech: '|smb|hp' } }));
const headerText = document.querySelector('#block-with-header h3:nth-of-type(2)')?.textContent.trim();
const daall = document.querySelector('#block-with-header p:nth-of-type(2) a')?.getAttribute('daa-ll')?.split('--')[1];
expect(headerText).to.equal(daall);
});
it('should limit analytics header length to default when analytics-header-limit metadata value is empty', async () => {
const defaultValue = 20;
document.body.outerHTML = await readFile({ path: './mocks/body.html' });
const analyticsHeaderLimit = '';
document.querySelector('meta[name="analytics-header-limit"]')?.setAttribute('content', analyticsHeaderLimit);
document.querySelectorAll('main > div').forEach((section, idx) => decorateSectionAnalytics(section, idx, { mep: { martech: '|smb|hp' } }));
const daall = document.querySelector('#block-with-header p:nth-of-type(2) a')?.getAttribute('daa-ll')?.split('--')[1];
expect(daall.length).to.be.at.most(defaultValue);
});
it('should limit analytics header length to default when analytics-header-limit metadata value is incorrect', async () => {
const defaultValue = 20;
document.body.outerHTML = await readFile({ path: './mocks/body.html' });
const analyticsHeaderLimit = 'offs';
document.querySelector('meta[name="analytics-header-limit"]')?.setAttribute('content', analyticsHeaderLimit);
document.querySelectorAll('main > div').forEach((section, idx) => decorateSectionAnalytics(section, idx, { mep: { martech: '|smb|hp' } }));
const daall = document.querySelector('#block-with-header p:nth-of-type(2) a')?.getAttribute('daa-ll')?.split('--')[1];
expect(daall.length).to.be.at.most(defaultValue);
});
it('should limit analytics header length to default when no metadata', async () => {
const defaultValue = 20;
document.body.outerHTML = await readFile({ path: './mocks/body.html' });
document.querySelector('meta[name="analytics-header-limit"]').remove();
document.querySelectorAll('main > div').forEach((section, idx) => decorateSectionAnalytics(section, idx, { mep: { martech: '|smb|hp' } }));
const daall = document.querySelector('#block-with-header p:nth-of-type(2) a')?.getAttribute('daa-ll')?.split('--')[1];
expect(daall.length).to.be.at.most(defaultValue);
});
it('should process tracking labels', () => {
const longString = 'This is a long string that should be truncated';
const processedString = processTrackingLabels(longString, { locale: { ietf: 'en-US' } }, 20);
Expand Down
5 changes: 3 additions & 2 deletions test/martech/mocks/body.html
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ <h3>Second Traditional Header</h3>
<p><a href="/otherpage.html">Traditional Link</a></p>
<div class="tracking-header">Tracking Header</div>
<p><a href="/otherpage.html" title="Title Only Link"></a></p>
<button class="tracking-header">Button Tracking Header</button>
<p><a href="/otherpage.html">Traditional Link</a></p>
</div>
</div>
<div class="text" id="block-without-header" data-block="true">
Expand Down Expand Up @@ -56,6 +58,5 @@ <h3 id="ai-for-graphic-designers" class="consonant-HalfHeightCard-title">AI for
</div>
</div>
</div>
</main>
</main>
</body>

0 comments on commit 42d51a0

Please sign in to comment.