diff --git a/spec/src/modules/tracker.js b/spec/src/modules/tracker.js index 518f3743..6fcd6f22 100644 --- a/spec/src/modules/tracker.js +++ b/spec/src/modules/tracker.js @@ -26,6 +26,7 @@ const timeoutRejectionMessage = 'AbortError: This operation was aborted'; const testAnalyticsTag = { param1: 'test', param2: 'test2' }; const utmParameters = 'utm_source=attentive&utm_medium=sms&utm_campaign=campaign_1'; const url = `http://localhost.test/path/name?query=term&category=cat&${utmParameters}`; +const referrer = 'https://www.google.com/'; function validateOriginReferrer(requestParams) { expect(requestParams).to.have.property('origin_referrer').to.contain('localhost.test/path/name'); @@ -42,7 +43,7 @@ function createLongUrl(length) { describe(`ConstructorIO - Tracker${bundledDescriptionSuffix}`, () => { let fetchSpy = null; let cleanup; - const jsdomOptions = { url }; + const jsdomOptions = { url, referrer }; const requestQueueOptions = { sendTrackingEvents: true, trackingSendDelay: 1, @@ -188,6 +189,31 @@ describe(`ConstructorIO - Tracker${bundledDescriptionSuffix}`, () => { expect(tracker.trackSessionStart()).to.equal(true); }); + it('Should send along document_referrer and canonical_url query param', (done) => { + const { tracker } = new ConstructorIO({ + apiKey: testApiKey, + fetch: fetchSpy, + ...requestQueueOptions, + }); + + tracker.on('success', (responseParams) => { + const requestParams = helpers.extractUrlParamsFromFetch(fetchSpy); + + // Request + expect(fetchSpy).to.have.been.called; + expect(requestParams).to.have.property('canonical_url').to.equal('https://localhost'); + expect(requestParams).to.have.property('document_referrer').to.equal(referrer); + + // Response + expect(responseParams).to.have.property('method').to.equal('GET'); + expect(responseParams).to.have.property('message').to.equal('ok'); + + done(); + }); + + expect(tracker.trackSessionStart()).to.equal(true); + }); + it('Should send along origin_referrer query param if sendReferrerWithTrackingEvents is not defined', (done) => { const { tracker } = new ConstructorIO({ apiKey: testApiKey, @@ -452,6 +478,31 @@ describe(`ConstructorIO - Tracker${bundledDescriptionSuffix}`, () => { expect(tracker.trackInputFocusV2(userInput, parameters)).to.equal(true); }); + it('Should send along document_referrer and canonical_url query param', (done) => { + const { tracker } = new ConstructorIO({ + apiKey: testApiKey, + fetch: fetchSpy, + ...requestQueueOptions, + }); + + tracker.on('success', (responseParams) => { + const requestParams = helpers.extractUrlParamsFromFetch(fetchSpy); + + // Request + expect(fetchSpy).to.have.been.called; + expect(requestParams).to.have.property('canonical_url').to.equal('https://localhost'); + expect(requestParams).to.have.property('document_referrer').to.equal(referrer); + + // Response + expect(responseParams).to.have.property('method').to.equal('GET'); + expect(responseParams).to.have.property('message').to.equal('ok'); + + done(); + }); + + expect(tracker.trackInputFocus()).to.equal(true); + }); + it('Should respond with a valid response', (done) => { const { tracker } = new ConstructorIO({ apiKey: testApiKey, @@ -1003,6 +1054,32 @@ describe(`ConstructorIO - Tracker${bundledDescriptionSuffix}`, () => { .to.equal(true); }); + it('Should send along document_referrer and canonical_url query param', (done) => { + const { tracker } = new ConstructorIO({ + apiKey: testApiKey, + fetch: fetchSpy, + ...requestQueueOptions, + }); + + tracker.on('success', (responseParams) => { + const requestParams = helpers.extractUrlParamsFromFetch(fetchSpy); + + // Request + expect(fetchSpy).to.have.been.called; + expect(requestParams).to.have.property('canonical_url').to.equal('https://localhost'); + expect(requestParams).to.have.property('document_referrer').to.equal(referrer); + validateOriginReferrer(requestParams); + + // Response + expect(responseParams).to.have.property('method').to.equal('GET'); + expect(responseParams).to.have.property('message').to.equal('ok'); + + done(); + }); + + expect(tracker.trackAutocompleteSelect(term, requiredParameters)).to.equal(true); + }); + it('Should throw an error when invalid term is provided', () => { const { tracker } = new ConstructorIO({ apiKey: testApiKey }); @@ -1350,6 +1427,32 @@ describe(`ConstructorIO - Tracker${bundledDescriptionSuffix}`, () => { expect(tracker.trackItemDetailLoad(requiredParameters)).to.equal(true); }); + it('Should send along document_referrer and canonical_url query param', (done) => { + const { tracker } = new ConstructorIO({ + apiKey: testApiKey, + fetch: fetchSpy, + ...requestQueueOptions, + }); + + tracker.on('success', (responseParams) => { + const requestParams = helpers.extractBodyParamsFromFetch(fetchSpy); + + // Request + expect(fetchSpy).to.have.been.called; + expect(requestParams).to.have.property('canonical_url').to.equal('https://localhost'); + expect(requestParams).to.have.property('document_referrer').to.equal(referrer); + + // Response + expect(responseParams).to.have.property('method').to.equal('POST'); + expect(responseParams).to.have.property('message').to.equal('ok'); + + done(); + }); + + expect(tracker.trackItemDetailLoad(Object.assign(requiredParameters, optionalParameters))) + .to.equal(true); + }); + it('Should respond with a valid response when required and optional parameters are provided', (done) => { const { tracker } = new ConstructorIO({ apiKey: testApiKey, @@ -1735,6 +1838,31 @@ describe(`ConstructorIO - Tracker${bundledDescriptionSuffix}`, () => { expect(tracker.trackSearchSubmit(term, requiredParameters)).to.equal(true); }); + it('Should send along document_referrer and canonical_url query param', (done) => { + const { tracker } = new ConstructorIO({ + apiKey: testApiKey, + fetch: fetchSpy, + ...requestQueueOptions, + }); + + tracker.on('success', (responseParams) => { + const requestParams = helpers.extractUrlParamsFromFetch(fetchSpy); + + // Request + expect(fetchSpy).to.have.been.called; + expect(requestParams).to.have.property('canonical_url').to.equal('https://localhost'); + expect(requestParams).to.have.property('document_referrer').to.equal(referrer); + + // Response + expect(responseParams).to.have.property('method').to.equal('GET'); + expect(responseParams).to.have.property('message').to.equal('ok'); + + done(); + }); + + expect(tracker.trackSearchSubmit(term, Object.assign(requiredParameters, optionalParameters))).to.equal(true); + }); + it('Should respond with a valid response when term, required and optional parameters are provided', (done) => { const { tracker } = new ConstructorIO({ apiKey: testApiKey, @@ -2174,6 +2302,38 @@ describe(`ConstructorIO - Tracker${bundledDescriptionSuffix}`, () => { expect(tracker.trackSearchResultsLoaded(term, requiredParameters)).to.equal(true); }); + it('Should send along document_referrer and canonical_url query param', (done) => { + const segments = ['foo', 'bar']; + const { tracker } = new ConstructorIO({ + apiKey: testApiKey, + segments, + fetch: fetchSpy, + ...requestQueueOptions, + }); + + tracker.on('success', (responseParams) => { + const requestParams = helpers.extractUrlParamsFromFetch(fetchSpy); + const bodyParams = helpers.extractBodyParamsFromFetch(fetchSpy); + + // Request + expect(fetchSpy).to.have.been.called; + expect(requestParams).to.have.property('canonical_url').to.equal('https://localhost'); + expect(requestParams).to.have.property('document_referrer').to.equal(referrer); + + // Body + expect(bodyParams).to.have.property('canonical_url').to.equal('https://localhost'); + expect(bodyParams).to.have.property('document_referrer').to.equal(referrer); + + // Response + expect(responseParams).to.have.property('method').to.equal('POST'); + expect(responseParams).to.have.property('message').to.equal('ok'); + + done(); + }); + + expect(tracker.trackSearchResultsLoaded(term, requiredParameters)).to.equal(true); + }); + it('Should respond with a valid response when term, required parameters and segments are provided', (done) => { const segments = ['foo', 'bar']; const { tracker } = new ConstructorIO({ @@ -2859,6 +3019,31 @@ describe(`ConstructorIO - Tracker${bundledDescriptionSuffix}`, () => { expect(tracker.trackSearchResultClick(term, requiredParameters)).to.equal(true); }); + it('Should send along document_referrer and canonical_url query param', (done) => { + const { tracker } = new ConstructorIO({ + apiKey: testApiKey, + fetch: fetchSpy, + ...requestQueueOptions, + }); + + tracker.on('success', (responseParams) => { + const requestParams = helpers.extractUrlParamsFromFetch(fetchSpy); + + // Request + expect(fetchSpy).to.have.been.called; + expect(requestParams).to.have.property('canonical_url').to.equal('https://localhost'); + expect(requestParams).to.have.property('document_referrer').to.equal(referrer); + + // Response + expect(responseParams).to.have.property('method').to.equal('GET'); + expect(responseParams).to.have.property('message').to.equal('ok'); + + done(); + }); + + expect(tracker.trackSearchResultClick(term, requiredParameters)).to.equal(true); + }); + it('Should respond with a valid response when term, required parameters and userId are provided', (done) => { const userId = 'user-id'; const { tracker } = new ConstructorIO({ @@ -3382,6 +3567,31 @@ describe(`ConstructorIO - Tracker${bundledDescriptionSuffix}`, () => { expect(tracker.trackConversion(term, clonedParameters)).to.equal(true); }); + it('Should send along document_referrer and canonical_url query param', (done) => { + const { tracker } = new ConstructorIO({ + apiKey: testApiKey, + fetch: fetchSpy, + ...requestQueueOptions, + }); + + tracker.on('success', (responseParams) => { + const requestParams = helpers.extractBodyParamsFromFetch(fetchSpy); + + // Request + expect(fetchSpy).to.have.been.called; + expect(requestParams).to.have.property('canonical_url').to.equal('https://localhost'); + expect(requestParams).to.have.property('document_referrer').to.equal(referrer); + + // Response + expect(responseParams).to.have.property('method').to.equal('POST'); + expect(responseParams).to.have.property('message').to.equal('ok'); + + done(); + }); + + expect(tracker.trackConversion(term, requiredParameters)).to.equal(true); + }); + it('Should respond with a valid response when term, required parameters and segments are provided', (done) => { const segments = ['foo', 'bar']; const { tracker } = new ConstructorIO({ @@ -3945,6 +4155,36 @@ describe(`ConstructorIO - Tracker${bundledDescriptionSuffix}`, () => { expect(tracker.trackPurchase(requiredParameters)).to.equal(true); }); + it('Should send along document_referrer and canonical_url query param', (done) => { + const { tracker } = new ConstructorIO({ + apiKey: testApiKey, + fetch: fetchSpy, + ...requestQueueOptions, + }); + + tracker.on('success', (responseParams) => { + const requestQueryParams = helpers.extractUrlParamsFromFetch(fetchSpy); + const requestBodyParams = helpers.extractBodyParamsFromFetch(fetchSpy); + + // Request + expect(fetchSpy).to.have.been.called; + expect(requestQueryParams).to.have.property('canonical_url').to.equal('https://localhost'); + expect(requestQueryParams).to.have.property('document_referrer').to.equal(referrer); + + // Body + expect(requestBodyParams).to.have.property('canonical_url').to.equal('https://localhost'); + expect(requestBodyParams).to.have.property('document_referrer').to.equal(referrer); + + // Response + expect(responseParams).to.have.property('method').to.equal('POST'); + expect(responseParams).to.have.property('message'); + + done(); + }); + + expect(tracker.trackPurchase(Object.assign(requiredParameters, optionalParameters))).to.equal(true); + }); + it('Should respond with a valid response when optional parameters are provided', (done) => { const { tracker } = new ConstructorIO({ apiKey: testApiKey, @@ -4410,6 +4650,34 @@ describe(`ConstructorIO - Tracker${bundledDescriptionSuffix}`, () => { expect(tracker.trackRecommendationView(requiredParameters)).to.equal(true); }); + it('Should send along document_referrer and canonical_url query param', (done) => { + const clonedParameters = cloneDeep(requiredParameters); + const { tracker } = new ConstructorIO({ + apiKey: testApiKey, + fetch: fetchSpy, + ...requestQueueOptions, + }); + + tracker.on('success', (responseParams) => { + const requestParams = helpers.extractBodyParamsFromFetch(fetchSpy); + + // Request + expect(fetchSpy).to.have.been.called; + expect(requestParams).to.have.property('canonical_url').to.equal('https://localhost'); + expect(requestParams).to.have.property('document_referrer').to.equal(referrer); + + // Response + expect(responseParams).to.have.property('method').to.equal('POST'); + expect(responseParams).to.have.property('message'); + + done(); + }); + + delete clonedParameters.section; + + expect(tracker.trackRecommendationView(clonedParameters)).to.equal(true); + }); + it('Should respond with a valid response and section should be defaulted when required parameters are provided', (done) => { const clonedParameters = cloneDeep(requiredParameters); const { tracker } = new ConstructorIO({ @@ -5093,6 +5361,31 @@ describe(`ConstructorIO - Tracker${bundledDescriptionSuffix}`, () => { expect(tracker.trackRecommendationClick(clonedParameters)).to.equal(true); }); + it('Should send along document_referrer and canonical_url query param', (done) => { + const { tracker } = new ConstructorIO({ + apiKey: testApiKey, + fetch: fetchSpy, + ...requestQueueOptions, + }); + + tracker.on('success', (responseParams) => { + const requestParams = helpers.extractBodyParamsFromFetch(fetchSpy); + + // Request + expect(fetchSpy).to.have.been.called; + expect(requestParams).to.have.property('canonical_url').to.equal('https://localhost'); + expect(requestParams).to.have.property('document_referrer').to.equal(referrer); + + // Response + expect(responseParams).to.have.property('method').to.equal('POST'); + expect(responseParams).to.have.property('message'); + + done(); + }); + + expect(tracker.trackRecommendationClick(requiredParameters)).to.equal(true); + }); + it('Should respond with a valid response when parameters and segments are provided', (done) => { const segments = ['foo', 'bar']; const { tracker } = new ConstructorIO({ @@ -5615,7 +5908,32 @@ describe(`ConstructorIO - Tracker${bundledDescriptionSuffix}`, () => { expect(tracker.trackBrowseResultsLoaded(clonedParameters)).to.equal(true); }); - it('Should respond with a valid response when required parameters and segments are provided', (done) => { + it('Should send along document_referrer and canonical_url query param', (done) => { + const { tracker } = new ConstructorIO({ + apiKey: testApiKey, + fetch: fetchSpy, + ...requestQueueOptions, + }); + + tracker.on('success', (responseParams) => { + const requestParams = helpers.extractBodyParamsFromFetch(fetchSpy); + + // Request + expect(fetchSpy).to.have.been.called; + expect(requestParams).to.have.property('canonical_url').to.equal('https://localhost'); + expect(requestParams).to.have.property('document_referrer').to.equal(referrer); + + // Response + expect(responseParams).to.have.property('method').to.equal('POST'); + expect(responseParams).to.have.property('message'); + + done(); + }); + + expect(tracker.trackBrowseResultsLoaded(requiredParameters)).to.equal(true); + }); + + it('Should respond with a valid response when required parameters and segments are provided', (done) => { const segments = ['foo', 'bar']; const { tracker } = new ConstructorIO({ apiKey: testApiKey, @@ -6009,6 +6327,31 @@ describe(`ConstructorIO - Tracker${bundledDescriptionSuffix}`, () => { expect(tracker.trackBrowseRedirect(clonedParameters)).to.equal(true); }); + it('Should send along document_referrer and canonical_url query param', (done) => { + const { tracker } = new ConstructorIO({ + apiKey: testApiKey, + fetch: fetchSpy, + ...requestQueueOptions, + }); + + tracker.on('success', (responseParams) => { + const requestParams = helpers.extractBodyParamsFromFetch(fetchSpy); + + // Request + expect(fetchSpy).to.have.been.called; + expect(requestParams).to.have.property('canonical_url').to.equal('https://localhost'); + expect(requestParams).to.have.property('document_referrer').to.equal(referrer); + + // Response + expect(responseParams).to.have.property('method').to.equal('POST'); + expect(responseParams).to.have.property('message'); + + done(); + }); + + expect(tracker.trackBrowseRedirect(requiredParameters)).to.equal(true); + }); + it('Should respond with a valid response when required parameters and segments are provided', (done) => { const segments = ['foo', 'bar']; const { tracker } = new ConstructorIO({ @@ -6399,6 +6742,31 @@ describe(`ConstructorIO - Tracker${bundledDescriptionSuffix}`, () => { expect(tracker.trackBrowseResultClick(clonedParameters)).to.equal(true); }); + it('Should send along document_referrer and canonical_url query param', (done) => { + const { tracker } = new ConstructorIO({ + apiKey: testApiKey, + fetch: fetchSpy, + ...requestQueueOptions, + }); + + tracker.on('success', (responseParams) => { + const requestParams = helpers.extractBodyParamsFromFetch(fetchSpy); + + // Request + expect(fetchSpy).to.have.been.called; + expect(requestParams).to.have.property('canonical_url').to.equal('https://localhost'); + expect(requestParams).to.have.property('document_referrer').to.equal(referrer); + + // Response + expect(responseParams).to.have.property('method').to.equal('POST'); + expect(responseParams).to.have.property('message'); + + done(); + }); + + expect(tracker.trackBrowseResultClick(requiredParameters)).to.equal(true); + }); + it('Should respond with a valid response when required parameters and segments are provided', (done) => { const segments = ['foo', 'bar']; const { tracker } = new ConstructorIO({ @@ -6824,6 +7192,31 @@ describe(`ConstructorIO - Tracker${bundledDescriptionSuffix}`, () => { expect(tracker.trackGenericResultClick(clonedParameters)).to.equal(true); }); + it('Should send along document_referrer and canonical_url query param', (done) => { + const { tracker } = new ConstructorIO({ + apiKey: testApiKey, + fetch: fetchSpy, + ...requestQueueOptions, + }); + + tracker.on('success', (responseParams) => { + const requestParams = helpers.extractBodyParamsFromFetch(fetchSpy); + + // Request + expect(fetchSpy).to.have.been.called; + expect(requestParams).to.have.property('canonical_url').to.equal('https://localhost'); + expect(requestParams).to.have.property('document_referrer').to.equal(referrer); + + // Response + expect(responseParams).to.have.property('method').to.equal('POST'); + expect(responseParams).to.have.property('message'); + + done(); + }); + + expect(tracker.trackGenericResultClick(requiredParameters)).to.equal(true); + }); + it('Should respond with a valid response when required parameters and segments are provided', (done) => { const segments = ['foo', 'bar']; const { tracker } = new ConstructorIO({ @@ -7253,6 +7646,31 @@ describe(`ConstructorIO - Tracker${bundledDescriptionSuffix}`, () => { expect(tracker.trackQuizResultsLoaded({ ...requiredParameters, result_count: 0 })).to.equal(true); }); + it('Should send along document_referrer and canonical_url query param', (done) => { + const { tracker } = new ConstructorIO({ + apiKey: testApiKey, + fetch: fetchSpy, + ...requestQueueOptions, + }); + + tracker.on('success', (responseParams) => { + const requestParams = helpers.extractUrlParamsFromFetch(fetchSpy); + + // Request + expect(fetchSpy).to.have.been.called; + expect(requestParams).to.have.property('canonical_url').to.equal('https://localhost'); + expect(requestParams).to.have.property('document_referrer').to.equal(referrer); + + // Response + expect(responseParams).to.have.property('method').to.equal('POST'); + expect(responseParams).to.have.property('message').to.equal('ok'); + + done(); + }); + + expect(tracker.trackQuizResultsLoaded(requiredParameters)).to.equal(true); + }); + it('Should respond with a valid response when required parameters and segments are provided', (done) => { const segments = ['foo', 'bar']; const { tracker } = new ConstructorIO({ @@ -7728,6 +8146,31 @@ describe(`ConstructorIO - Tracker${bundledDescriptionSuffix}`, () => { expect(tracker.trackQuizResultClick(requiredParameters)).to.equal(true); }); + it('Should send along document_referrer and canonical_url query param', (done) => { + const { tracker } = new ConstructorIO({ + apiKey: testApiKey, + fetch: fetchSpy, + ...requestQueueOptions, + }); + + tracker.on('success', (responseParams) => { + const requestParams = helpers.extractUrlParamsFromFetch(fetchSpy); + + // Request + expect(fetchSpy).to.have.been.called; + expect(requestParams).to.have.property('canonical_url').to.equal('https://localhost'); + expect(requestParams).to.have.property('document_referrer').to.equal(referrer); + + // Response + expect(responseParams).to.have.property('method').to.equal('POST'); + expect(responseParams).to.have.property('message').to.equal('ok'); + + done(); + }); + + expect(tracker.trackQuizResultClick(requiredParameters)).to.equal(true); + }); + it('Should respond with a valid response when required parameters and userId are provided', (done) => { const userId = 'user-id'; const { tracker } = new ConstructorIO({ @@ -8141,6 +8584,31 @@ describe(`ConstructorIO - Tracker${bundledDescriptionSuffix}`, () => { expect(tracker.trackQuizConversion(requiredParameters)).to.equal(true); }); + it('Should send along document_referrer and canonical_url query param', (done) => { + const { tracker } = new ConstructorIO({ + apiKey: testApiKey, + fetch: fetchSpy, + ...requestQueueOptions, + }); + + tracker.on('success', (responseParams) => { + const requestParams = helpers.extractUrlParamsFromFetch(fetchSpy); + + // Request + expect(fetchSpy).to.have.been.called; + expect(requestParams).to.have.property('canonical_url').to.equal('https://localhost'); + expect(requestParams).to.have.property('document_referrer').to.equal(referrer); + + // Response + expect(responseParams).to.have.property('method').to.equal('POST'); + expect(responseParams).to.have.property('message').to.equal('ok'); + + done(); + }); + + expect(tracker.trackQuizConversion(requiredParameters)).to.equal(true); + }); + it('Should respond with a valid response when required parameters and segments are provided', (done) => { const segments = ['foo', 'bar']; const { tracker } = new ConstructorIO({ @@ -8605,6 +9073,31 @@ describe(`ConstructorIO - Tracker${bundledDescriptionSuffix}`, () => { expect(tracker.trackAgentSubmit(requiredParameters)).to.equal(true); }); + it('Should send along document_referrer and canonical_url query param', (done) => { + const { tracker } = new ConstructorIO({ + apiKey: testApiKey, + fetch: fetchSpy, + ...requestQueueOptions, + }); + + tracker.on('success', (responseParams) => { + const requestParams = helpers.extractBodyParamsFromFetch(fetchSpy); + + // Request + expect(fetchSpy).to.have.been.called; + expect(requestParams).to.have.property('canonical_url').to.equal('https://localhost'); + expect(requestParams).to.have.property('document_referrer').to.equal(referrer); + + // Response + expect(responseParams).to.have.property('method').to.equal('POST'); + expect(responseParams).to.have.property('message').to.equal('ok'); + + done(); + }); + + expect(tracker.trackAgentSubmit(requiredParameters)).to.equal(true); + }); + it('Should respond with a valid response when term, required parameters and segments are provided', (done) => { const segments = ['foo', 'bar']; const { tracker } = new ConstructorIO({ @@ -8895,6 +9388,31 @@ describe(`ConstructorIO - Tracker${bundledDescriptionSuffix}`, () => { expect(tracker.trackAgentResultLoadStarted(requiredParameters)).to.equal(true); }); + it('Should respond with a valid response when term, required parameters and segments are provided', (done) => { + const { tracker } = new ConstructorIO({ + apiKey: testApiKey, + fetch: fetchSpy, + ...requestQueueOptions, + }); + + tracker.on('success', (responseParams) => { + const requestParams = helpers.extractBodyParamsFromFetch(fetchSpy); + + // Request + expect(fetchSpy).to.have.been.called; + expect(requestParams).to.have.property('canonical_url').to.equal('https://localhost'); + expect(requestParams).to.have.property('document_referrer').to.equal(referrer); + + // Response + expect(responseParams).to.have.property('method').to.equal('POST'); + expect(responseParams).to.have.property('message').to.equal('ok'); + + done(); + }); + + expect(tracker.trackAgentResultLoadStarted(requiredParameters)).to.equal(true); + }); + it('Should respond with a valid response when term, required parameters and segments are provided', (done) => { const segments = ['foo', 'bar']; const { tracker } = new ConstructorIO({ @@ -9188,6 +9706,31 @@ describe(`ConstructorIO - Tracker${bundledDescriptionSuffix}`, () => { expect(tracker.trackAgentResultLoadFinished(requiredParameters)).to.equal(true); }); + it('Should send along document_referrer and canonical_url query param', (done) => { + const { tracker } = new ConstructorIO({ + apiKey: testApiKey, + fetch: fetchSpy, + ...requestQueueOptions, + }); + + tracker.on('success', (responseParams) => { + const requestParams = helpers.extractBodyParamsFromFetch(fetchSpy); + + // Request + expect(fetchSpy).to.have.been.called; + expect(requestParams).to.have.property('canonical_url').to.equal('https://localhost'); + expect(requestParams).to.have.property('document_referrer').to.equal(referrer); + + // Response + expect(responseParams).to.have.property('method').to.equal('POST'); + expect(responseParams).to.have.property('message').to.equal('ok'); + + done(); + }); + + expect(tracker.trackAgentResultLoadFinished(requiredParameters)).to.equal(true); + }); + it('Should respond with a valid response when term, required parameters and segments are provided', (done) => { const segments = ['foo', 'bar']; const { tracker } = new ConstructorIO({ @@ -9489,6 +10032,31 @@ describe(`ConstructorIO - Tracker${bundledDescriptionSuffix}`, () => { expect(tracker.trackAgentResultClick(requiredParameters)).to.equal(true); }); + it('Should send along document_referrer and canonical_url query param', (done) => { + const { tracker } = new ConstructorIO({ + apiKey: testApiKey, + fetch: fetchSpy, + ...requestQueueOptions, + }); + + tracker.on('success', (responseParams) => { + const requestParams = helpers.extractUrlParamsFromFetch(fetchSpy); + + // Request + expect(fetchSpy).to.have.been.called; + expect(requestParams).to.have.property('canonical_url').to.equal('https://localhost'); + expect(requestParams).to.have.property('document_referrer').to.equal(referrer); + + // Response + expect(responseParams).to.have.property('method').to.equal('POST'); + expect(responseParams).to.have.property('message').to.equal('ok'); + + done(); + }); + + expect(tracker.trackAgentResultClick(requiredParameters)).to.equal(true); + }); + it('Should respond with a valid response when required parameters and segments are provided', (done) => { const segments = ['foo', 'bar']; const { tracker } = new ConstructorIO({ @@ -9808,11 +10376,9 @@ describe(`ConstructorIO - Tracker${bundledDescriptionSuffix}`, () => { expect(tracker.trackAgentResultView(requiredParameters)).to.equal(true); }); - it('Should respond with a valid response when required parameters and segments are provided', (done) => { - const segments = ['foo', 'bar']; + it('Should send along document_referrer and canonical_url query param', (done) => { const { tracker } = new ConstructorIO({ apiKey: testApiKey, - segments, fetch: fetchSpy, ...requestQueueOptions, }); @@ -9822,7 +10388,8 @@ describe(`ConstructorIO - Tracker${bundledDescriptionSuffix}`, () => { // Request expect(fetchSpy).to.have.been.called; - expect(requestParams).to.have.property('us').to.deep.equal(segments); + expect(requestParams).to.have.property('canonical_url').to.equal('https://localhost'); + expect(requestParams).to.have.property('document_referrer').to.equal(referrer); // Response expect(responseParams).to.have.property('method').to.equal('POST'); @@ -9834,12 +10401,12 @@ describe(`ConstructorIO - Tracker${bundledDescriptionSuffix}`, () => { expect(tracker.trackAgentResultView(requiredParameters)).to.equal(true); }); - it('Should respond with a valid response when required parameters and testCells are provided', (done) => { - const testCells = { foo: 'bar' }; + it('Should respond with a valid response when required parameters and segments are provided', (done) => { + const segments = ['foo', 'bar']; const { tracker } = new ConstructorIO({ apiKey: testApiKey, + segments, fetch: fetchSpy, - testCells, ...requestQueueOptions, }); @@ -9848,7 +10415,33 @@ describe(`ConstructorIO - Tracker${bundledDescriptionSuffix}`, () => { // Request expect(fetchSpy).to.have.been.called; - expect(requestParams).to.have.property(`ef-${Object.keys(testCells)[0]}`).to.equal(Object.values(testCells)[0]); + expect(requestParams).to.have.property('us').to.deep.equal(segments); + + // Response + expect(responseParams).to.have.property('method').to.equal('POST'); + expect(responseParams).to.have.property('message'); + + done(); + }); + + expect(tracker.trackAgentResultView(requiredParameters)).to.equal(true); + }); + + it('Should respond with a valid response when required parameters and testCells are provided', (done) => { + const testCells = { foo: 'bar' }; + const { tracker } = new ConstructorIO({ + apiKey: testApiKey, + fetch: fetchSpy, + testCells, + ...requestQueueOptions, + }); + + tracker.on('success', (responseParams) => { + const requestParams = helpers.extractBodyParamsFromFetch(fetchSpy); + + // Request + expect(fetchSpy).to.have.been.called; + expect(requestParams).to.have.property(`ef-${Object.keys(testCells)[0]}`).to.equal(Object.values(testCells)[0]); // Response expect(responseParams).to.have.property('method').to.equal('POST'); @@ -10102,6 +10695,31 @@ describe(`ConstructorIO - Tracker${bundledDescriptionSuffix}`, () => { expect(tracker.trackAgentSearchSubmit(requiredParameters)).to.equal(true); }); + it('Should send along document_referrer and canonical_url query param', (done) => { + const { tracker } = new ConstructorIO({ + apiKey: testApiKey, + fetch: fetchSpy, + ...requestQueueOptions, + }); + + tracker.on('success', (responseParams) => { + const requestParams = helpers.extractBodyParamsFromFetch(fetchSpy); + + // Request + expect(fetchSpy).to.have.been.called; + expect(requestParams).to.have.property('canonical_url').to.equal('https://localhost'); + expect(requestParams).to.have.property('document_referrer').to.equal(referrer); + + // Response + expect(responseParams).to.have.property('method').to.equal('POST'); + expect(responseParams).to.have.property('message').to.equal('ok'); + + done(); + }); + + expect(tracker.trackAgentSearchSubmit(requiredParameters)).to.equal(true); + }); + it('Should respond with a valid response when term, required parameters and segments are provided', (done) => { const segments = ['foo', 'bar']; const { tracker } = new ConstructorIO({ @@ -10392,6 +11010,31 @@ describe(`ConstructorIO - Tracker${bundledDescriptionSuffix}`, () => { expect(tracker.trackAssistantSubmit(requiredParameters)).to.equal(true); }); + it('Should send along document_referrer and canonical_url query param', (done) => { + const { tracker } = new ConstructorIO({ + apiKey: testApiKey, + fetch: fetchSpy, + ...requestQueueOptions, + }); + + tracker.on('success', (responseParams) => { + const requestParams = helpers.extractBodyParamsFromFetch(fetchSpy); + + // Request + expect(fetchSpy).to.have.been.called; + expect(requestParams).to.have.property('canonical_url').to.equal('https://localhost'); + expect(requestParams).to.have.property('document_referrer').to.equal(referrer); + + // Response + expect(responseParams).to.have.property('method').to.equal('POST'); + expect(responseParams).to.have.property('message').to.equal('ok'); + + done(); + }); + + expect(tracker.trackAssistantSubmit(requiredParameters)).to.equal(true); + }); + it('Should respond with a valid response when term, required parameters and segments are provided', (done) => { const segments = ['foo', 'bar']; const { tracker } = new ConstructorIO({ @@ -10682,6 +11325,31 @@ describe(`ConstructorIO - Tracker${bundledDescriptionSuffix}`, () => { expect(tracker.trackAssistantResultLoadStarted(requiredParameters)).to.equal(true); }); + it('Should send along document_referrer and canonical_url query param', (done) => { + const { tracker } = new ConstructorIO({ + apiKey: testApiKey, + fetch: fetchSpy, + ...requestQueueOptions, + }); + + tracker.on('success', (responseParams) => { + const requestParams = helpers.extractBodyParamsFromFetch(fetchSpy); + + // Request + expect(fetchSpy).to.have.been.called; + expect(requestParams).to.have.property('canonical_url').to.equal('https://localhost'); + expect(requestParams).to.have.property('document_referrer').to.equal(referrer); + + // Response + expect(responseParams).to.have.property('method').to.equal('POST'); + expect(responseParams).to.have.property('message').to.equal('ok'); + + done(); + }); + + expect(tracker.trackAssistantResultLoadStarted(requiredParameters)).to.equal(true); + }); + it('Should respond with a valid response when term, required parameters and segments are provided', (done) => { const segments = ['foo', 'bar']; const { tracker } = new ConstructorIO({ @@ -10975,6 +11643,31 @@ describe(`ConstructorIO - Tracker${bundledDescriptionSuffix}`, () => { expect(tracker.trackAssistantResultLoadFinished(requiredParameters)).to.equal(true); }); + it('Should send along document_referrer and canonical_url query param', (done) => { + const { tracker } = new ConstructorIO({ + apiKey: testApiKey, + fetch: fetchSpy, + ...requestQueueOptions, + }); + + tracker.on('success', (responseParams) => { + const requestParams = helpers.extractBodyParamsFromFetch(fetchSpy); + + // Request + expect(fetchSpy).to.have.been.called; + expect(requestParams).to.have.property('canonical_url').to.equal('https://localhost'); + expect(requestParams).to.have.property('document_referrer').to.equal(referrer); + + // Response + expect(responseParams).to.have.property('method').to.equal('POST'); + expect(responseParams).to.have.property('message').to.equal('ok'); + + done(); + }); + + expect(tracker.trackAssistantResultLoadFinished(requiredParameters)).to.equal(true); + }); + it('Should respond with a valid response when term, required parameters and segments are provided', (done) => { const segments = ['foo', 'bar']; const { tracker } = new ConstructorIO({ @@ -11276,6 +11969,31 @@ describe(`ConstructorIO - Tracker${bundledDescriptionSuffix}`, () => { expect(tracker.trackAssistantResultClick(requiredParameters)).to.equal(true); }); + it('Should send along document_referrer and canonical_url query param', (done) => { + const { tracker } = new ConstructorIO({ + apiKey: testApiKey, + fetch: fetchSpy, + ...requestQueueOptions, + }); + + tracker.on('success', (responseParams) => { + const requestParams = helpers.extractUrlParamsFromFetch(fetchSpy); + + // Request + expect(fetchSpy).to.have.been.called; + expect(requestParams).to.have.property('canonical_url').to.equal('https://localhost'); + expect(requestParams).to.have.property('document_referrer').to.equal(referrer); + + // Response + expect(responseParams).to.have.property('method').to.equal('POST'); + expect(responseParams).to.have.property('message').to.equal('ok'); + + done(); + }); + + expect(tracker.trackAssistantResultClick(requiredParameters)).to.equal(true); + }); + it('Should respond with a valid response when required parameters and segments are provided', (done) => { const segments = ['foo', 'bar']; const { tracker } = new ConstructorIO({ @@ -11595,6 +12313,31 @@ describe(`ConstructorIO - Tracker${bundledDescriptionSuffix}`, () => { expect(tracker.trackAssistantResultView(requiredParameters)).to.equal(true); }); + it('Should send along document_referrer and canonical_url query param', (done) => { + const { tracker } = new ConstructorIO({ + apiKey: testApiKey, + fetch: fetchSpy, + ...requestQueueOptions, + }); + + tracker.on('success', (responseParams) => { + const requestParams = helpers.extractBodyParamsFromFetch(fetchSpy); + + // Request + expect(fetchSpy).to.have.been.called; + expect(requestParams).to.have.property('canonical_url').to.equal('https://localhost'); + expect(requestParams).to.have.property('document_referrer').to.equal(referrer); + + // Response + expect(responseParams).to.have.property('method').to.equal('POST'); + expect(responseParams).to.have.property('message'); + + done(); + }); + + expect(tracker.trackAssistantResultView(requiredParameters)).to.equal(true); + }); + it('Should respond with a valid response when required parameters and segments are provided', (done) => { const segments = ['foo', 'bar']; const { tracker } = new ConstructorIO({ @@ -11889,6 +12632,31 @@ describe(`ConstructorIO - Tracker${bundledDescriptionSuffix}`, () => { expect(tracker.trackAssistantSearchSubmit(requiredParameters)).to.equal(true); }); + it('Should send along document_referrer and canonical_url query param', (done) => { + const { tracker } = new ConstructorIO({ + apiKey: testApiKey, + fetch: fetchSpy, + ...requestQueueOptions, + }); + + tracker.on('success', (responseParams) => { + const requestParams = helpers.extractBodyParamsFromFetch(fetchSpy); + + // Request + expect(fetchSpy).to.have.been.called; + expect(requestParams).to.have.property('canonical_url').to.equal('https://localhost'); + expect(requestParams).to.have.property('document_referrer').to.equal(referrer); + + // Response + expect(responseParams).to.have.property('method').to.equal('POST'); + expect(responseParams).to.have.property('message').to.equal('ok'); + + done(); + }); + + expect(tracker.trackAssistantSearchSubmit(requiredParameters)).to.equal(true); + }); + it('Should respond with a valid response when term, required parameters and segments are provided', (done) => { const segments = ['foo', 'bar']; const { tracker } = new ConstructorIO({ @@ -12201,6 +12969,31 @@ describe(`ConstructorIO - Tracker${bundledDescriptionSuffix}`, () => { expect(tracker.trackProductInsightsAgentViews(requiredParameters)).to.equal(true); }); + it('Should send along document_referrer and canonical_url query param', (done) => { + const { tracker } = new ConstructorIO({ + apiKey: testApiKey, + fetch: fetchSpy, + ...requestQueueOptions, + }); + + tracker.on('success', (responseParams) => { + const requestParams = helpers.extractBodyParamsFromFetch(fetchSpy); + + // Request + expect(fetchSpy).to.have.been.called; + expect(requestParams).to.have.property('canonical_url').to.equal('https://localhost'); + expect(requestParams).to.have.property('document_referrer').to.equal(referrer); + + // Response + expect(responseParams).to.have.property('method').to.equal('POST'); + expect(responseParams).to.have.property('message').to.equal('ok'); + + done(); + }); + + expect(tracker.trackProductInsightsAgentViews(requiredParameters)).to.equal(true); + }); + it('Should respond with a valid response when term, required parameters and segments are provided', (done) => { const segments = ['foo', 'bar']; const { tracker } = new ConstructorIO({ @@ -12505,6 +13298,31 @@ describe(`ConstructorIO - Tracker${bundledDescriptionSuffix}`, () => { expect(tracker.trackProductInsightsAgentView(requiredParameters)).to.equal(true); }); + it('Should send along document_referrer and canonical_url query param', (done) => { + const { tracker } = new ConstructorIO({ + apiKey: testApiKey, + fetch: fetchSpy, + ...requestQueueOptions, + }); + + tracker.on('success', (responseParams) => { + const requestParams = helpers.extractBodyParamsFromFetch(fetchSpy); + + // Request + expect(fetchSpy).to.have.been.called; + expect(requestParams).to.have.property('canonical_url').to.equal('https://localhost'); + expect(requestParams).to.have.property('document_referrer').to.equal(referrer); + + // Response + expect(responseParams).to.have.property('method').to.equal('POST'); + expect(responseParams).to.have.property('message').to.equal('ok'); + + done(); + }); + + expect(tracker.trackProductInsightsAgentView(requiredParameters)).to.equal(true); + }); + it('Should respond with a valid response when term, required parameters and segments are provided', (done) => { const segments = ['foo', 'bar']; const { tracker } = new ConstructorIO({ @@ -12800,6 +13618,33 @@ describe(`ConstructorIO - Tracker${bundledDescriptionSuffix}`, () => { expect(tracker.trackProductInsightsAgentOutOfView(requiredParameters)).to.equal(true); }); + it('Should send along document_referrer and canonical_url query param', (done) => { + const segments = ['foo', 'bar']; + const { tracker } = new ConstructorIO({ + apiKey: testApiKey, + segments, + fetch: fetchSpy, + ...requestQueueOptions, + }); + + tracker.on('success', (responseParams) => { + const requestParams = helpers.extractBodyParamsFromFetch(fetchSpy); + + // Request + expect(fetchSpy).to.have.been.called; + expect(requestParams).to.have.property('canonical_url').to.equal('https://localhost'); + expect(requestParams).to.have.property('document_referrer').to.equal(referrer); + + // Response + expect(responseParams).to.have.property('method').to.equal('POST'); + expect(responseParams).to.have.property('message').to.equal('ok'); + + done(); + }); + + expect(tracker.trackProductInsightsAgentOutOfView(requiredParameters)).to.equal(true); + }); + it('Should respond with a valid response when term, required parameters and segments are provided', (done) => { const segments = ['foo', 'bar']; const { tracker } = new ConstructorIO({ @@ -13095,6 +13940,31 @@ describe(`ConstructorIO - Tracker${bundledDescriptionSuffix}`, () => { expect(tracker.trackProductInsightsAgentFocus(requiredParameters)).to.equal(true); }); + it('Should send along document_referrer and canonical_url query param', (done) => { + const { tracker } = new ConstructorIO({ + apiKey: testApiKey, + fetch: fetchSpy, + ...requestQueueOptions, + }); + + tracker.on('success', (responseParams) => { + const requestParams = helpers.extractBodyParamsFromFetch(fetchSpy); + + // Request + expect(fetchSpy).to.have.been.called; + expect(requestParams).to.have.property('canonical_url').to.equal('https://localhost'); + expect(requestParams).to.have.property('document_referrer').to.equal(referrer); + + // Response + expect(responseParams).to.have.property('method').to.equal('POST'); + expect(responseParams).to.have.property('message').to.equal('ok'); + + done(); + }); + + expect(tracker.trackProductInsightsAgentFocus(requiredParameters)).to.equal(true); + }); + it('Should respond with a valid response when term, required parameters and segments are provided', (done) => { const segments = ['foo', 'bar']; const { tracker } = new ConstructorIO({ @@ -13391,6 +14261,31 @@ describe(`ConstructorIO - Tracker${bundledDescriptionSuffix}`, () => { expect(tracker.trackProductInsightsAgentQuestionClick(requiredParameters)).to.equal(true); }); + it('Should send along document_referrer and canonical_url query param', (done) => { + const { tracker } = new ConstructorIO({ + apiKey: testApiKey, + fetch: fetchSpy, + ...requestQueueOptions, + }); + + tracker.on('success', (responseParams) => { + const requestParams = helpers.extractBodyParamsFromFetch(fetchSpy); + + // Request + expect(fetchSpy).to.have.been.called; + expect(requestParams).to.have.property('canonical_url').to.equal('https://localhost'); + expect(requestParams).to.have.property('document_referrer').to.equal(referrer); + + // Response + expect(responseParams).to.have.property('method').to.equal('POST'); + expect(responseParams).to.have.property('message').to.equal('ok'); + + done(); + }); + + expect(tracker.trackProductInsightsAgentQuestionClick(requiredParameters)).to.equal(true); + }); + it('Should respond with a valid response when term, required parameters and segments are provided', (done) => { const segments = ['foo', 'bar']; const { tracker } = new ConstructorIO({ @@ -13687,6 +14582,31 @@ describe(`ConstructorIO - Tracker${bundledDescriptionSuffix}`, () => { expect(tracker.trackProductInsightsAgentQuestionSubmit(requiredParameters)).to.equal(true); }); + it('Should send along document_referrer and canonical_url query param', (done) => { + const { tracker } = new ConstructorIO({ + apiKey: testApiKey, + fetch: fetchSpy, + ...requestQueueOptions, + }); + + tracker.on('success', (responseParams) => { + const requestParams = helpers.extractBodyParamsFromFetch(fetchSpy); + + // Request + expect(fetchSpy).to.have.been.called; + expect(requestParams).to.have.property('canonical_url').to.equal('https://localhost'); + expect(requestParams).to.have.property('document_referrer').to.equal(referrer); + + // Response + expect(responseParams).to.have.property('method').to.equal('POST'); + expect(responseParams).to.have.property('message').to.equal('ok'); + + done(); + }); + + expect(tracker.trackProductInsightsAgentQuestionSubmit(requiredParameters)).to.equal(true); + }); + it('Should respond with a valid response when term, required parameters and segments are provided', (done) => { const segments = ['foo', 'bar']; const { tracker } = new ConstructorIO({ @@ -13985,6 +14905,31 @@ describe(`ConstructorIO - Tracker${bundledDescriptionSuffix}`, () => { expect(tracker.trackProductInsightsAgentAnswerView(requiredParameters)).to.equal(true); }); + it('Should send along document_referrer and canonical_url query param', (done) => { + const { tracker } = new ConstructorIO({ + apiKey: testApiKey, + fetch: fetchSpy, + ...requestQueueOptions, + }); + + tracker.on('success', (responseParams) => { + const requestParams = helpers.extractBodyParamsFromFetch(fetchSpy); + + // Request + expect(fetchSpy).to.have.been.called; + expect(requestParams).to.have.property('canonical_url').to.equal('https://localhost'); + expect(requestParams).to.have.property('document_referrer').to.equal(referrer); + + // Response + expect(responseParams).to.have.property('method').to.equal('POST'); + expect(responseParams).to.have.property('message').to.equal('ok'); + + done(); + }); + + expect(tracker.trackProductInsightsAgentAnswerView(requiredParameters)).to.equal(true); + }); + it('Should respond with a valid response when term, required parameters and segments are provided', (done) => { const segments = ['foo', 'bar']; const { tracker } = new ConstructorIO({ @@ -14283,6 +15228,31 @@ describe(`ConstructorIO - Tracker${bundledDescriptionSuffix}`, () => { expect(tracker.trackProductInsightsAgentAnswerFeedback(requiredParameters)).to.equal(true); }); + it('Should send along document_referrer and canonical_url query param', (done) => { + const { tracker } = new ConstructorIO({ + apiKey: testApiKey, + fetch: fetchSpy, + ...requestQueueOptions, + }); + + tracker.on('success', (responseParams) => { + const requestParams = helpers.extractBodyParamsFromFetch(fetchSpy); + + // Request + expect(fetchSpy).to.have.been.called; + expect(requestParams).to.have.property('canonical_url').to.equal('https://localhost'); + expect(requestParams).to.have.property('document_referrer').to.equal(referrer); + + // Response + expect(responseParams).to.have.property('method').to.equal('POST'); + expect(responseParams).to.have.property('message').to.equal('ok'); + + done(); + }); + + expect(tracker.trackProductInsightsAgentAnswerFeedback(requiredParameters)).to.equal(true); + }); + it('Should respond with a valid response when term, required parameters and segments are provided', (done) => { const segments = ['foo', 'bar']; const { tracker } = new ConstructorIO({ @@ -14567,6 +15537,8 @@ describe(`ConstructorIO - Tracker${bundledDescriptionSuffix}`, () => { expect(requestParams).to.have.property('s'); expect(requestParams).to.have.property('c').to.equal(clientVersion); expect(requestParams).to.have.property('_dt'); + expect(requestParams).to.have.property('canonical_url').to.equal('https://localhost'); + expect(requestParams).to.have.property('document_referrer').to.equal(referrer); expect(requestParams) .to.have.property('banner_ad_id') .to.equal(requiredParameters.bannerAdId); diff --git a/spec/src/utils/jsdom-global.js b/spec/src/utils/jsdom-global.js index cca0db2f..10e9f08f 100644 --- a/spec/src/utils/jsdom-global.js +++ b/spec/src/utils/jsdom-global.js @@ -14,7 +14,7 @@ if (bundled) { cioScriptTag = ``; } -const defaultHtml = `${cioScriptTag}`; +const defaultHtml = `${cioScriptTag}`; // define this here so that we only ever dynamically populate KEYS once. const KEYS = []; diff --git a/src/modules/tracker.js b/src/modules/tracker.js index 376b4385..e9e72eb4 100644 --- a/src/modules/tracker.js +++ b/src/modules/tracker.js @@ -21,6 +21,8 @@ function applyParams(parameters, options) { beaconMode, } = options; const { host, pathname, search } = helpers.getWindowLocation(); + const canonicalUrl = helpers.getCanonicalUrl(); + const documentReferrer = helpers.getDocumentReferrer(); const sendReferrerWithTrackingEvents = (options.sendReferrerWithTrackingEvents === false) ? false : true; // Defaults to 'true' @@ -50,6 +52,14 @@ function applyParams(parameters, options) { aggregateParams.key = apiKey; } + if (documentReferrer) { + aggregateParams.document_referrer = documentReferrer; + } + + if (canonicalUrl) { + aggregateParams.canonical_url = canonicalUrl; + } + if (testCells) { Object.keys(testCells).forEach((testCellKey) => { aggregateParams[`ef-${testCellKey}`] = testCells[testCellKey]; diff --git a/src/utils/helpers.js b/src/utils/helpers.js index 6c138c51..f779fcfc 100644 --- a/src/utils/helpers.js +++ b/src/utils/helpers.js @@ -91,6 +91,29 @@ const utils = { return {}; }, + getDocumentReferrer: () => { + if (utils.canUseDOM()) { + return document?.referrer; + } + + return null; + }, + + getCanonicalUrl: () => { + if (utils.canUseDOM()) { + const linkEle = document?.querySelector('link[rel="canonical"]'); + let canonicalURL = null; + + if (linkEle) { + canonicalURL = linkEle.getAttribute('href'); + } + + return canonicalURL; + } + + return null; + }, + dispatchEvent: (event) => { if (utils.canUseDOM()) { window.dispatchEvent(event);