Last touch: {{ lastSource }}
+ diff --git a/test/fixtures/route-change/nuxt.config.ts b/test/fixtures/route-change/nuxt.config.ts new file mode 100644 index 0000000..b4e2a29 --- /dev/null +++ b/test/fixtures/route-change/nuxt.config.ts @@ -0,0 +1,8 @@ +import UtmModule from '../../../src/module' + +export default defineNuxtConfig({ + modules: [UtmModule], + utm: { + trackOnRouteChange: true, + }, +}) diff --git a/test/fixtures/route-change/package.json b/test/fixtures/route-change/package.json new file mode 100644 index 0000000..6895968 --- /dev/null +++ b/test/fixtures/route-change/package.json @@ -0,0 +1,5 @@ +{ + "private": true, + "name": "route-change", + "type": "module" +} diff --git a/test/integration-route-change-pages.test.ts b/test/integration-route-change-pages.test.ts new file mode 100644 index 0000000..55072ae --- /dev/null +++ b/test/integration-route-change-pages.test.ts @@ -0,0 +1,27 @@ +import { fileURLToPath } from 'node:url' +import { describe, it, expect } from 'vitest' +import { setup, createPage } from '@nuxt/test-utils' + +type TrackingWindow = { trackedRoutes: string[] } + +describe('Route change tracking with pages', async () => { + await setup({ + rootDir: fileURLToPath(new URL('./fixtures/route-change-pages', import.meta.url)), + server: true, + browser: true, + }) + + it('tracks a prerendered landing once, then the route navigated to', async () => { + const page = await createPage('/static?utm_source=static') + await page.getByRole('link', { name: 'Next campaign' }).click() + await page.waitForFunction(() => + (window as unknown as TrackingWindow).trackedRoutes.includes('/next?utm_source=next'), + ) + + expect(await page.evaluate(() => (window as unknown as TrackingWindow).trackedRoutes)).toEqual([ + '/static?utm_source=static', + '/next?utm_source=next', + ]) + await page.close() + }) +}) diff --git a/test/integration-route-change.test.ts b/test/integration-route-change.test.ts new file mode 100644 index 0000000..adeb6d6 --- /dev/null +++ b/test/integration-route-change.test.ts @@ -0,0 +1,36 @@ +import { fileURLToPath } from 'node:url' +import { describe, it, expect } from 'vitest' +import { setup, createPage } from '@nuxt/test-utils' + +describe('Route change tracking without pages', async () => { + await setup({ + rootDir: fileURLToPath(new URL('./fixtures/route-change', import.meta.url)), + server: true, + browser: true, + }) + + it('captures a client-side navigation to new campaign parameters', async () => { + const page = await createPage('/?utm_source=landing') + await page.waitForFunction(() => window.localStorage.getItem('nuxt-utm-data')) + await page.getByRole('button', { name: 'Newsletter' }).click() + const lastTouch = page.getByText(/^Last touch:/) + await lastTouch.waitFor() + + expect(new URL(page.url()).search).toBe('?utm_source=newsletter') + expect(await lastTouch.textContent()).toBe('Last touch: newsletter') + const history = await page.evaluate(() => + JSON.parse(window.localStorage.getItem('nuxt-utm-data') ?? '[]').map( + (entry: { + utmParams: { utm_source?: string } + additionalInfo: { landingPageUrl: string } + }) => [entry.utmParams.utm_source, new URL(entry.additionalInfo.landingPageUrl).search], + ), + ) + expect(history).toEqual([ + ['newsletter', '?utm_source=newsletter'], + ['landing', '?utm_source=landing'], + ]) + + await page.close() + }) +})