cbrowser 7.2.0 → 7.4.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.
Files changed (84) hide show
  1. package/dist/analysis/bug-hunter.d.ts +32 -0
  2. package/dist/analysis/bug-hunter.d.ts.map +1 -0
  3. package/dist/analysis/bug-hunter.js +106 -0
  4. package/dist/analysis/bug-hunter.js.map +1 -0
  5. package/dist/analysis/chaos-testing.d.ts +41 -0
  6. package/dist/analysis/chaos-testing.d.ts.map +1 -0
  7. package/dist/analysis/chaos-testing.js +87 -0
  8. package/dist/analysis/chaos-testing.js.map +1 -0
  9. package/dist/analysis/index.d.ts +10 -0
  10. package/dist/analysis/index.d.ts.map +1 -0
  11. package/dist/analysis/index.js +26 -0
  12. package/dist/analysis/index.js.map +1 -0
  13. package/dist/analysis/natural-language.d.ts +43 -0
  14. package/dist/analysis/natural-language.d.ts.map +1 -0
  15. package/dist/analysis/natural-language.js +205 -0
  16. package/dist/analysis/natural-language.js.map +1 -0
  17. package/dist/analysis/persona-comparison.d.ts +31 -0
  18. package/dist/analysis/persona-comparison.d.ts.map +1 -0
  19. package/dist/analysis/persona-comparison.js +217 -0
  20. package/dist/analysis/persona-comparison.js.map +1 -0
  21. package/dist/browser.d.ts +1 -395
  22. package/dist/browser.d.ts.map +1 -1
  23. package/dist/browser.js +0 -4388
  24. package/dist/browser.js.map +1 -1
  25. package/dist/cli.js +198 -55
  26. package/dist/cli.js.map +1 -1
  27. package/dist/daemon.d.ts.map +1 -1
  28. package/dist/daemon.js +2 -1
  29. package/dist/daemon.js.map +1 -1
  30. package/dist/index.d.ts +4 -0
  31. package/dist/index.d.ts.map +1 -1
  32. package/dist/index.js +9 -0
  33. package/dist/index.js.map +1 -1
  34. package/dist/performance/index.d.ts +7 -0
  35. package/dist/performance/index.d.ts.map +1 -0
  36. package/dist/performance/index.js +23 -0
  37. package/dist/performance/index.js.map +1 -0
  38. package/dist/performance/metrics.d.ts +49 -0
  39. package/dist/performance/metrics.d.ts.map +1 -0
  40. package/dist/performance/metrics.js +386 -0
  41. package/dist/performance/metrics.js.map +1 -0
  42. package/dist/testing/coverage.d.ts +39 -0
  43. package/dist/testing/coverage.d.ts.map +1 -0
  44. package/dist/testing/coverage.js +713 -0
  45. package/dist/testing/coverage.js.map +1 -0
  46. package/dist/testing/flaky-detection.d.ts +28 -0
  47. package/dist/testing/flaky-detection.d.ts.map +1 -0
  48. package/dist/testing/flaky-detection.js +332 -0
  49. package/dist/testing/flaky-detection.js.map +1 -0
  50. package/dist/testing/index.d.ts +10 -0
  51. package/dist/testing/index.d.ts.map +1 -0
  52. package/dist/testing/index.js +26 -0
  53. package/dist/testing/index.js.map +1 -0
  54. package/dist/testing/nl-test-suite.d.ts +70 -0
  55. package/dist/testing/nl-test-suite.d.ts.map +1 -0
  56. package/dist/testing/nl-test-suite.js +427 -0
  57. package/dist/testing/nl-test-suite.js.map +1 -0
  58. package/dist/testing/test-repair.d.ts +36 -0
  59. package/dist/testing/test-repair.d.ts.map +1 -0
  60. package/dist/testing/test-repair.js +528 -0
  61. package/dist/testing/test-repair.js.map +1 -0
  62. package/dist/types.d.ts +125 -0
  63. package/dist/types.d.ts.map +1 -1
  64. package/dist/visual/ab-comparison.d.ts +23 -0
  65. package/dist/visual/ab-comparison.d.ts.map +1 -0
  66. package/dist/visual/ab-comparison.js +366 -0
  67. package/dist/visual/ab-comparison.js.map +1 -0
  68. package/dist/visual/cross-browser.d.ts +41 -0
  69. package/dist/visual/cross-browser.d.ts.map +1 -0
  70. package/dist/visual/cross-browser.js +442 -0
  71. package/dist/visual/cross-browser.js.map +1 -0
  72. package/dist/visual/index.d.ts +10 -0
  73. package/dist/visual/index.d.ts.map +1 -0
  74. package/dist/visual/index.js +26 -0
  75. package/dist/visual/index.js.map +1 -0
  76. package/dist/visual/regression.d.ts +55 -0
  77. package/dist/visual/regression.d.ts.map +1 -0
  78. package/dist/visual/regression.js +616 -0
  79. package/dist/visual/regression.js.map +1 -0
  80. package/dist/visual/responsive.d.ts +27 -0
  81. package/dist/visual/responsive.d.ts.map +1 -0
  82. package/dist/visual/responsive.js +450 -0
  83. package/dist/visual/responsive.js.map +1 -0
  84. package/package.json +32 -3
@@ -0,0 +1,442 @@
1
+ "use strict";
2
+ /**
3
+ * Cross-Browser Visual Testing (v7.1.0)
4
+ *
5
+ * Test how pages render across different browser engines.
6
+ */
7
+ Object.defineProperty(exports, "__esModule", { value: true });
8
+ exports.runCrossBrowserTest = runCrossBrowserTest;
9
+ exports.runCrossBrowserSuite = runCrossBrowserSuite;
10
+ exports.formatCrossBrowserReport = formatCrossBrowserReport;
11
+ exports.generateCrossBrowserHtmlReport = generateCrossBrowserHtmlReport;
12
+ exports.crossBrowserDiff = crossBrowserDiff;
13
+ const fs_1 = require("fs");
14
+ const path_1 = require("path");
15
+ const browser_js_1 = require("../browser.js");
16
+ const regression_js_1 = require("./regression.js");
17
+ /**
18
+ * Get the path for cross-browser screenshots
19
+ */
20
+ function getCrossBrowserScreenshotsPath() {
21
+ const baseDir = process.env.CBROWSER_DATA_DIR || (0, path_1.join)(process.cwd(), ".cbrowser");
22
+ const dir = (0, path_1.join)(baseDir, "cross-browser");
23
+ if (!(0, fs_1.existsSync)(dir)) {
24
+ (0, fs_1.mkdirSync)(dir, { recursive: true });
25
+ }
26
+ return dir;
27
+ }
28
+ /**
29
+ * Capture screenshot with a specific browser
30
+ */
31
+ async function captureWithBrowser(url, browserType, options = {}) {
32
+ const startTime = Date.now();
33
+ const browser = new browser_js_1.CBrowser({
34
+ browser: browserType,
35
+ viewportWidth: options.viewport?.width || 1920,
36
+ viewportHeight: options.viewport?.height || 1080,
37
+ });
38
+ try {
39
+ await browser.launch();
40
+ await browser.navigate(url);
41
+ // Wait if specified
42
+ if (options.waitForSelector) {
43
+ const page = await browser.getPage();
44
+ await page.waitForSelector(options.waitForSelector, { timeout: 10000 }).catch(() => { });
45
+ }
46
+ if (options.waitBeforeCapture) {
47
+ await new Promise(resolve => setTimeout(resolve, options.waitBeforeCapture));
48
+ }
49
+ // Take screenshot
50
+ const screenshotsPath = getCrossBrowserScreenshotsPath();
51
+ const filename = `${browserType}-${Date.now()}.png`;
52
+ const screenshotPath = (0, path_1.join)(screenshotsPath, filename);
53
+ const page = await browser.getPage();
54
+ await page.screenshot({ path: screenshotPath, fullPage: false });
55
+ // Get user agent
56
+ const userAgent = await page.evaluate(() => navigator.userAgent);
57
+ const viewport = page.viewportSize() || { width: 1920, height: 1080 };
58
+ return {
59
+ browser: browserType,
60
+ screenshotPath,
61
+ viewport,
62
+ userAgent,
63
+ timestamp: new Date().toISOString(),
64
+ captureTime: Date.now() - startTime,
65
+ };
66
+ }
67
+ finally {
68
+ await browser.close();
69
+ }
70
+ }
71
+ /**
72
+ * Run cross-browser visual test for a single URL
73
+ */
74
+ async function runCrossBrowserTest(url, options = {}) {
75
+ const startTime = Date.now();
76
+ const browsers = options.browsers || ["chromium", "firefox", "webkit"];
77
+ console.log(`\n🌐 Cross-Browser Visual Test`);
78
+ console.log(` URL: ${url}`);
79
+ console.log(` Browsers: ${browsers.join(", ")}\n`);
80
+ // Capture screenshots from each browser
81
+ const screenshots = [];
82
+ for (const browserType of browsers) {
83
+ console.log(` 📸 Capturing ${browserType}...`);
84
+ try {
85
+ const screenshot = await captureWithBrowser(url, browserType, options);
86
+ screenshots.push(screenshot);
87
+ console.log(` ✅ Captured in ${screenshot.captureTime}ms`);
88
+ }
89
+ catch (error) {
90
+ console.log(` ❌ Failed: ${error instanceof Error ? error.message : "Unknown error"}`);
91
+ }
92
+ }
93
+ if (screenshots.length < 2) {
94
+ return {
95
+ url,
96
+ screenshots,
97
+ comparisons: [],
98
+ overallStatus: "major_differences",
99
+ summary: "Could not capture enough screenshots for comparison",
100
+ problematicBrowsers: [],
101
+ duration: Date.now() - startTime,
102
+ timestamp: new Date().toISOString(),
103
+ };
104
+ }
105
+ // Compare all pairs of browsers
106
+ const comparisons = [];
107
+ let hasMinorDifferences = false;
108
+ let hasMajorDifferences = false;
109
+ const problematicBrowsers = new Set();
110
+ console.log(`\n 🔍 Comparing browsers...`);
111
+ for (let i = 0; i < screenshots.length; i++) {
112
+ for (let j = i + 1; j < screenshots.length; j++) {
113
+ const a = screenshots[i];
114
+ const b = screenshots[j];
115
+ console.log(` ${a.browser} vs ${b.browser}...`);
116
+ // Use the existing AI visual analysis
117
+ const analysis = await (0, regression_js_1.analyzeVisualDifferences)(a.screenshotPath, b.screenshotPath, { sensitivity: options.sensitivity || "medium" });
118
+ comparisons.push({
119
+ browserA: a.browser,
120
+ browserB: b.browser,
121
+ analysis,
122
+ screenshots: {
123
+ a: a.screenshotPath,
124
+ b: b.screenshotPath,
125
+ },
126
+ });
127
+ if (analysis.overallStatus === "fail") {
128
+ hasMajorDifferences = true;
129
+ problematicBrowsers.add(a.browser);
130
+ problematicBrowsers.add(b.browser);
131
+ console.log(` ❌ Major differences (${(analysis.similarityScore * 100).toFixed(1)}%)`);
132
+ }
133
+ else if (analysis.overallStatus === "warning") {
134
+ hasMinorDifferences = true;
135
+ console.log(` ⚠️ Minor differences (${(analysis.similarityScore * 100).toFixed(1)}%)`);
136
+ }
137
+ else {
138
+ console.log(` ✅ Consistent (${(analysis.similarityScore * 100).toFixed(1)}%)`);
139
+ }
140
+ }
141
+ }
142
+ const overallStatus = hasMajorDifferences
143
+ ? "major_differences"
144
+ : hasMinorDifferences
145
+ ? "minor_differences"
146
+ : "consistent";
147
+ const summary = overallStatus === "consistent"
148
+ ? "Page renders consistently across all tested browsers"
149
+ : overallStatus === "minor_differences"
150
+ ? "Minor rendering differences detected between browsers"
151
+ : "Significant rendering differences detected between browsers";
152
+ return {
153
+ url,
154
+ screenshots,
155
+ comparisons,
156
+ overallStatus,
157
+ summary,
158
+ problematicBrowsers: Array.from(problematicBrowsers),
159
+ duration: Date.now() - startTime,
160
+ timestamp: new Date().toISOString(),
161
+ };
162
+ }
163
+ /**
164
+ * Run cross-browser test suite
165
+ */
166
+ async function runCrossBrowserSuite(suite) {
167
+ const startTime = Date.now();
168
+ const results = [];
169
+ let consistent = 0;
170
+ let minorDifferences = 0;
171
+ let majorDifferences = 0;
172
+ console.log(`\n🌐 Cross-Browser Visual Test Suite: ${suite.name}`);
173
+ console.log(` Testing ${suite.urls.length} URL(s)...\n`);
174
+ for (const url of suite.urls) {
175
+ const result = await runCrossBrowserTest(url, suite.options);
176
+ results.push(result);
177
+ switch (result.overallStatus) {
178
+ case "consistent":
179
+ consistent++;
180
+ break;
181
+ case "minor_differences":
182
+ minorDifferences++;
183
+ break;
184
+ case "major_differences":
185
+ majorDifferences++;
186
+ break;
187
+ }
188
+ }
189
+ return {
190
+ suite,
191
+ results,
192
+ summary: {
193
+ total: suite.urls.length,
194
+ consistent,
195
+ minorDifferences,
196
+ majorDifferences,
197
+ },
198
+ duration: Date.now() - startTime,
199
+ timestamp: new Date().toISOString(),
200
+ };
201
+ }
202
+ /**
203
+ * Format cross-browser result as text report
204
+ */
205
+ function formatCrossBrowserReport(result) {
206
+ const lines = [];
207
+ lines.push("╔══════════════════════════════════════════════════════════════════════════════╗");
208
+ lines.push("║ CROSS-BROWSER VISUAL TEST REPORT ║");
209
+ lines.push("╚══════════════════════════════════════════════════════════════════════════════╝");
210
+ lines.push("");
211
+ const statusIcon = {
212
+ consistent: "✅",
213
+ minor_differences: "⚠️",
214
+ major_differences: "❌",
215
+ }[result.overallStatus];
216
+ const statusText = {
217
+ consistent: "CONSISTENT",
218
+ minor_differences: "MINOR DIFFERENCES",
219
+ major_differences: "MAJOR DIFFERENCES",
220
+ }[result.overallStatus];
221
+ lines.push(`${statusIcon} Status: ${statusText}`);
222
+ lines.push(`🔗 URL: ${result.url}`);
223
+ lines.push(`⏱️ Duration: ${(result.duration / 1000).toFixed(2)}s`);
224
+ lines.push("");
225
+ lines.push("───────────────────────────────────────────────────────────────────────────────");
226
+ lines.push("📸 BROWSER SCREENSHOTS");
227
+ lines.push("───────────────────────────────────────────────────────────────────────────────");
228
+ for (const screenshot of result.screenshots) {
229
+ lines.push(` ${screenshot.browser.toUpperCase()}`);
230
+ lines.push(` Viewport: ${screenshot.viewport.width}x${screenshot.viewport.height}`);
231
+ lines.push(` Capture time: ${screenshot.captureTime}ms`);
232
+ lines.push(` Path: ${screenshot.screenshotPath}`);
233
+ lines.push("");
234
+ }
235
+ lines.push("───────────────────────────────────────────────────────────────────────────────");
236
+ lines.push("🔍 BROWSER COMPARISONS");
237
+ lines.push("───────────────────────────────────────────────────────────────────────────────");
238
+ for (const comparison of result.comparisons) {
239
+ const compIcon = {
240
+ pass: "✅",
241
+ warning: "⚠️",
242
+ fail: "❌",
243
+ }[comparison.analysis.overallStatus];
244
+ lines.push(` ${comparison.browserA.toUpperCase()} vs ${comparison.browserB.toUpperCase()}: ${compIcon}`);
245
+ lines.push(` Similarity: ${(comparison.analysis.similarityScore * 100).toFixed(1)}%`);
246
+ lines.push(` ${comparison.analysis.summary}`);
247
+ if (comparison.analysis.changes.length > 0) {
248
+ for (const change of comparison.analysis.changes) {
249
+ lines.push(` - [${change.severity.toUpperCase()}] ${change.description}`);
250
+ }
251
+ }
252
+ lines.push("");
253
+ }
254
+ if (result.problematicBrowsers.length > 0) {
255
+ lines.push("───────────────────────────────────────────────────────────────────────────────");
256
+ lines.push("⚠️ BROWSERS WITH ISSUES");
257
+ lines.push("───────────────────────────────────────────────────────────────────────────────");
258
+ for (const browser of result.problematicBrowsers) {
259
+ lines.push(` • ${browser}`);
260
+ }
261
+ lines.push("");
262
+ }
263
+ lines.push("───────────────────────────────────────────────────────────────────────────────");
264
+ lines.push(`📝 SUMMARY: ${result.summary}`);
265
+ lines.push("───────────────────────────────────────────────────────────────────────────────");
266
+ return lines.join("\n");
267
+ }
268
+ /**
269
+ * Generate HTML report for cross-browser test suite
270
+ */
271
+ function generateCrossBrowserHtmlReport(suiteResult) {
272
+ const { suite, results, summary, duration, timestamp } = suiteResult;
273
+ return `<!DOCTYPE html>
274
+ <html lang="en">
275
+ <head>
276
+ <meta charset="UTF-8">
277
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
278
+ <title>Cross-Browser Visual Report - ${suite.name}</title>
279
+ <style>
280
+ * { box-sizing: border-box; margin: 0; padding: 0; }
281
+ body { font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif; background: #0f172a; color: #e2e8f0; line-height: 1.6; }
282
+ .container { max-width: 1400px; margin: 0 auto; padding: 2rem; }
283
+ h1 { font-size: 2rem; margin-bottom: 0.5rem; }
284
+ h2 { font-size: 1.25rem; margin-bottom: 1rem; color: #94a3b8; }
285
+ .header { text-align: center; margin-bottom: 2rem; }
286
+ .summary { display: grid; grid-template-columns: repeat(4, 1fr); gap: 1rem; margin-bottom: 2rem; }
287
+ .stat { background: #1e293b; padding: 1.5rem; border-radius: 0.5rem; text-align: center; }
288
+ .stat-value { font-size: 2rem; font-weight: bold; }
289
+ .stat-label { color: #94a3b8; font-size: 0.875rem; }
290
+ .consistent { color: #22c55e; }
291
+ .minor { color: #eab308; }
292
+ .major { color: #ef4444; }
293
+ .results { display: flex; flex-direction: column; gap: 2rem; }
294
+ .result-card { background: #1e293b; border-radius: 0.5rem; overflow: hidden; }
295
+ .result-header { padding: 1rem; border-bottom: 1px solid #334155; display: flex; justify-content: space-between; align-items: center; }
296
+ .result-body { padding: 1rem; }
297
+ .screenshots { display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: 1rem; margin-bottom: 1rem; }
298
+ .screenshot-card { background: #0f172a; border-radius: 0.25rem; padding: 1rem; text-align: center; }
299
+ .screenshot-card img { max-width: 100%; border-radius: 0.25rem; margin-top: 0.5rem; }
300
+ .browser-name { font-weight: bold; text-transform: capitalize; }
301
+ .comparisons { margin-top: 1rem; }
302
+ .comparison { padding: 0.75rem; background: #0f172a; border-radius: 0.25rem; margin-bottom: 0.5rem; }
303
+ .comparison-header { display: flex; justify-content: space-between; align-items: center; }
304
+ .badge { padding: 0.25rem 0.75rem; border-radius: 9999px; font-size: 0.75rem; font-weight: 600; }
305
+ .badge-consistent { background: #166534; color: #22c55e; }
306
+ .badge-minor { background: #713f12; color: #eab308; }
307
+ .badge-major { background: #7f1d1d; color: #ef4444; }
308
+ footer { text-align: center; color: #64748b; margin-top: 2rem; padding-top: 2rem; border-top: 1px solid #334155; }
309
+ </style>
310
+ </head>
311
+ <body>
312
+ <div class="container">
313
+ <div class="header">
314
+ <h1>🌐 Cross-Browser Visual Report</h1>
315
+ <h2>${suite.name}</h2>
316
+ <p style="color: #64748b;">Generated: ${new Date(timestamp).toLocaleString()}</p>
317
+ </div>
318
+
319
+ <div class="summary">
320
+ <div class="stat">
321
+ <div class="stat-value">${summary.total}</div>
322
+ <div class="stat-label">URLs Tested</div>
323
+ </div>
324
+ <div class="stat">
325
+ <div class="stat-value consistent">${summary.consistent}</div>
326
+ <div class="stat-label">Consistent</div>
327
+ </div>
328
+ <div class="stat">
329
+ <div class="stat-value minor">${summary.minorDifferences}</div>
330
+ <div class="stat-label">Minor Differences</div>
331
+ </div>
332
+ <div class="stat">
333
+ <div class="stat-value major">${summary.majorDifferences}</div>
334
+ <div class="stat-label">Major Differences</div>
335
+ </div>
336
+ </div>
337
+
338
+ <div class="results">
339
+ ${results.map(result => {
340
+ const statusClass = result.overallStatus === "consistent" ? "consistent" : result.overallStatus === "minor_differences" ? "minor" : "major";
341
+ const badgeClass = result.overallStatus === "consistent" ? "badge-consistent" : result.overallStatus === "minor_differences" ? "badge-minor" : "badge-major";
342
+ const statusText = result.overallStatus === "consistent" ? "Consistent" : result.overallStatus === "minor_differences" ? "Minor Differences" : "Major Differences";
343
+ return `
344
+ <div class="result-card">
345
+ <div class="result-header">
346
+ <div>
347
+ <strong>${result.url}</strong>
348
+ <div style="color: #64748b; font-size: 0.875rem;">${result.summary}</div>
349
+ </div>
350
+ <span class="badge ${badgeClass}">${statusText}</span>
351
+ </div>
352
+ <div class="result-body">
353
+ <h3 style="margin-bottom: 1rem; color: #94a3b8;">Screenshots</h3>
354
+ <div class="screenshots">
355
+ ${result.screenshots.map(s => `
356
+ <div class="screenshot-card">
357
+ <div class="browser-name">${s.browser}</div>
358
+ <div style="color: #64748b; font-size: 0.75rem;">${s.viewport.width}x${s.viewport.height} • ${s.captureTime}ms</div>
359
+ </div>
360
+ `).join("")}
361
+ </div>
362
+
363
+ <h3 style="margin: 1rem 0; color: #94a3b8;">Comparisons</h3>
364
+ <div class="comparisons">
365
+ ${result.comparisons.map(c => {
366
+ const cBadgeClass = c.analysis.overallStatus === "pass" ? "badge-consistent" : c.analysis.overallStatus === "warning" ? "badge-minor" : "badge-major";
367
+ return `
368
+ <div class="comparison">
369
+ <div class="comparison-header">
370
+ <span>${c.browserA} vs ${c.browserB}</span>
371
+ <span class="badge ${cBadgeClass}">${(c.analysis.similarityScore * 100).toFixed(1)}%</span>
372
+ </div>
373
+ <p style="color: #94a3b8; font-size: 0.875rem; margin-top: 0.5rem;">${c.analysis.summary}</p>
374
+ </div>
375
+ `;
376
+ }).join("")}
377
+ </div>
378
+ </div>
379
+ </div>
380
+ `;
381
+ }).join("")}
382
+ </div>
383
+
384
+ <footer>
385
+ Generated by CBrowser v7.2.0 | Test completed in ${(duration / 1000).toFixed(1)}s
386
+ </footer>
387
+ </div>
388
+ </body>
389
+ </html>`;
390
+ }
391
+ /**
392
+ * Compare page behavior across multiple browsers.
393
+ */
394
+ async function crossBrowserDiff(url, browsers = ["chromium", "firefox", "webkit"]) {
395
+ const { chromium, firefox, webkit } = await import("playwright");
396
+ const screenshots = {};
397
+ const metrics = {};
398
+ const differences = [];
399
+ const contents = {};
400
+ const browserLaunchers = { chromium, firefox, webkit };
401
+ for (const browserName of browsers) {
402
+ const launcher = browserLaunchers[browserName];
403
+ const browser = await launcher.launch({ headless: true });
404
+ const page = await browser.newPage();
405
+ const startTime = Date.now();
406
+ await page.goto(url, { waitUntil: "domcontentloaded" });
407
+ const loadTime = Date.now() - startTime;
408
+ // Capture metrics
409
+ const resourceCount = await page.evaluate(() => performance.getEntriesByType("resource").length);
410
+ metrics[browserName] = { loadTime, resourceCount };
411
+ // Capture screenshot
412
+ const screenshotPath = `/tmp/cross-browser-${browserName}-${Date.now()}.png`;
413
+ await page.screenshot({ path: screenshotPath, fullPage: true });
414
+ screenshots[browserName] = screenshotPath;
415
+ // Capture content hash
416
+ contents[browserName] = await page.evaluate(() => document.body.innerText.slice(0, 1000));
417
+ await browser.close();
418
+ }
419
+ // Compare timing
420
+ const loadTimes = Object.entries(metrics).map(([b, m]) => ({ browser: b, time: m.loadTime }));
421
+ const avgTime = loadTimes.reduce((sum, t) => sum + t.time, 0) / loadTimes.length;
422
+ const slowBrowsers = loadTimes.filter(t => t.time > avgTime * 1.5);
423
+ if (slowBrowsers.length > 0) {
424
+ differences.push({
425
+ type: "timing",
426
+ description: `Significantly slower in: ${slowBrowsers.map(b => `${b.browser} (${b.time}ms)`).join(", ")}`,
427
+ browsers: slowBrowsers.map(b => b.browser),
428
+ });
429
+ }
430
+ // Compare content
431
+ const contentValues = Object.values(contents);
432
+ const contentMismatch = contentValues.some(c => c !== contentValues[0]);
433
+ if (contentMismatch) {
434
+ differences.push({
435
+ type: "content",
436
+ description: "Page content differs between browsers",
437
+ browsers,
438
+ });
439
+ }
440
+ return { url, browsers, differences, screenshots, metrics };
441
+ }
442
+ //# sourceMappingURL=cross-browser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cross-browser.js","sourceRoot":"","sources":["../../src/visual/cross-browser.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Visual Testing Module
3
+ *
4
+ * AI-powered visual regression, cross-browser, responsive, and A/B comparison testing.
5
+ */
6
+ export * from "./regression.js";
7
+ export * from "./cross-browser.js";
8
+ export * from "./responsive.js";
9
+ export * from "./ab-comparison.js";
10
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/visual/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,cAAc,iBAAiB,CAAC;AAChC,cAAc,oBAAoB,CAAC;AACnC,cAAc,iBAAiB,CAAC;AAChC,cAAc,oBAAoB,CAAC"}
@@ -0,0 +1,26 @@
1
+ "use strict";
2
+ /**
3
+ * Visual Testing Module
4
+ *
5
+ * AI-powered visual regression, cross-browser, responsive, and A/B comparison testing.
6
+ */
7
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
8
+ if (k2 === undefined) k2 = k;
9
+ var desc = Object.getOwnPropertyDescriptor(m, k);
10
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
11
+ desc = { enumerable: true, get: function() { return m[k]; } };
12
+ }
13
+ Object.defineProperty(o, k2, desc);
14
+ }) : (function(o, m, k, k2) {
15
+ if (k2 === undefined) k2 = k;
16
+ o[k2] = m[k];
17
+ }));
18
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
19
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
20
+ };
21
+ Object.defineProperty(exports, "__esModule", { value: true });
22
+ __exportStar(require("./regression.js"), exports);
23
+ __exportStar(require("./cross-browser.js"), exports);
24
+ __exportStar(require("./responsive.js"), exports);
25
+ __exportStar(require("./ab-comparison.js"), exports);
26
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/visual/index.ts"],"names":[],"mappings":";AAAA;;;;GAIG;;;;;;;;;;;;;;;;AAEH,kDAAgC;AAChC,qDAAmC;AACnC,kDAAgC;AAChC,qDAAmC"}
@@ -0,0 +1,55 @@
1
+ /**
2
+ * AI Visual Regression Testing (v7.0.0)
3
+ *
4
+ * Capture baselines and compare screenshots using AI-powered analysis.
5
+ */
6
+ import type { VisualBaseline, AIVisualAnalysis, VisualRegressionResult, VisualRegressionOptions, VisualTestSuite, VisualTestSuiteResult } from "../types.js";
7
+ /**
8
+ * Load all visual baselines from storage
9
+ */
10
+ export declare function loadVisualBaselines(): VisualBaseline[];
11
+ /**
12
+ * Capture a visual baseline screenshot
13
+ */
14
+ export declare function captureVisualBaseline(url: string, name: string, options?: {
15
+ selector?: string;
16
+ device?: string;
17
+ viewport?: {
18
+ width: number;
19
+ height: number;
20
+ };
21
+ waitFor?: string | number;
22
+ }): Promise<VisualBaseline>;
23
+ /**
24
+ * List all visual baselines
25
+ */
26
+ export declare function listVisualBaselines(): VisualBaseline[];
27
+ /**
28
+ * Get a visual baseline by name
29
+ */
30
+ export declare function getVisualBaseline(name: string): VisualBaseline | undefined;
31
+ /**
32
+ * Delete a visual baseline
33
+ */
34
+ export declare function deleteVisualBaseline(name: string): boolean;
35
+ /**
36
+ * Analyze visual differences using AI
37
+ */
38
+ export declare function analyzeVisualDifferences(baselinePath: string, currentPath: string, options?: VisualRegressionOptions): Promise<AIVisualAnalysis>;
39
+ /**
40
+ * Run visual regression test against a baseline
41
+ */
42
+ export declare function runVisualRegression(url: string, baselineName: string, options?: VisualRegressionOptions): Promise<VisualRegressionResult>;
43
+ /**
44
+ * Run visual regression on multiple pages
45
+ */
46
+ export declare function runVisualRegressionSuite(suite: VisualTestSuite, options?: VisualRegressionOptions): Promise<VisualTestSuiteResult>;
47
+ /**
48
+ * Format visual regression result as text report
49
+ */
50
+ export declare function formatVisualRegressionReport(result: VisualRegressionResult): string;
51
+ /**
52
+ * Generate HTML report for visual regression suite
53
+ */
54
+ export declare function generateVisualRegressionHtmlReport(suiteResult: VisualTestSuiteResult): string;
55
+ //# sourceMappingURL=regression.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"regression.d.ts","sourceRoot":"","sources":["../../src/visual/regression.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAMH,OAAO,KAAK,EACV,cAAc,EAEd,gBAAgB,EAChB,sBAAsB,EACtB,uBAAuB,EACvB,eAAe,EACf,qBAAqB,EACtB,MAAM,aAAa,CAAC;AA0BrB;;GAEG;AACH,wBAAgB,mBAAmB,IAAI,cAAc,EAAE,CActD;AAYD;;GAEG;AACH,wBAAsB,qBAAqB,CACzC,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,MAAM,EACZ,OAAO,GAAE;IACP,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;IAC7C,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;CACtB,GACL,OAAO,CAAC,cAAc,CAAC,CA6DzB;AAED;;GAEG;AACH,wBAAgB,mBAAmB,IAAI,cAAc,EAAE,CAEtD;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,cAAc,GAAG,SAAS,CAG1E;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAkB1D;AAED;;GAEG;AACH,wBAAsB,wBAAwB,CAC5C,YAAY,EAAE,MAAM,EACpB,WAAW,EAAE,MAAM,EACnB,OAAO,GAAE,uBAA4B,GACpC,OAAO,CAAC,gBAAgB,CAAC,CAgG3B;AAsFD;;GAEG;AACH,wBAAsB,mBAAmB,CACvC,GAAG,EAAE,MAAM,EACX,YAAY,EAAE,MAAM,EACpB,OAAO,GAAE,uBAA4B,GACpC,OAAO,CAAC,sBAAsB,CAAC,CAyEjC;AAED;;GAEG;AACH,wBAAsB,wBAAwB,CAC5C,KAAK,EAAE,eAAe,EACtB,OAAO,GAAE,uBAA4B,GACpC,OAAO,CAAC,qBAAqB,CAAC,CAsDhC;AAED;;GAEG;AACH,wBAAgB,4BAA4B,CAAC,MAAM,EAAE,sBAAsB,GAAG,MAAM,CAkEnF;AAED;;GAEG;AACH,wBAAgB,kCAAkC,CAAC,WAAW,EAAE,qBAAqB,GAAG,MAAM,CAgH7F"}