Skip to content

Commit

Permalink
Add support for analytics.reset (#1183)
Browse files Browse the repository at this point in the history
  • Loading branch information
silesky authored Nov 8, 2024
1 parent ccc97f1 commit f50bd0f
Show file tree
Hide file tree
Showing 7 changed files with 76 additions and 1 deletion.
5 changes: 5 additions & 0 deletions .changeset/long-plums-repeat.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@segment/analytics-signals': minor
---

add support for analytics.reset()
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import { test, expect } from '@playwright/test'
import { waitForCondition } from '../../helpers/playwright-utils'
import { IndexPage } from './index-page'
import { pTimeout } from '@segment/analytics-core'

/**
* If a signal is generated, the signal buffer should be reset
* when the user clicks on the complex button.
*/
const edgeFn = `const processSignal = (signal) => {
// create a custom signal to echo out the current signal buffer
if (signal.type === 'userDefined') {
analytics.track('current signal buffer', { signalBuffer: signals.signalBuffer })
}
// clicking the complex button to clear the signal buffer
if (signal.type === 'interaction' && signal.data.eventType === 'click' && signal.data.target?.id === 'complex-button') {
analytics.reset()
}
}`

test('calls analytics.reset, and resets the signalBuffer after clear', async ({
page,
}) => {
const indexPage = await new IndexPage().loadAndWait(page, edgeFn)

await indexPage.addUserDefinedSignal({ num: 1 })
const resetCalled = page.evaluate<any>(() => {
return new Promise((resolve) => {
window.analytics.on('reset', resolve)
})
})

await waitForCondition(() => indexPage.trackingAPI.getEvents().length > 0, {
errorMessage:
'No track events found, should have an event with hasSignalsInBuffer: true',
})
const events = indexPage.trackingAPI.getEvents()
const buffer = events[0].properties!.signalBuffer
expect(buffer[0]).toMatchObject({ type: 'userDefined' })
expect(buffer[1]).toMatchObject({ type: 'navigation' })

indexPage.trackingAPI.clear()
await indexPage.clickComplexButton()
await pTimeout(resetCalled, 5000)
await indexPage.addUserDefinedSignal({ num: 2 })
await waitForCondition(() => indexPage.trackingAPI.getEvents().length > 0, {
errorMessage:
'No track events found, should only have one event in the buffer (the current signal)',
})
const events2 = indexPage.trackingAPI.getEvents()
const buffer2 = events2[0].properties!.signalBuffer
expect(buffer2).toHaveLength(1)
expect(buffer2[0]).toMatchObject({ type: 'userDefined' })
})
9 changes: 8 additions & 1 deletion packages/signals/signals/src/core/processor/sandbox.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,9 @@ export type MethodName =
/**
* Buffer of any analytics calls made during the processing of a signal
*/
export type AnalyticsMethodCalls = Record<MethodName, any[]>
export type AnalyticsMethodCalls = Record<MethodName, any[]> & {
reset: unknown[]
}

/**
* Proxy around the analytics client
Expand All @@ -31,6 +33,7 @@ class AnalyticsRuntime implements AnalyticsRuntimePublicApi {
alias: [],
screen: [],
group: [],
reset: [],
}

getCalls(): AnalyticsMethodCalls {
Expand Down Expand Up @@ -115,6 +118,10 @@ class AnalyticsRuntime implements AnalyticsRuntimePublicApi {
console.error(err)
}
}

reset = () => {
this.calls.reset.push([])
}
}

interface CodeSandbox {
Expand Down
3 changes: 3 additions & 0 deletions packages/signals/signals/src/core/signals/signals.ts
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,9 @@ export class Signals implements ISignals {
*/
async start(analytics: AnyAnalytics): Promise<void> {
const analyticsService = new AnalyticsService(analytics)
analyticsService.instance.on('reset', () => {
this.clearStorage()
})

this.globalSettings.update({
edgeFnDownloadURL: analyticsService.edgeFnSettings?.downloadURL,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,6 @@ export const analyticsMock: jest.Mocked<AnyAnalytics> = {
page: jest.fn(),
track: jest.fn(),
addSourceMiddleware: jest.fn(),
reset: jest.fn(),
on: jest.fn(),
}
2 changes: 2 additions & 0 deletions packages/signals/signals/src/types/analytics-api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,8 @@ export interface AnyAnalytics {
group(...args: any[]): void
alias(...args: any[]): void
screen(...args: any[]): void
reset(): void
on(name: 'reset', fn: (...args: any[]) => void): void
}

/**
Expand Down
1 change: 1 addition & 0 deletions packages/signals/signals/src/types/process-signal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ export interface AnalyticsRuntimePublicApi {
group: (...args: any[]) => void
page: (...args: any[]) => void
screen: (...args: any[]) => void
reset: () => void
}

export type ProcessSignalScope = {
Expand Down

0 comments on commit f50bd0f

Please sign in to comment.