Skip to content

Commit b81aeae

Browse files
committed
refactor(javascript): add browser package
1 parent 669e280 commit b81aeae

23 files changed

+3463
-0
lines changed
Lines changed: 306 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,306 @@
1+
/**
2+
* Breadcrumbs Management
3+
*/
4+
const buttonAddBreadcrumb = document.getElementById('btn-add-breadcrumb');
5+
const buttonGetBreadcrumbs = document.getElementById('btn-get-breadcrumbs');
6+
const buttonClearBreadcrumbs = document.getElementById('btn-clear-breadcrumbs');
7+
const breadcrumbsOutput = document.getElementById('breadcrumbs-output');
8+
9+
buttonAddBreadcrumb.addEventListener('click', () => {
10+
const message = document.getElementById('breadcrumbMessage').value;
11+
const type = document.getElementById('breadcrumbType').value;
12+
const level = document.getElementById('breadcrumbLevel').value;
13+
const category = document.getElementById('breadcrumbCategory').value;
14+
15+
if (!message.trim()) {
16+
alert('Breadcrumb message is required');
17+
18+
return;
19+
}
20+
21+
window.hawk.breadcrumbs.add({
22+
message,
23+
type,
24+
level,
25+
...(category.trim() && { category }),
26+
data: {
27+
timestamp: new Date().toISOString(),
28+
custom: 'manual breadcrumb',
29+
},
30+
});
31+
32+
breadcrumbsOutput.textContent = `✓ Breadcrumb added: ${message}`;
33+
});
34+
35+
buttonGetBreadcrumbs.addEventListener('click', () => {
36+
const breadcrumbs = window.hawk.breadcrumbs.get();
37+
38+
if (breadcrumbs.length === 0) {
39+
breadcrumbsOutput.textContent = 'No breadcrumbs yet';
40+
41+
return;
42+
}
43+
44+
breadcrumbsOutput.textContent = JSON.stringify(breadcrumbs, null, 2);
45+
});
46+
47+
buttonClearBreadcrumbs.addEventListener('click', () => {
48+
window.hawk.breadcrumbs.clear();
49+
breadcrumbsOutput.textContent = '✓ Breadcrumbs cleared';
50+
});
51+
52+
/**
53+
* Test All Breadcrumb Types
54+
*/
55+
const buttonTestDefault = document.getElementById('btn-test-default');
56+
const buttonTestRequest = document.getElementById('btn-test-request');
57+
const buttonTestUI = document.getElementById('btn-test-ui');
58+
const buttonTestNavigation = document.getElementById('btn-test-navigation');
59+
const buttonTestLogic = document.getElementById('btn-test-logic');
60+
const buttonTestError = document.getElementById('btn-test-error');
61+
const buttonTestAllTypes = document.getElementById('btn-test-all-types');
62+
63+
/**
64+
* Test Default breadcrumb (manual)
65+
*/
66+
buttonTestDefault.addEventListener('click', () => {
67+
/**
68+
* Default breadcrumbs are always added manually via hawk.breadcrumbs.add()
69+
*/
70+
window.hawk.breadcrumbs.add({
71+
type: 'default',
72+
level: 'info',
73+
category: 'user.action',
74+
message: 'User clicked on default event button',
75+
data: {
76+
action: 'button_click',
77+
context: 'breadcrumb_testing',
78+
},
79+
});
80+
breadcrumbsOutput.textContent = '✓ Default breadcrumb added manually';
81+
});
82+
83+
/**
84+
* Test Request breadcrumb (automatic via fetch)
85+
*/
86+
buttonTestRequest.addEventListener('click', async () => {
87+
breadcrumbsOutput.textContent = 'Testing request breadcrumb...';
88+
89+
try {
90+
const response = await fetch('https://api.github.com/zen');
91+
const text = await response.text();
92+
93+
breadcrumbsOutput.textContent = `✓ Request breadcrumb added (${response.status}): "${text}"`;
94+
} catch (error) {
95+
breadcrumbsOutput.textContent = `✗ Request failed: ${error.message}`;
96+
}
97+
});
98+
99+
/**
100+
* Test UI breadcrumb (automatic tracking)
101+
*/
102+
buttonTestUI.addEventListener('click', () => {
103+
/**
104+
* Create a test element and click it to trigger automatic UI breadcrumb
105+
* BreadcrumbManager automatically captures click events when trackClicks: true
106+
*/
107+
const testElement = document.createElement('button');
108+
109+
testElement.id = 'auto-click-test';
110+
testElement.className = 'test-button';
111+
testElement.textContent = 'Auto Test';
112+
testElement.style.position = 'absolute';
113+
testElement.style.opacity = '0';
114+
testElement.style.pointerEvents = 'none';
115+
document.body.appendChild(testElement);
116+
117+
/**
118+
* Trigger a click event
119+
*/
120+
testElement.click();
121+
122+
/**
123+
* Clean up
124+
*/
125+
setTimeout(() => {
126+
document.body.removeChild(testElement);
127+
}, 100);
128+
129+
breadcrumbsOutput.textContent = '✓ UI Click breadcrumb added automatically';
130+
});
131+
132+
/**
133+
* Test Navigation breadcrumb (automatic tracking)
134+
*/
135+
buttonTestNavigation.addEventListener('click', () => {
136+
/**
137+
* Change the hash to trigger automatic navigation breadcrumb
138+
* BreadcrumbManager automatically captures this event
139+
*/
140+
window.location.hash = 'breadcrumb-test-' + Date.now();
141+
142+
breadcrumbsOutput.textContent = '✓ Navigation breadcrumb added automatically';
143+
});
144+
145+
/**
146+
* Test Logic breadcrumb (manual)
147+
*/
148+
buttonTestLogic.addEventListener('click', () => {
149+
/**
150+
* Simulate some logic operations
151+
*/
152+
const startTime = performance.now();
153+
154+
/**
155+
* Complex calculation for testing
156+
*
157+
* @param {number} n - Number of iterations
158+
* @returns {number} Calculation result
159+
*/
160+
function complexCalculation(n) {
161+
let result = 0;
162+
163+
for (let i = 0; i < n; i++) {
164+
result += Math.sqrt(i);
165+
}
166+
167+
return result;
168+
}
169+
170+
const result = complexCalculation(10000);
171+
const duration = performance.now() - startTime;
172+
173+
/**
174+
* Logic breadcrumbs are always added manually to track application flow
175+
*/
176+
window.hawk.breadcrumbs.add({
177+
type: 'logic',
178+
level: 'debug',
179+
category: 'calculation.complex',
180+
message: 'Performed complex calculation',
181+
data: {
182+
operation: 'complexCalculation',
183+
iterations: 10000,
184+
result: result,
185+
durationMs: duration.toFixed(2),
186+
},
187+
});
188+
189+
breadcrumbsOutput.textContent = `✓ Logic breadcrumb added manually (${duration.toFixed(2)}ms)`;
190+
});
191+
192+
/**
193+
* Test Error breadcrumb (manual)
194+
*/
195+
buttonTestError.addEventListener('click', () => {
196+
try {
197+
/**
198+
* Intentionally cause an error but catch it
199+
*/
200+
JSON.parse('invalid json {{{');
201+
} catch (error) {
202+
/**
203+
* Caught errors can be manually added as breadcrumbs
204+
* Uncaught errors are sent to Hawk automatically, not as breadcrumbs
205+
*/
206+
window.hawk.breadcrumbs.add({
207+
type: 'error',
208+
level: 'error',
209+
category: 'json.parse',
210+
message: `JSON parse error: ${error.message}`,
211+
data: {
212+
error: error.name,
213+
message: error.message,
214+
input: 'invalid json {{{',
215+
},
216+
});
217+
218+
breadcrumbsOutput.textContent = `✓ Error breadcrumb added manually: ${error.message}`;
219+
}
220+
});
221+
222+
/**
223+
* Test All Types in sequence
224+
*/
225+
buttonTestAllTypes.addEventListener('click', async () => {
226+
breadcrumbsOutput.textContent = 'Running all breadcrumb types...';
227+
228+
/**
229+
* 1. Default
230+
*/
231+
window.hawk.breadcrumbs.add({
232+
type: 'default',
233+
level: 'info',
234+
message: 'Sequence started',
235+
});
236+
237+
await new Promise(resolve => setTimeout(resolve, 200));
238+
239+
/**
240+
* 2. Logic
241+
*/
242+
window.hawk.breadcrumbs.add({
243+
type: 'logic',
244+
level: 'debug',
245+
category: 'sequence.step',
246+
message: 'Processing step 1',
247+
data: {
248+
step: 1,
249+
},
250+
});
251+
252+
await new Promise(resolve => setTimeout(resolve, 200));
253+
254+
/**
255+
* 3. UI (automatic)
256+
*/
257+
const autoClickElement = document.createElement('button');
258+
259+
autoClickElement.id = 'sequence-auto-click';
260+
autoClickElement.style.position = 'absolute';
261+
autoClickElement.style.opacity = '0';
262+
autoClickElement.style.pointerEvents = 'none';
263+
document.body.appendChild(autoClickElement);
264+
autoClickElement.click();
265+
document.body.removeChild(autoClickElement);
266+
267+
await new Promise(resolve => setTimeout(resolve, 200));
268+
269+
/**
270+
* 4. Request (automatic)
271+
*/
272+
try {
273+
await fetch('https://api.github.com/zen');
274+
} catch (error) {
275+
/**
276+
* Fetch will be captured automatically
277+
*/
278+
}
279+
280+
await new Promise(resolve => setTimeout(resolve, 200));
281+
282+
/**
283+
* 5. Navigation (automatic)
284+
*/
285+
window.location.hash = 'sequence-test-' + Date.now();
286+
287+
await new Promise(resolve => setTimeout(resolve, 200));
288+
289+
/**
290+
* 6. Error
291+
*/
292+
try {
293+
throw new Error('Test error in sequence');
294+
} catch (error) {
295+
window.hawk.breadcrumbs.add({
296+
type: 'error',
297+
level: 'warning',
298+
message: `Caught error: ${error.message}`,
299+
data: {
300+
error: error.name,
301+
},
302+
});
303+
}
304+
305+
breadcrumbsOutput.textContent = '✓ All breadcrumb types added! Check "Get Breadcrumbs"';
306+
});

0 commit comments

Comments
 (0)