Remove "page ID" and "core page" code (#14913)

* Remove core page variables and dataLayer patch for UA/GA3 Fix #10733

Removes some code that supported our weird UA/GA3 setup including: page id, core page, dataLayer over-rides for click tracking, and variables indicating if a page has a video and download button.

- Remove: core-dataLayer.js and associated tests & init
- Functionality removed:
  - page-id
  - dataLayer "monkey patch" for UA
  - pageHasDownload, PageVersion, and releaseWindowVersion variables
- Removed jinja template code that supported the page-id JS
- Moved: amoExperiments to new files, converted to es6
This commit is contained in:
Stephanie Hobson 2024-09-03 10:31:57 -07:00 коммит произвёл GitHub
Родитель 554db18556
Коммит 8ff4c3d9c0
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: B5690EEEBB952194
29 изменённых файлов: 132 добавлений и 626 удалений

Просмотреть файл

@ -6,8 +6,6 @@
{% extends "base-error.html" %}
{% block gtm_page_id %}data-gtm-page-id="404"{% endblock %}
{% block page_title %}{{ ftl('not-found-page-not-found-page-page-not-found') }}{% endblock %}
{% block page_css %}

Просмотреть файл

@ -6,8 +6,6 @@
{% extends "base-error.html" %}
{% block gtm_page_id %}data-gtm-page-id="500"{% endblock %}
{% block page_title %}{{ ftl('error-page-error-page-internal-server-error') }}{% endblock %}
{% block page_css %}

Просмотреть файл

@ -6,7 +6,7 @@
<!doctype html>
{# Note the "windows" class, without javascript platform-specific assets default to windows #}
<html class="windows no-js" lang="{{ LANG|replace('en-US', 'en') }}" dir="{{ DIR }}" data-country-code="{{ country_code }}" data-needs-consent="{{ needs_data_consent(country_code) }}" data-latest-firefox="{{ latest_firefox_version }}" data-esr-versions="{{ esr_firefox_versions|join(' ') }}" {% if settings.GTM_CONTAINER_ID %}data-gtm-container-id="{{ settings.GTM_CONTAINER_ID }}"{% endif %} {% block gtm_page_id %}{% endblock %} {% if settings.STUB_ATTRIBUTION_RATE %}data-stub-attribution-rate="{{ settings.STUB_ATTRIBUTION_RATE }}"{% endif %} {% if settings.SENTRY_FRONTEND_DSN %}data-sentry-dsn="{{ settings.SENTRY_FRONTEND_DSN }}"{% endif %} {% block html_attrs %}{% endblock %}>
<html class="windows no-js" lang="{{ LANG|replace('en-US', 'en') }}" dir="{{ DIR }}" data-country-code="{{ country_code }}" data-needs-consent="{{ needs_data_consent(country_code) }}" data-latest-firefox="{{ latest_firefox_version }}" data-esr-versions="{{ esr_firefox_versions|join(' ') }}" {% if settings.GTM_CONTAINER_ID %}data-gtm-container-id="{{ settings.GTM_CONTAINER_ID }}"{% endif %} {% if settings.STUB_ATTRIBUTION_RATE %}data-stub-attribution-rate="{{ settings.STUB_ATTRIBUTION_RATE }}"{% endif %} {% if settings.SENTRY_FRONTEND_DSN %}data-sentry-dsn="{{ settings.SENTRY_FRONTEND_DSN }}"{% endif %} {% block html_attrs %}{% endblock %}>
<head>
<meta charset="utf-8">{# Note: Must be within first 512 bytes of page #}

Просмотреть файл

@ -16,12 +16,6 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1122305#c8
<!-- Site Container: NONE -->
{% if settings.GTM_CONTAINER_ID %}
<!--[if !IE]><!-->
{{ js_bundle('gtm-snippet') }}
<!--<![endif]-->
<!--[if IE 9]>
{{ js_bundle('gtm-snippet-ie') }}
<![endif]-->
{% endif %}
<!-- End Google Tag Manager -->

Просмотреть файл

@ -7,7 +7,6 @@
{% extends "firefox/releases/notes.html" %}
{% if release.product == 'Firefox for Android' %}
{% set page_id = 'data-gtm-page-id="/firefox/android/auroranotes/"' %}
{% set header_class = 'mzp-t-dark t-nightly' %}
{% set brand_product = 'nightly' %}
{% set download_button_primary %}
@ -18,7 +17,6 @@
{% endset %}
{% set download_all_link = firefox_url('android', 'all', channel='nightly') %}
{% elif release.product == 'Firefox' %}
{% set page_id = 'data-gtm-page-id="/firefox/auroranotes/"' %}
{% set header_class = 'mzp-t-dark' %}
{% set brand_product = 'developer t-aurora' %}
{% set download_title = 'Build, test, scale and more with the only browser built just for developers.' %}

Просмотреть файл

@ -10,7 +10,6 @@
{% set brand_product = 'beta' %}
{% if release.product == 'Firefox for Android' %}
{% set page_id = 'data-gtm-page-id="/firefox/android/beta/releasenotes"' %}
{% set download_button_primary %}
{{ download_firefox('beta', platform='android', alt_copy='Download Firefox for Android Beta', dom_id="download-android-beta-primary") }}
{% endset %}
@ -19,7 +18,6 @@
{% endset %}
{% set download_all_link = firefox_url('android', 'all', channel='beta') %}
{% elif release.product == 'Firefox' %}
{% set page_id = 'data-gtm-page-id="/firefox/beta/releasenotes/"' %}
{% set download_button_primary %}
{{ download_firefox('beta', platform='desktop', force_direct=True, alt_copy='Download Firefox Beta', dom_id="download-beta-primary") }}
{% endset %}

Просмотреть файл

@ -6,7 +6,6 @@
{% extends "firefox/releases/notes.html" %}
{% set page_id = 'data-gtm-page-id="/firefox/auroranotes/"' %}
{% set product_name = 'Firefox Developer Edition' %}
{% set header_class = 'mzp-t-dark t-developer' %}
{% set brand_product = 'developer' %}

Просмотреть файл

@ -6,8 +6,6 @@
{% extends "firefox/releases/notes.html" %}
{% set page_id ='data-gtm-page-id="/firefox/esr/releasenotes/"' %}
{% set download_button_primary %}
{{ download_firefox('esr', platform='desktop', force_direct=True, alt_copy='Download Firefox ESR', dom_id="download-esr-primary") }}
{% endset %}

Просмотреть файл

@ -21,7 +21,6 @@
{% set header_class = 'mzp-t-dark t-nightly' %}
{% set brand_product = 'nightly' %}
{% set page_id = 'data-gtm-page-id="/firefox/nightly/releasenotes"' %}
{% if release.is_latest %}
{% set primary_heading = 'See what landed recently in <span>Firefox Nightly</span>!'|safe %}

Просмотреть файл

@ -9,10 +9,6 @@
{% extends "firefox/base/base-protocol.html" %}
{# page ID for gtm #}
{# page_id may be over-ridden with more appropriate content #}
{% set page_id = page_id|default('data-gtm-page-id="/firefox/releasenotes/"') %}
{# product_name is the product and channel together. Example: Firefox for Android Beta. #}
{# product_name may be over-ridden with more appropriate content to avoid bad names like: Firefox Release Release #}
{% set product_name = product_name|default(release.product + ' ' + release.channel) %}
@ -43,7 +39,6 @@
{% block page_title_prefix %}{% endblock %}
{% block page_title %}{{ release.product }} {{ channel_name }} {{ release.version }}, See All New Features, Updates and Fixes{% endblock %}
{% block page_title_suffix %}{% endblock %}
{% block gtm_page_id %}{{ page_id }}{% endblock %}
{% block body_id %}notes{% endblock %}
{% block body_class %}mzp-t-firefox {{ theme_class }}{% endblock %}

Просмотреть файл

@ -8,7 +8,6 @@
{% from "macros.html" import google_play_button, apple_app_store_button with context %}
{% if release.product == 'Firefox for iOS' %}
{% set page_id = 'data-gtm-page-id="/firefox/ios/releasenotes/"' %}
{% set product_name = release.product %}
{% set download_button_primary %}
{{ apple_app_store_button(href=app_store_url('firefox', 'firefox-release-notes'), id='download-ios-primary') }}
@ -17,7 +16,6 @@
{{ apple_app_store_button(href=app_store_url('firefox', 'firefox-release-notes'), id='download-ios-secondary') }}
{% endset %}
{% elif release.product == 'Firefox for Android' %}
{% set page_id = 'data-gtm-page-id="/firefox/android/releasenotes/"' %}
{% set product_name = 'Firefox for Android' %}
{% set download_button_primary %}
{{ google_play_button(id='download-android-primary') }}

Просмотреть файл

@ -8,8 +8,6 @@
{% from "macros-protocol.html" import callout, callout_compact %}
{% block gtm_page_id %}data-gtm-page-id="/firefox/system-requirements/"{% endblock %}
{% set channel_name = '' if release.channel == 'Release' else release.channel %}
{% block page_title_prefix %}{% endblock %}

Просмотреть файл

@ -9,8 +9,6 @@
{# "noindex" pages should not have the canonical or hreflang tags: bug 1442331 #}
{% block canonical_urls %}<meta name="robots" content="noindex,follow">{% endblock %}
{% block gtm_page_id %}data-gtm-page-id="/firefox/whatsnew/"{% endblock %}
{# Exclude stub attribution for in-product pages: issus 9620 #}
{% block stub_attribution %}{% endblock %}

Просмотреть файл

@ -6,8 +6,6 @@
{% extends "base-protocol-mozilla.html" %}
{% block gtm_page_id %}data-gtm-page-id="Homepage"{% endblock %}
{% block extra_meta %}
<!-- validates bing webmaster tools -->
<meta name="msvalidate.01" content="B7B177115A634927D608514DA17B2574">

Просмотреть файл

@ -6,8 +6,6 @@
{% extends 'newsletter/base.html' %}
{% block gtm_page_id %}data-gtm-page-id="/newsletter/confirm/"{% endblock %}
{# "noindex" pages should not have the canonical or hreflang tags: bug 1442331 #}
{% block canonical_urls %}<meta name="robots" content="noindex,follow">{% endblock %}

Просмотреть файл

@ -6,8 +6,6 @@
{% extends 'newsletter/base.html' %}
{% block gtm_page_id %}data-gtm-page-id="/newsletter/country/"{% endblock %}
{# "noindex" pages should not have the canonical or hreflang tags: bug 1442331 #}
{% block canonical_urls %}<meta name="robots" content="noindex,follow">{% endblock %}

Просмотреть файл

@ -8,8 +8,6 @@
{# Template used for a user to manage their subscriptions #}
{% block gtm_page_id %}data-gtm-page-id="/newsletter/existing/"{% endblock %}
{# "noindex" pages should not have the canonical or hreflang tags: bug 1442331 #}
{% block canonical_urls %}<meta name="robots" content="noindex,follow">{% endblock %}

Просмотреть файл

@ -1,65 +0,0 @@
/*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
// init core dataLayer object and push into dataLayer
(function () {
'use strict';
var analytics = Mozilla.Analytics;
var client = Mozilla.Client;
var dataLayer = (window.dataLayer = window.dataLayer || []);
function sendCoreDataLayer() {
var dataLayerCore = {
event: 'core-datalayer-loaded',
pageHasDownload: analytics.pageHasDownload(),
pageVersion: analytics.getPageVersion(),
releaseWindowVersion: analytics.getLatestFxVersion()
};
dataLayer.push(dataLayerCore);
}
function initCoreDataLayer() {
if (client.isFirefoxDesktop || client.isFirefoxAndroid) {
client.getFirefoxDetails(function (details) {
dataLayer.push(details);
sendCoreDataLayer();
});
} else {
sendCoreDataLayer();
}
analytics.updateDataLayerPush();
}
// Init dataLayer event on DOM Ready.
if (typeof Mozilla.Utils !== 'undefined') {
Mozilla.Utils.onDocumentReady(function () {
initCoreDataLayer();
// Add GA custom dimension for AMO experiments (Issue 10175).
if (typeof window._SearchParams !== 'undefined') {
var params = new window._SearchParams().params;
var validParams = analytics.getAMOExperiment(params);
if (validParams) {
// UA
dataLayer.push({
'data-ex-name': validParams['experiment'],
'data-ex-variant': validParams['variation']
});
// GA4
dataLayer.push({
event: 'experiment_view',
id: validParams['experiment'],
variant: validParams['variation']
});
}
}
});
}
})();

Просмотреть файл

@ -1,46 +0,0 @@
/*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
if (typeof window.Mozilla === 'undefined') {
window.Mozilla = {};
}
(function (Mozilla) {
'use strict';
// init dataLayer object
var dataLayer = (window.dataLayer = window.dataLayer || []);
var Analytics = {};
/** Returns page ID used in Event Category for GA events tracked on page.
* @param {String} path - URL path name fallback if page ID does not exist.
* @return {String} GTM page ID.
*/
Analytics.getPageId = function (path) {
var pageId = document
.getElementsByTagName('html')[0]
.getAttribute('data-gtm-page-id');
var pathName = path ? path : document.location.pathname;
return pageId
? pageId
: pathName.replace(/^(\/\w{2}-\w{2}\/|\/\w{2,3}\/)/, '/');
};
Analytics.buildDataObject = function () {
var dataObj = {
event: 'page-id-loaded',
pageId: Analytics.getPageId()
};
return dataObj;
};
// Push page ID into dataLayer so it's ready when GTM container loads.
dataLayer.push(Analytics.buildDataObject());
Mozilla.Analytics = Analytics;
})(window.Mozilla);

Просмотреть файл

@ -1,118 +0,0 @@
/*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
/**
* Utility class for core dataLayer object to track contextual user and page data
*/
if (typeof window.Mozilla.Analytics === 'undefined') {
window.Mozilla.Analytics = {};
}
(function () {
'use strict';
var analytics = Mozilla.Analytics;
var isModernBrowser =
'querySelector' in document && 'querySelectorAll' in document;
/** Returns whether page has download button.
* @param {String} path - URL path name fallback if page ID does not exist.
* @return {String} string.
*/
analytics.pageHasDownload = function () {
if (!isModernBrowser) {
return 'false';
}
return document.querySelector('[data-download-os]') !== null
? 'true'
: 'false';
};
/** Returns page version.
* @param {String} path - URL path name fallback if page ID does not exist.
* @return {String} version number from URL.
*/
analytics.getPageVersion = function (path) {
var pathName = path ? path : document.location.pathname;
var versionResults = /firefox\/(\d+(?:\.\d+)?\.\da?\d?)/.exec(pathName);
return versionResults ? versionResults[1] : null;
};
/** Returns latest Fx version.
* @return {String} latest Fx version.
*/
analytics.getLatestFxVersion = function () {
return document
.getElementsByTagName('html')[0]
.getAttribute('data-latest-firefox');
};
analytics.getAMOExperiment = function (params) {
var allowedExperiment = /^\d{8}_amo_.[\w/.%-]{1,50}$/; // should match the format YYYYMMDD_amo_experiment_name.
var allowedVariation = /^[\w/.%-]{1,50}$/; // allow alpha numeric & common URL encoded chars.
if (
Object.prototype.hasOwnProperty.call(params, 'experiment') &&
Object.prototype.hasOwnProperty.call(params, 'variation')
) {
var experiment = decodeURIComponent(params['experiment']);
var variation = decodeURIComponent(params['variation']);
if (
allowedExperiment.test(experiment) &&
allowedVariation.test(variation)
) {
return {
experiment: experiment,
variation: variation
};
}
}
return null;
};
/** Monkey patch for dataLayer.push
* Adds href stripped of locale to link click objects when pushed to the dataLayer,
* also removes protocol and host if same as parent page from href.
*/
analytics.updateDataLayerPush = function (host) {
var dataLayer = (window.dataLayer = window.dataLayer || []);
var hostname = host || document.location.hostname;
dataLayer.defaultPush = dataLayer.push;
dataLayer.push = function () {
for (var i = 0; i < arguments.length; i++) {
if (arguments[i].event === 'gtm.linkClick') {
var element = arguments[i]['gtm.element'];
var href = element.href;
if (element.hostname === hostname) {
// remove host and locale from internal links
var path = href.replace(
/^(?:https?:\/\/)(?:[^/])*/,
''
);
var locale = path.match(
/^(\/\w{2}-\w{2}\/|\/\w{2,3}\/)/
);
path = locale ? path.replace(locale[0], '/') : path;
arguments[i].newClickHref = path;
} else {
arguments[i].newClickHref = href;
}
dataLayer.defaultPush(arguments[i]);
} else {
dataLayer.defaultPush(arguments[i]);
}
}
};
};
})();

Просмотреть файл

@ -0,0 +1,29 @@
/*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
import { getAMOExperiment } from './experiment-amo.es6.js';
const dataLayer = (window.dataLayer = window.dataLayer || []);
// Look for AMO experiment on DOM Ready.
if (typeof Mozilla.Utils !== 'undefined') {
Mozilla.Utils.onDocumentReady(() => {
// Add GA custom dimension for AMO experiments (Issue 10175).
if (typeof window._SearchParams !== 'undefined') {
const params = new window._SearchParams().params;
const validParams = getAMOExperiment(params);
if (validParams) {
// GA4
dataLayer.push({
event: 'experiment_view',
id: validParams['experiment'],
variant: validParams['variation']
});
}
}
});
}

Просмотреть файл

@ -0,0 +1,32 @@
/*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
function getAMOExperiment(params) {
const allowedExperiment = /^\d{8}_amo_.[\w/.%-]{1,50}$/; // should match the format YYYYMMDD_amo_experiment_name.
const allowedVariation = /^[\w/.%-]{1,50}$/; // allow alpha numeric & common URL encoded chars.
if (
Object.prototype.hasOwnProperty.call(params, 'experiment') &&
Object.prototype.hasOwnProperty.call(params, 'variation')
) {
const experiment = decodeURIComponent(params['experiment']);
const variation = decodeURIComponent(params['variation']);
if (
allowedExperiment.test(experiment) &&
allowedVariation.test(variation)
) {
return {
experiment: experiment,
variation: variation
};
}
}
return null;
}
export { getAMOExperiment };

Просмотреть файл

@ -1,70 +0,0 @@
/*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
import GTMSnippet from '../gtm-snippet.es6.js';
// Push page ID into dataLayer so it's ready when GTM container loads.
const dataLayer = (window.dataLayer = window.dataLayer || []);
/**
* Get the page ID from the data-gtm-page-id attribute on the html element.
* @returns {string} The page ID to be used in GTM.
*/
function getPageId() {
const pageId = document
.getElementsByTagName('html')[0]
.getAttribute('data-gtm-page-id');
const pathName = document.location.pathname;
return pageId
? pageId
: pathName.replace(/^(\/\w{2}-\w{2}\/|\/\w{2,3}\/)/, '/');
}
/**
* Monkey patch for dataLayer.push
* Adds href stripped of locale to link click objects when pushed to the dataLayer,
* also removes protocol and host if same as parent page from href.
*/
function updateDataLayerPush() {
const dataLayer = (window.dataLayer = window.dataLayer || []);
const hostname = document.location.hostname;
dataLayer.defaultPush = dataLayer.push;
dataLayer.push = function () {
for (let i = 0; i < arguments.length; i++) {
if (arguments[i].event === 'gtm.linkClick') {
const element = arguments[i]['gtm.element'];
const href = element.href;
if (element.hostname === hostname) {
// remove host and locale from internal links
let path = href.replace(/^(?:https?:\/\/)(?:[^/])*/, '');
const locale = path.match(/^(\/\w{2}-\w{2}\/|\/\w{2,3}\/)/);
path = locale ? path.replace(locale[0], '/') : path;
arguments[i].newClickHref = path;
} else {
arguments[i].newClickHref = href;
}
dataLayer.defaultPush(arguments[i]);
} else {
dataLayer.defaultPush(arguments[i]);
}
}
};
}
dataLayer.push({
event: 'page-id-loaded',
pageId: getPageId()
});
GTMSnippet.init();
// Monkey patch dataLayer.push() click events
updateDataLayerPush();

Просмотреть файл

@ -9,6 +9,10 @@ import { isApprovedToRun } from '../../base/experiment-utils.es6.js';
const href = window.location.href;
if (typeof window.dataLayer === 'undefined') {
window.dataLayer = [];
}
const init = () => {
if (href.indexOf('v=1') !== -1) {
window.dataLayer.push({

Просмотреть файл

@ -1256,8 +1256,7 @@
"files": [
"js/base/site.js",
"js/base/consent/privacy-helpers.js",
"js/base/mozilla-cookie-helper.js",
"js/base/core-datalayer-page-id.js"
"js/base/mozilla-cookie-helper.js"
],
"name": "site"
},
@ -1447,12 +1446,6 @@
],
"name": "gtm-snippet"
},
{
"files": [
"js/base/gtm/ie/gtm-snippet-ie-init.es6.js"
],
"name": "gtm-snippet-ie"
},
{
"files": [
"js/base/protocol/init-sidemenu.es6.js"
@ -1616,8 +1609,8 @@
},
{
"files": [
"js/base/core-datalayer.js",
"js/base/core-datalayer-init.js",
"js/base/experiment-amo.es6.js",
"js/base/experiment-amo-init.es6.js",
"js/base/datalayer-productdownload-init.es6.js"
],
"name": "data"

Просмотреть файл

@ -1,39 +0,0 @@
/*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
/* For reference read the Jasmine and Sinon docs
* Jasmine docs: https://jasmine.github.io/
* Sinon docs: http://sinonjs.org/docs/
*/
describe('core-datalayer-page-id.js', function () {
describe('getPageId', function () {
const html = document.documentElement;
afterEach(function () {
html.removeAttribute('data-gtm-page-id');
});
it('will grab data-gtm-page-id value if present on <html> element', function () {
html.setAttribute('data-gtm-page-id', 'test');
expect(Mozilla.Analytics.getPageId('/en-US/firefox/new/')).toBe(
'test'
);
});
it('will grab the pathname minus the first directory if no data-gtm-page-id value is present on <html> element', function () {
expect(Mozilla.Analytics.getPageId('/en-US/firefox/new/')).toBe(
'/firefox/new/'
);
});
it('will return the full page path when no data-gtm-page-id value is present and no locale is in page path', function () {
expect(Mozilla.Analytics.getPageId('/firefox/new/')).toBe(
'/firefox/new/'
);
});
});
});

Просмотреть файл

@ -1,238 +0,0 @@
/*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
/* For reference read the Jasmine and Sinon docs
* Jasmine docs: https://jasmine.github.io/
* Sinon docs: http://sinonjs.org/docs/
*/
describe('core-datalayer.js', function () {
describe('pageHasDownload', function () {
it('will return "true" when download button is present on page.', function () {
const downloadMarkup =
'<a class="download" href="#" data-link-type="download" data-download-os="Desktop">';
document.body.insertAdjacentHTML('beforeend', downloadMarkup);
expect(Mozilla.Analytics.pageHasDownload()).toBe('true');
const content = document.querySelector('.download');
content.parentNode.removeChild(content);
});
it('will return "false" when download button is not present on page.', function () {
expect(Mozilla.Analytics.pageHasDownload()).toBe('false');
});
});
describe('getPageVersion', function () {
it('will return the Firefox version number form the URL if present', function () {
expect(
Mozilla.Analytics.getPageVersion(
'https://www.mozilla.org/en-US/firefox/107.0.11/firstrun/'
)
).toBe('107.0.11');
expect(
Mozilla.Analytics.getPageVersion(
'https://www.mozilla.org/en-US/firefox/46.0.1/firstrun/learnmore/'
)
).toBe('46.0.1');
expect(
Mozilla.Analytics.getPageVersion(
'https://www.mozilla.org/en-US/firefox/11.0/whatsnew/'
)
).toBe('11.0');
expect(
Mozilla.Analytics.getPageVersion(
'https://www.mozilla.org/en-US/firefox/46.0.1a2/firstrun/'
)
).toBe('46.0.1a2');
expect(
Mozilla.Analytics.getPageVersion(
'https://www.mozilla.org/en-US/firefox/46.0a1/whatsnew/'
)
).toBe('46.0a1');
});
it('will return null if no version number present in URL', function () {
expect(
Mozilla.Analytics.getPageVersion(
'https://www.mozilla.org/en-US/'
)
).toBeNull();
expect(
Mozilla.Analytics.getPageVersion(
'https://www.mozilla.org/en-US/firefox/new'
)
).toBeNull();
expect(
Mozilla.Analytics.getPageVersion(
'https://www.mozilla.org/en-US/firefox/whatsnew'
)
).toBeNull();
});
});
describe('getLatestFxVersion', function () {
afterEach(function () {
document
.getElementsByTagName('html')[0]
.removeAttribute('data-latest-firefox');
});
it('will return the Firefox version from the data-latest-firefox attribute from the html element if present', function () {
document
.getElementsByTagName('html')[0]
.setAttribute('data-latest-firefox', '48.0');
expect(Mozilla.Analytics.getLatestFxVersion()).toBe('48.0');
});
it('will return null if no data-latest-firefox attribute is present on the html element', function () {
expect(Mozilla.Analytics.getLatestFxVersion()).toBe(null);
});
});
describe('getAMOExperiment', function () {
it('should return true when experiment and variation params are well formatted', function () {
const params = {
experiment: '20210708_amo_experiment_name',
variation: 'variation_1_name'
};
expect(Mozilla.Analytics.getAMOExperiment(params)).toEqual(params);
});
it('should return falsy when experiment and variation params are not specific to amo', function () {
const params = {
experiment: 'some_other_experiment',
variation: 'variation_1_name'
};
expect(Mozilla.Analytics.getAMOExperiment(params)).toBeFalsy();
});
it('should return falsy when experiment and variation params contain dangerous characters', function () {
const params = {
experiment: '20210708_amo_"><h1>hello</h1>',
variation: '<script>alert("test");</script>'
};
expect(Mozilla.Analytics.getAMOExperiment(params)).toBeFalsy();
const params2 = {
experiment: '20210708_amo_%22%3E%3Ch1%3Ehello%3C%2Fh1%3E',
variation: '%3Cscript%3Ealert%28%22test%22%29%3B%3C%2Fscript%3E'
};
expect(Mozilla.Analytics.getAMOExperiment(params2)).toBeFalsy();
});
it('should return falsy if parameters values are more than 50 chars', function () {
const params = {
experiment: '20210708_amo_experiment_name',
variation:
'a_very_very_very_very_very_long_experiment_variation_name_much_much_much_more_than_50_chars'
};
expect(Mozilla.Analytics.getAMOExperiment(params)).toBeFalsy();
const params2 = {
experiment:
'20210708_amo_a_very_very_very_long_experiment_name_much_much_much_much_more_than_50_chars',
variation: 'variation_1_name'
};
expect(Mozilla.Analytics.getAMOExperiment(params2)).toBeFalsy();
});
});
describe('updateDataLayerPush', function () {
beforeEach(function () {
const link =
'<a id="link" href="https://www.mozilla.org/en-US/firefox/new/">';
document.body.insertAdjacentHTML('beforeend', link);
window.dataLayer = [];
});
afterEach(function () {
const content = document.getElementById('link');
content.parentNode.removeChild(content);
delete window.dataLayer;
});
it('will add newClickHref property to link click object when pushed to the dataLayer', function () {
Mozilla.Analytics.updateDataLayerPush('www.allizom.org');
window.dataLayer.push({
event: 'gtm.linkClick',
'gtm.element': document.getElementById('link')
});
expect(window.dataLayer[0].newClickHref).toBeDefined();
});
it('will not add newClickHref property to object pushed to dataLayer if not a link click object', function () {
Mozilla.Analytics.updateDataLayerPush('www.allizom.org');
window.dataLayer.push({
event: 'gtm.click',
'gtm.element': document.getElementById('link')
});
expect(window.dataLayer[0].newClickHref).toBeUndefined();
});
it("will keep host in newClickHref when clicked link's href host value is different thatn the page's", function () {
Mozilla.Analytics.updateDataLayerPush('www.allizom.org');
window.dataLayer.push({
event: 'gtm.linkClick',
'gtm.element': document.getElementById('link')
});
expect(window.dataLayer[0].newClickHref).toEqual(
'https://www.mozilla.org/en-US/firefox/new/'
);
});
it("will remove host and locale in newClickHref when clicked link's href value matches the page's", function () {
const link = document.getElementById('link');
Mozilla.Analytics.updateDataLayerPush('www.mozilla.org');
// Bug 1278426
link.href = 'https://www.mozilla.org:443/en-US/firefox/new/';
window.dataLayer.push({
event: 'gtm.linkClick',
'gtm.element': link
});
expect(window.dataLayer[0].newClickHref).toEqual('/firefox/new/');
});
it('will remove host and non-en-US locale', function () {
const link = document.getElementById('link');
Mozilla.Analytics.updateDataLayerPush('www.mozilla.org');
link.href = 'https://www.mozilla.org:443/de/firefox/new/';
window.dataLayer.push({
event: 'gtm.linkClick',
'gtm.element': link
});
expect(window.dataLayer[0].newClickHref).toEqual('/firefox/new/');
});
it('will not remove locale if absent from the URL', function () {
const link = document.getElementById('link');
Mozilla.Analytics.updateDataLayerPush('www.mozilla.org');
link.href = 'https://www.mozilla.org/firefox/new/';
window.dataLayer.push({
event: 'gtm.linkClick',
'gtm.element': link
});
expect(window.dataLayer[0].newClickHref).toEqual('/firefox/new/');
});
});
});

Просмотреть файл

@ -0,0 +1,62 @@
/*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
/* For reference read the Jasmine and Sinon docs
* Jasmine docs: https://jasmine.github.io/
* Sinon docs: http://sinonjs.org/docs/
*/
import { getAMOExperiment } from '../../../../media/js/base/experiment-amo.es6';
describe('experiment-amo.js', function () {
describe('getAMOExperiment', function () {
it('should return true when experiment and variation params are well formatted', function () {
const params = {
experiment: '20210708_amo_experiment_name',
variation: 'variation_1_name'
};
expect(getAMOExperiment(params)).toEqual(params);
});
it('should return falsy when experiment and variation params are not specific to amo', function () {
const params = {
experiment: 'some_other_experiment',
variation: 'variation_1_name'
};
expect(getAMOExperiment(params)).toBeFalsy();
});
it('should return falsy when experiment and variation params contain dangerous characters', function () {
const params = {
experiment: '20210708_amo_"><h1>hello</h1>',
variation: '<script>alert("test");</script>'
};
expect(getAMOExperiment(params)).toBeFalsy();
const params2 = {
experiment: '20210708_amo_%22%3E%3Ch1%3Ehello%3C%2Fh1%3E',
variation: '%3Cscript%3Ealert%28%22test%22%29%3B%3C%2Fscript%3E'
};
expect(getAMOExperiment(params2)).toBeFalsy();
});
it('should return falsy if parameters values are more than 50 chars', function () {
const params = {
experiment: '20210708_amo_experiment_name',
variation:
'a_very_very_very_very_very_long_experiment_variation_name_much_much_much_more_than_50_chars'
};
expect(getAMOExperiment(params)).toBeFalsy();
const params2 = {
experiment:
'20210708_amo_a_very_very_very_long_experiment_name_much_much_much_much_more_than_50_chars',
variation: 'variation_1_name'
};
expect(getAMOExperiment(params2)).toBeFalsy();
});
});
});

Просмотреть файл

@ -20,8 +20,7 @@ module.exports = {
'media/js/base/search-params.js',
'media/js/base/mozilla-cookie-helper.js',
'media/js/base/mozilla-run.js',
'media/js/base/core-datalayer-page-id.js',
'media/js/base/core-datalayer.js',
'media/js/base/experiment-amo.es6.js',
'media/js/base/mozilla-fxa.js',
'media/js/base/mozilla-smoothscroll.js',
'media/js/base/stub-attribution/stub-attribution.js',