mcpbrowser 0.2.18 โ†’ 0.2.21

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.
@@ -0,0 +1,307 @@
1
+ import assert from 'assert';
2
+ import { prepareHtml } from '../src/mcp-browser.js';
3
+
4
+ console.log('๐Ÿงช Testing prepareHtml function\n');
5
+
6
+ let testsPassed = 0;
7
+ let testsFailed = 0;
8
+
9
+ function test(description, fn) {
10
+ try {
11
+ fn();
12
+ console.log(`โœ… ${description}`);
13
+ testsPassed++;
14
+ } catch (err) {
15
+ console.log(`โŒ ${description}`);
16
+ console.log(` Error: ${err.message}`);
17
+ testsFailed++;
18
+ }
19
+ }
20
+
21
+ // Test 1: Remove HTML comments
22
+ test('Should remove HTML comments', () => {
23
+ const html = '<div>Content<!-- This is a comment --></div>';
24
+ const result = prepareHtml(html, 'https://example.com');
25
+ assert(!result.includes('<!--'), 'Should not contain comment start');
26
+ assert(!result.includes('-->'), 'Should not contain comment end');
27
+ assert(result.includes('Content'), 'Should preserve content');
28
+ });
29
+
30
+ // Test 2: Remove script tags
31
+ test('Should remove script tags and their content', () => {
32
+ const html = '<div>Keep this</div><script>alert("remove");</script><div>And this</div>';
33
+ const result = prepareHtml(html, 'https://example.com');
34
+ assert(!result.includes('<script'), 'Should not contain script tag');
35
+ assert(!result.includes('alert'), 'Should not contain script content');
36
+ assert(result.includes('Keep this'), 'Should preserve content');
37
+ });
38
+
39
+ // Test 3: Remove style tags
40
+ test('Should remove style tags and their content', () => {
41
+ const html = '<div>Content</div><style>.class { color: red; }</style>';
42
+ const result = prepareHtml(html, 'https://example.com');
43
+ assert(!result.includes('<style'), 'Should not contain style tag');
44
+ assert(!result.includes('color: red'), 'Should not contain style content');
45
+ assert(result.includes('Content'), 'Should preserve content');
46
+ });
47
+
48
+ // Test 4: Remove meta tags
49
+ test('Should remove meta tags', () => {
50
+ const html = '<head><meta charset="utf-8"><meta name="viewport" content="width=device-width"></head><body>Content</body>';
51
+ const result = prepareHtml(html, 'https://example.com');
52
+ assert(!result.includes('<meta'), 'Should not contain meta tags');
53
+ assert(result.includes('Content'), 'Should preserve content');
54
+ });
55
+
56
+ // Test 5: Convert relative URLs in href
57
+ test('Should convert relative href URLs to absolute', () => {
58
+ const html = '<a href="/docs/page">Link</a>';
59
+ const result = prepareHtml(html, 'https://example.com');
60
+ assert(result.includes('href="https://example.com/docs/page"'), 'Should convert relative href to absolute');
61
+ });
62
+
63
+ // Test 6: Keep absolute URLs in href unchanged
64
+ test('Should keep absolute href URLs unchanged', () => {
65
+ const html = '<a href="https://other.com/page">Link</a>';
66
+ const result = prepareHtml(html, 'https://example.com');
67
+ assert(result.includes('href="https://other.com/page"'), 'Should keep absolute href unchanged');
68
+ });
69
+
70
+ // Test 7: Convert relative URLs in src
71
+ test('Should convert relative src URLs to absolute', () => {
72
+ const html = '<img src="/images/logo.png">';
73
+ const result = prepareHtml(html, 'https://example.com');
74
+ assert(result.includes('src="https://example.com/images/logo.png"'), 'Should convert relative src to absolute');
75
+ });
76
+
77
+ // Test 8: Keep absolute URLs in src unchanged
78
+ test('Should keep absolute src URLs unchanged', () => {
79
+ const html = '<img src="https://cdn.example.com/logo.png">';
80
+ const result = prepareHtml(html, 'https://example.com');
81
+ assert(result.includes('src="https://cdn.example.com/logo.png"'), 'Should keep absolute src unchanged');
82
+ });
83
+
84
+ // Test 9: Handle anchor links (should not modify)
85
+ test('Should not modify anchor links', () => {
86
+ const html = '<a href="#section">Jump</a>';
87
+ const result = prepareHtml(html, 'https://example.com');
88
+ assert(result.includes('href="#section"'), 'Should keep anchor links unchanged');
89
+ });
90
+
91
+ // Test 10: Handle mailto and tel links (should not modify)
92
+ test('Should not modify mailto and tel links', () => {
93
+ const html = '<a href="mailto:test@example.com">Email</a><a href="tel:+1234567890">Call</a>';
94
+ const result = prepareHtml(html, 'https://example.com');
95
+ assert(result.includes('href="mailto:test@example.com"'), 'Should keep mailto unchanged');
96
+ assert(result.includes('href="tel:+1234567890"'), 'Should keep tel unchanged');
97
+ });
98
+
99
+ // Test 11: Handle data URIs in src (should not modify)
100
+ test('Should not modify data URIs', () => {
101
+ const html = '<img src="data:image/png;base64,iVBORw0KGg==">';
102
+ const result = prepareHtml(html, 'https://example.com');
103
+ assert(result.includes('src="data:image/png;base64,iVBORw0KGg=="'), 'Should keep data URI unchanged');
104
+ });
105
+
106
+ // Test 12: Handle protocol-relative URLs (should not modify)
107
+ test('Should not modify protocol-relative URLs', () => {
108
+ const html = '<img src="//cdn.example.com/image.png">';
109
+ const result = prepareHtml(html, 'https://example.com');
110
+ assert(result.includes('src="//cdn.example.com/image.png"'), 'Should keep protocol-relative URL unchanged');
111
+ });
112
+
113
+ // Test 13: Handle empty or null HTML
114
+ test('Should handle empty HTML', () => {
115
+ const result = prepareHtml('', 'https://example.com');
116
+ assert.strictEqual(result, '', 'Should return empty string');
117
+ });
118
+
119
+ test('Should handle null HTML', () => {
120
+ const result = prepareHtml(null, 'https://example.com');
121
+ assert.strictEqual(result, '', 'Should return empty string for null');
122
+ });
123
+
124
+ // Test 14: Complex real-world example
125
+ test('Should handle complex HTML with multiple elements', () => {
126
+ const html = `
127
+ <!DOCTYPE html>
128
+ <html>
129
+ <head>
130
+ <meta charset="utf-8">
131
+ <title>Test Page</title>
132
+ <style>.test { color: blue; }</style>
133
+ <script>console.log("test");</script>
134
+ </head>
135
+ <body>
136
+ <!-- Main content -->
137
+ <div>
138
+ <a href="/page1">Page 1</a>
139
+ <a href="https://external.com">External</a>
140
+ <img src="/images/pic.jpg">
141
+ <script>alert("inline");</script>
142
+ </div>
143
+ </body>
144
+ </html>
145
+ `;
146
+ const result = prepareHtml(html, 'https://example.com/test/');
147
+
148
+ // Should not contain removed elements
149
+ assert(!result.includes('<meta'), 'Should remove meta');
150
+ assert(!result.includes('<style'), 'Should remove style');
151
+ assert(!result.includes('<script'), 'Should remove script');
152
+ assert(!result.includes('<!--'), 'Should remove comments');
153
+
154
+ // Should convert relative URLs
155
+ assert(result.includes('href="https://example.com/page1"'), 'Should convert relative href');
156
+ assert(result.includes('src="https://example.com/images/pic.jpg"'), 'Should convert relative src');
157
+
158
+ // Should keep absolute URLs
159
+ assert(result.includes('href="https://external.com"'), 'Should keep absolute href');
160
+
161
+ // Should preserve content
162
+ assert(result.includes('Page 1'), 'Should preserve content');
163
+ });
164
+
165
+ // Test 15: Verify script with attributes is removed
166
+ test('Should remove script tags with various attributes', () => {
167
+ const html = '<script type="text/javascript" async defer src="/app.js">console.log("test");</script>';
168
+ const result = prepareHtml(html, 'https://example.com');
169
+ assert(!result.includes('<script'), 'Should remove script with attributes');
170
+ assert(!result.includes('app.js'), 'Should remove script content');
171
+ });
172
+
173
+ // Test 16: Remove inline style attributes
174
+ test('Should remove inline style attributes', () => {
175
+ const html = '<div style="color: red; font-size: 14px;">Content</div>';
176
+ const result = prepareHtml(html, 'https://example.com');
177
+ assert(!result.includes('style='), 'Should remove style attribute');
178
+ assert(result.includes('Content'), 'Should preserve content');
179
+ });
180
+
181
+ // Test 17: Remove class attributes
182
+ test('Should remove class attributes', () => {
183
+ const html = '<div class="container main-content">Text</div>';
184
+ const result = prepareHtml(html, 'https://example.com');
185
+ assert(!result.includes('class='), 'Should remove class attribute');
186
+ assert(result.includes('Text'), 'Should preserve content');
187
+ });
188
+
189
+ // Test 18: Remove id attributes
190
+ test('Should remove id attributes', () => {
191
+ const html = '<div id="main-section">Content</div>';
192
+ const result = prepareHtml(html, 'https://example.com');
193
+ assert(!result.includes('id='), 'Should remove id attribute');
194
+ assert(result.includes('Content'), 'Should preserve content');
195
+ });
196
+
197
+ // Test 19: Remove data-* attributes
198
+ test('Should remove data-* attributes', () => {
199
+ const html = '<div data-id="123" data-value="test">Content</div>';
200
+ const result = prepareHtml(html, 'https://example.com');
201
+ assert(!result.includes('data-'), 'Should remove data attributes');
202
+ assert(result.includes('Content'), 'Should preserve content');
203
+ });
204
+
205
+ // Test 20: Remove event handler attributes
206
+ test('Should remove event handler attributes', () => {
207
+ const html = '<button onclick="handleClick()" onmouseover="hover()">Click</button>';
208
+ const result = prepareHtml(html, 'https://example.com');
209
+ assert(!result.includes('onclick='), 'Should remove onclick');
210
+ assert(!result.includes('onmouseover='), 'Should remove onmouseover');
211
+ assert(result.includes('Click'), 'Should preserve content');
212
+ });
213
+
214
+ // Test 21: Remove SVG tags
215
+ test('Should remove SVG tags and content', () => {
216
+ const html = '<div>Text</div><svg width="100" height="100"><circle cx="50" cy="50" r="40"/></svg>';
217
+ const result = prepareHtml(html, 'https://example.com');
218
+ assert(!result.includes('<svg'), 'Should remove svg tag');
219
+ assert(!result.includes('circle'), 'Should remove svg content');
220
+ assert(result.includes('Text'), 'Should preserve content');
221
+ });
222
+
223
+ // Test 22: Remove noscript tags
224
+ test('Should remove noscript tags and content', () => {
225
+ const html = '<div>Content</div><noscript>JavaScript is disabled</noscript>';
226
+ const result = prepareHtml(html, 'https://example.com');
227
+ assert(!result.includes('<noscript'), 'Should remove noscript tag');
228
+ assert(!result.includes('JavaScript is disabled'), 'Should remove noscript content');
229
+ assert(result.includes('Content'), 'Should preserve content');
230
+ });
231
+
232
+ // Test 23: Remove link tags
233
+ test('Should remove link tags', () => {
234
+ const html = '<head><link rel="stylesheet" href="/style.css"><link rel="preload" as="script"></head>';
235
+ const result = prepareHtml(html, 'https://example.com');
236
+ assert(!result.includes('<link'), 'Should remove link tags');
237
+ });
238
+
239
+ // Test 24: Remove role attributes
240
+ test('Should remove role attributes', () => {
241
+ const html = '<nav role="navigation">Menu</nav>';
242
+ const result = prepareHtml(html, 'https://example.com');
243
+ assert(!result.includes('role='), 'Should remove role attribute');
244
+ assert(result.includes('Menu'), 'Should preserve content');
245
+ });
246
+
247
+ // Test 25: Remove aria-* attributes
248
+ test('Should remove aria-* attributes', () => {
249
+ const html = '<button aria-label="Close" aria-pressed="false">X</button>';
250
+ const result = prepareHtml(html, 'https://example.com');
251
+ assert(!result.includes('aria-'), 'Should remove aria attributes');
252
+ assert(result.includes('X'), 'Should preserve content');
253
+ });
254
+
255
+ // Test 26: Collapse whitespace
256
+ test('Should collapse multiple whitespace into single space', () => {
257
+ const html = '<div>Line 1\n\n\n Line 2\t\t\tLine 3</div>';
258
+ const result = prepareHtml(html, 'https://example.com');
259
+ assert(!result.includes('\n\n'), 'Should remove multiple newlines');
260
+ assert(!result.includes(' '), 'Should remove multiple spaces');
261
+ assert(result.includes('Line 1'), 'Should preserve content');
262
+ });
263
+
264
+ // Test 27: Comprehensive test with all removals
265
+ test('Should handle HTML with all types of removals', () => {
266
+ const html = `
267
+ <div class="container" id="main" style="color: blue;" data-test="value" onclick="alert()">
268
+ <svg width="100"><circle/></svg>
269
+ <script>console.log("test");</script>
270
+ <style>.test { color: red; }</style>
271
+ <noscript>Enable JS</noscript>
272
+ <link rel="stylesheet" href="/style.css">
273
+ <div role="main" aria-label="content">
274
+ <a href="/page">Link</a>
275
+ <p>Text content</p>
276
+ </div>
277
+ </div>
278
+ `;
279
+ const result = prepareHtml(html, 'https://example.com/test/');
280
+
281
+ // Should remove all code attributes
282
+ assert(!result.includes('class='), 'Should remove class');
283
+ assert(!result.includes('id='), 'Should remove id');
284
+ assert(!result.includes('style='), 'Should remove style');
285
+ assert(!result.includes('data-'), 'Should remove data attributes');
286
+ assert(!result.includes('onclick='), 'Should remove onclick');
287
+ assert(!result.includes('role='), 'Should remove role');
288
+ assert(!result.includes('aria-'), 'Should remove aria');
289
+
290
+ // Should remove non-content elements
291
+ assert(!result.includes('<svg'), 'Should remove svg');
292
+ assert(!result.includes('<script'), 'Should remove script');
293
+ assert(!result.includes('<style'), 'Should remove style');
294
+ assert(!result.includes('<noscript'), 'Should remove noscript');
295
+ assert(!result.includes('<link'), 'Should remove link');
296
+
297
+ // Should preserve content and convert URLs
298
+ assert(result.includes('href="https://example.com/page"'), 'Should convert relative URL');
299
+ assert(result.includes('Text content'), 'Should preserve text');
300
+ });
301
+
302
+ console.log('\n==================================================');
303
+ console.log(`โœ… Tests Passed: ${testsPassed}`);
304
+ console.log(`โŒ Tests Failed: ${testsFailed}`);
305
+ console.log('==================================================\n');
306
+
307
+ process.exit(testsFailed > 0 ? 1 : 0);