@mkhuda/dom-screenshot 0.0.1 → 1.0.1
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/.gitattributes +1 -0
- package/EXAMPLES_QUICKSTART.md +240 -0
- package/README.md +542 -25
- package/TESTING.md +269 -0
- package/TESTING_STATUS.md +215 -0
- package/TEST_SETUP_SUMMARY.md +335 -0
- package/dist/dom-screenshot.d.ts +44 -272
- package/dist/dom-screenshot.d.ts.map +1 -0
- package/dist/dom-screenshot.esm.js +753 -0
- package/dist/dom-screenshot.esm.js.map +1 -0
- package/dist/dom-screenshot.min.js +2 -1
- package/dist/dom-screenshot.min.js.map +1 -0
- package/examples/README.md +211 -0
- package/examples/react-app/README.md +161 -0
- package/examples/react-app/index.html +12 -0
- package/examples/react-app/node_modules/.vite/deps/_metadata.json +46 -0
- package/examples/react-app/node_modules/.vite/deps/chunk-FK77NBP6.js +1895 -0
- package/examples/react-app/node_modules/.vite/deps/chunk-FK77NBP6.js.map +7 -0
- package/examples/react-app/node_modules/.vite/deps/chunk-VSODSHUF.js +21647 -0
- package/examples/react-app/node_modules/.vite/deps/chunk-VSODSHUF.js.map +7 -0
- package/examples/react-app/node_modules/.vite/deps/package.json +3 -0
- package/examples/react-app/node_modules/.vite/deps/react-dom.js +5 -0
- package/examples/react-app/node_modules/.vite/deps/react-dom.js.map +7 -0
- package/examples/react-app/node_modules/.vite/deps/react-dom_client.js +38 -0
- package/examples/react-app/node_modules/.vite/deps/react-dom_client.js.map +7 -0
- package/examples/react-app/node_modules/.vite/deps/react.js +4 -0
- package/examples/react-app/node_modules/.vite/deps/react.js.map +7 -0
- package/examples/react-app/node_modules/.vite/deps/react_jsx-dev-runtime.js +898 -0
- package/examples/react-app/node_modules/.vite/deps/react_jsx-dev-runtime.js.map +7 -0
- package/examples/react-app/node_modules/.vite/deps/react_jsx-runtime.js +910 -0
- package/examples/react-app/node_modules/.vite/deps/react_jsx-runtime.js.map +7 -0
- package/examples/react-app/package.json +21 -0
- package/examples/react-app/tsconfig.json +25 -0
- package/examples/react-app/tsconfig.node.json +10 -0
- package/examples/react-app/vite.config.ts +10 -0
- package/package.json +75 -44
- package/rollup.config.mjs +35 -0
- package/tests/README.md +394 -0
- package/tests/fixtures/html.ts +192 -0
- package/tests/fixtures/images.ts +86 -0
- package/tests/fixtures/styles.ts +288 -0
- package/tests/helpers/dom-helpers.ts +242 -0
- package/tests/mocks/canvas-mock.ts +94 -0
- package/tests/mocks/image-mock.ts +147 -0
- package/tests/mocks/xhr-mock.ts +202 -0
- package/tests/setup.ts +103 -0
- package/tests/unit/basic.test.ts +263 -0
- package/tests/unit/simple.test.ts +172 -0
- package/tsconfig.json +44 -20
- package/vitest.config.mts +35 -0
- package/rollup.config.js +0 -20
package/tests/README.md
ADDED
|
@@ -0,0 +1,394 @@
|
|
|
1
|
+
# DOM Screenshot Testing Guide
|
|
2
|
+
|
|
3
|
+
Complete testing setup for the dom-screenshot library using Vitest.
|
|
4
|
+
|
|
5
|
+
## 📋 Directory Structure
|
|
6
|
+
|
|
7
|
+
```
|
|
8
|
+
tests/
|
|
9
|
+
├── setup.ts # Global test setup and configuration
|
|
10
|
+
├── README.md # This file
|
|
11
|
+
├── unit/ # Unit tests
|
|
12
|
+
│ └── basic.test.ts # Basic functionality tests
|
|
13
|
+
├── integration/ # Integration tests (coming soon)
|
|
14
|
+
├── helpers/ # Test helper utilities
|
|
15
|
+
│ └── dom-helpers.ts # DOM manipulation helpers
|
|
16
|
+
├── mocks/ # Mock implementations
|
|
17
|
+
│ ├── canvas-mock.ts # Canvas API mocks
|
|
18
|
+
│ ├── image-mock.ts # Image loading mocks
|
|
19
|
+
│ └── xhr-mock.ts # XMLHttpRequest mocks
|
|
20
|
+
└── fixtures/ # Test data and fixtures
|
|
21
|
+
├── html.ts # HTML test fixtures
|
|
22
|
+
├── images.ts # Image data URLs
|
|
23
|
+
└── styles.ts # CSS and style fixtures
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## 🚀 Quick Start
|
|
27
|
+
|
|
28
|
+
### Install Dependencies
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
npm install
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
### Run Tests
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
# Run all tests
|
|
38
|
+
npm test
|
|
39
|
+
|
|
40
|
+
# Run tests once (CI mode)
|
|
41
|
+
npm run test:run
|
|
42
|
+
|
|
43
|
+
# Run tests in watch mode
|
|
44
|
+
npm run test:watch
|
|
45
|
+
|
|
46
|
+
# Run tests with UI
|
|
47
|
+
npm run test:ui
|
|
48
|
+
|
|
49
|
+
# Generate coverage report
|
|
50
|
+
npm run test:coverage
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
## 📝 Writing Tests
|
|
54
|
+
|
|
55
|
+
### Basic Test Template
|
|
56
|
+
|
|
57
|
+
```typescript
|
|
58
|
+
import { describe, it, expect, beforeEach, afterEach } from 'vitest';
|
|
59
|
+
import { domtoimage } from '../../src/dom-screenshot';
|
|
60
|
+
import { createSimpleDiv } from '../helpers/dom-helpers';
|
|
61
|
+
|
|
62
|
+
describe('My Test Suite', () => {
|
|
63
|
+
let container: HTMLElement;
|
|
64
|
+
|
|
65
|
+
beforeEach(() => {
|
|
66
|
+
container = document.createElement('div');
|
|
67
|
+
document.body.appendChild(container);
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
afterEach(() => {
|
|
71
|
+
if (container?.parentNode) {
|
|
72
|
+
container.parentNode.removeChild(container);
|
|
73
|
+
}
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
it('should do something', async () => {
|
|
77
|
+
const div = createSimpleDiv('Test');
|
|
78
|
+
const result = await domtoimage.toSvg(div);
|
|
79
|
+
|
|
80
|
+
expect(result).toBeValidSvgDataUrl();
|
|
81
|
+
});
|
|
82
|
+
});
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
## 🛠️ Test Helpers
|
|
86
|
+
|
|
87
|
+
### DOM Helpers (`helpers/dom-helpers.ts`)
|
|
88
|
+
|
|
89
|
+
Create test DOM elements easily:
|
|
90
|
+
|
|
91
|
+
```typescript
|
|
92
|
+
import {
|
|
93
|
+
createSimpleDiv,
|
|
94
|
+
createStyledDiv,
|
|
95
|
+
createColoredDiv,
|
|
96
|
+
createImageElement,
|
|
97
|
+
createCanvasElement,
|
|
98
|
+
createComplexDOM,
|
|
99
|
+
createDOMWithStyles,
|
|
100
|
+
createSVGElement,
|
|
101
|
+
wait
|
|
102
|
+
} from '../helpers/dom-helpers';
|
|
103
|
+
|
|
104
|
+
// Create a simple div
|
|
105
|
+
const div = createSimpleDiv('Hello');
|
|
106
|
+
|
|
107
|
+
// Create styled div
|
|
108
|
+
const styled = createStyledDiv('Content', { color: 'red' });
|
|
109
|
+
|
|
110
|
+
// Create colored div
|
|
111
|
+
const colored = createColoredDiv('Text', 'white', 'blue');
|
|
112
|
+
|
|
113
|
+
// Create complex DOM tree
|
|
114
|
+
const complex = createComplexDOM();
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
## 🎭 Mock Utilities
|
|
118
|
+
|
|
119
|
+
### Canvas Mocks (`mocks/canvas-mock.ts`)
|
|
120
|
+
|
|
121
|
+
Mock Canvas API operations:
|
|
122
|
+
|
|
123
|
+
```typescript
|
|
124
|
+
import {
|
|
125
|
+
mockCanvasToDataUrl,
|
|
126
|
+
mockCanvasToBlob,
|
|
127
|
+
mockCanvasContext,
|
|
128
|
+
createValidPngDataUrl,
|
|
129
|
+
createValidSvgDataUrl
|
|
130
|
+
} from '../mocks/canvas-mock';
|
|
131
|
+
|
|
132
|
+
// Mock canvas.toDataURL()
|
|
133
|
+
mockCanvasToDataUrl(createValidPngDataUrl());
|
|
134
|
+
|
|
135
|
+
// Mock canvas.toBlob()
|
|
136
|
+
mockCanvasToBlob(new Blob(['data']));
|
|
137
|
+
|
|
138
|
+
// Mock canvas context
|
|
139
|
+
const { fillRect, drawImage } = mockCanvasContext();
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
### Image Mocks (`mocks/image-mock.ts`)
|
|
143
|
+
|
|
144
|
+
Mock image loading:
|
|
145
|
+
|
|
146
|
+
```typescript
|
|
147
|
+
import {
|
|
148
|
+
mockImageSuccess,
|
|
149
|
+
mockImageError,
|
|
150
|
+
createImageDataUrl,
|
|
151
|
+
mockFileReaderDataUrl
|
|
152
|
+
} from '../mocks/image-mock';
|
|
153
|
+
|
|
154
|
+
// Mock successful image load
|
|
155
|
+
mockImageSuccess(10); // 10ms delay
|
|
156
|
+
|
|
157
|
+
// Mock image load error
|
|
158
|
+
mockImageError(10);
|
|
159
|
+
|
|
160
|
+
// Create image data URL
|
|
161
|
+
const dataUrl = createImageDataUrl('png'); // or 'jpeg', 'gif'
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
### XHR Mocks (`mocks/xhr-mock.ts`)
|
|
165
|
+
|
|
166
|
+
Mock XMLHttpRequest:
|
|
167
|
+
|
|
168
|
+
```typescript
|
|
169
|
+
import {
|
|
170
|
+
mockXhrSuccess,
|
|
171
|
+
mockXhrError,
|
|
172
|
+
mockXhrTimeout,
|
|
173
|
+
stubUrlPattern,
|
|
174
|
+
createBase64ImageData
|
|
175
|
+
} from '../mocks/xhr-mock';
|
|
176
|
+
|
|
177
|
+
// Mock successful XHR
|
|
178
|
+
mockXhrSuccess('response-data', 10);
|
|
179
|
+
|
|
180
|
+
// Mock XHR error
|
|
181
|
+
mockXhrError(404, 10);
|
|
182
|
+
|
|
183
|
+
// Mock XHR timeout
|
|
184
|
+
mockXhrTimeout(100);
|
|
185
|
+
|
|
186
|
+
// Stub specific URLs
|
|
187
|
+
stubUrlPattern(
|
|
188
|
+
/example\.com\/image/,
|
|
189
|
+
'image-data',
|
|
190
|
+
200
|
|
191
|
+
);
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
## 📦 Test Fixtures
|
|
195
|
+
|
|
196
|
+
### HTML Fixtures (`fixtures/html.ts`)
|
|
197
|
+
|
|
198
|
+
Pre-defined HTML strings for testing:
|
|
199
|
+
|
|
200
|
+
```typescript
|
|
201
|
+
import {
|
|
202
|
+
SIMPLE_HTML,
|
|
203
|
+
STYLED_HTML,
|
|
204
|
+
COMPLEX_HTML,
|
|
205
|
+
NESTED_HTML,
|
|
206
|
+
TEXT_HTML,
|
|
207
|
+
FORM_HTML,
|
|
208
|
+
COLOR_HTML,
|
|
209
|
+
BORDER_SHADOW_HTML,
|
|
210
|
+
MULTI_IMAGE_HTML,
|
|
211
|
+
TABLE_HTML,
|
|
212
|
+
SVG_HTML,
|
|
213
|
+
generateLargeHTML
|
|
214
|
+
} from '../fixtures/html';
|
|
215
|
+
|
|
216
|
+
// Use in tests
|
|
217
|
+
container.innerHTML = SIMPLE_HTML;
|
|
218
|
+
|
|
219
|
+
// Generate dynamic HTML
|
|
220
|
+
const large = generateLargeHTML(100); // 100 items
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
### Image Fixtures (`fixtures/images.ts`)
|
|
224
|
+
|
|
225
|
+
Pre-encoded image data URLs:
|
|
226
|
+
|
|
227
|
+
```typescript
|
|
228
|
+
import {
|
|
229
|
+
PNG_1X1_TRANSPARENT,
|
|
230
|
+
JPEG_1X1_RED,
|
|
231
|
+
GIF_1X1_BLUE,
|
|
232
|
+
SVG_CIRCLE,
|
|
233
|
+
TEST_IMAGES,
|
|
234
|
+
createTestImageElement,
|
|
235
|
+
createTestImageElements
|
|
236
|
+
} from '../fixtures/images';
|
|
237
|
+
|
|
238
|
+
// Use image data
|
|
239
|
+
const img = new Image();
|
|
240
|
+
img.src = PNG_1X1_TRANSPARENT;
|
|
241
|
+
|
|
242
|
+
// Create test image elements
|
|
243
|
+
const images = createTestImageElements(3);
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
### Style Fixtures (`fixtures/styles.ts`)
|
|
247
|
+
|
|
248
|
+
Pre-defined CSS styles for testing:
|
|
249
|
+
|
|
250
|
+
```typescript
|
|
251
|
+
import {
|
|
252
|
+
CSS_FIXTURES,
|
|
253
|
+
createStyleElement,
|
|
254
|
+
createPseudoElementCSS,
|
|
255
|
+
createDivWithPseudoElements
|
|
256
|
+
} from '../fixtures/styles';
|
|
257
|
+
|
|
258
|
+
// Use CSS fixtures
|
|
259
|
+
container.innerHTML = CSS_FIXTURES.gradientDiv;
|
|
260
|
+
|
|
261
|
+
// Create pseudo-elements
|
|
262
|
+
const div = createDivWithPseudoElements();
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
## 🧪 Custom Matchers
|
|
266
|
+
|
|
267
|
+
Custom expect matchers are available:
|
|
268
|
+
|
|
269
|
+
```typescript
|
|
270
|
+
// Check for valid data URL
|
|
271
|
+
expect(result).toBeValidDataUrl();
|
|
272
|
+
|
|
273
|
+
// Check for valid SVG data URL
|
|
274
|
+
expect(result).toBeValidSvgDataUrl();
|
|
275
|
+
|
|
276
|
+
// Check for valid PNG data URL
|
|
277
|
+
expect(result).toBeValidPngDataUrl();
|
|
278
|
+
```
|
|
279
|
+
|
|
280
|
+
## 📊 Test Coverage
|
|
281
|
+
|
|
282
|
+
Generate coverage reports:
|
|
283
|
+
|
|
284
|
+
```bash
|
|
285
|
+
npm run test:coverage
|
|
286
|
+
```
|
|
287
|
+
|
|
288
|
+
Coverage reports are generated in:
|
|
289
|
+
- `coverage/index.html` - HTML report
|
|
290
|
+
- `coverage/lcov.info` - LCOV format (for CI/CD)
|
|
291
|
+
- Console output - Summary
|
|
292
|
+
|
|
293
|
+
## 🔍 Debugging Tests
|
|
294
|
+
|
|
295
|
+
### Enable Debug Logging
|
|
296
|
+
|
|
297
|
+
```typescript
|
|
298
|
+
import { describe, it, expect, beforeEach } from 'vitest';
|
|
299
|
+
|
|
300
|
+
describe('Debug Example', () => {
|
|
301
|
+
it('should log debug info', () => {
|
|
302
|
+
console.log('Debugging info here');
|
|
303
|
+
expect(true).toBe(true);
|
|
304
|
+
});
|
|
305
|
+
});
|
|
306
|
+
```
|
|
307
|
+
|
|
308
|
+
### Run Single Test File
|
|
309
|
+
|
|
310
|
+
```bash
|
|
311
|
+
npx vitest tests/unit/basic.test.ts
|
|
312
|
+
```
|
|
313
|
+
|
|
314
|
+
### Run Single Test Suite
|
|
315
|
+
|
|
316
|
+
```bash
|
|
317
|
+
npx vitest -t "My Test Suite"
|
|
318
|
+
```
|
|
319
|
+
|
|
320
|
+
### Use Vitest UI
|
|
321
|
+
|
|
322
|
+
```bash
|
|
323
|
+
npm run test:ui
|
|
324
|
+
```
|
|
325
|
+
|
|
326
|
+
Opens an interactive UI at http://localhost:51204/__vitest__/
|
|
327
|
+
|
|
328
|
+
## 🔄 Continuous Integration
|
|
329
|
+
|
|
330
|
+
### GitHub Actions Example
|
|
331
|
+
|
|
332
|
+
```yaml
|
|
333
|
+
name: Tests
|
|
334
|
+
|
|
335
|
+
on: [push, pull_request]
|
|
336
|
+
|
|
337
|
+
jobs:
|
|
338
|
+
test:
|
|
339
|
+
runs-on: ubuntu-latest
|
|
340
|
+
steps:
|
|
341
|
+
- uses: actions/checkout@v3
|
|
342
|
+
- uses: actions/setup-node@v3
|
|
343
|
+
with:
|
|
344
|
+
node-version: '18'
|
|
345
|
+
- run: npm install
|
|
346
|
+
- run: npm run test:run
|
|
347
|
+
- run: npm run test:coverage
|
|
348
|
+
```
|
|
349
|
+
|
|
350
|
+
## 📚 Testing Best Practices
|
|
351
|
+
|
|
352
|
+
1. **Isolation**: Each test should be independent
|
|
353
|
+
2. **Cleanup**: Always clean up DOM in `afterEach`
|
|
354
|
+
3. **Mocking**: Mock external dependencies (Canvas, Image, XHR)
|
|
355
|
+
4. **Fixtures**: Use fixtures for consistent test data
|
|
356
|
+
5. **Naming**: Use descriptive test names
|
|
357
|
+
6. **Assertions**: Use specific assertions, not generic `toBeTruthy()`
|
|
358
|
+
7. **Async**: Always `await` promises and handle async operations
|
|
359
|
+
8. **Performance**: Keep tests fast (< 100ms each if possible)
|
|
360
|
+
|
|
361
|
+
## 🐛 Common Issues
|
|
362
|
+
|
|
363
|
+
### Canvas Not Available
|
|
364
|
+
Canvas is mocked in jsdom. Use `mockCanvasToDataUrl()` for PNG/JPEG tests.
|
|
365
|
+
|
|
366
|
+
### Image Loading Fails
|
|
367
|
+
Use `mockImageSuccess()` or `mockImageError()` to control image behavior.
|
|
368
|
+
|
|
369
|
+
### XHR Requests Fail
|
|
370
|
+
Use `mockXhrSuccess()`, `mockXhrError()`, or `stubUrlPattern()` to mock network requests.
|
|
371
|
+
|
|
372
|
+
### Tests Timeout
|
|
373
|
+
Increase timeout or mock async operations that have delays.
|
|
374
|
+
|
|
375
|
+
## 📖 Resources
|
|
376
|
+
|
|
377
|
+
- [Vitest Documentation](https://vitest.dev/)
|
|
378
|
+
- [Chai Assertion Library](https://www.chaijs.com/)
|
|
379
|
+
- [jsdom Documentation](https://github.com/jsdom/jsdom)
|
|
380
|
+
- [Sinon.js Mocking](https://sinonjs.org/)
|
|
381
|
+
|
|
382
|
+
## 🤝 Contributing
|
|
383
|
+
|
|
384
|
+
When adding new features:
|
|
385
|
+
|
|
386
|
+
1. Write tests first (TDD)
|
|
387
|
+
2. Ensure all tests pass: `npm run test:run`
|
|
388
|
+
3. Check coverage: `npm run test:coverage`
|
|
389
|
+
4. Update this documentation
|
|
390
|
+
5. Submit PR with tests
|
|
391
|
+
|
|
392
|
+
---
|
|
393
|
+
|
|
394
|
+
Happy testing! 🎉
|
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* HTML test fixtures
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Simple HTML fixture
|
|
7
|
+
*/
|
|
8
|
+
export const SIMPLE_HTML = `
|
|
9
|
+
<div style="width: 100px; height: 100px; background-color: blue;">
|
|
10
|
+
<p>Hello World</p>
|
|
11
|
+
</div>
|
|
12
|
+
`;
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* HTML with styled elements
|
|
16
|
+
*/
|
|
17
|
+
export const STYLED_HTML = `
|
|
18
|
+
<div style="
|
|
19
|
+
width: 200px;
|
|
20
|
+
height: 200px;
|
|
21
|
+
background: linear-gradient(to right, #ff0000, #00ff00);
|
|
22
|
+
border-radius: 10px;
|
|
23
|
+
padding: 20px;
|
|
24
|
+
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
|
|
25
|
+
">
|
|
26
|
+
<h1 style="color: white; font-size: 24px; margin: 0;">Styled Content</h1>
|
|
27
|
+
<p style="color: #f0f0f0; font-size: 14px;">This is a paragraph with custom styling.</p>
|
|
28
|
+
</div>
|
|
29
|
+
`;
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* HTML with various elements
|
|
33
|
+
*/
|
|
34
|
+
export const COMPLEX_HTML = `
|
|
35
|
+
<div style="width: 300px; background-color: #f5f5f5; padding: 20px;">
|
|
36
|
+
<h1>Title</h1>
|
|
37
|
+
<p>Paragraph text</p>
|
|
38
|
+
<ul>
|
|
39
|
+
<li>Item 1</li>
|
|
40
|
+
<li>Item 2</li>
|
|
41
|
+
<li>Item 3</li>
|
|
42
|
+
</ul>
|
|
43
|
+
<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+M9QDwADhgGAWjR9awAAAABJRU5ErkJggg==" alt="test" style="width: 50px; height: 50px;" />
|
|
44
|
+
</div>
|
|
45
|
+
`;
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* HTML with nested divs
|
|
49
|
+
*/
|
|
50
|
+
export const NESTED_HTML = `
|
|
51
|
+
<div style="background-color: #ddd; padding: 10px;">
|
|
52
|
+
<div style="background-color: #ccc; padding: 10px;">
|
|
53
|
+
<div style="background-color: #bbb; padding: 10px;">
|
|
54
|
+
<p>Nested content</p>
|
|
55
|
+
</div>
|
|
56
|
+
</div>
|
|
57
|
+
</div>
|
|
58
|
+
`;
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* HTML with text and spans
|
|
62
|
+
*/
|
|
63
|
+
export const TEXT_HTML = `
|
|
64
|
+
<div style="font-family: Arial, sans-serif; font-size: 16px; line-height: 1.5;">
|
|
65
|
+
<p>This is <strong>bold</strong> text.</p>
|
|
66
|
+
<p>This is <em>italic</em> text.</p>
|
|
67
|
+
<p>This is <span style="color: red;">colored</span> text.</p>
|
|
68
|
+
</div>
|
|
69
|
+
`;
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* HTML with forms
|
|
73
|
+
*/
|
|
74
|
+
export const FORM_HTML = `
|
|
75
|
+
<div>
|
|
76
|
+
<form>
|
|
77
|
+
<input type="text" value="Test input" style="padding: 5px; border: 1px solid #ccc;" />
|
|
78
|
+
<textarea style="padding: 5px; border: 1px solid #ccc;">Test textarea value</textarea>
|
|
79
|
+
<button type="submit">Submit</button>
|
|
80
|
+
</form>
|
|
81
|
+
</div>
|
|
82
|
+
`;
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* HTML with colors
|
|
86
|
+
*/
|
|
87
|
+
export const COLOR_HTML = `
|
|
88
|
+
<div style="display: flex; gap: 10px;">
|
|
89
|
+
<div style="width: 50px; height: 50px; background-color: red;"></div>
|
|
90
|
+
<div style="width: 50px; height: 50px; background-color: green;"></div>
|
|
91
|
+
<div style="width: 50px; height: 50px; background-color: blue;"></div>
|
|
92
|
+
<div style="width: 50px; height: 50px; background-color: yellow;"></div>
|
|
93
|
+
</div>
|
|
94
|
+
`;
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* HTML with borders and shadows
|
|
98
|
+
*/
|
|
99
|
+
export const BORDER_SHADOW_HTML = `
|
|
100
|
+
<div style="
|
|
101
|
+
width: 150px;
|
|
102
|
+
height: 150px;
|
|
103
|
+
background-color: white;
|
|
104
|
+
border: 2px solid #333;
|
|
105
|
+
border-radius: 8px;
|
|
106
|
+
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
|
|
107
|
+
padding: 15px;
|
|
108
|
+
">
|
|
109
|
+
<p style="margin: 0; text-align: center;">Bordered & Shadowed</p>
|
|
110
|
+
</div>
|
|
111
|
+
`;
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* HTML with transformations
|
|
115
|
+
*/
|
|
116
|
+
export const TRANSFORM_HTML = `
|
|
117
|
+
<div style="
|
|
118
|
+
width: 100px;
|
|
119
|
+
height: 100px;
|
|
120
|
+
background-color: blue;
|
|
121
|
+
transform: rotate(45deg);
|
|
122
|
+
"></div>
|
|
123
|
+
`;
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* HTML with multiple images
|
|
127
|
+
*/
|
|
128
|
+
export const MULTI_IMAGE_HTML = `
|
|
129
|
+
<div style="display: flex; gap: 10px;">
|
|
130
|
+
<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+M9QDwADhgGAWjR9awAAAABJRU5ErkJggg==" alt="img1" style="width: 50px; height: 50px;" />
|
|
131
|
+
<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+M9QDwADhgGAWjR9awAAAABJRU5ErkJggg==" alt="img2" style="width: 50px; height: 50px;" />
|
|
132
|
+
<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+M9QDwADhgGAWjR9awAAAABJRU5ErkJggg==" alt="img3" style="width: 50px; height: 50px;" />
|
|
133
|
+
</div>
|
|
134
|
+
`;
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* HTML with table
|
|
138
|
+
*/
|
|
139
|
+
export const TABLE_HTML = `
|
|
140
|
+
<table style="border-collapse: collapse; width: 200px;">
|
|
141
|
+
<tr style="background-color: #ddd;">
|
|
142
|
+
<th style="border: 1px solid #333; padding: 8px;">Column 1</th>
|
|
143
|
+
<th style="border: 1px solid #333; padding: 8px;">Column 2</th>
|
|
144
|
+
</tr>
|
|
145
|
+
<tr>
|
|
146
|
+
<td style="border: 1px solid #333; padding: 8px;">Data 1</td>
|
|
147
|
+
<td style="border: 1px solid #333; padding: 8px;">Data 2</td>
|
|
148
|
+
</tr>
|
|
149
|
+
<tr>
|
|
150
|
+
<td style="border: 1px solid #333; padding: 8px;">Data 3</td>
|
|
151
|
+
<td style="border: 1px solid #333; padding: 8px;">Data 4</td>
|
|
152
|
+
</tr>
|
|
153
|
+
</table>
|
|
154
|
+
`;
|
|
155
|
+
|
|
156
|
+
/**
|
|
157
|
+
* HTML with SVG
|
|
158
|
+
*/
|
|
159
|
+
export const SVG_HTML = `
|
|
160
|
+
<div>
|
|
161
|
+
<svg width="100" height="100" xmlns="http://www.w3.org/2000/svg">
|
|
162
|
+
<circle cx="50" cy="50" r="40" fill="blue" />
|
|
163
|
+
<rect x="10" y="10" width="30" height="30" fill="red" />
|
|
164
|
+
</svg>
|
|
165
|
+
</div>
|
|
166
|
+
`;
|
|
167
|
+
|
|
168
|
+
/**
|
|
169
|
+
* Empty div fixture
|
|
170
|
+
*/
|
|
171
|
+
export const EMPTY_HTML = `<div></div>`;
|
|
172
|
+
|
|
173
|
+
/**
|
|
174
|
+
* Large HTML for performance testing
|
|
175
|
+
*/
|
|
176
|
+
export function generateLargeHTML(itemCount: number = 100): string {
|
|
177
|
+
let html = '<div style="background-color: #f5f5f5; padding: 10px;">';
|
|
178
|
+
for (let i = 0; i < itemCount; i++) {
|
|
179
|
+
html += `
|
|
180
|
+
<div style="
|
|
181
|
+
background-color: ${i % 2 === 0 ? '#fff' : '#ddd'};
|
|
182
|
+
padding: 5px;
|
|
183
|
+
margin: 5px;
|
|
184
|
+
border: 1px solid #ccc;
|
|
185
|
+
">
|
|
186
|
+
<p>Item ${i + 1}</p>
|
|
187
|
+
</div>
|
|
188
|
+
`;
|
|
189
|
+
}
|
|
190
|
+
html += '</div>';
|
|
191
|
+
return html;
|
|
192
|
+
}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Image test fixtures
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Base64-encoded 1x1 transparent PNG
|
|
7
|
+
*/
|
|
8
|
+
export const PNG_1X1_TRANSPARENT =
|
|
9
|
+
'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+M9QDwADhgGAWjR9awAAAABJRU5ErkJggg==';
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Base64-encoded 1x1 red JPEG
|
|
13
|
+
*/
|
|
14
|
+
export const JPEG_1X1_RED =
|
|
15
|
+
'data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0aHBwgJC4nICIsIxwcKDcpLDAxNDQ0Hyc5PTgyPC4zNDL/2wBDAQkJCQwLDBgNDRgyIRwhMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjL/wAARCAABAAEDASIAAhEBAxEB/8QAFQABAQAAAAAAAAAAAAAAAAAAAAv/xAAUEAEAAAAAAAAAAAAAAAAAAAAA/8VAFQEBAQAAAAAAAAAAAAAAAAAAAAX/xAAUEQEAAAAAAAAAAAAAAAAAAAAA/9oADAMBAAIRAxEAPwCwAA8A/9k=';
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Base64-encoded 1x1 blue GIF
|
|
19
|
+
*/
|
|
20
|
+
export const GIF_1X1_BLUE =
|
|
21
|
+
'data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==';
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* SVG data URL
|
|
25
|
+
*/
|
|
26
|
+
export const SVG_CIRCLE =
|
|
27
|
+
'data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22100%22%20height%3D%22100%22%3E%3Ccircle%20cx%3D%2250%22%20cy%3D%2250%22%20r%3D%2240%22%20fill%3D%22blue%22%2F%3E%3C%2Fsvg%3E';
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Invalid/broken image data URL
|
|
31
|
+
*/
|
|
32
|
+
export const INVALID_IMAGE_URL = 'data:image/png;base64,invalid-base64-data!!!';
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Remote image URL (would require network)
|
|
36
|
+
*/
|
|
37
|
+
export const REMOTE_IMAGE_URL = 'https://example.com/image.png';
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* CORS-restricted image URL
|
|
41
|
+
*/
|
|
42
|
+
export const CORS_IMAGE_URL = 'https://other-domain.com/image.png';
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Collection of all test images
|
|
46
|
+
*/
|
|
47
|
+
export const TEST_IMAGES = {
|
|
48
|
+
png: PNG_1X1_TRANSPARENT,
|
|
49
|
+
jpeg: JPEG_1X1_RED,
|
|
50
|
+
gif: GIF_1X1_BLUE,
|
|
51
|
+
svg: SVG_CIRCLE,
|
|
52
|
+
invalid: INVALID_IMAGE_URL,
|
|
53
|
+
remote: REMOTE_IMAGE_URL,
|
|
54
|
+
cors: CORS_IMAGE_URL,
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Create a test image HTML element
|
|
59
|
+
*/
|
|
60
|
+
export function createTestImageElement(
|
|
61
|
+
src: string = PNG_1X1_TRANSPARENT,
|
|
62
|
+
alt: string = 'test'
|
|
63
|
+
): HTMLImageElement {
|
|
64
|
+
const img = document.createElement('img');
|
|
65
|
+
img.src = src;
|
|
66
|
+
img.alt = alt;
|
|
67
|
+
img.style.width = '50px';
|
|
68
|
+
img.style.height = '50px';
|
|
69
|
+
return img;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Create multiple test images
|
|
74
|
+
*/
|
|
75
|
+
export function createTestImageElements(count: number = 3): HTMLImageElement[] {
|
|
76
|
+
const images: HTMLImageElement[] = [];
|
|
77
|
+
const formats = ['png', 'jpeg', 'gif'] as const;
|
|
78
|
+
|
|
79
|
+
for (let i = 0; i < count; i++) {
|
|
80
|
+
const format = formats[i % formats.length];
|
|
81
|
+
const src = TEST_IMAGES[format];
|
|
82
|
+
images.push(createTestImageElement(src, `test-${i}`));
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
return images;
|
|
86
|
+
}
|