Skip to content

Commit f50bd0f

Browse files
authored
Add support for analytics.reset (#1183)
1 parent ccc97f1 commit f50bd0f

File tree

7 files changed

+76
-1
lines changed

7 files changed

+76
-1
lines changed

.changeset/long-plums-repeat.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@segment/analytics-signals': minor
3+
---
4+
5+
add support for analytics.reset()
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
import { test, expect } from '@playwright/test'
2+
import { waitForCondition } from '../../helpers/playwright-utils'
3+
import { IndexPage } from './index-page'
4+
import { pTimeout } from '@segment/analytics-core'
5+
6+
/**
7+
* If a signal is generated, the signal buffer should be reset
8+
* when the user clicks on the complex button.
9+
*/
10+
const edgeFn = `const processSignal = (signal) => {
11+
// create a custom signal to echo out the current signal buffer
12+
if (signal.type === 'userDefined') {
13+
analytics.track('current signal buffer', { signalBuffer: signals.signalBuffer })
14+
}
15+
16+
// clicking the complex button to clear the signal buffer
17+
if (signal.type === 'interaction' && signal.data.eventType === 'click' && signal.data.target?.id === 'complex-button') {
18+
analytics.reset()
19+
}
20+
}`
21+
22+
test('calls analytics.reset, and resets the signalBuffer after clear', async ({
23+
page,
24+
}) => {
25+
const indexPage = await new IndexPage().loadAndWait(page, edgeFn)
26+
27+
await indexPage.addUserDefinedSignal({ num: 1 })
28+
const resetCalled = page.evaluate<any>(() => {
29+
return new Promise((resolve) => {
30+
window.analytics.on('reset', resolve)
31+
})
32+
})
33+
34+
await waitForCondition(() => indexPage.trackingAPI.getEvents().length > 0, {
35+
errorMessage:
36+
'No track events found, should have an event with hasSignalsInBuffer: true',
37+
})
38+
const events = indexPage.trackingAPI.getEvents()
39+
const buffer = events[0].properties!.signalBuffer
40+
expect(buffer[0]).toMatchObject({ type: 'userDefined' })
41+
expect(buffer[1]).toMatchObject({ type: 'navigation' })
42+
43+
indexPage.trackingAPI.clear()
44+
await indexPage.clickComplexButton()
45+
await pTimeout(resetCalled, 5000)
46+
await indexPage.addUserDefinedSignal({ num: 2 })
47+
await waitForCondition(() => indexPage.trackingAPI.getEvents().length > 0, {
48+
errorMessage:
49+
'No track events found, should only have one event in the buffer (the current signal)',
50+
})
51+
const events2 = indexPage.trackingAPI.getEvents()
52+
const buffer2 = events2[0].properties!.signalBuffer
53+
expect(buffer2).toHaveLength(1)
54+
expect(buffer2[0]).toMatchObject({ type: 'userDefined' })
55+
})

packages/signals/signals/src/core/processor/sandbox.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,9 @@ export type MethodName =
1818
/**
1919
* Buffer of any analytics calls made during the processing of a signal
2020
*/
21-
export type AnalyticsMethodCalls = Record<MethodName, any[]>
21+
export type AnalyticsMethodCalls = Record<MethodName, any[]> & {
22+
reset: unknown[]
23+
}
2224

2325
/**
2426
* Proxy around the analytics client
@@ -31,6 +33,7 @@ class AnalyticsRuntime implements AnalyticsRuntimePublicApi {
3133
alias: [],
3234
screen: [],
3335
group: [],
36+
reset: [],
3437
}
3538

3639
getCalls(): AnalyticsMethodCalls {
@@ -115,6 +118,10 @@ class AnalyticsRuntime implements AnalyticsRuntimePublicApi {
115118
console.error(err)
116119
}
117120
}
121+
122+
reset = () => {
123+
this.calls.reset.push([])
124+
}
118125
}
119126

120127
interface CodeSandbox {

packages/signals/signals/src/core/signals/signals.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,9 @@ export class Signals implements ISignals {
8888
*/
8989
async start(analytics: AnyAnalytics): Promise<void> {
9090
const analyticsService = new AnalyticsService(analytics)
91+
analyticsService.instance.on('reset', () => {
92+
this.clearStorage()
93+
})
9194

9295
this.globalSettings.update({
9396
edgeFnDownloadURL: analyticsService.edgeFnSettings?.downloadURL,

packages/signals/signals/src/test-helpers/mocks/analytics-mock.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,4 +20,6 @@ export const analyticsMock: jest.Mocked<AnyAnalytics> = {
2020
page: jest.fn(),
2121
track: jest.fn(),
2222
addSourceMiddleware: jest.fn(),
23+
reset: jest.fn(),
24+
on: jest.fn(),
2325
}

packages/signals/signals/src/types/analytics-api.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,8 @@ export interface AnyAnalytics {
6666
group(...args: any[]): void
6767
alias(...args: any[]): void
6868
screen(...args: any[]): void
69+
reset(): void
70+
on(name: 'reset', fn: (...args: any[]) => void): void
6971
}
7072

7173
/**

packages/signals/signals/src/types/process-signal.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ export interface AnalyticsRuntimePublicApi {
1414
group: (...args: any[]) => void
1515
page: (...args: any[]) => void
1616
screen: (...args: any[]) => void
17+
reset: () => void
1718
}
1819

1920
export type ProcessSignalScope = {

0 commit comments

Comments
 (0)