browser-cdp 0.2.1 → 0.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.
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # browser-cdp
2
2
 
3
- Browser automation via Chrome DevTools Protocol. Control Chrome, Brave, Comet, or Edge using your real browser - same fingerprint, real cookies, no automation detection.
3
+ Browser automation via Chrome DevTools Protocol. Control Chrome, Brave, or Edge using your real browser - same fingerprint, real cookies, no automation detection.
4
4
 
5
5
  ## Install
6
6
 
@@ -25,6 +25,12 @@ browser-cdp screenshot
25
25
 
26
26
  # Interactive element picker
27
27
  browser-cdp pick '<message>'
28
+
29
+ # Stream browser console output
30
+ browser-cdp console [--duration=SECONDS]
31
+
32
+ # Show page performance metrics
33
+ browser-cdp insights [--json]
28
34
  ```
29
35
 
30
36
  ## Environment Variables
@@ -32,7 +38,7 @@ browser-cdp pick '<message>'
32
38
  | Variable | Description | Default |
33
39
  |----------|-------------|---------|
34
40
  | `DEBUG_PORT` | CDP debugging port | `9222` |
35
- | `BROWSER` | Browser to use (chrome, brave, comet, edge) | `chrome` |
41
+ | `BROWSER` | Browser to use (chrome, brave, edge) | `chrome` |
36
42
  | `BROWSER_PATH` | Custom browser executable path | (auto-detect) |
37
43
 
38
44
  ## Examples
@@ -54,6 +60,16 @@ browser-cdp screenshot
54
60
 
55
61
  # Pick elements interactively
56
62
  browser-cdp pick "Select the login button"
63
+
64
+ # Stream console output for 10 seconds
65
+ browser-cdp console --duration=10
66
+
67
+ # Get page performance insights
68
+ browser-cdp insights
69
+ # Returns: TTFB, First Paint, FCP, DOM loaded, resources, memory
70
+
71
+ # Get insights as JSON
72
+ browser-cdp insights --json
57
73
  ```
58
74
 
59
75
  ## Pre-started Browser
@@ -78,7 +94,6 @@ browser-cdp nav https://example.com
78
94
  |---------|---------|
79
95
  | Chrome | `chrome` (default) |
80
96
  | Brave | `brave` |
81
- | Comet | `comet` |
82
97
  | Edge | `edge` |
83
98
 
84
99
  ## Platform Support
package/cli.js CHANGED
@@ -16,6 +16,8 @@ const commands = {
16
16
  eval: "./eval.js",
17
17
  screenshot: "./screenshot.js",
18
18
  pick: "./pick.js",
19
+ console: "./console.js",
20
+ insights: "./insights.js",
19
21
  };
20
22
 
21
23
  function printUsage() {
@@ -29,17 +31,20 @@ function printUsage() {
29
31
  console.log(" eval '<code>' Evaluate JavaScript in page");
30
32
  console.log(" screenshot Take screenshot of current page");
31
33
  console.log(" pick '<message>' Interactive element picker");
34
+ console.log(" console Stream browser console output");
35
+ console.log(" insights Show page performance metrics");
32
36
  console.log("");
33
37
  console.log("Environment:");
34
38
  console.log(" DEBUG_PORT CDP port (default: 9222)");
35
- console.log(" BROWSER Browser to use (chrome, brave, comet, edge)");
39
+ console.log(" BROWSER Browser to use (chrome, brave, edge)");
36
40
  console.log(" BROWSER_PATH Custom browser executable path");
37
41
  console.log("");
38
42
  console.log("Examples:");
39
43
  console.log(" browser-cdp start brave");
40
44
  console.log(" browser-cdp nav https://google.com");
41
45
  console.log(" browser-cdp eval 'document.title'");
42
- console.log(" browser-cdp screenshot");
46
+ console.log(" browser-cdp console --duration=10");
47
+ console.log(" browser-cdp insights --json");
43
48
  process.exit(0);
44
49
  }
45
50
 
package/console.js ADDED
@@ -0,0 +1,77 @@
1
+ #!/usr/bin/env node
2
+
3
+ import { chromium } from "playwright";
4
+
5
+ const DEFAULT_PORT = process.env.DEBUG_PORT || 9222;
6
+
7
+ const args = process.argv.slice(2);
8
+ const duration = args.find((a) => a.startsWith("--duration="));
9
+ const durationMs = duration ? parseInt(duration.split("=")[1]) * 1000 : null;
10
+ const showHelp = args.includes("--help") || args.includes("-h");
11
+
12
+ if (showHelp) {
13
+ console.log("Usage: console.js [--duration=SECONDS]");
14
+ console.log("\nCapture browser console output in real-time.");
15
+ console.log("\nOptions:");
16
+ console.log(" --duration=N Stop after N seconds (default: run until Ctrl+C)");
17
+ console.log("\nExamples:");
18
+ console.log(" console.js # Stream console logs until Ctrl+C");
19
+ console.log(" console.js --duration=5 # Capture for 5 seconds");
20
+ process.exit(0);
21
+ }
22
+
23
+ const browser = await chromium.connectOverCDP(`http://localhost:${DEFAULT_PORT}`);
24
+ const contexts = browser.contexts();
25
+ const context = contexts[0];
26
+
27
+ if (!context) {
28
+ console.error("No browser context found");
29
+ process.exit(1);
30
+ }
31
+
32
+ const pages = context.pages();
33
+ const page = pages[pages.length - 1];
34
+
35
+ if (!page) {
36
+ console.error("No active tab found");
37
+ process.exit(1);
38
+ }
39
+
40
+ const formatTime = () => new Date().toISOString().split("T")[1].slice(0, 12);
41
+
42
+ const typeColors = {
43
+ log: "\x1b[0m", // default
44
+ info: "\x1b[36m", // cyan
45
+ warn: "\x1b[33m", // yellow
46
+ error: "\x1b[31m", // red
47
+ debug: "\x1b[90m", // gray
48
+ };
49
+ const reset = "\x1b[0m";
50
+
51
+ page.on("console", (msg) => {
52
+ const type = msg.type();
53
+ const color = typeColors[type] || typeColors.log;
54
+ const text = msg.text();
55
+ console.log(`${color}[${formatTime()}] [${type.toUpperCase()}] ${text}${reset}`);
56
+ });
57
+
58
+ page.on("pageerror", (error) => {
59
+ console.log(`\x1b[31m[${formatTime()}] [PAGE ERROR] ${error.message}${reset}`);
60
+ });
61
+
62
+ console.error(`Listening for console output... (Ctrl+C to stop)`);
63
+
64
+ if (durationMs) {
65
+ await new Promise((r) => setTimeout(r, durationMs));
66
+ await browser.close();
67
+ } else {
68
+ // Keep running until interrupted
69
+ process.on("SIGINT", async () => {
70
+ console.error("\nStopping...");
71
+ await browser.close();
72
+ process.exit(0);
73
+ });
74
+
75
+ // Keep the process alive
76
+ await new Promise(() => {});
77
+ }
package/insights.js ADDED
@@ -0,0 +1,133 @@
1
+ #!/usr/bin/env node
2
+
3
+ import { chromium } from "playwright";
4
+
5
+ const DEFAULT_PORT = process.env.DEBUG_PORT || 9222;
6
+
7
+ const args = process.argv.slice(2);
8
+ const showHelp = args.includes("--help") || args.includes("-h");
9
+ const jsonOutput = args.includes("--json");
10
+
11
+ if (showHelp) {
12
+ console.log("Usage: insights.js [--json]");
13
+ console.log("\nCollect page performance insights and Web Vitals.");
14
+ console.log("\nOptions:");
15
+ console.log(" --json Output as JSON");
16
+ console.log("\nMetrics collected:");
17
+ console.log(" - Page load timing (DOM, load, first paint)");
18
+ console.log(" - Web Vitals (LCP, FID, CLS, FCP, TTFB)");
19
+ console.log(" - Resource counts and sizes");
20
+ console.log(" - JavaScript heap usage");
21
+ process.exit(0);
22
+ }
23
+
24
+ const browser = await chromium.connectOverCDP(`http://localhost:${DEFAULT_PORT}`);
25
+ const contexts = browser.contexts();
26
+ const context = contexts[0];
27
+
28
+ if (!context) {
29
+ console.error("No browser context found");
30
+ process.exit(1);
31
+ }
32
+
33
+ const pages = context.pages();
34
+ const page = pages[pages.length - 1];
35
+
36
+ if (!page) {
37
+ console.error("No active tab found");
38
+ process.exit(1);
39
+ }
40
+
41
+ // Collect performance metrics
42
+ const metrics = await page.evaluate(() => {
43
+ const perf = performance;
44
+ const timing = perf.timing || {};
45
+ const navigation = perf.getEntriesByType("navigation")[0] || {};
46
+ const paint = perf.getEntriesByType("paint") || [];
47
+ const resources = perf.getEntriesByType("resource") || [];
48
+
49
+ // Calculate timing metrics
50
+ const navStart = timing.navigationStart || navigation.startTime || 0;
51
+ const domContentLoaded = (timing.domContentLoadedEventEnd || navigation.domContentLoadedEventEnd || 0) - navStart;
52
+ const loadComplete = (timing.loadEventEnd || navigation.loadEventEnd || 0) - navStart;
53
+ const firstPaint = paint.find((p) => p.name === "first-paint")?.startTime || 0;
54
+ const firstContentfulPaint = paint.find((p) => p.name === "first-contentful-paint")?.startTime || 0;
55
+ const ttfb = (timing.responseStart || navigation.responseStart || 0) - navStart;
56
+
57
+ // Resource breakdown
58
+ const resourceStats = resources.reduce(
59
+ (acc, r) => {
60
+ acc.count++;
61
+ acc.totalSize += r.transferSize || 0;
62
+ const type = r.initiatorType || "other";
63
+ acc.byType[type] = (acc.byType[type] || 0) + 1;
64
+ return acc;
65
+ },
66
+ { count: 0, totalSize: 0, byType: {} }
67
+ );
68
+
69
+ // Try to get LCP (requires PerformanceObserver to have recorded it)
70
+ let lcp = null;
71
+ try {
72
+ const lcpEntries = perf.getEntriesByType("largest-contentful-paint");
73
+ if (lcpEntries.length > 0) {
74
+ lcp = lcpEntries[lcpEntries.length - 1].startTime;
75
+ }
76
+ } catch (e) {}
77
+
78
+ // Memory info (Chrome only)
79
+ let memory = null;
80
+ if (perf.memory) {
81
+ memory = {
82
+ usedJSHeapSize: Math.round(perf.memory.usedJSHeapSize / 1024 / 1024),
83
+ totalJSHeapSize: Math.round(perf.memory.totalJSHeapSize / 1024 / 1024),
84
+ };
85
+ }
86
+
87
+ return {
88
+ url: location.href,
89
+ timing: {
90
+ ttfb: Math.round(ttfb),
91
+ firstPaint: Math.round(firstPaint),
92
+ firstContentfulPaint: Math.round(firstContentfulPaint),
93
+ domContentLoaded: Math.round(domContentLoaded),
94
+ loadComplete: Math.round(loadComplete),
95
+ lcp: lcp ? Math.round(lcp) : null,
96
+ },
97
+ resources: {
98
+ count: resourceStats.count,
99
+ totalSizeKB: Math.round(resourceStats.totalSize / 1024),
100
+ byType: resourceStats.byType,
101
+ },
102
+ memory,
103
+ };
104
+ });
105
+
106
+ if (jsonOutput) {
107
+ console.log(JSON.stringify(metrics, null, 2));
108
+ } else {
109
+ console.log(`Page Insights: ${metrics.url}\n`);
110
+
111
+ console.log("Timing:");
112
+ console.log(` TTFB: ${metrics.timing.ttfb}ms`);
113
+ console.log(` First Paint: ${metrics.timing.firstPaint}ms`);
114
+ console.log(` First Contentful Paint: ${metrics.timing.firstContentfulPaint}ms`);
115
+ console.log(` DOM Content Loaded: ${metrics.timing.domContentLoaded}ms`);
116
+ console.log(` Load Complete: ${metrics.timing.loadComplete}ms`);
117
+ if (metrics.timing.lcp) {
118
+ console.log(` Largest Contentful Paint: ${metrics.timing.lcp}ms`);
119
+ }
120
+
121
+ console.log("\nResources:");
122
+ console.log(` Total: ${metrics.resources.count} requests`);
123
+ console.log(` Size: ${metrics.resources.totalSizeKB} KB`);
124
+ console.log(` Breakdown: ${Object.entries(metrics.resources.byType).map(([k, v]) => `${k}(${v})`).join(", ")}`);
125
+
126
+ if (metrics.memory) {
127
+ console.log("\nMemory:");
128
+ console.log(` JS Heap Used: ${metrics.memory.usedJSHeapSize} MB`);
129
+ console.log(` JS Heap Total: ${metrics.memory.totalJSHeapSize} MB`);
130
+ }
131
+ }
132
+
133
+ await browser.close();
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "browser-cdp",
3
- "version": "0.2.1",
4
- "description": "Browser automation via Chrome DevTools Protocol - control Chrome, Brave, Comet, Edge with real browser profiles",
3
+ "version": "0.3.0",
4
+ "description": "Browser automation via Chrome DevTools Protocol - control Chrome, Brave, Edge with real browser profiles",
5
5
  "type": "module",
6
6
  "bin": {
7
7
  "browser-cdp": "./cli.js"
@@ -16,6 +16,8 @@
16
16
  "eval.js",
17
17
  "screenshot.js",
18
18
  "pick.js",
19
+ "console.js",
20
+ "insights.js",
19
21
  "README.md",
20
22
  "LICENSE"
21
23
  ],
package/start.js CHANGED
@@ -30,12 +30,6 @@ const BROWSERS = {
30
30
  ? `${process.env.HOME}/Library/Application Support/BraveSoftware/Brave-Browser/`
31
31
  : `${process.env.HOME}/.config/BraveSoftware/Brave-Browser/`,
32
32
  },
33
- comet: {
34
- name: "Comet",
35
- path: isMac ? "/Applications/Comet.app/Contents/MacOS/Comet" : "/usr/bin/comet",
36
- process: "Comet",
37
- profileSource: null,
38
- },
39
33
  edge: {
40
34
  name: "Microsoft Edge",
41
35
  path: isMac
@@ -55,19 +49,18 @@ function printUsage() {
55
49
  console.log("\nBrowsers:");
56
50
  console.log(" chrome - Google Chrome (default)");
57
51
  console.log(" brave - Brave Browser");
58
- console.log(" comet - Comet Browser");
59
52
  console.log(" edge - Microsoft Edge");
60
53
  console.log("\nOptions:");
61
54
  console.log(" --isolated Use isolated profile (default: real profile)");
62
55
  console.log(" --port=N Use custom debugging port (default: 9222)");
63
56
  console.log("\nEnvironment variables:");
64
- console.log(" BROWSER Default browser (chrome, brave, comet, edge)");
57
+ console.log(" BROWSER Default browser (chrome, brave, edge)");
65
58
  console.log(" BROWSER_PATH Custom browser executable path");
66
59
  console.log(" DEBUG_PORT Custom debugging port");
67
60
  console.log("\nExamples:");
68
61
  console.log(" start.js # Start Chrome with real profile");
69
62
  console.log(" start.js brave # Start Brave with real profile");
70
- console.log(" start.js comet --isolated # Start Comet with isolated profile");
63
+ console.log(" start.js edge --isolated # Start Edge with isolated profile");
71
64
  console.log(" start.js --port=9333 # Start Chrome on port 9333");
72
65
  process.exit(1);
73
66
  }