diff --git a/src/app/components/ATIAnalytics/canonical/index.test.tsx b/src/app/components/ATIAnalytics/canonical/index.test.tsx index 33b404b057d..536ef8e1457 100644 --- a/src/app/components/ATIAnalytics/canonical/index.test.tsx +++ b/src/app/components/ATIAnalytics/canonical/index.test.tsx @@ -1,4 +1,5 @@ import React from 'react'; +import { Helmet } from 'react-helmet'; import { render, act, @@ -30,6 +31,28 @@ describe('Canonical ATI Analytics', () => { expect(mockSendBeacon).toHaveBeenCalledWith(expectedUrl); }); + it('should render lite Helmet script when isLite is true', () => { + jest.spyOn(isOperaProxy, 'default').mockImplementation(() => false); + + const expectedUrl = `${atiBaseUrl}${mockPageviewParams}`; + + act(() => { + render(, { + isLite: true, + }); + }); + + const helmet = Helmet.peek(); + + expect(helmet.scriptTags).toHaveLength(1); + expect(helmet.scriptTags[0].innerHTML).toEqual(` + var xhr = new XMLHttpRequest(); + xhr.open("GET", "${expectedUrl}", true); + xhr.withCredentials = true; + xhr.send(); +`); + }); + it('should not send beacon when browser is Opera Mini', () => { jest.spyOn(isOperaProxy, 'default').mockImplementation(() => true); diff --git a/src/app/components/ATIAnalytics/canonical/index.tsx b/src/app/components/ATIAnalytics/canonical/index.tsx index 6ac8a037608..394b0bd4c83 100644 --- a/src/app/components/ATIAnalytics/canonical/index.tsx +++ b/src/app/components/ATIAnalytics/canonical/index.tsx @@ -1,4 +1,4 @@ -import React, { useContext, useEffect, useState, Fragment } from 'react'; +import React, { useContext, useEffect, useState } from 'react'; import { getEnvConfig } from '#app/lib/utilities/getEnvConfig'; import { RequestContext } from '#app/contexts/RequestContext'; import isOperaProxy from '#app/lib/utilities/isOperaProxy'; @@ -6,20 +6,16 @@ import { Helmet } from 'react-helmet'; import sendBeacon from '../../../lib/analyticsUtils/sendBeacon'; import { ATIAnalyticsProps } from '../types'; import sendBeaconOperaMiniScript from './sendBeaconOperaMiniScript'; +import sendBeaconLite from './sendBeaconLite'; const getNoJsATIPageViewUrl = (atiPageViewUrl: string) => atiPageViewUrl.includes('x8=[simorgh]') ? atiPageViewUrl.replace('x8=[simorgh]', 'x8=[simorgh-nojs]') : `${atiPageViewUrl}&x8=[simorgh-nojs]`; -const renderNoScriptTrackingPixel = ( - atiPageViewUrl: string, - isLite: boolean, -) => { - const ImgPixelWrapper = isLite ? Fragment : 'noscript'; - +const renderNoScriptTrackingPixel = (atiPageViewUrl: string) => { return ( - + ); }; @@ -44,6 +40,16 @@ const addOperaMiniExtremeScript = (atiPageViewUrlString: string) => { ); }; +const addLiteScript = (atiPageViewUrlString: string) => { + const script = sendBeaconLite(atiPageViewUrlString); + + return ( + + + + ); +}; + const CanonicalATIAnalytics = ({ pageviewParams }: ATIAnalyticsProps) => { const { isLite } = useContext(RequestContext); @@ -58,8 +64,9 @@ const CanonicalATIAnalytics = ({ pageviewParams }: ATIAnalyticsProps) => { return ( <> - {addOperaMiniExtremeScript(atiPageViewUrlString)} - {renderNoScriptTrackingPixel(atiPageViewUrl, isLite)} + {isLite && addLiteScript(atiPageViewUrlString)} + {!isLite && addOperaMiniExtremeScript(atiPageViewUrlString)} + {renderNoScriptTrackingPixel(atiPageViewUrl)} ); }; diff --git a/src/app/components/ATIAnalytics/canonical/sendBeaconLite.test.ts b/src/app/components/ATIAnalytics/canonical/sendBeaconLite.test.ts new file mode 100644 index 00000000000..95d2c3a85b6 --- /dev/null +++ b/src/app/components/ATIAnalytics/canonical/sendBeaconLite.test.ts @@ -0,0 +1,35 @@ +/* eslint-disable no-eval */ +import sendBeaconLite from './sendBeaconLite'; + +let XMLHttpRequestSpy: jest.SpyInstance; + +describe('sendBeaconLite', () => { + const XMLHttpRequestMock: Partial = { + open: jest.fn(), + withCredentials: false, + send: jest.fn(), + }; + + beforeEach(() => { + XMLHttpRequestSpy = jest.spyOn(window, 'XMLHttpRequest'); + }); + + afterEach(() => { + XMLHttpRequestSpy.mockRestore(); + jest.clearAllMocks(); + }); + + it('should send beacon with XHR', () => { + XMLHttpRequestSpy.mockImplementation( + () => XMLHttpRequestMock as XMLHttpRequest, + ); + + eval(sendBeaconLite('https://foobar.com')); + + expect(XMLHttpRequestMock.open).toHaveBeenCalledWith( + 'GET', + 'https://foobar.com', + true, + ); + }); +}); diff --git a/src/app/components/ATIAnalytics/canonical/sendBeaconLite.ts b/src/app/components/ATIAnalytics/canonical/sendBeaconLite.ts new file mode 100644 index 00000000000..387975e2e95 --- /dev/null +++ b/src/app/components/ATIAnalytics/canonical/sendBeaconLite.ts @@ -0,0 +1,8 @@ +const sendBeaconLite = (atiPageViewUrlString: string) => ` + var xhr = new XMLHttpRequest(); + xhr.open("GET", "${atiPageViewUrlString}", true); + xhr.withCredentials = true; + xhr.send(); +`; + +export default sendBeaconLite;