@brightdata/cli 0.1.4 → 0.1.6

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 (88) hide show
  1. package/README.md +354 -0
  2. package/dist/__tests__/browser/connection.test.d.ts +2 -0
  3. package/dist/__tests__/browser/connection.test.d.ts.map +1 -0
  4. package/dist/__tests__/browser/connection.test.js +168 -0
  5. package/dist/__tests__/browser/connection.test.js.map +1 -0
  6. package/dist/__tests__/browser/daemon.test.d.ts +2 -0
  7. package/dist/__tests__/browser/daemon.test.d.ts.map +1 -0
  8. package/dist/__tests__/browser/daemon.test.js +586 -0
  9. package/dist/__tests__/browser/daemon.test.js.map +1 -0
  10. package/dist/__tests__/browser/entrypoint.test.d.ts +2 -0
  11. package/dist/__tests__/browser/entrypoint.test.d.ts.map +1 -0
  12. package/dist/__tests__/browser/entrypoint.test.js +53 -0
  13. package/dist/__tests__/browser/entrypoint.test.js.map +1 -0
  14. package/dist/__tests__/browser/ipc.test.d.ts +2 -0
  15. package/dist/__tests__/browser/ipc.test.d.ts.map +1 -0
  16. package/dist/__tests__/browser/ipc.test.js +199 -0
  17. package/dist/__tests__/browser/ipc.test.js.map +1 -0
  18. package/dist/__tests__/browser/lifecycle.test.d.ts +2 -0
  19. package/dist/__tests__/browser/lifecycle.test.d.ts.map +1 -0
  20. package/dist/__tests__/browser/lifecycle.test.js +176 -0
  21. package/dist/__tests__/browser/lifecycle.test.js.map +1 -0
  22. package/dist/__tests__/browser/snapshot.test.d.ts +2 -0
  23. package/dist/__tests__/browser/snapshot.test.d.ts.map +1 -0
  24. package/dist/__tests__/browser/snapshot.test.js +202 -0
  25. package/dist/__tests__/browser/snapshot.test.js.map +1 -0
  26. package/dist/__tests__/commands/browser.test.d.ts +2 -0
  27. package/dist/__tests__/commands/browser.test.d.ts.map +1 -0
  28. package/dist/__tests__/commands/browser.test.js +431 -0
  29. package/dist/__tests__/commands/browser.test.js.map +1 -0
  30. package/dist/__tests__/utils/browser-credentials.test.d.ts +2 -0
  31. package/dist/__tests__/utils/browser-credentials.test.d.ts.map +1 -0
  32. package/dist/__tests__/utils/browser-credentials.test.js +81 -0
  33. package/dist/__tests__/utils/browser-credentials.test.js.map +1 -0
  34. package/dist/browser/connection.d.ts +24 -0
  35. package/dist/browser/connection.d.ts.map +1 -0
  36. package/dist/browser/connection.js +55 -0
  37. package/dist/browser/connection.js.map +1 -0
  38. package/dist/browser/daemon.d.ts +130 -0
  39. package/dist/browser/daemon.d.ts.map +1 -0
  40. package/dist/browser/daemon.js +645 -0
  41. package/dist/browser/daemon.js.map +1 -0
  42. package/dist/browser/entrypoint.d.ts +20 -0
  43. package/dist/browser/entrypoint.d.ts.map +1 -0
  44. package/dist/browser/entrypoint.js +46 -0
  45. package/dist/browser/entrypoint.js.map +1 -0
  46. package/dist/browser/interaction.d.ts +32 -0
  47. package/dist/browser/interaction.d.ts.map +1 -0
  48. package/dist/browser/interaction.js +215 -0
  49. package/dist/browser/interaction.js.map +1 -0
  50. package/dist/browser/ipc.d.ts +52 -0
  51. package/dist/browser/ipc.d.ts.map +1 -0
  52. package/dist/browser/ipc.js +254 -0
  53. package/dist/browser/ipc.js.map +1 -0
  54. package/dist/browser/lifecycle.d.ts +31 -0
  55. package/dist/browser/lifecycle.d.ts.map +1 -0
  56. package/dist/browser/lifecycle.js +202 -0
  57. package/dist/browser/lifecycle.js.map +1 -0
  58. package/dist/browser/screenshot.d.ts +19 -0
  59. package/dist/browser/screenshot.d.ts.map +1 -0
  60. package/dist/browser/screenshot.js +44 -0
  61. package/dist/browser/screenshot.js.map +1 -0
  62. package/dist/browser/snapshot.d.ts +48 -0
  63. package/dist/browser/snapshot.d.ts.map +1 -0
  64. package/dist/browser/snapshot.js +490 -0
  65. package/dist/browser/snapshot.js.map +1 -0
  66. package/dist/commands/browser.d.ts +62 -0
  67. package/dist/commands/browser.d.ts.map +1 -0
  68. package/dist/commands/browser.js +615 -0
  69. package/dist/commands/browser.js.map +1 -0
  70. package/dist/commands/scrape.d.ts.map +1 -1
  71. package/dist/commands/scrape.js +11 -1
  72. package/dist/commands/scrape.js.map +1 -1
  73. package/dist/commands/search.d.ts.map +1 -1
  74. package/dist/commands/search.js +53 -1
  75. package/dist/commands/search.js.map +1 -1
  76. package/dist/index.js +39 -25
  77. package/dist/index.js.map +1 -1
  78. package/dist/types/search.d.ts +30 -2
  79. package/dist/types/search.d.ts.map +1 -1
  80. package/dist/utils/browser-credentials.d.ts +5 -0
  81. package/dist/utils/browser-credentials.d.ts.map +1 -0
  82. package/dist/utils/browser-credentials.js +53 -0
  83. package/dist/utils/browser-credentials.js.map +1 -0
  84. package/dist/utils/client.d.ts +1 -0
  85. package/dist/utils/client.d.ts.map +1 -1
  86. package/dist/utils/client.js +2 -0
  87. package/dist/utils/client.js.map +1 -1
  88. package/package.json +2 -1
package/README.md CHANGED
@@ -25,6 +25,7 @@
25
25
  | `brightdata scrape` | Scrape any URL — bypasses CAPTCHAs, JS rendering, anti-bot protections |
26
26
  | `brightdata search` | Google / Bing / Yandex search with structured JSON output |
27
27
  | `brightdata pipelines` | Extract structured data from 40+ platforms (Amazon, LinkedIn, TikTok…) |
28
+ | `brightdata browser` | Control a real browser via Bright Data's Scraping Browser — navigate, snapshot, click, type, and more |
28
29
  | `brightdata zones` | List and inspect your Bright Data proxy zones |
29
30
  | `brightdata budget` | View account balance and per-zone cost & bandwidth |
30
31
  | `brightdata skill` | Install Bright Data AI agent skills into your coding agent |
@@ -44,6 +45,7 @@
44
45
  - [scrape](#scrape)
45
46
  - [search](#search)
46
47
  - [pipelines](#pipelines)
48
+ - [browser](#browser)
47
49
  - [status](#status)
48
50
  - [zones](#zones)
49
51
  - [budget](#budget)
@@ -292,6 +294,333 @@ See [Dataset Types Reference](#dataset-types-reference) for the full list.
292
294
 
293
295
  ---
294
296
 
297
+ ### `browser`
298
+
299
+ Control a real browser session powered by [Bright Data's Scraping Browser](https://brightdata.com/products/scraping-browser). A lightweight local daemon holds the browser connection open between commands, giving you persistent state without reconnecting on every call.
300
+
301
+ ```bash
302
+ brightdata browser open <url> # Start a session and navigate
303
+ brightdata browser snapshot # Get an accessibility tree of the page
304
+ brightdata browser screenshot [path] # Take a PNG screenshot
305
+ brightdata browser click <ref> # Click an element
306
+ brightdata browser type <ref> <text> # Type into an element
307
+ brightdata browser fill <ref> <value> # Fill a form field
308
+ brightdata browser select <ref> <value> # Select a dropdown option
309
+ brightdata browser check <ref> # Check a checkbox / radio
310
+ brightdata browser uncheck <ref> # Uncheck a checkbox
311
+ brightdata browser hover <ref> # Hover over an element
312
+ brightdata browser scroll # Scroll the page
313
+ brightdata browser get text [selector] # Get text content
314
+ brightdata browser get html [selector] # Get HTML content
315
+ brightdata browser back # Navigate back
316
+ brightdata browser forward # Navigate forward
317
+ brightdata browser reload # Reload the page
318
+ brightdata browser network # Show captured network requests
319
+ brightdata browser cookies # Show cookies
320
+ brightdata browser status # Show session state
321
+ brightdata browser sessions # List all active sessions
322
+ brightdata browser close # Close session and stop daemon
323
+ ```
324
+
325
+ **Global flags** (work with every subcommand)
326
+
327
+ | Flag | Description |
328
+ |---|---|
329
+ | `--session <name>` | Session name — run multiple isolated sessions in parallel (default: `default`) |
330
+ | `--country <code>` | Geo-target by ISO country code (e.g. `us`, `de`). On `open`, changing country reconnects the browser |
331
+ | `--zone <name>` | Scraping Browser zone (default: `cli_browser`) |
332
+ | `--timeout <ms>` | IPC command timeout in milliseconds (default: `30000`) |
333
+ | `--idle-timeout <ms>` | Daemon auto-shutdown after idle (default: `600000` = 10 min) |
334
+ | `--json` / `--pretty` | JSON output |
335
+ | `-o, --output <path>` | Write output to file |
336
+ | `-k, --api-key <key>` | Override API key |
337
+
338
+ ---
339
+
340
+ #### `browser open <url>`
341
+
342
+ Navigate to a URL. Starts the daemon and browser session automatically if not already running.
343
+
344
+ ```bash
345
+ brightdata browser open https://example.com
346
+ brightdata browser open https://amazon.com --country us --session shop
347
+ ```
348
+
349
+ | Flag | Description |
350
+ |---|---|
351
+ | `--country <code>` | Geo-targeting. Reconnects the browser if the country changes on an existing session |
352
+ | `--zone <name>` | Browser zone name |
353
+ | `--idle-timeout <ms>` | Daemon idle timeout for this session |
354
+
355
+ ---
356
+
357
+ #### `browser snapshot`
358
+
359
+ Capture the page as a text accessibility tree. This is the primary way AI agents read page content — far more token-efficient than raw HTML.
360
+
361
+ ```bash
362
+ brightdata browser snapshot
363
+ brightdata browser snapshot --compact # Interactive elements + ancestors only
364
+ brightdata browser snapshot --interactive # Interactive elements as a flat list
365
+ brightdata browser snapshot --depth 3 # Limit tree depth
366
+ brightdata browser snapshot --selector "main" # Scope to a CSS subtree
367
+ brightdata browser snapshot --wrap # Wrap output in AI-safe content boundaries
368
+ ```
369
+
370
+ **Output format:**
371
+ ```
372
+ Page: Example Domain
373
+ URL: https://example.com
374
+
375
+ - heading "Example Domain" [level=1]
376
+ - paragraph "This domain is for use in illustrative examples."
377
+ - link "More information..." [ref=e1]
378
+ ```
379
+
380
+ Each interactive element gets a `ref` (e.g. `e1`, `e2`) that you pass to `click`, `type`, `fill`, etc.
381
+
382
+ | Flag | Description |
383
+ |---|---|
384
+ | `--compact` | Only interactive elements and their ancestors (70–90% fewer tokens) |
385
+ | `--interactive` | Only interactive elements, as a flat list |
386
+ | `--depth <n>` | Limit tree depth to a non-negative integer |
387
+ | `--selector <sel>` | Scope snapshot to elements matching a CSS selector |
388
+ | `--wrap` | Wrap output in `--- BRIGHTDATA_BROWSER_CONTENT ... ---` boundaries (useful for AI agent prompt injection safety) |
389
+
390
+ ---
391
+
392
+ #### `browser screenshot [path]`
393
+
394
+ Capture a PNG screenshot of the current viewport.
395
+
396
+ ```bash
397
+ brightdata browser screenshot
398
+ brightdata browser screenshot ./result.png
399
+ brightdata browser screenshot --full-page -o page.png
400
+ brightdata browser screenshot --base64
401
+ ```
402
+
403
+ | Flag | Description |
404
+ |---|---|
405
+ | `[path]` | Where to save the PNG (default: temp directory) |
406
+ | `--full-page` | Capture the full scrollable page, not just the viewport |
407
+ | `--base64` | Output base64-encoded PNG data instead of saving to a file |
408
+
409
+ ---
410
+
411
+ #### `browser click <ref>`
412
+
413
+ Click an element by its snapshot ref.
414
+
415
+ ```bash
416
+ brightdata browser click e3
417
+ brightdata browser click e3 --session shop
418
+ ```
419
+
420
+ ---
421
+
422
+ #### `browser type <ref> <text>`
423
+
424
+ Type text into an element. Clears the field first by default.
425
+
426
+ ```bash
427
+ brightdata browser type e5 "search query"
428
+ brightdata browser type e5 " more text" --append # Append to existing value
429
+ brightdata browser type e5 "search query" --submit # Press Enter after typing
430
+ ```
431
+
432
+ | Flag | Description |
433
+ |---|---|
434
+ | `--append` | Append to existing value using key-by-key simulation |
435
+ | `--submit` | Press Enter after typing |
436
+
437
+ ---
438
+
439
+ #### `browser fill <ref> <value>`
440
+
441
+ Fill a form field directly (no keyboard simulation). Use `type` if you need to trigger `keydown`/`keyup` events.
442
+
443
+ ```bash
444
+ brightdata browser fill e2 "user@example.com"
445
+ ```
446
+
447
+ ---
448
+
449
+ #### `browser select <ref> <value>`
450
+
451
+ Select a dropdown option by its visible label.
452
+
453
+ ```bash
454
+ brightdata browser select e4 "United States"
455
+ ```
456
+
457
+ ---
458
+
459
+ #### `browser check <ref>` / `browser uncheck <ref>`
460
+
461
+ Check or uncheck a checkbox or radio button.
462
+
463
+ ```bash
464
+ brightdata browser check e7
465
+ brightdata browser uncheck e7
466
+ ```
467
+
468
+ ---
469
+
470
+ #### `browser hover <ref>`
471
+
472
+ Hover the mouse over an element (triggers hover states, tooltips, dropdowns).
473
+
474
+ ```bash
475
+ brightdata browser hover e2
476
+ ```
477
+
478
+ ---
479
+
480
+ #### `browser scroll`
481
+
482
+ Scroll the viewport or scroll an element into view.
483
+
484
+ ```bash
485
+ brightdata browser scroll # Scroll down 300px (default)
486
+ brightdata browser scroll --direction up
487
+ brightdata browser scroll --direction down --distance 600
488
+ brightdata browser scroll --ref e10 # Scroll element e10 into view
489
+ ```
490
+
491
+ | Flag | Description |
492
+ |---|---|
493
+ | `--direction <dir>` | `up`, `down`, `left`, `right` (default: `down`) |
494
+ | `--distance <px>` | Pixels to scroll (default: `300`) |
495
+ | `--ref <ref>` | Scroll this element into view instead of the viewport |
496
+
497
+ ---
498
+
499
+ #### `browser get text [selector]`
500
+
501
+ Get the text content of the page or a scoped element.
502
+
503
+ ```bash
504
+ brightdata browser get text # Full page text
505
+ brightdata browser get text "h1" # Text of the first h1
506
+ brightdata browser get text "#price" # Text inside #price
507
+ ```
508
+
509
+ ---
510
+
511
+ #### `browser get html [selector]`
512
+
513
+ Get the HTML of the page or a scoped element.
514
+
515
+ ```bash
516
+ brightdata browser get html # Full page outer HTML
517
+ brightdata browser get html ".product" # innerHTML of .product
518
+ brightdata browser get html --pretty # JSON output with selector field
519
+ ```
520
+
521
+ ---
522
+
523
+ #### `browser network`
524
+
525
+ Show HTTP requests captured since the last navigation.
526
+
527
+ ```bash
528
+ brightdata browser network
529
+ brightdata browser network --json
530
+ ```
531
+
532
+ **Example output:**
533
+ ```
534
+ Network Requests (5 total):
535
+ [GET] https://example.com/ => [200]
536
+ [GET] https://example.com/style.css => [200]
537
+ [POST] https://api.example.com/track => [204]
538
+ ```
539
+
540
+ ---
541
+
542
+ #### `browser cookies`
543
+
544
+ Show cookies for the active session.
545
+
546
+ ```bash
547
+ brightdata browser cookies
548
+ brightdata browser cookies --pretty
549
+ ```
550
+
551
+ ---
552
+
553
+ #### `browser status`
554
+
555
+ Show the current state of a browser session.
556
+
557
+ ```bash
558
+ brightdata browser status
559
+ brightdata browser status --session shop --pretty
560
+ ```
561
+
562
+ ---
563
+
564
+ #### `browser sessions`
565
+
566
+ List all active browser daemon sessions.
567
+
568
+ ```bash
569
+ brightdata browser sessions
570
+ brightdata browser sessions --pretty
571
+ ```
572
+
573
+ ---
574
+
575
+ #### `browser close`
576
+
577
+ Close a session and stop its daemon.
578
+
579
+ ```bash
580
+ brightdata browser close # Close the default session
581
+ brightdata browser close --session shop # Close a named session
582
+ brightdata browser close --all # Close all active sessions
583
+ ```
584
+
585
+ ---
586
+
587
+ **Example: AI agent workflow**
588
+
589
+ ```bash
590
+ # Open a US-targeted session
591
+ brightdata browser open https://example.com --country us
592
+
593
+ # Read the page structure (compact for token efficiency)
594
+ brightdata browser snapshot --compact
595
+
596
+ # Interact using refs from the snapshot
597
+ brightdata browser click e3
598
+ brightdata browser type e5 "search query" --submit
599
+
600
+ # Get updated snapshot after interaction
601
+ brightdata browser snapshot --compact
602
+
603
+ # Save a screenshot for visual verification
604
+ brightdata browser screenshot ./result.png
605
+
606
+ # Done
607
+ brightdata browser close
608
+ ```
609
+
610
+ **Example: multi-session comparison**
611
+
612
+ ```bash
613
+ brightdata browser open https://amazon.com --session us --country us
614
+ brightdata browser open https://amazon.com --session de --country de
615
+
616
+ brightdata browser snapshot --session us --json > us.json
617
+ brightdata browser snapshot --session de --json > de.json
618
+
619
+ brightdata browser close --all
620
+ ```
621
+
622
+ ---
623
+
295
624
  ### `status`
296
625
 
297
626
  Check the status of an async snapshot job (returned by `--async` or `pipelines`).
@@ -516,6 +845,8 @@ CLI flags → Environment variables → config.json → Defaults
516
845
  | `BRIGHTDATA_UNLOCKER_ZONE` | Default Web Unlocker zone |
517
846
  | `BRIGHTDATA_SERP_ZONE` | Default SERP zone |
518
847
  | `BRIGHTDATA_POLLING_TIMEOUT` | Default polling timeout in seconds |
848
+ | `BRIGHTDATA_BROWSER_ZONE` | Default Scraping Browser zone (default: `cli_browser`) |
849
+ | `BRIGHTDATA_DAEMON_DIR` | Override the directory used for browser daemon socket and PID files |
519
850
 
520
851
  ```bash
521
852
  BRIGHTDATA_API_KEY=xxx BRIGHTDATA_UNLOCKER_ZONE=my_zone \
@@ -671,6 +1002,29 @@ brightdata pipelines amazon_product <url> --timeout 1200
671
1002
  export BRIGHTDATA_POLLING_TIMEOUT=1200
672
1003
  ```
673
1004
 
1005
+ **`No active browser session "default"`**
1006
+ ```bash
1007
+ # Start a session first
1008
+ brightdata browser open https://example.com
1009
+ ```
1010
+
1011
+ **Browser daemon won't start**
1012
+ ```bash
1013
+ # Check if a stale socket file exists and clear it
1014
+ brightdata browser close
1015
+ # Then retry
1016
+ brightdata browser open https://example.com
1017
+ ```
1018
+
1019
+ **Element ref not found after interaction**
1020
+
1021
+ Refs are re-assigned on every `snapshot` call. If you navigate or click (which may cause the page to change), take a fresh snapshot before using refs again:
1022
+ ```bash
1023
+ brightdata browser click e3
1024
+ brightdata browser snapshot --compact # refresh refs
1025
+ brightdata browser type e5 "text"
1026
+ ```
1027
+
674
1028
  **Garbled output in non-interactive terminal**
675
1029
 
676
1030
  Colors and spinners are disabled automatically when not in a TTY. If you still see ANSI codes, add `| cat` at the end of your command.
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=connection.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"connection.test.d.ts","sourceRoot":"","sources":["../../../src/__tests__/browser/connection.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,168 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const events_1 = require("events");
4
+ const vitest_1 = require("vitest");
5
+ const connection_1 = require("../../browser/connection");
6
+ class Mock_page extends events_1.EventEmitter {
7
+ closed = false;
8
+ isClosed() {
9
+ return this.closed;
10
+ }
11
+ close_page() {
12
+ this.closed = true;
13
+ this.emit('close');
14
+ }
15
+ }
16
+ class Mock_context extends events_1.EventEmitter {
17
+ mock_pages;
18
+ constructor(mock_pages = [new Mock_page()]) {
19
+ super();
20
+ this.mock_pages = mock_pages;
21
+ }
22
+ async newPage() {
23
+ const page = new Mock_page();
24
+ this.mock_pages.push(page);
25
+ this.emit('page', page);
26
+ return page;
27
+ }
28
+ pages() {
29
+ return this.mock_pages;
30
+ }
31
+ first_page() {
32
+ return this.mock_pages[0];
33
+ }
34
+ }
35
+ class Mock_browser extends events_1.EventEmitter {
36
+ contexts_error = null;
37
+ mock_contexts;
38
+ constructor(mock_contexts = [new Mock_context()]) {
39
+ super();
40
+ this.mock_contexts = mock_contexts;
41
+ }
42
+ contexts() {
43
+ if (this.contexts_error)
44
+ throw this.contexts_error;
45
+ return this.mock_contexts;
46
+ }
47
+ async newContext() {
48
+ const context = new Mock_context([]);
49
+ this.mock_contexts.push(context);
50
+ return context;
51
+ }
52
+ break_health_check(message = 'stale browser') {
53
+ this.contexts_error = new Error(message);
54
+ }
55
+ disconnect() {
56
+ this.emit('disconnected');
57
+ }
58
+ first_context() {
59
+ return this.mock_contexts[0];
60
+ }
61
+ }
62
+ const create_state = () => ({
63
+ browser: null,
64
+ cdp_endpoint: 'wss://example.test',
65
+ connected: false,
66
+ dom_refs: new Map(),
67
+ page: null,
68
+ });
69
+ const create_hooks = () => {
70
+ const hooks = {
71
+ on_context: vitest_1.vi.fn(),
72
+ on_page: vitest_1.vi.fn(),
73
+ };
74
+ return hooks;
75
+ };
76
+ (0, vitest_1.describe)('browser/connection', () => {
77
+ (0, vitest_1.it)('connects and reuses the first existing page', async () => {
78
+ const state = create_state();
79
+ const hooks = create_hooks();
80
+ const browser = new Mock_browser();
81
+ const result = await (0, connection_1.connect_browser)(state, {
82
+ connect_over_cdp: vitest_1.vi.fn(async () => browser),
83
+ }, hooks);
84
+ (0, vitest_1.expect)(result.browser).toBe(browser);
85
+ (0, vitest_1.expect)(result.page).toBe(browser.first_context().first_page());
86
+ (0, vitest_1.expect)(hooks.on_context).toHaveBeenCalledTimes(1);
87
+ (0, vitest_1.expect)(hooks.on_page).toHaveBeenCalledWith(result.page);
88
+ });
89
+ (0, vitest_1.it)('clears connection state when the active browser disconnects', async () => {
90
+ const state = create_state();
91
+ state.dom_refs.set('r1', '#hero');
92
+ const browser = new Mock_browser();
93
+ const { page } = await (0, connection_1.connect_browser)(state, {
94
+ connect_over_cdp: vitest_1.vi.fn(async () => browser),
95
+ });
96
+ state.browser = browser;
97
+ state.page = page;
98
+ state.connected = true;
99
+ browser.disconnect();
100
+ (0, vitest_1.expect)(state.browser).toBe(null);
101
+ (0, vitest_1.expect)(state.page).toBe(null);
102
+ (0, vitest_1.expect)(state.connected).toBe(false);
103
+ (0, vitest_1.expect)(state.dom_refs.size).toBe(0);
104
+ });
105
+ (0, vitest_1.it)('reconnects when the current browser fails the health check', async () => {
106
+ const state = create_state();
107
+ const first_browser = new Mock_browser();
108
+ const second_browser = new Mock_browser();
109
+ state.browser = first_browser;
110
+ state.page = first_browser.first_context().first_page();
111
+ state.connected = true;
112
+ state.dom_refs.set('r2', '#signup');
113
+ first_browser.break_health_check();
114
+ const connect_over_cdp = vitest_1.vi.fn()
115
+ .mockResolvedValueOnce(second_browser);
116
+ const hooks = create_hooks();
117
+ const page = await (0, connection_1.ensure_connected)(state, { connect_over_cdp }, hooks);
118
+ (0, vitest_1.expect)(connect_over_cdp).toHaveBeenCalledTimes(1);
119
+ (0, vitest_1.expect)(state.browser).toBe(second_browser);
120
+ (0, vitest_1.expect)(state.page).toBe(page);
121
+ (0, vitest_1.expect)(state.connected).toBe(true);
122
+ (0, vitest_1.expect)(state.dom_refs.size).toBe(0);
123
+ (0, vitest_1.expect)(hooks.on_page).toHaveBeenCalledWith(page);
124
+ });
125
+ (0, vitest_1.it)('reuses a healthy browser connection without reconnecting', async () => {
126
+ const browser = new Mock_browser();
127
+ const state = create_state();
128
+ state.browser = browser;
129
+ state.page = browser.first_context().first_page();
130
+ state.connected = false;
131
+ const connect_over_cdp = vitest_1.vi.fn();
132
+ const page = await (0, connection_1.ensure_connected)(state, {
133
+ connect_over_cdp: connect_over_cdp,
134
+ });
135
+ (0, vitest_1.expect)(page).toBe(state.page);
136
+ (0, vitest_1.expect)(state.connected).toBe(true);
137
+ (0, vitest_1.expect)(connect_over_cdp).not.toHaveBeenCalled();
138
+ });
139
+ (0, vitest_1.it)('creates a new page when the current page is closed', async () => {
140
+ const browser = new Mock_browser([new Mock_context([])]);
141
+ const state = create_state();
142
+ state.browser = browser;
143
+ const closed_page = new Mock_page();
144
+ closed_page.close_page();
145
+ state.page = closed_page;
146
+ state.connected = true;
147
+ const hooks = create_hooks();
148
+ const page = await (0, connection_1.ensure_connected)(state, {
149
+ connect_over_cdp: vitest_1.vi.fn(),
150
+ }, hooks);
151
+ (0, vitest_1.expect)(page).toBe(browser.first_context().first_page());
152
+ (0, vitest_1.expect)(state.page).toBe(page);
153
+ (0, vitest_1.expect)(hooks.on_page).toHaveBeenCalledWith(page);
154
+ });
155
+ (0, vitest_1.it)('can clear connection state explicitly', () => {
156
+ const state = create_state();
157
+ state.browser = {};
158
+ state.page = {};
159
+ state.connected = true;
160
+ state.dom_refs.set('r3', '#footer');
161
+ (0, connection_1.clear_connection_state)(state);
162
+ (0, vitest_1.expect)(state.browser).toBe(null);
163
+ (0, vitest_1.expect)(state.page).toBe(null);
164
+ (0, vitest_1.expect)(state.connected).toBe(false);
165
+ (0, vitest_1.expect)(state.dom_refs.size).toBe(0);
166
+ });
167
+ });
168
+ //# sourceMappingURL=connection.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"connection.test.js","sourceRoot":"","sources":["../../../src/__tests__/browser/connection.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=daemon.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"daemon.test.d.ts","sourceRoot":"","sources":["../../../src/__tests__/browser/daemon.test.ts"],"names":[],"mappings":""}