humanbehavior-js 0.0.9 → 0.1.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/dist/cjs/index.js +345 -184
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/react/index.js +51 -77
- package/dist/cjs/react/index.js.map +1 -1
- package/dist/esm/index.js +345 -184
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/react/index.js +48 -77
- package/dist/esm/react/index.js.map +1 -1
- package/dist/index.min.js +2 -2
- package/dist/index.min.js.map +1 -1
- package/dist/types/index.d.ts +60 -12
- package/dist/types/react/index.d.ts +8 -9
- package/package.json +2 -1
- package/readme.md +127 -105
- package/simple-spa.html +544 -0
- package/src/api.ts +4 -134
- package/src/react/index.tsx +61 -28
- package/src/tracker.ts +404 -87
package/simple-spa.html
ADDED
|
@@ -0,0 +1,544 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8">
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
6
|
+
<title>HumanBehavior SDK - Simple SPA Demo</title>
|
|
7
|
+
<style>
|
|
8
|
+
body {
|
|
9
|
+
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
|
10
|
+
margin: 0;
|
|
11
|
+
padding: 20px;
|
|
12
|
+
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
|
13
|
+
min-height: 100vh;
|
|
14
|
+
color: white;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
.container {
|
|
18
|
+
max-width: 800px;
|
|
19
|
+
margin: 0 auto;
|
|
20
|
+
background: rgba(255, 255, 255, 0.1);
|
|
21
|
+
backdrop-filter: blur(10px);
|
|
22
|
+
border-radius: 20px;
|
|
23
|
+
padding: 40px;
|
|
24
|
+
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.1);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
h1 {
|
|
28
|
+
text-align: center;
|
|
29
|
+
margin-bottom: 30px;
|
|
30
|
+
font-size: 2.5em;
|
|
31
|
+
text-shadow: 0 2px 4px rgba(0, 0, 0, 0.3);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
.nav {
|
|
35
|
+
display: flex;
|
|
36
|
+
justify-content: center;
|
|
37
|
+
gap: 20px;
|
|
38
|
+
margin-bottom: 40px;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
.nav button {
|
|
42
|
+
background: rgba(255, 255, 255, 0.2);
|
|
43
|
+
border: 2px solid rgba(255, 255, 255, 0.3);
|
|
44
|
+
color: white;
|
|
45
|
+
padding: 12px 24px;
|
|
46
|
+
border-radius: 25px;
|
|
47
|
+
cursor: pointer;
|
|
48
|
+
font-size: 16px;
|
|
49
|
+
transition: all 0.3s ease;
|
|
50
|
+
backdrop-filter: blur(5px);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
.nav button:hover {
|
|
54
|
+
background: rgba(255, 255, 255, 0.3);
|
|
55
|
+
transform: translateY(-2px);
|
|
56
|
+
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.2);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
.nav button.active {
|
|
60
|
+
background: rgba(255, 255, 255, 0.4);
|
|
61
|
+
border-color: rgba(255, 255, 255, 0.6);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
.content {
|
|
65
|
+
background: rgba(255, 255, 255, 0.1);
|
|
66
|
+
border-radius: 15px;
|
|
67
|
+
padding: 30px;
|
|
68
|
+
min-height: 400px;
|
|
69
|
+
backdrop-filter: blur(5px);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
.button {
|
|
73
|
+
background: linear-gradient(45deg, #ff6b6b, #ee5a24);
|
|
74
|
+
color: white;
|
|
75
|
+
border: none;
|
|
76
|
+
padding: 12px 24px;
|
|
77
|
+
border-radius: 25px;
|
|
78
|
+
cursor: pointer;
|
|
79
|
+
font-size: 16px;
|
|
80
|
+
margin: 10px;
|
|
81
|
+
transition: all 0.3s ease;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
.button:hover {
|
|
85
|
+
transform: translateY(-2px);
|
|
86
|
+
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
.button.secondary {
|
|
90
|
+
background: linear-gradient(45deg, #4834d4, #686de0);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
.button.success {
|
|
94
|
+
background: linear-gradient(45deg, #00b894, #00cec9);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
.status {
|
|
98
|
+
background: rgba(0, 0, 0, 0.2);
|
|
99
|
+
border-radius: 10px;
|
|
100
|
+
padding: 15px;
|
|
101
|
+
margin: 20px 0;
|
|
102
|
+
font-family: monospace;
|
|
103
|
+
font-size: 14px;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
.logs {
|
|
107
|
+
background: rgba(0, 0, 0, 0.3);
|
|
108
|
+
border-radius: 10px;
|
|
109
|
+
padding: 15px;
|
|
110
|
+
margin: 20px 0;
|
|
111
|
+
max-height: 200px;
|
|
112
|
+
overflow-y: auto;
|
|
113
|
+
font-family: monospace;
|
|
114
|
+
font-size: 12px;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
.fade-in {
|
|
118
|
+
animation: fadeIn 0.5s ease-in;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
@keyframes fadeIn {
|
|
122
|
+
from { opacity: 0; transform: translateY(20px); }
|
|
123
|
+
to { opacity: 1; transform: translateY(0); }
|
|
124
|
+
}
|
|
125
|
+
</style>
|
|
126
|
+
</head>
|
|
127
|
+
<body>
|
|
128
|
+
<div class="container">
|
|
129
|
+
<h1>HumanBehavior SDK - Simple SPA Demo</h1>
|
|
130
|
+
|
|
131
|
+
<div class="nav">
|
|
132
|
+
<button class="nav-btn active" data-page="home">🏠 Home</button>
|
|
133
|
+
<button class="nav-btn" data-page="about">ℹ️ About</button>
|
|
134
|
+
<button class="nav-btn" data-page="demo">🎯 Demo</button>
|
|
135
|
+
<button class="nav-btn" data-page="status">📊 Status</button>
|
|
136
|
+
</div>
|
|
137
|
+
|
|
138
|
+
<div id="content" class="content fade-in">
|
|
139
|
+
<!-- Content will be loaded here -->
|
|
140
|
+
</div>
|
|
141
|
+
</div>
|
|
142
|
+
|
|
143
|
+
<!-- Load the HumanBehavior SDK -->
|
|
144
|
+
<script src="dist/index.min.js"></script>
|
|
145
|
+
|
|
146
|
+
<script>
|
|
147
|
+
// Global tracker instance
|
|
148
|
+
let tracker = null;
|
|
149
|
+
let currentPage = 'home';
|
|
150
|
+
|
|
151
|
+
// Page content definitions
|
|
152
|
+
const pages = {
|
|
153
|
+
home: {
|
|
154
|
+
title: '🏠 Home',
|
|
155
|
+
content: `
|
|
156
|
+
<h2>Welcome to HumanBehavior SDK Demo</h2>
|
|
157
|
+
<p>This is a single-page application that demonstrates session continuity across page navigations.</p>
|
|
158
|
+
|
|
159
|
+
<div class="status">
|
|
160
|
+
<strong>Session Info:</strong><br>
|
|
161
|
+
Session ID: <span id="sessionId">Loading...</span><br>
|
|
162
|
+
End User ID: <span id="endUserId">Loading...</span><br>
|
|
163
|
+
Current URL: <span id="currentUrl">Loading...</span>
|
|
164
|
+
</div>
|
|
165
|
+
|
|
166
|
+
<h3>Test Actions</h3>
|
|
167
|
+
<button class="button" onclick="trackCustomEvent('home_button_click', {page: 'home'})">
|
|
168
|
+
Track Custom Event
|
|
169
|
+
</button>
|
|
170
|
+
<button class="button secondary" onclick="testConsoleLog()">
|
|
171
|
+
Test Console Log
|
|
172
|
+
</button>
|
|
173
|
+
<button class="button success" onclick="testConsoleError()">
|
|
174
|
+
Test Console Error
|
|
175
|
+
</button>
|
|
176
|
+
|
|
177
|
+
<div class="logs" id="logs">
|
|
178
|
+
<div>Logs will appear here...</div>
|
|
179
|
+
</div>
|
|
180
|
+
`
|
|
181
|
+
},
|
|
182
|
+
|
|
183
|
+
about: {
|
|
184
|
+
title: 'ℹ️ About',
|
|
185
|
+
content: `
|
|
186
|
+
<h2>About This Demo</h2>
|
|
187
|
+
<p>This single-page application demonstrates how the HumanBehavior SDK maintains session continuity across page navigations.</p>
|
|
188
|
+
|
|
189
|
+
<h3>Key Features</h3>
|
|
190
|
+
<ul>
|
|
191
|
+
<li><strong>Session Continuity:</strong> The tracker never reinitializes when navigating between pages</li>
|
|
192
|
+
<li><strong>URL Tracking:</strong> All navigation events are captured and sent to the server</li>
|
|
193
|
+
<li><strong>Event Recording:</strong> User interactions, console logs, and custom events are all tracked</li>
|
|
194
|
+
<li><strong>Real-time Updates:</strong> Session information updates in real-time</li>
|
|
195
|
+
</ul>
|
|
196
|
+
|
|
197
|
+
<div class="status">
|
|
198
|
+
<strong>Current Session:</strong><br>
|
|
199
|
+
Session ID: <span id="sessionId-about">Loading...</span><br>
|
|
200
|
+
Page Load Time: <span id="pageLoadTime">Loading...</span>
|
|
201
|
+
</div>
|
|
202
|
+
|
|
203
|
+
<button class="button" onclick="trackCustomEvent('about_page_viewed', {section: 'about'})">
|
|
204
|
+
Track About Page View
|
|
205
|
+
</button>
|
|
206
|
+
`
|
|
207
|
+
},
|
|
208
|
+
|
|
209
|
+
demo: {
|
|
210
|
+
title: '🎯 Interactive Demo',
|
|
211
|
+
content: `
|
|
212
|
+
<h2>Interactive Demo</h2>
|
|
213
|
+
<p>Test various tracking features and see them in action.</p>
|
|
214
|
+
|
|
215
|
+
<h3>Form Interaction</h3>
|
|
216
|
+
<form onsubmit="handleFormSubmit(event)">
|
|
217
|
+
<input type="text" id="demoInput" placeholder="Type something..." style="padding: 10px; border-radius: 5px; border: none; margin: 10px; width: 200px;">
|
|
218
|
+
<button type="submit" class="button">Submit Form</button>
|
|
219
|
+
</form>
|
|
220
|
+
|
|
221
|
+
<h3>Custom Events</h3>
|
|
222
|
+
<button class="button" onclick="trackCustomEvent('demo_button_1', {button: 'demo1'})">Demo Button 1</button>
|
|
223
|
+
<button class="button secondary" onclick="trackCustomEvent('demo_button_2', {button: 'demo2'})">Demo Button 2</button>
|
|
224
|
+
<button class="button success" onclick="trackCustomEvent('demo_button_3', {button: 'demo3'})">Demo Button 3</button>
|
|
225
|
+
|
|
226
|
+
<div class="logs" id="demoLogs">
|
|
227
|
+
<div>Demo events will appear here...</div>
|
|
228
|
+
</div>
|
|
229
|
+
`
|
|
230
|
+
},
|
|
231
|
+
|
|
232
|
+
status: {
|
|
233
|
+
title: '📊 Session Status',
|
|
234
|
+
content: `
|
|
235
|
+
<h2>Session Status & Debug Info</h2>
|
|
236
|
+
|
|
237
|
+
<div class="status">
|
|
238
|
+
<strong>Tracker Status:</strong><br>
|
|
239
|
+
Initialized: <span id="trackerInitialized">Loading...</span><br>
|
|
240
|
+
Session ID: <span id="sessionId-status">Loading...</span><br>
|
|
241
|
+
End User ID: <span id="endUserId-status">Loading...</span><br>
|
|
242
|
+
Current URL: <span id="currentUrl-status">Loading...</span><br>
|
|
243
|
+
Connection Status: <span id="connectionStatus">Loading...</span>
|
|
244
|
+
</div>
|
|
245
|
+
|
|
246
|
+
<h3>Actions</h3>
|
|
247
|
+
<button class="button" onclick="viewLogs()">View Logs</button>
|
|
248
|
+
<button class="button secondary" onclick="testConnection()">Test Connection</button>
|
|
249
|
+
<button class="button success" onclick="clearLogs()">Clear Logs</button>
|
|
250
|
+
|
|
251
|
+
<div class="logs" id="statusLogs">
|
|
252
|
+
<div>Status logs will appear here...</div>
|
|
253
|
+
</div>
|
|
254
|
+
`
|
|
255
|
+
}
|
|
256
|
+
};
|
|
257
|
+
|
|
258
|
+
// Initialize the application
|
|
259
|
+
async function initApp() {
|
|
260
|
+
try {
|
|
261
|
+
console.log('Starting SPA initialization...');
|
|
262
|
+
|
|
263
|
+
// Check if SDK is loaded
|
|
264
|
+
if (typeof HumanBehaviorTracker === 'undefined') {
|
|
265
|
+
throw new Error('HumanBehaviorTracker SDK not loaded. Check if dist/index.js exists.');
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
// Initialize HumanBehavior tracker
|
|
269
|
+
console.log('Initializing tracker...');
|
|
270
|
+
tracker = HumanBehaviorTracker.init('13c3e029-ca45-4a3c-a33b-f5dcb297e31c', {
|
|
271
|
+
logLevel: 'debug',
|
|
272
|
+
redactFields: ['password', 'credit_card']
|
|
273
|
+
});
|
|
274
|
+
|
|
275
|
+
console.log('Tracker created, waiting for initialization...');
|
|
276
|
+
|
|
277
|
+
// Wait for tracker to initialize
|
|
278
|
+
if (tracker.initializationPromise) {
|
|
279
|
+
await tracker.initializationPromise;
|
|
280
|
+
console.log('Tracker initialized successfully');
|
|
281
|
+
} else {
|
|
282
|
+
console.log('No initialization promise, continuing...');
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
// Set up navigation
|
|
286
|
+
setupNavigation();
|
|
287
|
+
|
|
288
|
+
// Load initial page
|
|
289
|
+
loadPage('home');
|
|
290
|
+
|
|
291
|
+
// Update status periodically
|
|
292
|
+
setInterval(updateStatus, 2000);
|
|
293
|
+
|
|
294
|
+
console.log('SPA App initialized successfully');
|
|
295
|
+
addLog('SPA App initialized successfully');
|
|
296
|
+
|
|
297
|
+
} catch (error) {
|
|
298
|
+
console.error('Failed to initialize SPA app:', error);
|
|
299
|
+
addLog('Error initializing app: ' + error.message);
|
|
300
|
+
|
|
301
|
+
// Show error in content
|
|
302
|
+
document.getElementById('content').innerHTML = `
|
|
303
|
+
<h2>Initialization Error</h2>
|
|
304
|
+
<p>Failed to initialize the HumanBehavior SDK:</p>
|
|
305
|
+
<div class="status">
|
|
306
|
+
<strong>Error:</strong> ${error.message}<br>
|
|
307
|
+
<strong>Stack:</strong> ${error.stack}
|
|
308
|
+
</div>
|
|
309
|
+
<button class="button" onclick="location.reload()">Reload Page</button>
|
|
310
|
+
`;
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
// Set up client-side navigation
|
|
315
|
+
function setupNavigation() {
|
|
316
|
+
const navButtons = document.querySelectorAll('.nav-btn');
|
|
317
|
+
|
|
318
|
+
navButtons.forEach(button => {
|
|
319
|
+
button.addEventListener('click', () => {
|
|
320
|
+
const page = button.dataset.page;
|
|
321
|
+
navigateToPage(page);
|
|
322
|
+
});
|
|
323
|
+
});
|
|
324
|
+
|
|
325
|
+
// Handle browser back/forward buttons
|
|
326
|
+
window.addEventListener('popstate', (event) => {
|
|
327
|
+
const page = event.state?.page || 'home';
|
|
328
|
+
loadPage(page);
|
|
329
|
+
updateActiveNavButton(page);
|
|
330
|
+
});
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
// Navigate to a page
|
|
334
|
+
function navigateToPage(page) {
|
|
335
|
+
if (page === currentPage) return;
|
|
336
|
+
|
|
337
|
+
console.log(`Navigating from ${currentPage} to ${page}`);
|
|
338
|
+
|
|
339
|
+
// Update URL without page reload
|
|
340
|
+
history.pushState({ page }, pages[page].title, `#${page}`);
|
|
341
|
+
|
|
342
|
+
// Load the page content
|
|
343
|
+
loadPage(page);
|
|
344
|
+
|
|
345
|
+
// Update active nav button
|
|
346
|
+
updateActiveNavButton(page);
|
|
347
|
+
|
|
348
|
+
// Track navigation event
|
|
349
|
+
if (tracker && tracker.trackNavigationEvent) {
|
|
350
|
+
try {
|
|
351
|
+
tracker.trackNavigationEvent('spa_navigation', currentPage, page);
|
|
352
|
+
} catch (error) {
|
|
353
|
+
console.error('Failed to track navigation:', error);
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
currentPage = page;
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
// Load page content
|
|
361
|
+
function loadPage(page) {
|
|
362
|
+
const contentDiv = document.getElementById('content');
|
|
363
|
+
const pageData = pages[page];
|
|
364
|
+
|
|
365
|
+
if (!pageData) {
|
|
366
|
+
contentDiv.innerHTML = '<h2>Page not found</h2>';
|
|
367
|
+
return;
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
// Add fade-in animation
|
|
371
|
+
contentDiv.classList.remove('fade-in');
|
|
372
|
+
void contentDiv.offsetWidth; // Trigger reflow
|
|
373
|
+
contentDiv.classList.add('fade-in');
|
|
374
|
+
|
|
375
|
+
contentDiv.innerHTML = pageData.content;
|
|
376
|
+
|
|
377
|
+
// Update page title
|
|
378
|
+
document.title = `HumanBehavior SDK - ${pageData.title}`;
|
|
379
|
+
|
|
380
|
+
// Track page view
|
|
381
|
+
if (tracker && tracker.trackPageView) {
|
|
382
|
+
try {
|
|
383
|
+
tracker.trackPageView();
|
|
384
|
+
} catch (error) {
|
|
385
|
+
console.error('Failed to track pageview:', error);
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
addLog(`Navigated to ${page} page`);
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
// Update active navigation button
|
|
393
|
+
function updateActiveNavButton(page) {
|
|
394
|
+
document.querySelectorAll('.nav-btn').forEach(btn => {
|
|
395
|
+
btn.classList.remove('active');
|
|
396
|
+
});
|
|
397
|
+
const activeButton = document.querySelector(`[data-page="${page}"]`);
|
|
398
|
+
if (activeButton) {
|
|
399
|
+
activeButton.classList.add('active');
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
// Update status information
|
|
404
|
+
function updateStatus() {
|
|
405
|
+
if (!tracker) return;
|
|
406
|
+
|
|
407
|
+
try {
|
|
408
|
+
// Update session info
|
|
409
|
+
const sessionIdElements = document.querySelectorAll('#sessionId, #sessionId-about, #sessionId-status');
|
|
410
|
+
const sessionId = tracker.getSessionId ? tracker.getSessionId() : 'Not available';
|
|
411
|
+
sessionIdElements.forEach(el => {
|
|
412
|
+
el.textContent = sessionId;
|
|
413
|
+
});
|
|
414
|
+
|
|
415
|
+
const endUserIdElements = document.querySelectorAll('#endUserId, #endUserId-status');
|
|
416
|
+
const endUserId = tracker.endUserId || 'Not set';
|
|
417
|
+
endUserIdElements.forEach(el => {
|
|
418
|
+
el.textContent = endUserId;
|
|
419
|
+
});
|
|
420
|
+
|
|
421
|
+
const currentUrlElements = document.querySelectorAll('#currentUrl, #currentUrl-status');
|
|
422
|
+
const currentUrl = window.location.href;
|
|
423
|
+
currentUrlElements.forEach(el => {
|
|
424
|
+
el.textContent = currentUrl;
|
|
425
|
+
});
|
|
426
|
+
|
|
427
|
+
const trackerInitialized = document.getElementById('trackerInitialized');
|
|
428
|
+
if (trackerInitialized) {
|
|
429
|
+
trackerInitialized.textContent = tracker.initialized ? 'Yes' : 'No';
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
const connectionStatus = document.getElementById('connectionStatus');
|
|
433
|
+
if (connectionStatus && tracker.getConnectionStatus) {
|
|
434
|
+
const status = tracker.getConnectionStatus();
|
|
435
|
+
connectionStatus.textContent = status.blocked ? 'Blocked' : 'Connected';
|
|
436
|
+
}
|
|
437
|
+
|
|
438
|
+
const pageLoadTime = document.getElementById('pageLoadTime');
|
|
439
|
+
if (pageLoadTime) {
|
|
440
|
+
pageLoadTime.textContent = new Date().toLocaleTimeString();
|
|
441
|
+
}
|
|
442
|
+
} catch (error) {
|
|
443
|
+
console.error('Error updating status:', error);
|
|
444
|
+
}
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
// Track custom events
|
|
448
|
+
async function trackCustomEvent(eventName, properties = {}) {
|
|
449
|
+
if (!tracker) {
|
|
450
|
+
addLog('Tracker not available');
|
|
451
|
+
return;
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
try {
|
|
455
|
+
if (tracker.customEvent) {
|
|
456
|
+
await tracker.customEvent(eventName, properties);
|
|
457
|
+
addLog(`Custom event tracked: ${eventName}`, properties);
|
|
458
|
+
} else {
|
|
459
|
+
addLog('customEvent method not available');
|
|
460
|
+
}
|
|
461
|
+
} catch (error) {
|
|
462
|
+
addLog(`Error tracking event: ${error.message}`);
|
|
463
|
+
}
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
// Test console logging
|
|
467
|
+
function testConsoleLog() {
|
|
468
|
+
console.log('This is a test console log message');
|
|
469
|
+
addLog('Console log test executed');
|
|
470
|
+
}
|
|
471
|
+
|
|
472
|
+
function testConsoleError() {
|
|
473
|
+
console.error('This is a test console error message');
|
|
474
|
+
addLog('Console error test executed');
|
|
475
|
+
}
|
|
476
|
+
|
|
477
|
+
// Handle form submission
|
|
478
|
+
function handleFormSubmit(event) {
|
|
479
|
+
event.preventDefault();
|
|
480
|
+
const input = document.getElementById('demoInput');
|
|
481
|
+
const value = input.value;
|
|
482
|
+
|
|
483
|
+
trackCustomEvent('form_submitted', { value: value });
|
|
484
|
+
addLog(`Form submitted with value: ${value}`);
|
|
485
|
+
|
|
486
|
+
input.value = '';
|
|
487
|
+
}
|
|
488
|
+
|
|
489
|
+
// View logs
|
|
490
|
+
function viewLogs() {
|
|
491
|
+
if (tracker && tracker.viewLogs) {
|
|
492
|
+
tracker.viewLogs();
|
|
493
|
+
} else {
|
|
494
|
+
addLog('viewLogs method not available');
|
|
495
|
+
}
|
|
496
|
+
}
|
|
497
|
+
|
|
498
|
+
// Test connection
|
|
499
|
+
async function testConnection() {
|
|
500
|
+
if (!tracker) {
|
|
501
|
+
addLog('Tracker not available');
|
|
502
|
+
return;
|
|
503
|
+
}
|
|
504
|
+
|
|
505
|
+
try {
|
|
506
|
+
if (tracker.testConnection) {
|
|
507
|
+
const result = await tracker.testConnection();
|
|
508
|
+
addLog(`Connection test: ${result.success ? 'Success' : 'Failed'}`, result);
|
|
509
|
+
} else {
|
|
510
|
+
addLog('testConnection method not available');
|
|
511
|
+
}
|
|
512
|
+
} catch (error) {
|
|
513
|
+
addLog(`Connection test error: ${error.message}`);
|
|
514
|
+
}
|
|
515
|
+
}
|
|
516
|
+
|
|
517
|
+
// Clear logs
|
|
518
|
+
function clearLogs() {
|
|
519
|
+
const logElements = document.querySelectorAll('.logs');
|
|
520
|
+
logElements.forEach(el => {
|
|
521
|
+
el.innerHTML = '<div>Logs cleared...</div>';
|
|
522
|
+
});
|
|
523
|
+
}
|
|
524
|
+
|
|
525
|
+
// Add log message
|
|
526
|
+
function addLog(message, data = null) {
|
|
527
|
+
const logElements = document.querySelectorAll('.logs');
|
|
528
|
+
const timestamp = new Date().toLocaleTimeString();
|
|
529
|
+
const logEntry = `<div>[${timestamp}] ${message}${data ? ' - ' + JSON.stringify(data) : ''}</div>`;
|
|
530
|
+
|
|
531
|
+
logElements.forEach(el => {
|
|
532
|
+
el.innerHTML += logEntry;
|
|
533
|
+
el.scrollTop = el.scrollHeight;
|
|
534
|
+
});
|
|
535
|
+
|
|
536
|
+
// Also log to console
|
|
537
|
+
console.log(`[${timestamp}] ${message}`, data);
|
|
538
|
+
}
|
|
539
|
+
|
|
540
|
+
// Initialize the app when the page loads
|
|
541
|
+
document.addEventListener('DOMContentLoaded', initApp);
|
|
542
|
+
</script>
|
|
543
|
+
</body>
|
|
544
|
+
</html>
|