Skip to content

Commit c5ce1cd

Browse files
committed
feat(replay): account for V2 trigger groups
1 parent d7391a3 commit c5ce1cd

File tree

7 files changed

+1315
-36
lines changed

7 files changed

+1315
-36
lines changed
Lines changed: 153 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,153 @@
1+
/**
2+
* Tests for tracking which trigger groups caused recording to start
3+
*/
4+
5+
import { SessionRecordingTriggerGroup } from '../../../types'
6+
7+
describe('Trigger Group Tracking', () => {
8+
describe('Session Properties', () => {
9+
it('should include properties showing which trigger groups caused recording', () => {
10+
// This test documents the expected session properties that will be set
11+
// Only groups that BOTH matched AND were sampled are included
12+
13+
const expectedSessionProperties = {
14+
// Properties available to all users for analytics
15+
$sdk_debug_replay_recording_trigger_groups: [
16+
{
17+
id: 'error-tracking',
18+
name: 'Error Tracking',
19+
matched: true, // Conditions were met
20+
sampled: true, // Sample rate hit
21+
},
22+
],
23+
$sdk_debug_replay_recording_trigger_group_ids: ['error-tracking'],
24+
$sdk_debug_replay_recording_trigger_group_names: ['Error Tracking'],
25+
}
26+
27+
// These properties will be present on ALL events captured during the session
28+
// Despite the $sdk_debug_ prefix, they're available to all users
29+
expect(expectedSessionProperties).toBeDefined()
30+
})
31+
32+
it('should handle multiple groups causing recording (union behavior)', () => {
33+
const expectedSessionProperties = {
34+
$sdk_debug_replay_recording_trigger_groups: [
35+
{
36+
id: 'errors',
37+
name: 'Error Tracking',
38+
matched: true,
39+
sampled: true,
40+
},
41+
{
42+
id: 'premium-users',
43+
name: 'Premium Users',
44+
matched: true,
45+
sampled: true,
46+
},
47+
],
48+
$sdk_debug_replay_recording_trigger_group_ids: ['errors', 'premium-users'],
49+
$sdk_debug_replay_recording_trigger_group_names: ['Error Tracking', 'Premium Users'],
50+
}
51+
52+
// When multiple groups both match AND sample, ALL are tracked
53+
expect(expectedSessionProperties.$sdk_debug_replay_recording_trigger_group_ids).toHaveLength(2)
54+
})
55+
56+
it('should NOT include groups that matched but were sampled out', () => {
57+
// Example: Group "low-priority" matched (conditions met) but sample rate missed (10% = 0.1)
58+
// This group should NOT appear in the session properties because it didn't cause recording
59+
60+
const expectedSessionProperties = {
61+
$sdk_debug_replay_recording_trigger_groups: [], // Empty - group didn't cause recording
62+
$sdk_debug_replay_recording_trigger_group_ids: [],
63+
$sdk_debug_replay_recording_trigger_group_names: [],
64+
}
65+
66+
// Only groups that BOTH matched AND sampled are included
67+
expect(expectedSessionProperties.$sdk_debug_replay_recording_trigger_groups).toHaveLength(0)
68+
})
69+
})
70+
71+
describe('Custom Events', () => {
72+
it('should emit custom event when sampling decision is made for each group', () => {
73+
const expectedCustomEvent = {
74+
tag: 'triggerGroupSamplingDecisionMade',
75+
payload: {
76+
group_id: 'error-tracking',
77+
group_name: 'Error Tracking',
78+
sampleRate: 1.0,
79+
isSampled: true,
80+
},
81+
}
82+
83+
// This custom event is added to the recording when sampling decisions are made
84+
expect(expectedCustomEvent).toBeDefined()
85+
})
86+
})
87+
88+
describe('Analytics Use Cases', () => {
89+
it('should enable filtering recordings by trigger group in analytics', () => {
90+
// Example: Find all recordings caused by error tracking
91+
const query = `
92+
SELECT *
93+
FROM recordings
94+
WHERE 'error-tracking' IN $sdk_debug_replay_recording_trigger_group_ids
95+
`
96+
97+
expect(query).toBeDefined()
98+
})
99+
100+
it('should enable understanding trigger group effectiveness', () => {
101+
// Example: Compare how many sessions each group triggers
102+
const query = `
103+
SELECT
104+
group_id,
105+
COUNT(*) as sessions_triggered
106+
FROM recordings,
107+
LATERAL VIEW EXPLODE($sdk_debug_replay_recording_trigger_group_ids) AS group_id
108+
GROUP BY group_id
109+
`
110+
111+
expect(query).toBeDefined()
112+
})
113+
114+
it('should enable debugging why a session was recorded', () => {
115+
// For any given recording, you can see exactly which trigger group(s) caused it
116+
// If a group is in this array, it means:
117+
// 1. Its conditions were met (matched)
118+
// 2. Its sample rate hit (sampled)
119+
// 3. It caused recording to start
120+
121+
const debugInfo = {
122+
// Check if error tracking group caused this recording
123+
wasErrorTracking: (groupIds: string[]) => groupIds.includes('error-tracking'),
124+
125+
// Get all trigger groups that caused recording
126+
getAllCauses: (groups: Array<{ id: string; name: string }>) => groups.map((g) => g.name),
127+
}
128+
129+
expect(debugInfo).toBeDefined()
130+
})
131+
})
132+
133+
describe('Type Definitions', () => {
134+
it('should have proper TypeScript types for trigger groups', () => {
135+
const group: SessionRecordingTriggerGroup = {
136+
id: 'test-group',
137+
name: 'Test Group',
138+
sampleRate: 0.5,
139+
minDurationMs: 1000,
140+
conditions: {
141+
matchType: 'any',
142+
events: ['error'],
143+
urls: [{ url: '/checkout', matching: 'regex' }],
144+
flag: 'beta-users',
145+
},
146+
}
147+
148+
expect(group.id).toBe('test-group')
149+
expect(group.sampleRate).toBe(0.5)
150+
expect(group.conditions.matchType).toBe('any')
151+
})
152+
})
153+
})

0 commit comments

Comments
 (0)