bug-report-js 2.3.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.
Binary file
Binary file
Binary file
package/manifest.json ADDED
@@ -0,0 +1,43 @@
1
+ {
2
+ "manifest_version": 3,
3
+ "name": "Local Bug Logger",
4
+ "version": "2.0.0",
5
+ "description": "Fängt die letzten 50 Aktionen ab und generiert einen DSGVO-sicheren HTML-Bug-Report mit annotiertem Screenshot.",
6
+ "permissions": [
7
+ "activeTab",
8
+ "scripting",
9
+ "webRequest",
10
+ "downloads"
11
+ ],
12
+ "host_permissions": [
13
+ "<all_urls>"
14
+ ],
15
+ "background": {
16
+ "service_worker": "background.js"
17
+ },
18
+ "content_scripts": [
19
+ {
20
+ "matches": [
21
+ "<all_urls>"
22
+ ],
23
+ "js": [
24
+ "content.js"
25
+ ],
26
+ "run_at": "document_start"
27
+ }
28
+ ],
29
+ "action": {
30
+ "default_popup": "popup.html",
31
+ "default_icon": {
32
+ "16": "icons/icon16.png",
33
+ "48": "icons/icon48.png",
34
+ "128": "icons/icon128.png"
35
+ },
36
+ "default_title": "Bug Report erstellen"
37
+ },
38
+ "icons": {
39
+ "16": "icons/icon16.png",
40
+ "48": "icons/icon48.png",
41
+ "128": "icons/icon128.png"
42
+ }
43
+ }
package/package.json ADDED
@@ -0,0 +1,27 @@
1
+ {
2
+ "name": "bug-report-js",
3
+ "version": "2.3.0",
4
+ "description": "A drop-in JavaScript widget to generate comprehensive bug reports with DOM capture, interactions, console logs, and JS errors.",
5
+ "main": "website/bug-report.js",
6
+ "scripts": {
7
+ "test": "echo \"Error: no test specified\" && exit 1"
8
+ },
9
+ "repository": {
10
+ "type": "git",
11
+ "url": "git+https://github.com/TeamStriebigSebastian/Bug-Report-Widget.git"
12
+ },
13
+ "keywords": [
14
+ "bug",
15
+ "report",
16
+ "widget",
17
+ "feedback",
18
+ "DOM capture",
19
+ "interactions"
20
+ ],
21
+ "author": "Antigravity",
22
+ "license": "MIT",
23
+ "bugs": {
24
+ "url": "https://github.com/TeamStriebigSebastian/Bug-Report-Widget/issues"
25
+ },
26
+ "homepage": "https://github.com/TeamStriebigSebastian/Bug-Report-Widget#readme"
27
+ }
package/popup.css ADDED
@@ -0,0 +1,289 @@
1
+ /* ═══════════════════════════════════════════════════════════════════
2
+ Bug Report Extension — Popup Styles
3
+ ═══════════════════════════════════════════════════════════════════ */
4
+
5
+ :root {
6
+ --bg-primary: #0f1117;
7
+ --bg-secondary: #1a1d27;
8
+ --bg-card: #222636;
9
+ --bg-card-hover: #2a2f42;
10
+ --border: #2d3348;
11
+ --text-primary: #e8eaf0;
12
+ --text-secondary: #9096a8;
13
+ --text-muted: #636882;
14
+ --accent-primary: #6366f1;
15
+ --accent-primary-hover: #7577f5;
16
+ --accent-glow: rgba(99, 102, 241, 0.2);
17
+ --danger: #ef4444;
18
+ --success: #22c55e;
19
+ --warning: #f59e0b;
20
+ --radius-sm: 6px;
21
+ --radius-md: 10px;
22
+ --radius-lg: 14px;
23
+ }
24
+
25
+ * {
26
+ margin: 0;
27
+ padding: 0;
28
+ box-sizing: border-box;
29
+ }
30
+
31
+ body {
32
+ font-family: 'Segoe UI', -apple-system, BlinkMacSystemFont, 'Helvetica Neue', sans-serif;
33
+ background: var(--bg-primary);
34
+ color: var(--text-primary);
35
+ width: 340px;
36
+ min-height: 200px;
37
+ overflow: hidden;
38
+ }
39
+
40
+ /* ── Container ──────────────────────────────────────────────────── */
41
+
42
+ .popup-container {
43
+ padding: 16px;
44
+ }
45
+
46
+ /* ── Header ─────────────────────────────────────────────────────── */
47
+
48
+ .popup-header {
49
+ display: flex;
50
+ align-items: center;
51
+ gap: 8px;
52
+ margin-bottom: 16px;
53
+ padding-bottom: 12px;
54
+ border-bottom: 1px solid var(--border);
55
+ }
56
+
57
+ .popup-logo {
58
+ font-size: 22px;
59
+ line-height: 1;
60
+ }
61
+
62
+ .popup-title {
63
+ font-size: 16px;
64
+ font-weight: 700;
65
+ letter-spacing: -0.02em;
66
+ flex: 1;
67
+ }
68
+
69
+ .popup-version {
70
+ font-size: 11px;
71
+ color: var(--text-muted);
72
+ background: var(--bg-secondary);
73
+ padding: 2px 7px;
74
+ border-radius: 20px;
75
+ border: 1px solid var(--border);
76
+ }
77
+
78
+ /* ── States ─────────────────────────────────────────────────────── */
79
+
80
+ .popup-state {
81
+ animation: fadeIn 0.2s ease-out;
82
+ }
83
+
84
+ .popup-state.hidden {
85
+ display: none;
86
+ }
87
+
88
+ @keyframes fadeIn {
89
+ from {
90
+ opacity: 0;
91
+ transform: translateY(4px);
92
+ }
93
+ to {
94
+ opacity: 1;
95
+ transform: translateY(0);
96
+ }
97
+ }
98
+
99
+ /* ── Loading ────────────────────────────────────────────────────── */
100
+
101
+ #stateLoading {
102
+ display: flex;
103
+ flex-direction: column;
104
+ align-items: center;
105
+ padding: 32px 0;
106
+ gap: 14px;
107
+ }
108
+
109
+ .spinner {
110
+ width: 28px;
111
+ height: 28px;
112
+ border: 3px solid var(--border);
113
+ border-top-color: var(--accent-primary);
114
+ border-radius: 50%;
115
+ animation: spin 0.8s linear infinite;
116
+ }
117
+
118
+ @keyframes spin {
119
+ to { transform: rotate(360deg); }
120
+ }
121
+
122
+ /* ── Info Text ──────────────────────────────────────────────────── */
123
+
124
+ .popup-info-text {
125
+ font-size: 12.5px;
126
+ color: var(--text-secondary);
127
+ line-height: 1.5;
128
+ margin-bottom: 12px;
129
+ }
130
+
131
+ .popup-info-text.subtle {
132
+ color: var(--text-muted);
133
+ text-align: center;
134
+ }
135
+
136
+ .popup-status-text {
137
+ font-size: 13px;
138
+ color: var(--text-secondary);
139
+ font-weight: 500;
140
+ }
141
+
142
+ /* ── URL Preview ────────────────────────────────────────────────── */
143
+
144
+ .popup-url {
145
+ font-size: 11.5px;
146
+ color: var(--accent-primary);
147
+ background: var(--bg-secondary);
148
+ padding: 8px 10px;
149
+ border-radius: var(--radius-sm);
150
+ border: 1px solid var(--border);
151
+ margin-bottom: 14px;
152
+ white-space: nowrap;
153
+ overflow: hidden;
154
+ text-overflow: ellipsis;
155
+ font-family: 'SF Mono', 'Fira Code', 'Consolas', monospace;
156
+ }
157
+
158
+ /* ── Stats Grid ─────────────────────────────────────────────────── */
159
+
160
+ .popup-stats {
161
+ display: grid;
162
+ grid-template-columns: 1fr 1fr;
163
+ gap: 8px;
164
+ margin-bottom: 14px;
165
+ }
166
+
167
+ .stat-card {
168
+ background: var(--bg-card);
169
+ border: 1px solid var(--border);
170
+ border-radius: var(--radius-md);
171
+ padding: 10px;
172
+ text-align: center;
173
+ transition: background 0.15s ease, border-color 0.15s ease;
174
+ }
175
+
176
+ .stat-card:hover {
177
+ background: var(--bg-card-hover);
178
+ border-color: var(--accent-primary);
179
+ }
180
+
181
+ .stat-icon {
182
+ font-size: 16px;
183
+ margin-bottom: 4px;
184
+ }
185
+
186
+ .stat-value {
187
+ font-size: 20px;
188
+ font-weight: 700;
189
+ color: var(--text-primary);
190
+ letter-spacing: -0.03em;
191
+ }
192
+
193
+ .stat-label {
194
+ font-size: 10.5px;
195
+ color: var(--text-muted);
196
+ text-transform: uppercase;
197
+ letter-spacing: 0.04em;
198
+ margin-top: 2px;
199
+ }
200
+
201
+ /* ── Privacy Note ───────────────────────────────────────────────── */
202
+
203
+ .popup-privacy-note {
204
+ font-size: 11px;
205
+ color: var(--text-muted);
206
+ background: rgba(34, 197, 94, 0.06);
207
+ border: 1px solid rgba(34, 197, 94, 0.15);
208
+ border-radius: var(--radius-sm);
209
+ padding: 8px 10px;
210
+ margin-bottom: 16px;
211
+ line-height: 1.5;
212
+ }
213
+
214
+ /* ── Buttons ────────────────────────────────────────────────────── */
215
+
216
+ .popup-actions {
217
+ display: flex;
218
+ gap: 8px;
219
+ }
220
+
221
+ .btn {
222
+ flex: 1;
223
+ display: flex;
224
+ align-items: center;
225
+ justify-content: center;
226
+ gap: 6px;
227
+ padding: 10px 14px;
228
+ border: none;
229
+ border-radius: var(--radius-md);
230
+ font-size: 13px;
231
+ font-weight: 600;
232
+ cursor: pointer;
233
+ transition: all 0.15s ease;
234
+ font-family: inherit;
235
+ }
236
+
237
+ .btn-primary {
238
+ background: var(--accent-primary);
239
+ color: white;
240
+ box-shadow: 0 2px 8px var(--accent-glow);
241
+ }
242
+
243
+ .btn-primary:hover {
244
+ background: var(--accent-primary-hover);
245
+ box-shadow: 0 4px 16px var(--accent-glow);
246
+ transform: translateY(-1px);
247
+ }
248
+
249
+ .btn-primary:active {
250
+ transform: translateY(0);
251
+ }
252
+
253
+ .btn-primary:disabled {
254
+ opacity: 0.5;
255
+ cursor: not-allowed;
256
+ transform: none;
257
+ box-shadow: none;
258
+ }
259
+
260
+ .btn-secondary {
261
+ background: var(--bg-card);
262
+ color: var(--text-secondary);
263
+ border: 1px solid var(--border);
264
+ }
265
+
266
+ .btn-secondary:hover {
267
+ background: var(--bg-card-hover);
268
+ color: var(--text-primary);
269
+ border-color: var(--text-muted);
270
+ }
271
+
272
+ .btn-icon {
273
+ font-size: 14px;
274
+ }
275
+
276
+ /* ── Success / Error ────────────────────────────────────────────── */
277
+
278
+ .success-icon,
279
+ .error-icon {
280
+ font-size: 36px;
281
+ text-align: center;
282
+ margin-bottom: 10px;
283
+ }
284
+
285
+ #stateSuccess,
286
+ #stateError {
287
+ text-align: center;
288
+ padding: 24px 0 8px;
289
+ }
package/popup.html ADDED
@@ -0,0 +1,92 @@
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>Bug Report</title>
7
+ <link rel="stylesheet" href="popup.css">
8
+ </head>
9
+ <body>
10
+ <div class="popup-container">
11
+ <!-- Header -->
12
+ <div class="popup-header">
13
+ <div class="popup-logo">🐛</div>
14
+ <div class="popup-title">Bug Report</div>
15
+ <div class="popup-version" id="versionLabel">v2.0.0</div>
16
+ </div>
17
+
18
+ <!-- Loading State -->
19
+ <div class="popup-state" id="stateLoading">
20
+ <div class="spinner"></div>
21
+ <p class="popup-status-text">Collecting data…</p>
22
+ </div>
23
+
24
+ <!-- Preview State -->
25
+ <div class="popup-state hidden" id="statePreview">
26
+ <p class="popup-info-text">
27
+ The following information will be included in the bug report for the current page:
28
+ </p>
29
+
30
+ <div class="popup-url" id="previewUrl" title=""></div>
31
+
32
+ <div class="popup-stats">
33
+ <div class="stat-card">
34
+ <div class="stat-icon">👆</div>
35
+ <div class="stat-value" id="statInteractions">0</div>
36
+ <div class="stat-label">Interactions</div>
37
+ </div>
38
+ <div class="stat-card">
39
+ <div class="stat-icon">📋</div>
40
+ <div class="stat-value" id="statConsoleLogs">0</div>
41
+ <div class="stat-label">Console Logs</div>
42
+ </div>
43
+ <div class="stat-card">
44
+ <div class="stat-icon">⚠️</div>
45
+ <div class="stat-value" id="statErrors">0</div>
46
+ <div class="stat-label">JS Errors</div>
47
+ </div>
48
+ <div class="stat-card">
49
+ <div class="stat-icon">🌐</div>
50
+ <div class="stat-value" id="statNetwork">0</div>
51
+ <div class="stat-label">Network Req.</div>
52
+ </div>
53
+ </div>
54
+
55
+ <p class="popup-privacy-note">
56
+ 🔒 Sensitive data (emails, tokens, passwords, API keys) will be automatically redacted.
57
+ </p>
58
+
59
+ <div class="popup-actions">
60
+ <button class="btn btn-primary" id="btnDownload">
61
+ <span class="btn-icon">📥</span>
62
+ Download Report
63
+ </button>
64
+ <button class="btn btn-secondary" id="btnCancel">
65
+ Cancel
66
+ </button>
67
+ </div>
68
+ </div>
69
+
70
+ <!-- Success State -->
71
+ <div class="popup-state hidden" id="stateSuccess">
72
+ <div class="success-icon">✅</div>
73
+ <p class="popup-status-text">Report downloaded!</p>
74
+ <p class="popup-info-text subtle">
75
+ Bitte die HTML-Datei an Ihren Support-Kanal weiterleiten.
76
+ </p>
77
+ </div>
78
+
79
+ <!-- Error State -->
80
+ <div class="popup-state hidden" id="stateError">
81
+ <div class="error-icon">❌</div>
82
+ <p class="popup-status-text">Something went wrong</p>
83
+ <p class="popup-info-text subtle" id="errorMessage"></p>
84
+ <div class="popup-actions">
85
+ <button class="btn btn-secondary" id="btnRetry">Retry</button>
86
+ </div>
87
+ </div>
88
+ </div>
89
+
90
+ <script src="popup.js"></script>
91
+ </body>
92
+ </html>
package/popup.js ADDED
@@ -0,0 +1,126 @@
1
+ /**
2
+ * popup.js — Popup controller for Bug Report Extension
3
+ *
4
+ * Manages:
5
+ * - Loading preview counts from background/content script
6
+ * - Showing summary before download
7
+ * - Triggering download or cancel
8
+ */
9
+
10
+ // ── DOM References ───────────────────────────────────────────────
11
+
12
+ const stateLoading = document.getElementById('stateLoading');
13
+ const statePreview = document.getElementById('statePreview');
14
+ const stateSuccess = document.getElementById('stateSuccess');
15
+ const stateError = document.getElementById('stateError');
16
+
17
+ const previewUrl = document.getElementById('previewUrl');
18
+ const statInteractions = document.getElementById('statInteractions');
19
+ const statConsoleLogs = document.getElementById('statConsoleLogs');
20
+ const statErrors = document.getElementById('statErrors');
21
+ const statNetwork = document.getElementById('statNetwork');
22
+ const errorMessage = document.getElementById('errorMessage');
23
+
24
+ const btnDownload = document.getElementById('btnDownload');
25
+ const btnCancel = document.getElementById('btnCancel');
26
+ const btnRetry = document.getElementById('btnRetry');
27
+
28
+ // ── State Management ─────────────────────────────────────────────
29
+
30
+ function showState(stateEl) {
31
+ [stateLoading, statePreview, stateSuccess, stateError].forEach((el) => {
32
+ el.classList.add('hidden');
33
+ });
34
+ stateEl.classList.remove('hidden');
35
+ }
36
+
37
+ // ── Get Active Tab ───────────────────────────────────────────────
38
+
39
+ async function getActiveTabId() {
40
+ const [tab] = await chrome.tabs.query({ active: true, currentWindow: true });
41
+ return tab?.id;
42
+ }
43
+
44
+ // ── Load Preview ─────────────────────────────────────────────────
45
+
46
+ async function loadPreview() {
47
+ showState(stateLoading);
48
+
49
+ try {
50
+ const tabId = await getActiveTabId();
51
+ if (!tabId) throw new Error('No active tab found.');
52
+
53
+ const preview = await chrome.runtime.sendMessage({
54
+ type: 'GET_REPORT_PREVIEW',
55
+ tabId,
56
+ });
57
+
58
+ if (preview.error) throw new Error(preview.error);
59
+
60
+ // Populate UI
61
+ const truncatedUrl =
62
+ preview.url.length > 60 ? preview.url.substring(0, 57) + '…' : preview.url;
63
+ previewUrl.textContent = truncatedUrl;
64
+ previewUrl.title = preview.url;
65
+
66
+ statInteractions.textContent = preview.interactionCount || 0;
67
+ statConsoleLogs.textContent = preview.consoleLogCount || 0;
68
+ statErrors.textContent = preview.jsErrorCount || 0;
69
+ statNetwork.textContent = preview.networkRequestCount || 0;
70
+
71
+ showState(statePreview);
72
+ } catch (err) {
73
+ errorMessage.textContent = err.message || 'Could not load page data.';
74
+ showState(stateError);
75
+ }
76
+ }
77
+
78
+ // ── Download Report ──────────────────────────────────────────────
79
+
80
+ async function triggerDownload() {
81
+ btnDownload.disabled = true;
82
+ btnDownload.innerHTML = '<span class="spinner" style="width:16px;height:16px;border-width:2px;"></span> Generating…';
83
+
84
+ try {
85
+ const tabId = await getActiveTabId();
86
+ if (!tabId) throw new Error('No active tab found.');
87
+
88
+ const result = await chrome.runtime.sendMessage({
89
+ type: 'DOWNLOAD_REPORT',
90
+ tabId,
91
+ });
92
+
93
+ if (result.cancelled) {
94
+ // User cancelled the Ist/Soll prompt — reset button and stay on preview
95
+ btnDownload.disabled = false;
96
+ btnDownload.innerHTML = '<span class="btn-icon">📥</span> Download Report';
97
+ return;
98
+ }
99
+
100
+ if (!result.success) throw new Error(result.error || 'Download failed.');
101
+
102
+ showState(stateSuccess);
103
+
104
+ // Auto-close after 2.5 seconds
105
+ setTimeout(() => window.close(), 2500);
106
+ } catch (err) {
107
+ errorMessage.textContent = err.message || 'Failed to generate report.';
108
+ showState(stateError);
109
+ }
110
+ }
111
+
112
+ // ── Event Listeners ──────────────────────────────────────────────
113
+
114
+ btnDownload.addEventListener('click', triggerDownload);
115
+
116
+ btnCancel.addEventListener('click', () => {
117
+ window.close();
118
+ });
119
+
120
+ btnRetry.addEventListener('click', () => {
121
+ loadPreview();
122
+ });
123
+
124
+ // ── Init ─────────────────────────────────────────────────────────
125
+
126
+ loadPreview();