@interfere/next 0.0.0-alpha.10 → 0.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -0
- package/dist/__tests__/build/with-interfere-coverage.test.d.ts +2 -0
- package/dist/__tests__/build/with-interfere-coverage.test.d.ts.map +1 -0
- package/dist/__tests__/build/with-interfere-coverage.test.js +338 -0
- package/dist/__tests__/build/with-interfere-coverage.test.js.map +1 -0
- package/dist/__tests__/build/with-interfere.test.d.ts +2 -0
- package/dist/__tests__/build/with-interfere.test.d.ts.map +1 -0
- package/dist/__tests__/build/with-interfere.test.js +466 -0
- package/dist/__tests__/build/with-interfere.test.js.map +1 -0
- package/dist/__tests__/core/client.test.d.ts +2 -0
- package/dist/__tests__/core/client.test.d.ts.map +1 -0
- package/dist/__tests__/core/client.test.js +373 -0
- package/dist/__tests__/core/client.test.js.map +1 -0
- package/dist/__tests__/core/debug.test.d.ts +2 -0
- package/dist/__tests__/core/debug.test.d.ts.map +1 -0
- package/dist/__tests__/core/debug.test.js +277 -0
- package/dist/__tests__/core/debug.test.js.map +1 -0
- package/dist/__tests__/core/encoders.test.d.ts +2 -0
- package/dist/__tests__/core/encoders.test.d.ts.map +1 -0
- package/dist/__tests__/core/encoders.test.js +56 -0
- package/dist/__tests__/core/encoders.test.js.map +1 -0
- package/dist/__tests__/core/persistence.test.d.ts +2 -0
- package/dist/__tests__/core/persistence.test.d.ts.map +1 -0
- package/dist/__tests__/core/persistence.test.js +129 -0
- package/dist/__tests__/core/persistence.test.js.map +1 -0
- package/dist/__tests__/core/rage-click.test.d.ts +2 -0
- package/dist/__tests__/core/rage-click.test.d.ts.map +1 -0
- package/dist/__tests__/core/rage-click.test.js +121 -0
- package/dist/__tests__/core/rage-click.test.js.map +1 -0
- package/dist/__tests__/core/session-manager.test.d.ts +2 -0
- package/dist/__tests__/core/session-manager.test.d.ts.map +1 -0
- package/dist/__tests__/core/session-manager.test.js +1132 -0
- package/dist/__tests__/core/session-manager.test.js.map +1 -0
- package/dist/__tests__/integration/release-upload.test.d.ts +2 -0
- package/dist/__tests__/integration/release-upload.test.d.ts.map +1 -0
- package/dist/__tests__/integration/release-upload.test.js +173 -0
- package/dist/__tests__/integration/release-upload.test.js.map +1 -0
- package/dist/__tests__/react/provider.test.d.ts +2 -0
- package/dist/__tests__/react/provider.test.d.ts.map +1 -0
- package/dist/__tests__/react/provider.test.jsx +166 -0
- package/dist/__tests__/react/provider.test.jsx.map +1 -0
- package/dist/__tests__/session/persistence.test.d.ts +2 -0
- package/dist/__tests__/session/persistence.test.d.ts.map +1 -0
- package/dist/__tests__/session/persistence.test.js +129 -0
- package/dist/__tests__/session/persistence.test.js.map +1 -0
- package/dist/__tests__/session/replay.test.d.ts +2 -0
- package/dist/__tests__/session/replay.test.d.ts.map +1 -0
- package/dist/__tests__/session/replay.test.js +296 -0
- package/dist/__tests__/session/replay.test.js.map +1 -0
- package/dist/__tests__/session/session-summary.test.d.ts +2 -0
- package/dist/__tests__/session/session-summary.test.d.ts.map +1 -0
- package/dist/__tests__/session/session-summary.test.js +763 -0
- package/dist/__tests__/session/session-summary.test.js.map +1 -0
- package/dist/build/index.d.ts +3 -0
- package/dist/build/index.d.ts.map +1 -0
- package/dist/build/index.js +2 -0
- package/dist/build/index.js.map +1 -0
- package/dist/build/with-interfere.d.ts +54 -0
- package/dist/build/with-interfere.d.ts.map +1 -0
- package/dist/build/with-interfere.js +267 -0
- package/dist/build/with-interfere.js.map +1 -0
- package/dist/core/client-core.d.ts +27 -0
- package/dist/core/client-core.d.ts.map +1 -0
- package/dist/core/client-core.js +164 -0
- package/dist/core/client-core.js.map +1 -0
- package/dist/core/client.d.ts +70 -18
- package/dist/core/client.d.ts.map +1 -1
- package/dist/core/client.js +112 -104
- package/dist/core/client.js.map +1 -1
- package/dist/core/client.test.js +227 -92
- package/dist/core/client.test.js.map +1 -1
- package/dist/core/constants.d.ts +12 -0
- package/dist/core/constants.d.ts.map +1 -0
- package/dist/core/constants.js +17 -0
- package/dist/core/constants.js.map +1 -0
- package/dist/core/debug.d.ts +47 -0
- package/dist/core/debug.d.ts.map +1 -0
- package/dist/core/debug.js +79 -0
- package/dist/core/debug.js.map +1 -0
- package/dist/core/encoders.test.js +20 -19
- package/dist/core/encoders.test.js.map +1 -1
- package/dist/core/error-handlers.d.ts.map +1 -1
- package/dist/core/error-handlers.js +42 -41
- package/dist/core/error-handlers.js.map +1 -1
- package/dist/core/runtime.d.ts +7 -0
- package/dist/core/runtime.d.ts.map +1 -0
- package/dist/core/runtime.js +16 -0
- package/dist/core/runtime.js.map +1 -0
- package/dist/index.d.ts +10 -7
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -7
- package/dist/index.js.map +1 -1
- package/dist/next/error-boundary.d.ts +5 -5
- package/dist/next/error-boundary.d.ts.map +1 -1
- package/dist/next/error-boundary.jsx +5 -5
- package/dist/next/middleware.d.ts +1 -1
- package/dist/next/middleware.js +13 -13
- package/dist/persistence/index.d.ts +5 -0
- package/dist/persistence/index.d.ts.map +1 -0
- package/dist/persistence/index.js +67 -0
- package/dist/persistence/index.js.map +1 -0
- package/dist/persistence/storage.d.ts +5 -0
- package/dist/persistence/storage.d.ts.map +1 -0
- package/dist/persistence/storage.js +67 -0
- package/dist/persistence/storage.js.map +1 -0
- package/dist/react/provider.d.ts +9 -5
- package/dist/react/provider.d.ts.map +1 -1
- package/dist/react/provider.jsx +33 -10
- package/dist/react/provider.jsx.map +1 -1
- package/dist/session/constants.d.ts +19 -0
- package/dist/session/constants.d.ts.map +1 -0
- package/dist/session/constants.js +34 -0
- package/dist/session/constants.js.map +1 -0
- package/dist/session/persistence.d.ts +58 -0
- package/dist/session/persistence.d.ts.map +1 -0
- package/dist/session/persistence.js +180 -0
- package/dist/session/persistence.js.map +1 -0
- package/dist/session/persistence.test.d.ts +2 -0
- package/dist/session/persistence.test.d.ts.map +1 -0
- package/dist/session/persistence.test.js +129 -0
- package/dist/session/persistence.test.js.map +1 -0
- package/dist/session/rage-click.d.ts +17 -0
- package/dist/session/rage-click.d.ts.map +1 -0
- package/dist/session/rage-click.js +104 -0
- package/dist/session/rage-click.js.map +1 -0
- package/dist/session/rage-click.test.d.ts +2 -0
- package/dist/session/rage-click.test.d.ts.map +1 -0
- package/dist/session/rage-click.test.js +124 -0
- package/dist/session/rage-click.test.js.map +1 -0
- package/dist/session/replay.d.ts +2 -2
- package/dist/session/replay.d.ts.map +1 -1
- package/dist/session/replay.js +57 -24
- package/dist/session/replay.js.map +1 -1
- package/dist/session/session-manager.d.ts +126 -0
- package/dist/session/session-manager.d.ts.map +1 -0
- package/dist/session/session-manager.js +635 -0
- package/dist/session/session-manager.js.map +1 -0
- package/dist/session/session-manager.test.d.ts +2 -0
- package/dist/session/session-manager.test.d.ts.map +1 -0
- package/dist/session/session-manager.test.js +1134 -0
- package/dist/session/session-manager.test.js.map +1 -0
- package/dist/session/session-summary.d.ts +2 -2
- package/dist/session/session-summary.d.ts.map +1 -1
- package/dist/session/session-summary.js +94 -47
- package/dist/session/session-summary.js.map +1 -1
- package/dist/storage/index.d.ts +5 -0
- package/dist/storage/index.d.ts.map +1 -0
- package/dist/storage/index.js +67 -0
- package/dist/storage/index.js.map +1 -0
- package/dist/types/storage.d.ts +7 -0
- package/dist/types/storage.d.ts.map +1 -0
- package/dist/types/storage.js +2 -0
- package/dist/types/storage.js.map +1 -0
- package/package.json +24 -7
|
@@ -0,0 +1,277 @@
|
|
|
1
|
+
import { describe, it, expect, vi, beforeEach } from "vitest";
|
|
2
|
+
import { DebugUtils } from "../../core/debug.js";
|
|
3
|
+
// Mock dependencies
|
|
4
|
+
const mockSessionManager = {
|
|
5
|
+
checkAndGetSessionAndWindowId: vi.fn(),
|
|
6
|
+
sessionTimeoutMs: 30000,
|
|
7
|
+
};
|
|
8
|
+
const mockPersistence = {
|
|
9
|
+
isDisabled: vi.fn(),
|
|
10
|
+
};
|
|
11
|
+
const mockConfig = {
|
|
12
|
+
buildId: "test-build-id",
|
|
13
|
+
releaseId: "test-release-id",
|
|
14
|
+
persistence: "localStorage",
|
|
15
|
+
};
|
|
16
|
+
const mockRuntime = "browser";
|
|
17
|
+
// Mock window and storage APIs
|
|
18
|
+
const mockLocalStorage = {
|
|
19
|
+
length: 3,
|
|
20
|
+
key: vi.fn((index) => {
|
|
21
|
+
const keys = ["interfere_session", "other_key", "interfere_window"];
|
|
22
|
+
return keys[index] || null;
|
|
23
|
+
}),
|
|
24
|
+
};
|
|
25
|
+
const mockSessionStorage = {
|
|
26
|
+
length: 2,
|
|
27
|
+
key: vi.fn((index) => {
|
|
28
|
+
const keys = ["interfere_session", "interfere_window"];
|
|
29
|
+
return keys[index] || null;
|
|
30
|
+
}),
|
|
31
|
+
};
|
|
32
|
+
const mockWindow = {
|
|
33
|
+
localStorage: mockLocalStorage,
|
|
34
|
+
sessionStorage: mockSessionStorage,
|
|
35
|
+
};
|
|
36
|
+
Object.defineProperty(global, "window", {
|
|
37
|
+
value: mockWindow,
|
|
38
|
+
writable: true,
|
|
39
|
+
});
|
|
40
|
+
describe("DebugUtils", () => {
|
|
41
|
+
let debugUtils;
|
|
42
|
+
beforeEach(() => {
|
|
43
|
+
vi.clearAllMocks();
|
|
44
|
+
debugUtils = new DebugUtils({
|
|
45
|
+
config: mockConfig,
|
|
46
|
+
sessionManager: mockSessionManager,
|
|
47
|
+
persistence: mockPersistence,
|
|
48
|
+
surface: "test-surface",
|
|
49
|
+
runtime: mockRuntime,
|
|
50
|
+
});
|
|
51
|
+
});
|
|
52
|
+
describe("constructor", () => {
|
|
53
|
+
it("should initialize with provided parameters", () => {
|
|
54
|
+
expect(debugUtils).toBeDefined();
|
|
55
|
+
});
|
|
56
|
+
});
|
|
57
|
+
describe("getDebugInfo", () => {
|
|
58
|
+
it("should return complete debug information", () => {
|
|
59
|
+
const mockSessionData = {
|
|
60
|
+
sessionId: "test-session-id",
|
|
61
|
+
windowId: "test-window-id",
|
|
62
|
+
sessionStartTimestamp: 1000000,
|
|
63
|
+
lastActivityTimestamp: 1005000,
|
|
64
|
+
};
|
|
65
|
+
mockSessionManager.checkAndGetSessionAndWindowId.mockReturnValue(mockSessionData);
|
|
66
|
+
mockPersistence.isDisabled.mockReturnValue(false);
|
|
67
|
+
const result = debugUtils.getDebugInfo(5);
|
|
68
|
+
expect(result).toEqual({
|
|
69
|
+
sessionId: "test-session-id",
|
|
70
|
+
windowId: "test-window-id",
|
|
71
|
+
sessionStartTimestamp: 1000000,
|
|
72
|
+
lastActivityTimestamp: 1005000,
|
|
73
|
+
sessionTimeoutMs: 30000,
|
|
74
|
+
sessionAge: expect.any(Number),
|
|
75
|
+
timeSinceLastActivity: expect.any(Number),
|
|
76
|
+
isSessionActive: true,
|
|
77
|
+
config: mockConfig,
|
|
78
|
+
storageInfo: {
|
|
79
|
+
canUseLocalStorage: true,
|
|
80
|
+
canUseSessionStorage: false,
|
|
81
|
+
storageKeys: ["localStorage: interfere_session", "localStorage: interfere_window"],
|
|
82
|
+
},
|
|
83
|
+
queueLength: 5,
|
|
84
|
+
surface: "test-surface",
|
|
85
|
+
runtime: "browser",
|
|
86
|
+
buildId: "test-build-id",
|
|
87
|
+
releaseId: "test-release-id",
|
|
88
|
+
});
|
|
89
|
+
});
|
|
90
|
+
it("should handle null session data", () => {
|
|
91
|
+
mockSessionManager.checkAndGetSessionAndWindowId.mockReturnValue({
|
|
92
|
+
sessionId: null,
|
|
93
|
+
windowId: null,
|
|
94
|
+
sessionStartTimestamp: null,
|
|
95
|
+
lastActivityTimestamp: null,
|
|
96
|
+
});
|
|
97
|
+
mockPersistence.isDisabled.mockReturnValue(false);
|
|
98
|
+
const result = debugUtils.getDebugInfo(0);
|
|
99
|
+
expect(result.sessionId).toBeNull();
|
|
100
|
+
expect(result.windowId).toBeNull();
|
|
101
|
+
expect(result.sessionStartTimestamp).toBeNull();
|
|
102
|
+
expect(result.lastActivityTimestamp).toBeNull();
|
|
103
|
+
expect(result.sessionAge).toBe(0);
|
|
104
|
+
expect(result.timeSinceLastActivity).toBe(0);
|
|
105
|
+
});
|
|
106
|
+
it("should calculate session age correctly", () => {
|
|
107
|
+
const now = Date.now();
|
|
108
|
+
const sessionStart = now - 60000; // 1 minute ago
|
|
109
|
+
mockSessionManager.checkAndGetSessionAndWindowId.mockReturnValue({
|
|
110
|
+
sessionId: "test-session",
|
|
111
|
+
windowId: "test-window",
|
|
112
|
+
sessionStartTimestamp: sessionStart,
|
|
113
|
+
lastActivityTimestamp: now - 30000, // 30 seconds ago
|
|
114
|
+
});
|
|
115
|
+
mockPersistence.isDisabled.mockReturnValue(false);
|
|
116
|
+
const result = debugUtils.getDebugInfo(0);
|
|
117
|
+
expect(result.sessionAge).toBeGreaterThan(59000);
|
|
118
|
+
expect(result.sessionAge).toBeLessThan(61000);
|
|
119
|
+
expect(result.timeSinceLastActivity).toBeGreaterThan(29000);
|
|
120
|
+
expect(result.timeSinceLastActivity).toBeLessThan(31000);
|
|
121
|
+
});
|
|
122
|
+
it("should determine session active status correctly", () => {
|
|
123
|
+
const now = Date.now();
|
|
124
|
+
// Active session (last activity within timeout)
|
|
125
|
+
mockSessionManager.checkAndGetSessionAndWindowId.mockReturnValue({
|
|
126
|
+
sessionId: "test-session",
|
|
127
|
+
windowId: "test-window",
|
|
128
|
+
sessionStartTimestamp: now - 60000,
|
|
129
|
+
lastActivityTimestamp: now - 10000, // 10 seconds ago
|
|
130
|
+
});
|
|
131
|
+
mockPersistence.isDisabled.mockReturnValue(false);
|
|
132
|
+
let result = debugUtils.getDebugInfo(0);
|
|
133
|
+
expect(result.isSessionActive).toBe(true);
|
|
134
|
+
// Inactive session (last activity beyond timeout)
|
|
135
|
+
mockSessionManager.checkAndGetSessionAndWindowId.mockReturnValue({
|
|
136
|
+
sessionId: "test-session",
|
|
137
|
+
windowId: "test-window",
|
|
138
|
+
sessionStartTimestamp: now - 60000,
|
|
139
|
+
lastActivityTimestamp: now - 40000, // 40 seconds ago
|
|
140
|
+
});
|
|
141
|
+
result = debugUtils.getDebugInfo(0);
|
|
142
|
+
expect(result.isSessionActive).toBe(false);
|
|
143
|
+
});
|
|
144
|
+
});
|
|
145
|
+
describe("getStorageInfo", () => {
|
|
146
|
+
it("should return localStorage info when persistence is localStorage", () => {
|
|
147
|
+
mockPersistence.isDisabled.mockReturnValue(false);
|
|
148
|
+
const result = debugUtils.getDebugInfo(0);
|
|
149
|
+
expect(result.storageInfo.canUseLocalStorage).toBe(true);
|
|
150
|
+
expect(result.storageInfo.canUseSessionStorage).toBe(false);
|
|
151
|
+
expect(result.storageInfo.storageKeys).toEqual([
|
|
152
|
+
"localStorage: interfere_session",
|
|
153
|
+
"localStorage: interfere_window",
|
|
154
|
+
]);
|
|
155
|
+
});
|
|
156
|
+
it("should return sessionStorage info when persistence is sessionStorage", () => {
|
|
157
|
+
const debugUtilsWithSessionStorage = new DebugUtils({
|
|
158
|
+
config: { ...mockConfig, persistence: "sessionStorage" },
|
|
159
|
+
sessionManager: mockSessionManager,
|
|
160
|
+
persistence: mockPersistence,
|
|
161
|
+
surface: "test-surface",
|
|
162
|
+
runtime: mockRuntime,
|
|
163
|
+
});
|
|
164
|
+
mockPersistence.isDisabled.mockReturnValue(false);
|
|
165
|
+
const result = debugUtilsWithSessionStorage.getDebugInfo(0);
|
|
166
|
+
expect(result.storageInfo.canUseLocalStorage).toBe(false);
|
|
167
|
+
expect(result.storageInfo.canUseSessionStorage).toBe(true);
|
|
168
|
+
expect(result.storageInfo.storageKeys).toEqual([
|
|
169
|
+
"sessionStorage: interfere_session",
|
|
170
|
+
"sessionStorage: interfere_window",
|
|
171
|
+
]);
|
|
172
|
+
});
|
|
173
|
+
it("should return disabled storage info when persistence is disabled", () => {
|
|
174
|
+
mockPersistence.isDisabled.mockReturnValue(true);
|
|
175
|
+
const result = debugUtils.getDebugInfo(0);
|
|
176
|
+
expect(result.storageInfo.canUseLocalStorage).toBe(false);
|
|
177
|
+
expect(result.storageInfo.canUseSessionStorage).toBe(false);
|
|
178
|
+
expect(result.storageInfo.storageKeys).toEqual([]);
|
|
179
|
+
});
|
|
180
|
+
it("should handle missing window object", () => {
|
|
181
|
+
// @ts-expect-error - Testing non-browser environment
|
|
182
|
+
delete global.window;
|
|
183
|
+
mockPersistence.isDisabled.mockReturnValue(false);
|
|
184
|
+
const result = debugUtils.getDebugInfo(0);
|
|
185
|
+
expect(result.storageInfo.canUseLocalStorage).toBe(false);
|
|
186
|
+
expect(result.storageInfo.canUseSessionStorage).toBe(false);
|
|
187
|
+
expect(result.storageInfo.storageKeys).toEqual([]);
|
|
188
|
+
});
|
|
189
|
+
it("should handle missing localStorage", () => {
|
|
190
|
+
const mockWindowWithoutLocalStorage = {
|
|
191
|
+
sessionStorage: mockSessionStorage,
|
|
192
|
+
};
|
|
193
|
+
Object.defineProperty(global, "window", {
|
|
194
|
+
value: mockWindowWithoutLocalStorage,
|
|
195
|
+
writable: true,
|
|
196
|
+
});
|
|
197
|
+
mockPersistence.isDisabled.mockReturnValue(false);
|
|
198
|
+
const result = debugUtils.getDebugInfo(0);
|
|
199
|
+
expect(result.storageInfo.canUseLocalStorage).toBe(false);
|
|
200
|
+
expect(result.storageInfo.canUseSessionStorage).toBe(false);
|
|
201
|
+
expect(result.storageInfo.storageKeys).toEqual([]);
|
|
202
|
+
});
|
|
203
|
+
it("should handle missing sessionStorage", () => {
|
|
204
|
+
const mockWindowWithoutSessionStorage = {
|
|
205
|
+
localStorage: mockLocalStorage,
|
|
206
|
+
};
|
|
207
|
+
Object.defineProperty(global, "window", {
|
|
208
|
+
value: mockWindowWithoutSessionStorage,
|
|
209
|
+
writable: true,
|
|
210
|
+
});
|
|
211
|
+
const debugUtilsWithSessionStorage = new DebugUtils({
|
|
212
|
+
config: { ...mockConfig, persistence: "sessionStorage" },
|
|
213
|
+
sessionManager: mockSessionManager,
|
|
214
|
+
persistence: mockPersistence,
|
|
215
|
+
surface: "test-surface",
|
|
216
|
+
runtime: mockRuntime,
|
|
217
|
+
});
|
|
218
|
+
mockPersistence.isDisabled.mockReturnValue(false);
|
|
219
|
+
const result = debugUtilsWithSessionStorage.getDebugInfo(0);
|
|
220
|
+
expect(result.storageInfo.canUseLocalStorage).toBe(false);
|
|
221
|
+
expect(result.storageInfo.canUseSessionStorage).toBe(false);
|
|
222
|
+
expect(result.storageInfo.storageKeys).toEqual([]);
|
|
223
|
+
});
|
|
224
|
+
it("should handle storage access errors", () => {
|
|
225
|
+
const mockStorageWithError = {
|
|
226
|
+
length: 3,
|
|
227
|
+
key: vi.fn(() => {
|
|
228
|
+
throw new Error("Storage access denied");
|
|
229
|
+
}),
|
|
230
|
+
};
|
|
231
|
+
const mockWindowWithErrorStorage = {
|
|
232
|
+
localStorage: mockStorageWithError,
|
|
233
|
+
sessionStorage: mockSessionStorage,
|
|
234
|
+
};
|
|
235
|
+
Object.defineProperty(global, "window", {
|
|
236
|
+
value: mockWindowWithErrorStorage,
|
|
237
|
+
writable: true,
|
|
238
|
+
});
|
|
239
|
+
mockPersistence.isDisabled.mockReturnValue(false);
|
|
240
|
+
const result = debugUtils.getDebugInfo(0);
|
|
241
|
+
expect(result.storageInfo.canUseLocalStorage).toBe(true);
|
|
242
|
+
expect(result.storageInfo.canUseSessionStorage).toBe(false);
|
|
243
|
+
expect(result.storageInfo.storageKeys).toEqual([]);
|
|
244
|
+
});
|
|
245
|
+
it("should filter storage keys to only interfere_ prefixed keys", () => {
|
|
246
|
+
const mockStorageWithMixedKeys = {
|
|
247
|
+
length: 5,
|
|
248
|
+
key: vi.fn((index) => {
|
|
249
|
+
const keys = [
|
|
250
|
+
"interfere_session",
|
|
251
|
+
"other_key",
|
|
252
|
+
"interfere_window",
|
|
253
|
+
"another_key",
|
|
254
|
+
"interfere_debug",
|
|
255
|
+
];
|
|
256
|
+
return keys[index] || null;
|
|
257
|
+
}),
|
|
258
|
+
};
|
|
259
|
+
const mockWindowWithMixedStorage = {
|
|
260
|
+
localStorage: mockStorageWithMixedKeys,
|
|
261
|
+
sessionStorage: mockSessionStorage,
|
|
262
|
+
};
|
|
263
|
+
Object.defineProperty(global, "window", {
|
|
264
|
+
value: mockWindowWithMixedStorage,
|
|
265
|
+
writable: true,
|
|
266
|
+
});
|
|
267
|
+
mockPersistence.isDisabled.mockReturnValue(false);
|
|
268
|
+
const result = debugUtils.getDebugInfo(0);
|
|
269
|
+
expect(result.storageInfo.storageKeys).toEqual([
|
|
270
|
+
"localStorage: interfere_session",
|
|
271
|
+
"localStorage: interfere_window",
|
|
272
|
+
"localStorage: interfere_debug",
|
|
273
|
+
]);
|
|
274
|
+
});
|
|
275
|
+
});
|
|
276
|
+
});
|
|
277
|
+
//# sourceMappingURL=debug.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"debug.test.js","sourceRoot":"","sources":["../../../src/__tests__/core/debug.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"encoders.test.d.ts","sourceRoot":"","sources":["../../../src/__tests__/core/encoders.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/** biome-ignore-all lint/style/noMagicNumbers: Self-explanatory */
|
|
2
|
+
import { describe, expect, it } from "vitest";
|
|
3
|
+
import { decode, encode } from "../../core/encoders.js";
|
|
4
|
+
describe("encoders", () => {
|
|
5
|
+
describe("encode", () => {
|
|
6
|
+
it("encodes strings to Uint8Array", () => {
|
|
7
|
+
const result = encode("hello");
|
|
8
|
+
expect(result).toBeInstanceOf(Uint8Array);
|
|
9
|
+
expect(new TextDecoder().decode(result)).toBe('"hello"');
|
|
10
|
+
});
|
|
11
|
+
it("encodes objects to Uint8Array", () => {
|
|
12
|
+
const obj = { foo: "bar", num: 123 };
|
|
13
|
+
const result = encode(obj);
|
|
14
|
+
expect(result).toBeInstanceOf(Uint8Array);
|
|
15
|
+
expect(new TextDecoder().decode(result)).toBe('{"foo":"bar","num":123}');
|
|
16
|
+
});
|
|
17
|
+
it("encodes arrays to Uint8Array", () => {
|
|
18
|
+
const arr = [1, 2, 3];
|
|
19
|
+
const result = encode(arr);
|
|
20
|
+
expect(result).toBeInstanceOf(Uint8Array);
|
|
21
|
+
expect(new TextDecoder().decode(result)).toBe("[1,2,3]");
|
|
22
|
+
});
|
|
23
|
+
it("encodes null", () => {
|
|
24
|
+
expect(new TextDecoder().decode(encode(null))).toBe("null");
|
|
25
|
+
});
|
|
26
|
+
it("handles undefined by encoding as null", () => {
|
|
27
|
+
// JSON.stringify(undefined) returns undefined, which becomes empty string
|
|
28
|
+
// This is expected behavior for JSON
|
|
29
|
+
const result = encode(undefined);
|
|
30
|
+
expect(result).toBeInstanceOf(Uint8Array);
|
|
31
|
+
});
|
|
32
|
+
});
|
|
33
|
+
describe("decode", () => {
|
|
34
|
+
it("decodes Uint8Array back to original values", () => {
|
|
35
|
+
const testCases = [
|
|
36
|
+
"hello",
|
|
37
|
+
{ foo: "bar", num: 123 },
|
|
38
|
+
[1, 2, 3],
|
|
39
|
+
null,
|
|
40
|
+
true,
|
|
41
|
+
false,
|
|
42
|
+
42,
|
|
43
|
+
];
|
|
44
|
+
for (const original of testCases) {
|
|
45
|
+
const encoded = encode(original);
|
|
46
|
+
const decoded = decode(encoded);
|
|
47
|
+
expect(decoded).toEqual(original);
|
|
48
|
+
}
|
|
49
|
+
});
|
|
50
|
+
it("throws on invalid JSON", () => {
|
|
51
|
+
const invalidJson = new TextEncoder().encode("not valid json");
|
|
52
|
+
expect(() => decode(invalidJson)).toThrow();
|
|
53
|
+
});
|
|
54
|
+
});
|
|
55
|
+
});
|
|
56
|
+
//# sourceMappingURL=encoders.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"encoders.test.js","sourceRoot":"","sources":["../../../src/__tests__/core/encoders.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"persistence.test.d.ts","sourceRoot":"","sources":["../../../src/__tests__/core/persistence.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
import { beforeEach, describe, expect, it, vi } from "vitest";
|
|
2
|
+
import { InterferePersistence } from "../../session/persistence.js";
|
|
3
|
+
// Test constants
|
|
4
|
+
const TEST_NUMBER_VALUE = 42;
|
|
5
|
+
const TEST_STRING_VALUE = "testValue";
|
|
6
|
+
// Mock storage for testing
|
|
7
|
+
const createMockStorage = () => {
|
|
8
|
+
const store = {};
|
|
9
|
+
return {
|
|
10
|
+
_is_supported: () => true,
|
|
11
|
+
_parse: (key) => {
|
|
12
|
+
const value = store[key];
|
|
13
|
+
return value ? JSON.parse(value) : null;
|
|
14
|
+
},
|
|
15
|
+
_set: (key, value) => {
|
|
16
|
+
store[key] = JSON.stringify(value);
|
|
17
|
+
},
|
|
18
|
+
_remove: (key) => {
|
|
19
|
+
delete store[key];
|
|
20
|
+
},
|
|
21
|
+
};
|
|
22
|
+
};
|
|
23
|
+
describe("InterferePersistence", () => {
|
|
24
|
+
let mockStorage;
|
|
25
|
+
let persistence;
|
|
26
|
+
beforeEach(() => {
|
|
27
|
+
mockStorage = createMockStorage();
|
|
28
|
+
persistence = new InterferePersistence({ persistence: "localStorage" }, "test-surface", false, { customStorage: mockStorage });
|
|
29
|
+
});
|
|
30
|
+
describe("property management", () => {
|
|
31
|
+
it("should set and get properties", () => {
|
|
32
|
+
persistence.setProperty("testKey", TEST_STRING_VALUE);
|
|
33
|
+
expect(persistence.getProperty("testKey")).toBe(TEST_STRING_VALUE);
|
|
34
|
+
});
|
|
35
|
+
it("should return typed properties", () => {
|
|
36
|
+
persistence.setProperty("number", TEST_NUMBER_VALUE);
|
|
37
|
+
const value = persistence.getProperty("number");
|
|
38
|
+
expect(value).toBe(TEST_NUMBER_VALUE);
|
|
39
|
+
});
|
|
40
|
+
it("should remove individual properties", () => {
|
|
41
|
+
persistence.setProperty("key1", "value1");
|
|
42
|
+
persistence.setProperty("key2", "value2");
|
|
43
|
+
persistence.removeProp("key1");
|
|
44
|
+
expect(persistence.getProperty("key1")).toBeUndefined();
|
|
45
|
+
expect(persistence.getProperty("key2")).toBe("value2");
|
|
46
|
+
});
|
|
47
|
+
it("should get all properties as immutable copy", () => {
|
|
48
|
+
persistence.setProperty("key1", "value1");
|
|
49
|
+
persistence.setProperty("key2", "value2");
|
|
50
|
+
const props = persistence.getAllProperties();
|
|
51
|
+
expect(props).toEqual({ key1: "value1", key2: "value2" });
|
|
52
|
+
// Should be immutable - modifying the returned object shouldn't affect internal state
|
|
53
|
+
const modifiableProps = props;
|
|
54
|
+
modifiableProps.key3 = "value3";
|
|
55
|
+
expect(persistence.getProperty("key3")).toBeUndefined();
|
|
56
|
+
});
|
|
57
|
+
});
|
|
58
|
+
describe("register method", () => {
|
|
59
|
+
it("should register new properties", () => {
|
|
60
|
+
const result = persistence.register({
|
|
61
|
+
key1: "value1",
|
|
62
|
+
key2: TEST_NUMBER_VALUE,
|
|
63
|
+
});
|
|
64
|
+
expect(result).toBe(true);
|
|
65
|
+
expect(persistence.getProperty("key1")).toBe("value1");
|
|
66
|
+
expect(persistence.getProperty("key2")).toBe(TEST_NUMBER_VALUE);
|
|
67
|
+
});
|
|
68
|
+
it("should detect changes with shallow equality by default", () => {
|
|
69
|
+
const obj1 = { nested: "value" };
|
|
70
|
+
const obj2 = { nested: "value" };
|
|
71
|
+
persistence.register({ testObj: obj1 });
|
|
72
|
+
const result = persistence.register({ testObj: obj2 });
|
|
73
|
+
// Should detect change even though content is same (shallow equality)
|
|
74
|
+
expect(result).toBe(true);
|
|
75
|
+
});
|
|
76
|
+
it("should use deep equality when enabled", () => {
|
|
77
|
+
const deepPersistence = new InterferePersistence({ persistence: "localStorage" }, "test-surface-deep", false, { customStorage: mockStorage, useDeepEquality: true });
|
|
78
|
+
const obj1 = { nested: "value" };
|
|
79
|
+
const obj2 = { nested: "value" };
|
|
80
|
+
deepPersistence.register({ testObj: obj1 });
|
|
81
|
+
const result = deepPersistence.register({ testObj: obj2 });
|
|
82
|
+
// Should not detect change with deep equality
|
|
83
|
+
expect(result).toBe(false);
|
|
84
|
+
});
|
|
85
|
+
it("should return false when no changes detected", () => {
|
|
86
|
+
persistence.register({ key1: "value1" });
|
|
87
|
+
const result = persistence.register({ key1: "value1" });
|
|
88
|
+
expect(result).toBe(false);
|
|
89
|
+
});
|
|
90
|
+
});
|
|
91
|
+
describe("disabled state", () => {
|
|
92
|
+
it("should not save when disabled", () => {
|
|
93
|
+
persistence.setDisabled(true);
|
|
94
|
+
persistence.setProperty("key", "value");
|
|
95
|
+
// Create new instance to check if data was persisted
|
|
96
|
+
const newPersistence = new InterferePersistence({ persistence: "localStorage" }, "test-surface", false, { customStorage: mockStorage });
|
|
97
|
+
expect(newPersistence.getProperty("key")).toBeUndefined();
|
|
98
|
+
});
|
|
99
|
+
it("should only save on enable if props exist", () => {
|
|
100
|
+
const spySet = vi.spyOn(mockStorage, "_set");
|
|
101
|
+
// Enable with no props
|
|
102
|
+
persistence.setDisabled(false);
|
|
103
|
+
expect(spySet).not.toHaveBeenCalled();
|
|
104
|
+
// Add props then enable
|
|
105
|
+
persistence.setProperty("key", "value");
|
|
106
|
+
persistence.setDisabled(true);
|
|
107
|
+
persistence.setDisabled(false);
|
|
108
|
+
expect(spySet).toHaveBeenCalled();
|
|
109
|
+
});
|
|
110
|
+
});
|
|
111
|
+
describe("backward compatibility", () => {
|
|
112
|
+
it("should support deprecated unregister method", () => {
|
|
113
|
+
persistence.setProperty("key", "value");
|
|
114
|
+
persistence.unregister("key");
|
|
115
|
+
expect(persistence.getProperty("key")).toBeUndefined();
|
|
116
|
+
});
|
|
117
|
+
});
|
|
118
|
+
describe("initialization optimization", () => {
|
|
119
|
+
it("should not build storage when disabled", () => {
|
|
120
|
+
const disabledPersistence = new InterferePersistence({ persistence: "localStorage" }, "test-surface", true // disabled
|
|
121
|
+
);
|
|
122
|
+
// Should not throw even without custom storage
|
|
123
|
+
expect(() => {
|
|
124
|
+
disabledPersistence.setProperty("key", "value");
|
|
125
|
+
}).not.toThrow();
|
|
126
|
+
});
|
|
127
|
+
});
|
|
128
|
+
});
|
|
129
|
+
//# sourceMappingURL=persistence.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"persistence.test.js","sourceRoot":"","sources":["../../../src/__tests__/core/persistence.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rage-click.test.d.ts","sourceRoot":"","sources":["../../../src/__tests__/core/rage-click.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
import { describe, expect, it } from "vitest";
|
|
2
|
+
import RageClick from "../../session/rage-click.js";
|
|
3
|
+
// Test constants
|
|
4
|
+
const TEST_X = 100;
|
|
5
|
+
const TEST_Y = 100;
|
|
6
|
+
const SMALL_OFFSET = 5;
|
|
7
|
+
const MEDIUM_OFFSET = 10;
|
|
8
|
+
const MEDIUM_LARGE_OFFSET = 15;
|
|
9
|
+
const LARGE_OFFSET = 50;
|
|
10
|
+
const VERY_LARGE_OFFSET = 100;
|
|
11
|
+
const SHORT_DELAY = 100;
|
|
12
|
+
const MEDIUM_DELAY = 200;
|
|
13
|
+
const LONG_DELAY = 300;
|
|
14
|
+
const VERY_LONG_DELAY = 400;
|
|
15
|
+
const CUSTOM_TIMEOUT = 500;
|
|
16
|
+
const VERY_LATE_DELAY = 1500;
|
|
17
|
+
const MUCH_LATER_DELAY = 3000;
|
|
18
|
+
const MAX_TEXT_TEST_LENGTH = 150;
|
|
19
|
+
const EXPECTED_TRUNCATED_LENGTH = 100;
|
|
20
|
+
describe("RageClick", () => {
|
|
21
|
+
it("should detect rage click with default settings", () => {
|
|
22
|
+
const detector = new RageClick();
|
|
23
|
+
const baseTime = Date.now();
|
|
24
|
+
// First two clicks should not trigger
|
|
25
|
+
expect(detector.isRageClick(TEST_X, TEST_Y, baseTime)).toBe(false);
|
|
26
|
+
expect(detector.isRageClick(TEST_X + SMALL_OFFSET, TEST_Y + SMALL_OFFSET, baseTime + SHORT_DELAY)).toBe(false);
|
|
27
|
+
// Third click should trigger rage click
|
|
28
|
+
expect(detector.isRageClick(TEST_X - SMALL_OFFSET, TEST_Y - SMALL_OFFSET, baseTime + MEDIUM_DELAY)).toBe(true);
|
|
29
|
+
});
|
|
30
|
+
it("should not detect rage click if clicks are too far apart", () => {
|
|
31
|
+
const detector = new RageClick();
|
|
32
|
+
const baseTime = Date.now();
|
|
33
|
+
// Clicks outside the radius threshold (default 30px)
|
|
34
|
+
expect(detector.isRageClick(TEST_X, TEST_Y, baseTime)).toBe(false);
|
|
35
|
+
expect(detector.isRageClick(TEST_X + LARGE_OFFSET, TEST_Y, baseTime + SHORT_DELAY)).toBe(false);
|
|
36
|
+
expect(detector.isRageClick(TEST_X, TEST_Y + LARGE_OFFSET, baseTime + MEDIUM_DELAY)).toBe(false);
|
|
37
|
+
// Should not trigger even with more clicks
|
|
38
|
+
expect(detector.isRageClick(TEST_X + VERY_LARGE_OFFSET, TEST_Y, baseTime + LONG_DELAY)).toBe(false);
|
|
39
|
+
});
|
|
40
|
+
it("should not detect rage click if clicks are too slow", () => {
|
|
41
|
+
const detector = new RageClick();
|
|
42
|
+
const baseTime = Date.now();
|
|
43
|
+
// Spread clicks over a longer time period so they don't form a rage click
|
|
44
|
+
expect(detector.isRageClick(TEST_X, TEST_Y, baseTime)).toBe(false);
|
|
45
|
+
expect(detector.isRageClick(TEST_X + SMALL_OFFSET, TEST_Y + SMALL_OFFSET, baseTime + VERY_LATE_DELAY)).toBe(false); // Gap too large
|
|
46
|
+
expect(detector.isRageClick(TEST_X - SMALL_OFFSET, TEST_Y - SMALL_OFFSET, baseTime + MUCH_LATER_DELAY)).toBe(false); // Gap too large
|
|
47
|
+
});
|
|
48
|
+
it("should use static configuration values", () => {
|
|
49
|
+
const detector = new RageClick();
|
|
50
|
+
const baseTime = Date.now();
|
|
51
|
+
// Static config uses 3 clicks within 1000ms and 30px radius
|
|
52
|
+
// First click
|
|
53
|
+
expect(detector.isRageClick(TEST_X, TEST_Y, baseTime)).toBe(false);
|
|
54
|
+
// Second click
|
|
55
|
+
expect(detector.isRageClick(TEST_X + MEDIUM_OFFSET, TEST_Y + MEDIUM_OFFSET, baseTime + MEDIUM_DELAY)).toBe(false);
|
|
56
|
+
// Third click should trigger rage click
|
|
57
|
+
expect(detector.isRageClick(TEST_X + MEDIUM_LARGE_OFFSET, TEST_Y + MEDIUM_LARGE_OFFSET, baseTime + VERY_LONG_DELAY)).toBe(true);
|
|
58
|
+
});
|
|
59
|
+
it("should reset after detecting rage click", () => {
|
|
60
|
+
const detector = new RageClick();
|
|
61
|
+
const baseTime = Date.now();
|
|
62
|
+
// Trigger first rage click
|
|
63
|
+
expect(detector.isRageClick(TEST_X, TEST_Y, baseTime)).toBe(false);
|
|
64
|
+
expect(detector.isRageClick(TEST_X + SMALL_OFFSET, TEST_Y + SMALL_OFFSET, baseTime + SHORT_DELAY)).toBe(false);
|
|
65
|
+
expect(detector.isRageClick(TEST_X - SMALL_OFFSET, TEST_Y - SMALL_OFFSET, baseTime + MEDIUM_DELAY)).toBe(true);
|
|
66
|
+
// Should reset and require 3 new clicks
|
|
67
|
+
expect(detector.isRageClick(TEST_X, TEST_Y, baseTime + LONG_DELAY)).toBe(false);
|
|
68
|
+
expect(detector.isRageClick(TEST_X + SMALL_OFFSET, TEST_Y + SMALL_OFFSET, baseTime + VERY_LONG_DELAY)).toBe(false);
|
|
69
|
+
expect(detector.isRageClick(TEST_X - SMALL_OFFSET, TEST_Y - SMALL_OFFSET, baseTime + CUSTOM_TIMEOUT)).toBe(true);
|
|
70
|
+
});
|
|
71
|
+
it("should filter out old clicks", () => {
|
|
72
|
+
const detector = new RageClick();
|
|
73
|
+
const baseTime = Date.now();
|
|
74
|
+
// Add some old clicks
|
|
75
|
+
expect(detector.isRageClick(TEST_X, TEST_Y, baseTime)).toBe(false);
|
|
76
|
+
expect(detector.isRageClick(TEST_X + SMALL_OFFSET, TEST_Y + SMALL_OFFSET, baseTime + SHORT_DELAY)).toBe(false);
|
|
77
|
+
// Wait longer than timeout, then add new clicks
|
|
78
|
+
const laterTime = baseTime + VERY_LATE_DELAY; // After timeout window
|
|
79
|
+
expect(detector.isRageClick(TEST_X, TEST_Y, laterTime)).toBe(false);
|
|
80
|
+
expect(detector.isRageClick(TEST_X + SMALL_OFFSET, TEST_Y + SMALL_OFFSET, laterTime + SHORT_DELAY)).toBe(false);
|
|
81
|
+
expect(detector.isRageClick(TEST_X - SMALL_OFFSET, TEST_Y - SMALL_OFFSET, laterTime + MEDIUM_DELAY)).toBe(true);
|
|
82
|
+
});
|
|
83
|
+
it("should extract element information correctly", () => {
|
|
84
|
+
const detector = new RageClick();
|
|
85
|
+
// Mock DOM element
|
|
86
|
+
const mockElement = {
|
|
87
|
+
tagName: "BUTTON",
|
|
88
|
+
className: "test-class",
|
|
89
|
+
id: "test-id",
|
|
90
|
+
innerText: "Click me!",
|
|
91
|
+
getAttribute: (attr) => attr === "aria-label" ? "Test Button" : null,
|
|
92
|
+
};
|
|
93
|
+
const elementInfo = detector.getElementInfo(mockElement);
|
|
94
|
+
expect(elementInfo).toEqual({
|
|
95
|
+
tagName: "button",
|
|
96
|
+
className: "test-class",
|
|
97
|
+
id: "test-id",
|
|
98
|
+
text: "Click me!",
|
|
99
|
+
ariaLabel: "Test Button",
|
|
100
|
+
});
|
|
101
|
+
});
|
|
102
|
+
it("should handle null element gracefully", () => {
|
|
103
|
+
const detector = new RageClick();
|
|
104
|
+
const elementInfo = detector.getElementInfo(null);
|
|
105
|
+
expect(elementInfo).toEqual({});
|
|
106
|
+
});
|
|
107
|
+
it("should truncate long text", () => {
|
|
108
|
+
const detector = new RageClick();
|
|
109
|
+
// Mock element with long text
|
|
110
|
+
const longText = "a".repeat(MAX_TEXT_TEST_LENGTH);
|
|
111
|
+
const mockElement = {
|
|
112
|
+
tagName: "DIV",
|
|
113
|
+
innerText: longText,
|
|
114
|
+
getAttribute: () => null,
|
|
115
|
+
};
|
|
116
|
+
const elementInfo = detector.getElementInfo(mockElement);
|
|
117
|
+
expect(elementInfo.text).toHaveLength(EXPECTED_TRUNCATED_LENGTH);
|
|
118
|
+
expect(elementInfo.text).toBe("a".repeat(EXPECTED_TRUNCATED_LENGTH));
|
|
119
|
+
});
|
|
120
|
+
});
|
|
121
|
+
//# sourceMappingURL=rage-click.test.js.map
|