Files
what-to-eat/test/clarityPlugin.test.ts
T

83 lines
3.2 KiB
TypeScript

import { afterEach, describe, expect, it, vi } from 'vitest'
afterEach(() => {
vi.unstubAllGlobals()
vi.restoreAllMocks()
})
async function setup(projectId = 'ks1ebw03i5', path = '/') {
vi.resetModules()
window.history.replaceState({}, '', path)
const send = vi.fn()
const load = vi.fn().mockResolvedValue({})
const script = vi.fn(() => ({ proxy: { clarity: send }, load }))
const ready = vi.fn()
const beforeEach = vi.fn()
vi.stubGlobal('defineNuxtPlugin', (setup: () => void) => setup)
vi.stubGlobal('useRuntimeConfig', () => ({ public: { clarityProjectId: projectId, clarityDomains: window.location.hostname } }))
vi.stubGlobal('useScriptClarity', script)
vi.stubGlobal('onNuxtReady', ready)
vi.stubGlobal('useRouter', () => ({ beforeEach }))
const { default: plugin } = await import('../apps/web/app/plugins/clarity.client')
;(plugin as unknown as () => void)()
return { send, load, script, ready, beforeEach }
}
describe('clarity client integration', () => {
it('loads once after Nuxt is ready and forwards legacy and funnel action names', async () => {
const { send, load, script, ready } = await setup()
expect(script).toHaveBeenCalledExactlyOnceWith({
id: 'ks1ebw03i5',
scriptOptions: { bundle: false, proxy: false, trigger: 'manual' },
scriptInput: { src: 'https://www.clarity.ms/tag/ks1ebw03i5', referrerpolicy: 'no-referrer' },
})
expect(load).not.toHaveBeenCalled()
ready.mock.calls[0]![0]()
expect(load).toHaveBeenCalledTimes(1)
const { trackCookEvent } = await import('../apps/web/app/utils/analytics')
trackCookEvent('click_stuff')
trackCookEvent('click_tool')
trackCookEvent('click_dish')
trackCookEvent('view_cook')
trackCookEvent('select_ingredients')
trackCookEvent('view_results')
trackCookEvent('results_empty')
trackCookEvent('view_recipe_detail')
trackCookEvent('click_recipe_video')
expect(send.mock.calls).toEqual([
['event', 'click_stuff'],
['event', 'click_tool'],
['event', 'click_dish'],
['event', 'view_cook'],
['event', 'select_ingredients'],
['event', 'view_results'],
['event', 'results_empty'],
['event', 'view_recipe_detail'],
['event', 'click_recipe_video'],
])
})
it('skips disabled projects and direct auth callback entries', async () => {
expect((await setup('')).script).not.toHaveBeenCalled()
expect((await setup('ks1ebw03i5', '/auth/callback?ticket=secret')).script).not.toHaveBeenCalled()
})
it('respects Do Not Track', async () => {
vi.stubGlobal('navigator', { doNotTrack: '1' })
expect((await setup()).script).not.toHaveBeenCalled()
})
it('stops before navigating to auth and prevents a deferred script load or more events', async () => {
const stop = vi.fn()
vi.stubGlobal('clarity', stop)
const { beforeEach, ready, load, send } = await setup()
beforeEach.mock.calls[0]![0]({ fullPath: '/auth/callback?ticket=secret' })
expect(stop).toHaveBeenCalledWith('stop')
ready.mock.calls[0]![0]()
expect(load).not.toHaveBeenCalled()
const { trackCookEvent } = await import('../apps/web/app/utils/analytics')
trackCookEvent('click_dish')
expect(send).not.toHaveBeenCalled()
})
})