cbrowser 6.5.0 → 7.0.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.
package/dist/cli.js CHANGED
@@ -14,8 +14,8 @@ const daemon_js_1 = require("./daemon.js");
14
14
  function showHelp() {
15
15
  console.log(`
16
16
  ╔══════════════════════════════════════════════════════════════════════════════╗
17
- ║ CBrowser CLI v6.5.0 ║
18
- ║ AI-powered browser automation with test coverage mapping
17
+ ║ CBrowser CLI v7.0.0 ║
18
+ ║ AI-powered browser automation with AI visual regression testing
19
19
  ╚══════════════════════════════════════════════════════════════════════════════╝
20
20
 
21
21
  NAVIGATION
@@ -202,6 +202,36 @@ VISUAL REGRESSION (v2.5.0)
202
202
  visual list List all saved baselines
203
203
  visual delete <name> Delete a baseline
204
204
 
205
+ AI VISUAL REGRESSION (v7.0.0)
206
+ ai-visual capture <url> Capture AI-analyzed visual baseline
207
+ --name <name> Baseline name (required)
208
+ --selector <sel> Capture specific element instead of viewport
209
+ --device <device> Device emulation (iphone-15, pixel-7, etc.)
210
+ --width <n> Viewport width (default: 1920)
211
+ --height <n> Viewport height (default: 1080)
212
+ --wait <ms|selector> Wait before capture (ms or CSS selector)
213
+ Examples:
214
+ cbrowser ai-visual capture "https://example.com" --name homepage
215
+ cbrowser ai-visual capture "https://example.com/dashboard" --name dashboard --device iphone-15
216
+
217
+ ai-visual test <url> <baseline> Test current page against baseline using AI
218
+ --threshold <n> Similarity threshold 0-1 (default: 0.9)
219
+ --sensitivity <level> Detection sensitivity: low, medium, high (default: medium)
220
+ --html Generate HTML report
221
+ --output <file> Save JSON report to file
222
+ Examples:
223
+ cbrowser ai-visual test "https://staging.example.com" homepage
224
+ cbrowser ai-visual test "https://staging.example.com" homepage --sensitivity high
225
+
226
+ ai-visual suite <file.json> Run visual regression suite
227
+ --threshold <n> Global similarity threshold (default: 0.9)
228
+ --html Generate HTML report
229
+ --output <file> Save JSON report to file
230
+
231
+ ai-visual list List all AI visual baselines
232
+ ai-visual show <name> Show baseline details
233
+ ai-visual delete <name> Delete a baseline
234
+
205
235
  ACCESSIBILITY (v2.5.0)
206
236
  a11y audit Run WCAG accessibility audit
207
237
  --url <url> Navigate to URL first
@@ -1884,6 +1914,208 @@ async function main() {
1884
1914
  break;
1885
1915
  }
1886
1916
  // =========================================================================
1917
+ // AI Visual Regression (v7.0.0)
1918
+ // =========================================================================
1919
+ case "ai-visual": {
1920
+ const subcommand = args[0];
1921
+ switch (subcommand) {
1922
+ case "capture": {
1923
+ const url = args[1];
1924
+ if (!url || !options.name) {
1925
+ console.error("Usage: cbrowser ai-visual capture <url> --name <name> [options]");
1926
+ console.error(" --selector <sel> Capture specific element");
1927
+ console.error(" --device <device> Device emulation");
1928
+ console.error(" --width <n> Viewport width");
1929
+ console.error(" --height <n> Viewport height");
1930
+ console.error(" --wait <ms|sel> Wait before capture");
1931
+ process.exit(1);
1932
+ }
1933
+ console.log(`📸 Capturing visual baseline: ${options.name}`);
1934
+ console.log(` URL: ${url}`);
1935
+ const baseline = await (0, browser_js_1.captureVisualBaseline)(url, options.name, {
1936
+ selector: options.selector,
1937
+ device: options.device,
1938
+ viewport: options.width || options.height ? {
1939
+ width: parseInt(options.width) || 1920,
1940
+ height: parseInt(options.height) || 1080,
1941
+ } : undefined,
1942
+ waitFor: options.wait ? (/^\d+$/.test(options.wait)
1943
+ ? parseInt(options.wait)
1944
+ : options.wait) : undefined,
1945
+ });
1946
+ console.log(`\n✅ Baseline captured successfully!`);
1947
+ console.log(` ID: ${baseline.id}`);
1948
+ console.log(` Viewport: ${baseline.viewport.width}x${baseline.viewport.height}`);
1949
+ console.log(` Screenshot: ${baseline.screenshotPath}`);
1950
+ break;
1951
+ }
1952
+ case "test": {
1953
+ const url = args[1];
1954
+ const baselineName = args[2];
1955
+ if (!url || !baselineName) {
1956
+ console.error("Usage: cbrowser ai-visual test <url> <baseline-name> [options]");
1957
+ console.error(" --threshold <n> Similarity threshold 0-1 (default: 0.9)");
1958
+ console.error(" --sensitivity <l> low, medium, high (default: medium)");
1959
+ console.error(" --html Generate HTML report");
1960
+ console.error(" --output <file> Save JSON report");
1961
+ process.exit(1);
1962
+ }
1963
+ console.log(`\n🔍 Running AI visual regression test...`);
1964
+ console.log(` URL: ${url}`);
1965
+ console.log(` Baseline: ${baselineName}\n`);
1966
+ const result = await (0, browser_js_1.runVisualRegression)(url, baselineName, {
1967
+ threshold: options.threshold ? parseFloat(options.threshold) : 0.9,
1968
+ sensitivity: options.sensitivity || "medium",
1969
+ generateDiff: true,
1970
+ });
1971
+ // Print report
1972
+ console.log((0, browser_js_1.formatVisualRegressionReport)(result));
1973
+ // Save JSON output if requested
1974
+ if (options.output && !options.html) {
1975
+ const fs = await import("fs");
1976
+ fs.writeFileSync(options.output, JSON.stringify(result, null, 2));
1977
+ console.log(`\n📄 JSON report saved to: ${options.output}`);
1978
+ }
1979
+ // Generate HTML report if requested
1980
+ if (options.html) {
1981
+ const fs = await import("fs");
1982
+ const suiteResult = {
1983
+ suite: {
1984
+ name: baselineName,
1985
+ pages: [{ name: baselineName, url, baselineName }],
1986
+ },
1987
+ results: [result],
1988
+ summary: {
1989
+ total: 1,
1990
+ passed: result.passed ? 1 : 0,
1991
+ failed: result.passed ? 0 : 1,
1992
+ warnings: result.analysis.overallStatus === "warning" ? 1 : 0,
1993
+ },
1994
+ duration: result.duration,
1995
+ timestamp: new Date().toISOString(),
1996
+ };
1997
+ const htmlReport = (0, browser_js_1.generateVisualRegressionHtmlReport)(suiteResult);
1998
+ const outputPath = options.output || `visual-regression-${baselineName}-${Date.now()}.html`;
1999
+ fs.writeFileSync(outputPath, htmlReport);
2000
+ console.log(`\n📄 HTML report saved to: ${outputPath}`);
2001
+ }
2002
+ if (!result.passed) {
2003
+ process.exit(1);
2004
+ }
2005
+ break;
2006
+ }
2007
+ case "suite": {
2008
+ const suiteFile = args[1];
2009
+ if (!suiteFile) {
2010
+ console.error("Usage: cbrowser ai-visual suite <file.json> [options]");
2011
+ console.error(" --threshold <n> Global similarity threshold");
2012
+ console.error(" --html Generate HTML report");
2013
+ console.error(" --output <file> Save report to file");
2014
+ process.exit(1);
2015
+ }
2016
+ const fs = await import("fs");
2017
+ if (!fs.existsSync(suiteFile)) {
2018
+ console.error(`Suite file not found: ${suiteFile}`);
2019
+ process.exit(1);
2020
+ }
2021
+ const suite = JSON.parse(fs.readFileSync(suiteFile, "utf-8"));
2022
+ console.log(`\n🔍 Running visual regression suite: ${suite.name}`);
2023
+ const result = await (0, browser_js_1.runVisualRegressionSuite)(suite, {
2024
+ threshold: options.threshold ? parseFloat(options.threshold) : 0.9,
2025
+ });
2026
+ // Save outputs
2027
+ if (options.output && !options.html) {
2028
+ fs.writeFileSync(options.output, JSON.stringify(result, null, 2));
2029
+ console.log(`📄 JSON report saved to: ${options.output}`);
2030
+ }
2031
+ if (options.html) {
2032
+ const htmlReport = (0, browser_js_1.generateVisualRegressionHtmlReport)(result);
2033
+ const outputPath = options.output || `visual-suite-${Date.now()}.html`;
2034
+ fs.writeFileSync(outputPath, htmlReport);
2035
+ console.log(`📄 HTML report saved to: ${outputPath}`);
2036
+ }
2037
+ if (result.summary.failed > 0) {
2038
+ process.exit(1);
2039
+ }
2040
+ break;
2041
+ }
2042
+ case "list": {
2043
+ const baselines = (0, browser_js_1.listVisualBaselines)();
2044
+ if (baselines.length === 0) {
2045
+ console.log("\nNo AI visual baselines saved.\n");
2046
+ console.log("Capture one with:");
2047
+ console.log(" cbrowser ai-visual capture <url> --name <name>\n");
2048
+ }
2049
+ else {
2050
+ console.log("\n📸 AI Visual Baselines:\n");
2051
+ console.log("┌──────────────────────┬─────────────────────────────────┬────────────────────┬──────────────┐");
2052
+ console.log("│ Name │ URL │ Viewport │ Created │");
2053
+ console.log("├──────────────────────┼─────────────────────────────────┼────────────────────┼──────────────┤");
2054
+ for (const b of baselines) {
2055
+ const name = b.name.substring(0, 20).padEnd(20);
2056
+ const url = b.url.substring(0, 31).padEnd(31);
2057
+ const viewport = `${b.viewport.width}x${b.viewport.height}`.padEnd(18);
2058
+ const created = new Date(b.timestamp).toLocaleDateString().padEnd(12);
2059
+ console.log(`│ ${name} │ ${url} │ ${viewport} │ ${created} │`);
2060
+ }
2061
+ console.log("└──────────────────────┴─────────────────────────────────┴────────────────────┴──────────────┘\n");
2062
+ }
2063
+ break;
2064
+ }
2065
+ case "show": {
2066
+ const name = args[1];
2067
+ if (!name) {
2068
+ console.error("Usage: cbrowser ai-visual show <name>");
2069
+ process.exit(1);
2070
+ }
2071
+ const baseline = (0, browser_js_1.getVisualBaseline)(name);
2072
+ if (!baseline) {
2073
+ console.error(`Baseline not found: ${name}`);
2074
+ process.exit(1);
2075
+ }
2076
+ console.log("\n📸 AI Visual Baseline Details:\n");
2077
+ console.log(` Name: ${baseline.name}`);
2078
+ console.log(` ID: ${baseline.id}`);
2079
+ console.log(` URL: ${baseline.url}`);
2080
+ console.log(` Viewport: ${baseline.viewport.width}x${baseline.viewport.height}`);
2081
+ if (baseline.device) {
2082
+ console.log(` Device: ${baseline.device}`);
2083
+ }
2084
+ if (baseline.selector) {
2085
+ console.log(` Selector: ${baseline.selector}`);
2086
+ }
2087
+ console.log(` Created: ${baseline.timestamp}`);
2088
+ console.log(` Screenshot: ${baseline.screenshotPath}`);
2089
+ console.log("");
2090
+ break;
2091
+ }
2092
+ case "delete": {
2093
+ const name = args[1];
2094
+ if (!name) {
2095
+ console.error("Usage: cbrowser ai-visual delete <name>");
2096
+ process.exit(1);
2097
+ }
2098
+ if ((0, browser_js_1.deleteVisualBaseline)(name)) {
2099
+ console.log(`✅ Baseline deleted: ${name}`);
2100
+ }
2101
+ else {
2102
+ console.error(`Baseline not found: ${name}`);
2103
+ process.exit(1);
2104
+ }
2105
+ break;
2106
+ }
2107
+ default:
2108
+ console.error("Usage: cbrowser ai-visual [capture|test|suite|list|show|delete]");
2109
+ console.error(" cbrowser ai-visual capture <url> --name <name>");
2110
+ console.error(" cbrowser ai-visual test <url> <baseline>");
2111
+ console.error(" cbrowser ai-visual suite <file.json>");
2112
+ console.error(" cbrowser ai-visual list");
2113
+ console.error(" cbrowser ai-visual show <name>");
2114
+ console.error(" cbrowser ai-visual delete <name>");
2115
+ }
2116
+ break;
2117
+ }
2118
+ // =========================================================================
1887
2119
  // Accessibility (Tier 2)
1888
2120
  // =========================================================================
1889
2121
  case "a11y": {