browserscale-ts 1.7.1 → 1.9.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/client.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import type { Transport } from "@connectrpc/connect";
2
2
  import type { Locator } from "./locator.ts";
3
- import type { DOMResult, DragResult, ElementResult, EvaluateResult, InterceptedRequest, InterceptedResponse, InspectResult, NavigateResult, NetworkCaptureOptions, PageInfo, ScreenshotResult, ReadCanvasResult, SelectOptionResult, WaitResult, IceServer, StreamAnswer, ReactionInfo } from "./types.ts";
3
+ import type { DOMResult, DragResult, ElementResult, EvaluateResult, InterceptedRequest, InterceptedResponse, InspectResult, NavigateResult, NetworkCaptureOptions, PageInfo, ScreenshotResult, ReadCanvasResult, SelectOptionResult, SessionUsage, WaitResult, IceServer, StreamAnswer, ReactionInfo } from "./types.ts";
4
4
  import type { ClickOpts, FillOpts, GetDOMOpts, GetObservationOpts, LoadHTMLOpts, NavigateOpts, ReactionOpts, ScreenshotOpts, ReadCanvasOpts, SelectOpts, WaitOpts } from "./options.ts";
5
5
  import type { HeaderModification, RequestPattern } from "./network.ts";
6
6
  import { NetworkCapture, type NetworkExchangeHandler } from "./network-capture.ts";
@@ -13,9 +13,7 @@ import type { AuthSession } from "./auth-session.ts";
13
13
  * CloudBrowser is the SDK-side handle for an active browserscale browser session.
14
14
  *
15
15
  * One CloudBrowser corresponds to exactly one browser context, which
16
- * always has at least one page. The session is implicitly bound to its
17
- * primary page server-side — the proto's page_id field is currently
18
- * ignored server-side, so the SDK never sets it.
16
+ * always has at least one page; its commands act on the primary page.
19
17
  *
20
18
  * Construct via rentBrowser() / createWebSocketBrowser() — never
21
19
  * directly.
@@ -27,7 +25,7 @@ export declare class CloudBrowser {
27
25
  private readonly _transport;
28
26
  private readonly _fingerprint;
29
27
  private readonly _stopFn?;
30
- constructor(transport: Transport, sessionId: string, apiKey: string, fingerprint: string, stopFn?: () => Promise<void>);
28
+ constructor(transport: Transport, sessionId: string, apiKey: string, fingerprint: string, stopFn?: () => Promise<SessionUsage | undefined>);
31
29
  /** Returns the unique server-assigned id for this browser session. */
32
30
  getSessionId(): string;
33
31
  /** Returns the API key used to rent this session. */
@@ -42,12 +40,21 @@ export declare class CloudBrowser {
42
40
  * {@link createWebSocketBrowser} the rental stays untouched; only the
43
41
  * transport is closed.
44
42
  *
45
- * @throws UNKNOWN_ERROR - the stop API or the transport close failed
43
+ * @returns SessionUsage what the session consumed over its whole life, read
44
+ * as it was torn down - no {@link CloudBrowser.getUsage} call is needed
45
+ * before stopping. Undefined when the server could not report it, and for
46
+ * a handle that owns no rental.
47
+ *
48
+ * Rejects only when the stop API or the transport close fails. The session is
49
+ * released either way; retrying a stop is safe.
46
50
  *
47
51
  * @example
48
- * await browser.stopBrowser();
52
+ * const usage = await browser.stopBrowser();
53
+ * if (usage) {
54
+ * console.log(`ran ${usage.wallTime}s, ${usage.cpuTime}s CPU, peak ${usage.peakMemory} bytes`);
55
+ * }
49
56
  */
50
- stopBrowser(): Promise<void>;
57
+ stopBrowser(): Promise<SessionUsage | undefined>;
51
58
  /**
52
59
  * Changes the runtime proxy for this session.
53
60
  *
@@ -60,7 +67,9 @@ export declare class CloudBrowser {
60
67
  * @param proxyUsername - proxy auth user; empty for unauthenticated proxies
61
68
  * @param proxyPassword - proxy auth password; empty for unauthenticated proxies
62
69
  *
63
- * @throws UNKNOWN_ERROR - the proxy could not be applied
70
+ * Rejects only on a transport failure - a dead session, a page that is gone,
71
+ * a broken connection. This call has no semantic failure of its own, so there
72
+ * are no error codes to branch on.
64
73
  *
65
74
  * @example
66
75
  * await browser.setProxy("proxy.example.com", 8080, "user", "pass");
@@ -76,13 +85,36 @@ export declare class CloudBrowser {
76
85
  *
77
86
  * @returns PageInfo[] for every page currently open in the context
78
87
  *
79
- * @throws UNKNOWN_ERROR - the pages could not be enumerated
88
+ * Rejects only on a transport failure - a dead session, a page that is gone,
89
+ * a broken connection. This call has no semantic failure of its own, so there
90
+ * are no error codes to branch on.
80
91
  *
81
92
  * @example
82
93
  * const pages = await browser.getPages();
83
94
  * for (const p of pages) console.log(p.url, p.title);
84
95
  */
85
96
  getPages(): Promise<PageInfo[]>;
97
+ /**
98
+ * Reports what this session's browser has consumed so far.
99
+ *
100
+ * Everything but minMemory and averageMemory only ever grows, so polling and
101
+ * diffing two readings gives the cost of what ran in between. The final
102
+ * figures need no call of their own: {@link CloudBrowser.stopBrowser} resolves
103
+ * with them.
104
+ *
105
+ * @returns SessionUsage as of now
106
+ *
107
+ * Rejects only on a transport failure - a dead session, a broken connection.
108
+ * This call has no semantic failure of its own, so there are no error codes to
109
+ * branch on.
110
+ *
111
+ * @example
112
+ * const before = await browser.getUsage();
113
+ * await browser.navigate("https://example.com");
114
+ * const after = await browser.getUsage();
115
+ * console.log(`navigation cost ${after.cpuTime - before.cpuTime}s of CPU`);
116
+ */
117
+ getUsage(): Promise<SessionUsage>;
86
118
  /**
87
119
  * Navigates the page to url.
88
120
  *
@@ -96,7 +128,16 @@ export declare class CloudBrowser {
96
128
  * @returns NavigateResult with the final resolved URL and the frameId
97
129
  * of the main frame after navigation
98
130
  *
99
- * @throws UNKNOWN_ERROR - the navigation failed or timed out
131
+ * @throws timeout - nothing committed before the deadline; the page may still
132
+ * be loading, so a longer timeout can be the whole fix
133
+ * @throws net_error - the URL never loaded: DNS, TLS, a refused connection, or
134
+ * a proxy that could not reach it. The message carries the underlying net
135
+ * error name, which is what separates a bad proxy from a bad host - worth
136
+ * logging, since the two need different fixes
137
+ * @throws crashed - the renderer died mid-navigation; the page is unusable and
138
+ * has to be navigated again
139
+ *
140
+ * @see {@link CommandError} for reading the code off the rejection
100
141
  *
101
142
  * @example
102
143
  * await browser.navigate("https://example.com");
@@ -114,7 +155,11 @@ export declare class CloudBrowser {
114
155
  * @param html - response body to serve
115
156
  * @param opts - optional headers and statusCode (default 200)
116
157
  *
117
- * @throws UNKNOWN_ERROR - the interceptor could not be installed
158
+ * @throws timeout - the page never requested the URL, so the prepared
159
+ * response had nobody to hand it to; usually the navigation was cancelled
160
+ * or redirected away before reaching it
161
+ *
162
+ * @see {@link CommandError} for reading the code off the rejection
118
163
  *
119
164
  * @example
120
165
  * await browser.loadHTML("https://example.com", "<h1>hi</h1>");
@@ -133,16 +178,34 @@ export declare class CloudBrowser {
133
178
  * The generic T is a TypeScript hint only — there is no runtime
134
179
  * validation that the JS expression actually returned that type.
135
180
  *
181
+ * A falsy answer and a broken expression are different outcomes. Returning
182
+ * null, false or undefined is a successful evaluation and resolves normally;
183
+ * an expression that throws or will not compile rejects with a
184
+ * {@link CommandError}, so a typo can never read as "the page says null".
185
+ *
136
186
  * @param expression - JavaScript expression evaluated in the main frame
137
187
  *
138
188
  * @returns EvaluateResult with either value (non-Element) or element
139
189
  * metadata (Element)
140
190
  *
141
- * @throws UNKNOWN_ERROR - the expression threw or could not be compiled
191
+ * @throws {@link CommandError} - code `"threw"` (the expression raised; the
192
+ * message carries the exception text), `"not_run"` (it could not be
193
+ * compiled, or execution never started), `"aborted"` (the browser stopped
194
+ * execution) or `"no_context"` (the frame had no live script context)
142
195
  *
143
196
  * @example
144
197
  * const res = await browser.evaluate<string>("document.title");
145
198
  * console.log(res.value);
199
+ *
200
+ * @example
201
+ * // Telling a false answer from a broken expression.
202
+ * try {
203
+ * const res = await browser.evaluate<boolean>("window.__ready === true");
204
+ * if (!res.value) { /* legitimately not ready yet *\/ }
205
+ * } catch (e) {
206
+ * if (e instanceof CommandError) throw new Error(`expression broken: ${e.message}`);
207
+ * throw e;
208
+ * }
146
209
  */
147
210
  evaluate<T = unknown>(expression: string): Promise<EvaluateResult<T>>;
148
211
  /**
@@ -438,7 +501,9 @@ export declare class CloudBrowser {
438
501
  * @returns DOMResult with the JSON string in `.dom` (the `.hash` field
439
502
  * is populated by {@link getDOMHash}, not by this call)
440
503
  *
441
- * @throws UNKNOWN_ERROR - the DOM could not be retrieved
504
+ * Rejects only on a transport failure - a dead session, a page that is gone,
505
+ * a broken connection. This call has no semantic failure of its own, so there
506
+ * are no error codes to branch on.
442
507
  *
443
508
  * @example
444
509
  * const { dom } = await browser.getDOM();
@@ -456,7 +521,9 @@ export declare class CloudBrowser {
456
521
  *
457
522
  * @returns 16-char hex string (the first 8 bytes of sha256 of the DOM JSON)
458
523
  *
459
- * @throws UNKNOWN_ERROR - the hash could not be computed
524
+ * Rejects only on a transport failure. The hash is computed from a serialized
525
+ * tree, so there is no semantic failure of its own and no error codes to branch
526
+ * on.
460
527
  *
461
528
  * @example
462
529
  * const hash = await browser.getDOMHash();
@@ -496,7 +563,11 @@ export declare class CloudBrowser {
496
563
  *
497
564
  * @returns the observation in the requested format, ready to hand to a model
498
565
  *
499
- * @throws UNKNOWN_ERROR - the observation could not be produced
566
+ * @throws not_found - the requested scope root is not on the page, so there
567
+ * was nothing to observe. Distinct from an observation that comes back
568
+ * empty, which means the scope exists and holds nothing worth reporting
569
+ *
570
+ * @see {@link CommandError} for reading the code off the rejection
500
571
  *
501
572
  * @example
502
573
  * const obs = await browser.getObservation();
@@ -517,7 +588,11 @@ export declare class CloudBrowser {
517
588
  * @returns ScreenshotResult with the base64 image in `dataBase64` and the
518
589
  * physical pixel `width`/`height`
519
590
  *
520
- * @throws UNKNOWN_ERROR - the screenshot could not be captured
591
+ * @throws capture_failed - the page had no frame to copy. A page that has not
592
+ * produced one yet, or is not being composited at the moment, has nothing to
593
+ * hand over; retrying after it renders usually works
594
+ *
595
+ * @see {@link CommandError} for reading the code off the rejection
521
596
  *
522
597
  * @example
523
598
  * const shot = await browser.screenshot({ format: "png" });
@@ -541,11 +616,15 @@ export declare class CloudBrowser {
541
616
  * canvas `width`/`height`, resolved `frameId`/`backendNodeId` and the
542
617
  * `originClean` flag
543
618
  *
544
- * @throws INVALID_LOCATOR - target is empty, uses at(x,y), or has multiple targets
545
- * @throws ELEMENT_NOT_FOUND - no element matched the locator
546
- * @throws FRAME_NOT_FOUND - the requested frame does not exist
547
- * @throws TIMEOUT - the operation exceeded the server-side timeout
548
- * @throws PAGE_NOT_ALIVE - the page has been closed
619
+ * @throws not_found - no element matched the locator
620
+ * @throws not_element - the expression was truthy but did not yield an element
621
+ * @throws not_readable - the target was found but is not a readable canvas
622
+ *
623
+ * A target that is empty, uses `at(x, y)` or names several things at once is
624
+ * rejected before anything is sent. A closed page or a frame that is gone is a
625
+ * transport failure rather than a code.
626
+ *
627
+ * @see {@link CommandError} for reading the code off the rejection
549
628
  *
550
629
  * @example
551
630
  * const res = await browser.readCanvas(css("#game canvas"));
@@ -568,7 +647,9 @@ export declare class CloudBrowser {
568
647
  *
569
648
  * @param patterns - URL wildcards to block; empty array clears the list
570
649
  *
571
- * @throws UNKNOWN_ERROR - the blocklist could not be applied
650
+ * Rejects only on a transport failure - a dead session, a page that is gone,
651
+ * a broken connection. This call has no semantic failure of its own, so there
652
+ * are no error codes to branch on.
572
653
  *
573
654
  * @example
574
655
  * await browser.setBlockList([
@@ -589,7 +670,9 @@ export declare class CloudBrowser {
589
670
  * @param blobName - server-side identifier of the snapshot to serve from
590
671
  * @param patterns - URL wildcards to redirect to the cache; empty disables
591
672
  *
592
- * @throws UNKNOWN_ERROR - the static paths could not be configured
673
+ * Rejects only on a transport failure - a dead session, a page that is gone,
674
+ * a broken connection. This call has no semantic failure of its own, so there
675
+ * are no error codes to branch on.
593
676
  *
594
677
  * @example
595
678
  * await browser.setStaticPaths("snap-2026-05", ["*.example.com/*"]);
@@ -610,7 +693,12 @@ export declare class CloudBrowser {
610
693
  * (the captured method/URL/headers/body; null if intercepted with
611
694
  * no body)
612
695
  *
613
- * @throws UNKNOWN_ERROR - the wait timed out or no patterns were supplied
696
+ * @throws timeout - no request matched any pattern before the deadline.
697
+ * Nothing occurring is an answer, and it stays distinguishable from a
698
+ * connection that died on the way. Supplying no patterns is a caller mistake
699
+ * rather than an outcome, and rejects separately
700
+ *
701
+ * @see {@link CommandError} for reading the code off the rejection
614
702
  *
615
703
  * @example
616
704
  * const { index, request } = await browser.waitForAnyRequest(
@@ -638,6 +726,13 @@ export declare class CloudBrowser {
638
726
  * @returns object with `index` (matched pattern index) and `response`
639
727
  * (the captured status/headers/body; null if no body was returned)
640
728
  *
729
+ * @throws timeout - no response matched any pattern before the deadline.
730
+ * Nothing occurring is an answer, and it stays distinguishable from a
731
+ * connection that died on the way. Supplying no patterns is a caller mistake
732
+ * rather than an outcome, and rejects separately
733
+ *
734
+ * @see {@link CommandError} for reading the code off the rejection
735
+ *
641
736
  * @example
642
737
  * const { index, response } = await browser.waitForAnyResponse(
643
738
  * [{ url: "*\/api/login" }],
@@ -667,7 +762,10 @@ export declare class CloudBrowser {
667
762
  * were actually sent on the wire after modifications were applied;
668
763
  * null when no request payload was reported
669
764
  *
670
- * @throws UNKNOWN_ERROR - no matching request appeared within the timeout
765
+ * @throws timeout - no matching request appeared before the deadline, so
766
+ * nothing was modified
767
+ *
768
+ * @see {@link CommandError} for reading the code off the rejection
671
769
  *
672
770
  * @example
673
771
  * const req = await browser.modifyRequest("*\/api/me", {
@@ -708,7 +806,9 @@ export declare class CloudBrowser {
708
806
  * @returns NetworkCapture handle for stopping the capture and inspecting how
709
807
  * it ended
710
808
  *
711
- * @throws UNKNOWN_ERROR - the capture could not be started
809
+ * Rejects only on a transport failure - a dead session, a page that is gone,
810
+ * a broken connection. This call has no semantic failure of its own, so there
811
+ * are no error codes to branch on.
712
812
  *
713
813
  * @example
714
814
  * const capture = await browser.captureNetwork(
@@ -732,7 +832,9 @@ export declare class CloudBrowser {
732
832
  *
733
833
  * @param opts - which requests to capture and whether to keep bodies
734
834
  *
735
- * @throws UNKNOWN_ERROR - the capture could not be started
835
+ * Rejects only on a transport failure - a dead session, a page that is gone,
836
+ * a broken connection. This call has no semantic failure of its own, so there
837
+ * are no error codes to branch on.
736
838
  */
737
839
  startNetworkCapture(opts: NetworkCaptureOptions): Promise<void>;
738
840
  /**
@@ -740,7 +842,8 @@ export declare class CloudBrowser {
740
842
  *
741
843
  * @returns whether a capture was running
742
844
  *
743
- * @throws UNKNOWN_ERROR - the capture could not be stopped
845
+ * Rejects only on a transport failure. Stopping a capture that is not running
846
+ * is a no-op rather than a failure, so there are no error codes to branch on.
744
847
  */
745
848
  stopNetworkCapture(): Promise<boolean>;
746
849
  /**
@@ -757,7 +860,8 @@ export declare class CloudBrowser {
757
860
  * @returns NetworkCapture attached to whatever capture is running; onExchange
758
861
  * simply never fires when none is
759
862
  *
760
- * @throws UNKNOWN_ERROR - the subscription could not be opened
863
+ * Rejects only on a transport failure: opening the subscription has no semantic
864
+ * failure of its own.
761
865
  */
762
866
  streamNetworkExchanges(onExchange: NetworkExchangeHandler): Promise<NetworkCapture>;
763
867
  /**
@@ -810,13 +914,21 @@ export declare class CloudBrowser {
810
914
  * @param onResync called when the copy had to be rebuilt, after the new tree
811
915
  * is in place. Rebuilding is automatic; this is for telling the user why
812
916
  * their expanded nodes collapsed.
813
- * @throws UNKNOWN_ERROR - the mirror could not be started
917
+ * @throws mirror_failed - the page could not be serialized, usually a document
918
+ * that went away while the tree was being built. No mirror is left running
919
+ *
920
+ * @see {@link CommandError} for reading the code off the rejection
814
921
  */
815
922
  mirrorDom(opts: DomMirrorOptions, onChange: DomChangeHandler, onResync?: DomResyncHandler): Promise<DomMirror>;
816
923
  /**
817
924
  * Starts (or restarts) the page's mirror and returns the main document,
818
925
  * without subscribing to changes. {@link CloudBrowser.mirrorDom} is what you
819
926
  * normally want; this is the raw command.
927
+ *
928
+ * @throws mirror_failed - the page could not be serialized, usually a document
929
+ * that went away while the tree was being built. No mirror is left running
930
+ *
931
+ * @see {@link CommandError} for reading the code off the rejection
820
932
  */
821
933
  startDomMirror(opts?: DomMirrorOptions): Promise<DomSnapshot>;
822
934
  /** Stops the page's mirror, every frame of it. Idempotent. */
@@ -827,6 +939,17 @@ export declare class CloudBrowser {
827
939
  *
828
940
  * On an `<iframe>` the one child is the document it hosts, and this call is
829
941
  * what starts mirroring that frame.
942
+ *
943
+ * An id that is simply unknown is not a failure: the call resolves with an
944
+ * empty result.
945
+ *
946
+ * @throws not_mirrored - the page has no mirror, or frameId is not part of the
947
+ * one it has; start a mirror first, and after a resync fetch the current tree
948
+ * before addressing nodes again
949
+ * @throws mirror_failed - the subtree could not be serialized, usually a
950
+ * document that went away mid-read
951
+ *
952
+ * @see {@link CommandError} for reading the code off the rejection
830
953
  */
831
954
  getDomChildren(backendNodeId: number, frameId?: string, depth?: number): Promise<{
832
955
  children: string;
@@ -835,6 +958,13 @@ export declare class CloudBrowser {
835
958
  /**
836
959
  * Stops reporting changes inside a node, and inside any frame below it.
837
960
  * {@link DomMirror.collapse} calls this.
961
+ *
962
+ * @throws not_mirrored - the page has no mirror, or frameId is not part of
963
+ * the one it has; this is what replaying ids from a tree that has since
964
+ * been resynced looks like, so fetch the current tree and address the node
965
+ * again
966
+ *
967
+ * @see {@link CommandError} for reading the code off the rejection
838
968
  */
839
969
  releaseDomSubtree(backendNodeId: number, frameId?: string): Promise<void>;
840
970
  /**
@@ -842,6 +972,16 @@ export declare class CloudBrowser {
842
972
  * with its own children, crossing into frames where it has to and starting
843
973
  * the ones it passes through. {@link DomMirror.reveal} calls this and
844
974
  * splices it in.
975
+ *
976
+ * An id that is simply unknown is not a failure: the call resolves with an
977
+ * empty result.
978
+ *
979
+ * @throws not_mirrored - the page has no mirror, or frameId is not part of the
980
+ * one it has
981
+ * @throws mirror_failed - the path could not be serialized, usually a document
982
+ * that went away mid-read
983
+ *
984
+ * @see {@link CommandError} for reading the code off the rejection
845
985
  */
846
986
  revealDomNode(backendNodeId: number, frameId?: string): Promise<{
847
987
  path: string;
@@ -856,6 +996,10 @@ export declare class CloudBrowser {
856
996
  * whole tree just to hash it. The two answer different questions: a hash
857
997
  * compares content, a revision only says whether this document moved since
858
998
  * you last asked.
999
+ *
1000
+ * Rejects only on a transport failure - a dead session, a page that is gone,
1001
+ * a broken connection. This call has no semantic failure of its own, so there
1002
+ * are no error codes to branch on.
859
1003
  */
860
1004
  getDomRevision(frameId?: string): Promise<number>;
861
1005
  /**
@@ -863,7 +1007,9 @@ export declare class CloudBrowser {
863
1007
  *
864
1008
  * @returns CookieParam[], one per cookie in the context
865
1009
  *
866
- * @throws UNKNOWN_ERROR - the cookies could not be read
1010
+ * Rejects only on a transport failure - a dead session, a page that is gone,
1011
+ * a broken connection. This call has no semantic failure of its own, so there
1012
+ * are no error codes to branch on.
867
1013
  *
868
1014
  * @example
869
1015
  * const cookies = await browser.getCookies();
@@ -878,7 +1024,9 @@ export declare class CloudBrowser {
878
1024
  *
879
1025
  * @param cookies - cookies to write; empty array is a no-op
880
1026
  *
881
- * @throws UNKNOWN_ERROR - the cookies could not be written
1027
+ * Rejects only on a transport failure - a dead session, a page that is gone,
1028
+ * a broken connection. This call has no semantic failure of its own, so there
1029
+ * are no error codes to branch on.
882
1030
  *
883
1031
  * @example
884
1032
  * await browser.setCookies([
@@ -889,7 +1037,9 @@ export declare class CloudBrowser {
889
1037
  /**
890
1038
  * Deletes every cookie in the browser context.
891
1039
  *
892
- * @throws UNKNOWN_ERROR - the cookies could not be cleared
1040
+ * Rejects only on a transport failure - a dead session, a page that is gone,
1041
+ * a broken connection. This call has no semantic failure of its own, so there
1042
+ * are no error codes to branch on.
893
1043
  *
894
1044
  * @example
895
1045
  * await browser.clearCookies();
@@ -908,7 +1058,9 @@ export declare class CloudBrowser {
908
1058
  *
909
1059
  * @returns StorageOriginEntry[], one per origin with localStorage data
910
1060
  *
911
- * @throws UNKNOWN_ERROR - the storage could not be read
1061
+ * Rejects only on a transport failure - a dead session, a page that is gone,
1062
+ * a broken connection. This call has no semantic failure of its own, so there
1063
+ * are no error codes to branch on.
912
1064
  *
913
1065
  * @example
914
1066
  * const storage = await browser.getStorage();
@@ -928,7 +1080,9 @@ export declare class CloudBrowser {
928
1080
  *
929
1081
  * @param storage - entries to write, grouped by origin
930
1082
  *
931
- * @throws UNKNOWN_ERROR - the storage could not be written
1083
+ * Rejects only on a transport failure - a dead session, a page that is gone,
1084
+ * a broken connection. This call has no semantic failure of its own, so there
1085
+ * are no error codes to branch on.
932
1086
  *
933
1087
  * @example
934
1088
  * await browser.setStorage([
@@ -948,7 +1102,9 @@ export declare class CloudBrowser {
948
1102
  * @param origin - if set, only this origin's storage is deleted
949
1103
  * (e.g. "https://example.com"); omit to delete all origins
950
1104
  *
951
- * @throws UNKNOWN_ERROR - the storage could not be cleared
1105
+ * Rejects only on a transport failure - a dead session, a page that is gone,
1106
+ * a broken connection. This call has no semantic failure of its own, so there
1107
+ * are no error codes to branch on.
952
1108
  *
953
1109
  * @example
954
1110
  * // Wipe one origin.
@@ -968,7 +1124,9 @@ export declare class CloudBrowser {
968
1124
  *
969
1125
  * @returns AuthSession, or undefined when there is nothing to export
970
1126
  *
971
- * @throws UNKNOWN_ERROR - the auth session could not be read
1127
+ * Rejects only on a transport failure - a dead session, a page that is gone,
1128
+ * a broken connection. This call has no semantic failure of its own, so there
1129
+ * are no error codes to branch on.
972
1130
  *
973
1131
  * @example
974
1132
  * const auth = await browser.getAuthSession();
@@ -984,7 +1142,9 @@ export declare class CloudBrowser {
984
1142
  *
985
1143
  * @param session - session as returned by getAuthSession()
986
1144
  *
987
- * @throws UNKNOWN_ERROR - the auth session could not be written
1145
+ * Rejects only on a transport failure - a dead session, a page that is gone,
1146
+ * a broken connection. This call has no semantic failure of its own, so there
1147
+ * are no error codes to branch on.
988
1148
  *
989
1149
  * @example
990
1150
  * await browser.setAuthSession(saved);
@@ -1006,7 +1166,9 @@ export declare class CloudBrowser {
1006
1166
  * @returns InspectResult with the resolved backendNodeId, frameId, tag
1007
1167
  * name, trimmed textContent, visibility and bounds
1008
1168
  *
1009
- * @throws UNKNOWN_ERROR - the hit-test failed
1169
+ * Rejects only on a transport failure - a dead session, a page that is gone,
1170
+ * a broken connection. This call has no semantic failure of its own, so there
1171
+ * are no error codes to branch on.
1010
1172
  *
1011
1173
  * @example
1012
1174
  * const r = await browser.inspectAtPosition(200, 300);
@@ -1023,7 +1185,9 @@ export declare class CloudBrowser {
1023
1185
  * @param frameId - id of the frame the node lives in; empty string
1024
1186
  * targets the main frame
1025
1187
  *
1026
- * @throws UNKNOWN_ERROR - the highlight could not be applied
1188
+ * Rejects only on a transport failure - a dead session, a page that is gone,
1189
+ * a broken connection. This call has no semantic failure of its own, so there
1190
+ * are no error codes to branch on.
1027
1191
  *
1028
1192
  * @example
1029
1193
  * await browser.highlightNode(res.backendNodeId, res.frameId);
@@ -1039,7 +1203,11 @@ export declare class CloudBrowser {
1039
1203
  *
1040
1204
  * @param text - the text to insert at the caret
1041
1205
  *
1042
- * @throws UNKNOWN_ERROR - the text could not be inserted
1206
+ * @throws no_focus - nothing in the page holds focus, so there is no caret to
1207
+ * insert at; click the field first
1208
+ * @throws busy - another action is already running on this page
1209
+ *
1210
+ * @see {@link CommandError} for reading the code off the rejection
1043
1211
  *
1044
1212
  * @example
1045
1213
  * await browser.insertText("hello world");
@@ -1065,7 +1233,10 @@ export declare class CloudBrowser {
1065
1233
  * @param opts - optional: `clearFirst` clears the focused field (Ctrl+A,
1066
1234
  * Delete) before typing
1067
1235
  *
1068
- * @throws UNKNOWN_ERROR - the page/context was torn down mid-stream
1236
+ * `type` has no semantic failure of its own: the keys land wherever focus
1237
+ * happens to be, so there is no target it can miss. Only the page or context
1238
+ * being torn down mid-stream surfaces, and that is a transport failure rather
1239
+ * than a code.
1069
1240
  *
1070
1241
  * @example
1071
1242
  * // OTP field that auto-advances across boxes.
@@ -1088,7 +1259,11 @@ export declare class CloudBrowser {
1088
1259
  * `modifiers` (bit-flag: Alt=1, Ctrl=2, Meta=4, Shift=8),
1089
1260
  * `location` (0=standard, 1=left, 2=right, 3=numpad)
1090
1261
  *
1091
- * @throws UNKNOWN_ERROR - the event could not be dispatched
1262
+ * @throws no_focus - nothing in the page holds focus, so the key has nowhere
1263
+ * to go; click the field first
1264
+ * @throws busy - another action is already running on this page
1265
+ *
1266
+ * @see {@link CommandError} for reading the code off the rejection
1092
1267
  *
1093
1268
  * @example
1094
1269
  * // Ctrl+A
@@ -1126,7 +1301,9 @@ export declare class CloudBrowser {
1126
1301
  *
1127
1302
  * @returns the selected text, or `""` when nothing is selected
1128
1303
  *
1129
- * @throws UNKNOWN_ERROR - the selection could not be read
1304
+ * Rejects only on a transport failure - a dead session, a page that is gone,
1305
+ * a broken connection. This call has no semantic failure of its own, so there
1306
+ * are no error codes to branch on.
1130
1307
  *
1131
1308
  * @example
1132
1309
  * const sel = await browser.getSelection();
@@ -1148,8 +1325,10 @@ export declare class CloudBrowser {
1148
1325
  *
1149
1326
  * @returns empty string on success — the solution is applied server-side
1150
1327
  *
1151
- * @throws UNKNOWN_ERROR - no captcha appeared within timeoutMs, or the
1152
- * detected captcha could not be solved within retryAmount attempts
1328
+ * Rejects when no captcha appeared within imeoutMs, or when the one that did
1329
+ * could not be solved within
1330
+ etryAmount attempts. Neither carries a code:
1331
+ * solving runs outside the page, so there is no per-command code set here.
1153
1332
  *
1154
1333
  * @example
1155
1334
  * await browser.solveCaptcha({ retryAmount: 2 });
@@ -1169,7 +1348,8 @@ export declare class CloudBrowser {
1169
1348
  *
1170
1349
  * @returns the ICE servers for the client `RTCPeerConnection`
1171
1350
  *
1172
- * @throws UNKNOWN_ERROR - TURN is not configured on the server
1351
+ * Rejects when TURN is not configured on the server. That is a deployment
1352
+ * condition rather than a per-call outcome, so it carries no code.
1173
1353
  *
1174
1354
  * @example
1175
1355
  * const ice = await browser.getStreamConfig();
@@ -1186,8 +1366,16 @@ export declare class CloudBrowser {
1186
1366
  * @returns the SDP answer to apply as the remote description, plus the
1187
1367
  * viewport to map input coordinates into
1188
1368
  *
1189
- * @throws UNKNOWN_ERROR - the offer was empty, TURN is unconfigured, or the
1190
- * browser could not negotiate the stream
1369
+ * @throws already_active - a stream is already running on this session; stop it
1370
+ * before starting another
1371
+ * @throws negotiation_failed - the browser could not agree on a connection. The
1372
+ * message carries the negotiator's own diagnostic, which is usually where the
1373
+ * actual cause is
1374
+ *
1375
+ * An empty offer or an unconfigured TURN setup is a caller mistake rather than
1376
+ * an outcome, and rejects separately.
1377
+ *
1378
+ * @see {@link CommandError} for reading the code off the rejection
1191
1379
  *
1192
1380
  * @example
1193
1381
  * const { answerSdp, viewport } = await browser.startStream(offer.sdp);
@@ -1198,17 +1386,18 @@ export declare class CloudBrowser {
1198
1386
  * Tears down the live video stream for the session's page. Safe to call even
1199
1387
  * if no stream is running.
1200
1388
  *
1201
- * @throws UNKNOWN_ERROR - the stream could not be stopped
1389
+ * Rejects only on a transport failure. Stopping a stream that is not running is
1390
+ * a no-op rather than a failure, so there are no error codes to branch on.
1202
1391
  *
1203
1392
  * @example
1204
1393
  * await browser.stopStream();
1205
1394
  */
1206
1395
  stopStream(): Promise<void>;
1207
1396
  /**
1208
- * Registers a one-shot "reaction": a background poller (one shared loop per
1209
- * page) watches for the `match` locator and, as soon as it matches, clicks it
1210
- * with the full smart-click machinery (scroll, human path, occlusion gate,
1211
- * evade) — then removes itself. The poller yields to any in-flight input
1397
+ * Registers a one-shot "reaction": the browser watches for the `match`
1398
+ * locator in the background and, as soon as it matches, clicks it the same
1399
+ * way {@link CloudBrowser.click} does (scroll, human path, occlusion check) —
1400
+ * then removes itself. The reaction yields to any in-flight input
1212
1401
  * action and only fires while the pointer is idle, so a reaction naturally
1213
1402
  * slots into the gaps of a retrying foreground action (e.g. it dismisses a
1214
1403
  * newsletter modal blocking a {@link CloudBrowser.click}, after which the
@@ -1247,6 +1436,10 @@ export declare class CloudBrowser {
1247
1436
  *
1248
1437
  * @returns true if a pending reaction with this id existed and was removed
1249
1438
  *
1439
+ * Removing an id that is not registered is a no-op rather than an error, so the
1440
+ * returned boolean - not a rejection - is what tells you whether anything was
1441
+ * there. Rejects only on a transport failure.
1442
+ *
1250
1443
  * @example
1251
1444
  * const removed = await browser.removeReaction(id);
1252
1445
  */
@@ -1257,6 +1450,10 @@ export declare class CloudBrowser {
1257
1450
  *
1258
1451
  * @returns the pending reactions for the page
1259
1452
  *
1453
+ * Rejects only on a transport failure - a dead session, a page that is gone,
1454
+ * a broken connection. This call has no semantic failure of its own, so there
1455
+ * are no error codes to branch on.
1456
+ *
1260
1457
  * @example
1261
1458
  * const pending = await browser.listReactions();
1262
1459
  * for (const r of pending) console.log(r.reactionId, r.matchSelector);
@@ -1285,7 +1482,10 @@ export declare class CloudBrowser {
1285
1482
  * @returns the return value and the script's whole console output. A script
1286
1483
  * that threw is reported as `success: false`, not as a rejection
1287
1484
  *
1288
- * @throws UNKNOWN_ERROR - the script could not be delivered to the browser
1485
+ * Rejects only on a transport failure. A script that fails to compile or throws
1486
+ * is not a rejection: the returned result has success: false and
1487
+ esult holds
1488
+ * the message, so a broken script stays distinguishable from a broken connection.
1289
1489
  *
1290
1490
  * @example
1291
1491
  * const result = await browser.runScript(`
@@ -1320,7 +1520,8 @@ export declare class CloudBrowser {
1320
1520
  *
1321
1521
  * @returns ScriptRun handle for awaiting or cancelling the run
1322
1522
  *
1323
- * @throws UNKNOWN_ERROR - the run could not be started
1523
+ * Rejects only on a transport failure: a script that fails to compile or throws
1524
+ * surfaces on the run itself rather than here.
1324
1525
  *
1325
1526
  * @example
1326
1527
  * const run = await browser.startScript(source, (ev) => {
@@ -1347,7 +1548,8 @@ export declare class CloudBrowser {
1347
1548
  *
1348
1549
  * @returns ScriptFollow handle for stopping the subscription
1349
1550
  *
1350
- * @throws UNKNOWN_ERROR - the subscription could not be opened
1551
+ * Rejects only on a transport failure: opening the subscription has no semantic
1552
+ * failure of its own.
1351
1553
  *
1352
1554
  * @example
1353
1555
  * const follow = await browser.followScript(runId, (ev) => {
@@ -1372,7 +1574,9 @@ export declare class CloudBrowser {
1372
1574
  * @returns how many runs were cancelled; 0 when the id named nothing in
1373
1575
  * flight
1374
1576
  *
1375
- * @throws UNKNOWN_ERROR - the cancel could not be delivered
1577
+ * Rejects only on a transport failure. Cancelling runs that have already
1578
+ * finished, or none at all, is a no-op - read the returned count to learn how
1579
+ * many were actually stopped.
1376
1580
  *
1377
1581
  * @example
1378
1582
  * await browser.stopScripts(""); // abandon everything running
@@ -1388,7 +1592,9 @@ export declare class CloudBrowser {
1388
1592
  *
1389
1593
  * @returns one entry per run still executing
1390
1594
  *
1391
- * @throws UNKNOWN_ERROR - the session could not be queried
1595
+ * Rejects only on a transport failure - a dead session, a broken connection.
1596
+ * This call has no semantic failure of its own, so there are no error codes to
1597
+ * branch on.
1392
1598
  *
1393
1599
  * @example
1394
1600
  * for (const run of await browser.listScriptRuns()) {