@guardian/ophan-tracker-js 2.2.4 → 2.2.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -41,28 +41,43 @@ const getDataLinkNames = (el, dataLinkNames = []) => {
41
41
  };
42
42
  if (typeof document.addEventListener === 'function') {
43
43
  document.addEventListener('click', function (e) {
44
- let anchorTarget, info;
45
- anchorTarget = validAncestorAnchorElement(e.target);
46
- if (!anchorTarget) {
47
- // If no anchor element was clicked, exit early.
44
+ let target = e.target;
45
+ let info;
46
+ // For anchors, use validAncestorAnchorElement
47
+ const anchorTarget = validAncestorAnchorElement(target);
48
+ const nonTrackableElements = [
49
+ 'div',
50
+ 'span',
51
+ 'p',
52
+ 'section',
53
+ 'article',
54
+ 'main',
55
+ 'header',
56
+ 'footer',
57
+ 'nav',
58
+ ];
59
+ if (nonTrackableElements.includes(target.tagName.toLowerCase()) &&
60
+ !anchorTarget) {
48
61
  return;
49
62
  }
63
+ // If it's an anchor, use anchorTarget, otherwise use the original target
64
+ const trackingTarget = anchorTarget || target;
50
65
  info = {
51
66
  from: [location.protocol, '//', location.host, location.pathname].join(''),
52
- to: anchorTarget ? anchorTarget.href : void 0,
53
- referringComponent: getContainingComponent(e.target),
54
- referringDataLinkNames: getDataLinkNames(e.target),
67
+ to: trackingTarget.href || undefined,
68
+ referringComponent: getContainingComponent(trackingTarget),
69
+ referringDataLinkNames: getDataLinkNames(trackingTarget),
55
70
  refPlatform: ophan.servingPlatform(),
56
71
  refViewId: ophan.viewId,
57
72
  };
58
- if (info.referringDataLinkNames != null) {
73
+ if (info.referringDataLinkNames && info.referringDataLinkNames.length > 0) {
59
74
  transmit.sendMore({
60
75
  clickComponent: info.referringComponent,
61
76
  clickLinkNames: info.referringDataLinkNames,
62
77
  });
63
78
  }
64
- if (anchorTarget != null) {
65
- // then we may be about to navigate away from this page, so store to send on next request
79
+ if (anchorTarget) {
80
+ // If it's an anchor, we may be about to navigate away from this page, so store to send on next request
66
81
  return ophan.storeDataToSendOnNextEvent(info);
67
82
  }
68
83
  }, false);
@@ -1,4 +1,4 @@
1
- import clickPathCapture, { getContainingComponent, validAncestorAnchorElement } from '../click-path-capture.js';
1
+ import clickPathCapture, { getContainingComponent, validAncestorAnchorElement, } from '../click-path-capture.js';
2
2
  import ophan from '../core.js';
3
3
  import transmit from '../transmit.js';
4
4
  const { getDataLinkNames } = clickPathCapture;
@@ -11,6 +11,8 @@ describe('click-path-capture.js', () => {
11
11
  <span id="testElement1"></span>
12
12
  </a>
13
13
  <span id="nonLinkElement">Non-link element</span>
14
+ <button id="testButton" data-link-name="buttonLink" data-component="buttonComponent">Click Me</button>
15
+ <label id="testLabel" data-link-name="labelLink" data-component="labelComponent">Label Text</label>
14
16
  </div>
15
17
  </div>
16
18
  <div id="testElement2" data-component="component2"></div>
@@ -46,7 +48,7 @@ describe('click-path-capture.js', () => {
46
48
  </div>
47
49
  `;
48
50
  const element = document.getElementById('testElement1');
49
- expect(getContainingComponent(element)).toBe("nested-component");
51
+ expect(getContainingComponent(element)).toBe('nested-component');
50
52
  });
51
53
  });
52
54
  describe('getDataLinkNames', () => {
@@ -62,8 +64,13 @@ describe('click-path-capture.js', () => {
62
64
  describe('click event handling', () => {
63
65
  let transmitSendMoreSpy, ophanStoreDataToSendOnNextEventSpy;
64
66
  beforeEach(() => {
65
- transmitSendMoreSpy = jest.spyOn(transmit, 'sendMore').mockImplementation(() => { });
66
- ophanStoreDataToSendOnNextEventSpy = jest.spyOn(ophan, 'storeDataToSendOnNextEvent').mockImplementation(() => { });
67
+ jest.clearAllMocks();
68
+ transmitSendMoreSpy = jest
69
+ .spyOn(transmit, 'sendMore')
70
+ .mockImplementation(() => { });
71
+ ophanStoreDataToSendOnNextEventSpy = jest
72
+ .spyOn(ophan, 'storeDataToSendOnNextEvent')
73
+ .mockImplementation(() => { });
67
74
  });
68
75
  afterEach(() => {
69
76
  jest.clearAllMocks();
@@ -71,9 +78,36 @@ describe('click-path-capture.js', () => {
71
78
  test('should send request and store data when a link is clicked', () => {
72
79
  const element = document.getElementById('testElement1');
73
80
  element.click();
74
- expect(transmitSendMoreSpy).toHaveBeenCalled();
81
+ expect(transmitSendMoreSpy).toHaveBeenCalledWith({
82
+ clickComponent: 'component1',
83
+ clickLinkNames: ['link1'],
84
+ });
75
85
  expect(ophanStoreDataToSendOnNextEventSpy).toHaveBeenCalled();
76
86
  });
87
+ test('should send request but not store data when a button is clicked', () => {
88
+ const element = document.getElementById('testButton');
89
+ element.click();
90
+ expect(transmitSendMoreSpy).toHaveBeenCalledWith({
91
+ clickComponent: 'buttonComponent',
92
+ clickLinkNames: ['buttonLink'],
93
+ });
94
+ expect(ophanStoreDataToSendOnNextEventSpy).not.toHaveBeenCalled();
95
+ });
96
+ test('should send request but not store data when a label is clicked', () => {
97
+ const element = document.getElementById('testLabel');
98
+ element.click();
99
+ expect(transmitSendMoreSpy).toHaveBeenCalledWith({
100
+ clickComponent: 'labelComponent',
101
+ clickLinkNames: ['labelLink'],
102
+ });
103
+ expect(ophanStoreDataToSendOnNextEventSpy).not.toHaveBeenCalled();
104
+ });
105
+ test('should not send request when a non-trackable element is clicked', () => {
106
+ const element = document.getElementById('nonLinkElement');
107
+ element.click();
108
+ expect(transmitSendMoreSpy).not.toHaveBeenCalled();
109
+ expect(ophanStoreDataToSendOnNextEventSpy).not.toHaveBeenCalled();
110
+ });
77
111
  test('should not send request when a non-link element within a container is clicked', () => {
78
112
  const element = document.getElementById('testElement4');
79
113
  element.click();
@@ -1,12 +1,12 @@
1
- import type { Consent } from './consent.js';
1
+ import type { AbTestInfo } from './abtest.js';
2
+ import type { Acquisition } from './acquisition.js';
2
3
  import type { ComponentEvent } from './component-event.js';
4
+ import type { Consent } from './consent.js';
3
5
  import type { InPageClick } from './inpageclick.js';
4
- import type { AbTestInfo } from './abtest.js';
6
+ import { Interaction } from './interaction.js';
5
7
  import type { AudioEvent, VideoEvent } from './media.js';
6
- import type { TMembershipTier, TSubscriptionType } from './subscription.js';
7
8
  import type { TPlatform } from './platform.js';
8
- import type { Acquisition } from './acquisition.js';
9
- import { Interaction } from './interaction.js';
9
+ import type { TMembershipTier, TSubscriptionType } from './subscription.js';
10
10
  /**
11
11
  * Details about a page view - only populated for _PAGE_VIEW
12
12
  * event types
@@ -26,7 +26,7 @@ interface PageView {
26
26
  totalDaysVisited?: number;
27
27
  /** Calculated average days between recent visits */
28
28
  averageDaysBetweenRecentVisits?: number;
29
- /** Is this browser a regular visitor to the Guardian */
29
+ /** No longer used in Ophan. Replaced by Frequency */
30
30
  regular?: boolean;
31
31
  subscriptionType?: TSubscriptionType;
32
32
  membershipTier?: TMembershipTier;
@@ -50,4 +50,4 @@ export type Product =
50
50
  /**
51
51
  * Supporter plus tier.
52
52
  */
53
- | "SUPPORTER_PLUS";
53
+ | "GUARDIAN_PATRON" | "SUPPORTER_PLUS";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@guardian/ophan-tracker-js",
3
- "version": "2.2.4",
3
+ "version": "2.2.6",
4
4
  "type": "module",
5
5
  "engines": {
6
6
  "node": ">=16"
@@ -11,6 +11,23 @@
11
11
  ],
12
12
  "main": "NPM-dist/ng.js",
13
13
  "types": "NPM-dist/types/ng.d.ts",
14
+ "exports": {
15
+ ".": {
16
+ "import": "./NPM-dist/ng.js",
17
+ "types": "./NPM-dist/types/ng.d.ts"
18
+ },
19
+ "./MMA": {
20
+ "import": "./NPM-dist/manage-my-account.js",
21
+ "types": "./NPM-dist/types/manage-my-account.d.ts"
22
+ }
23
+ },
24
+ "typesVersions": {
25
+ "*": {
26
+ "MMA": [
27
+ "NPM-dist/types/manage-my-account.d.ts"
28
+ ]
29
+ }
30
+ },
14
31
  "devDependencies": {
15
32
  "@babel/preset-env": "^7.22.10",
16
33
  "@babel/preset-typescript": "^7.24.7",
@@ -1,26 +0,0 @@
1
- /**
2
- * A set of UTM parameters
3
- * https://en.wikipedia.org/wiki/UTM_parameters
4
- */
5
- interface UtmParameters {
6
- /**
7
- * Identifies which site sent the traffic
8
- */
9
- utmSource?: string;
10
- /**
11
- * Identifies what type of link was used, such as cost per click or email.
12
- */
13
- utmMedium?: string;
14
- /**
15
- * Identifies a specific product promotion or strategic campaign.
16
- */
17
- utmCampaign?: string;
18
- /**
19
- * Identifies search terms.
20
- */
21
- utmTerm?: string;
22
- /**
23
- * Identifies what specifically was clicked to bring the user to the site, such as a banner ad or a text link. It is often used for A/B testing and content-targeted ads.
24
- */
25
- utmContent?: string;
26
- }
@@ -1 +0,0 @@
1
- "use strict";