browserscale-ts 1.0.1 → 1.2.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/errors.js CHANGED
@@ -1,15 +1,22 @@
1
1
  /**
2
- * BrowserScaleError is the single error type thrown by all SDK methods. It wraps
3
- * either:
2
+ * BrowserScaleError is the base class for every error thrown by the SDK. It
3
+ * wraps either:
4
4
  * - a client-side validation failure (bad locator, missing patterns, …)
5
5
  * - a server-side gRPC error (Connect's ConnectError, available as `cause`)
6
6
  *
7
- * Catch it with `instanceof BrowserScaleError`:
7
+ * Semantic action failures (an occluded click, a wait timeout, an option that
8
+ * did not exist, …) are thrown as the typed subclasses below, each carrying the
9
+ * same structured detail the Go SDK exposes via `errors.As` — plus the partial
10
+ * result of the attempted action on `.result`, so a single `catch` gives you
11
+ * both the diagnostics and the resolved coordinates.
12
+ *
13
+ * Catch the base for anything, or narrow to a subclass for the detail:
8
14
  *
9
15
  * try {
10
16
  * await browser.click(css("#btn"));
11
17
  * } catch (e) {
12
- * if (e instanceof BrowserScaleError) { ... }
18
+ * if (e instanceof ClickError) console.log(e.code, e.occluder?.tagName);
19
+ * else if (e instanceof BrowserScaleError) { ... }
13
20
  * }
14
21
  */
15
22
  export class BrowserScaleError extends Error {
@@ -19,3 +26,112 @@ export class BrowserScaleError extends Error {
19
26
  this.name = "BrowserScaleError";
20
27
  }
21
28
  }
29
+ /**
30
+ * ClickError is thrown by {@link CloudBrowser.click} when the click did not
31
+ * land — the target was found but another element covered the intended point.
32
+ * `occluder` describes the blocker; `result` carries the resolved element and
33
+ * coordinates (success is false).
34
+ *
35
+ * It is also nested under {@link FillError} / {@link DragError} as the
36
+ * underlying click-core failure; in that nested form `result` is undefined
37
+ * (the partial result lives on the outer error).
38
+ */
39
+ export class ClickError extends BrowserScaleError {
40
+ constructor(init) {
41
+ super(formatMessage("click", init.code, init.message));
42
+ this.name = "ClickError";
43
+ this.code = init.code;
44
+ this.occluder = init.occluder;
45
+ this.evadeAttempted = init.evadeAttempted ?? false;
46
+ this.result = init.result;
47
+ }
48
+ }
49
+ /**
50
+ * FillError is thrown by {@link CloudBrowser.fill} when the field could not be
51
+ * focused/typed. Fill focuses with the exact same smart click as
52
+ * {@link CloudBrowser.click}, so a pre-typing failure is a click failure:
53
+ * `code` mirrors it and the full click diagnostics live under `clickError`.
54
+ */
55
+ export class FillError extends BrowserScaleError {
56
+ constructor(init) {
57
+ super(formatMessage("fill", init.code, init.message));
58
+ this.name = "FillError";
59
+ this.code = init.code;
60
+ this.clickError = init.clickError;
61
+ this.result = init.result;
62
+ }
63
+ }
64
+ /**
65
+ * DragError is thrown by {@link CloudBrowser.dragBy} / {@link CloudBrowser.dragTo}
66
+ * when the source element could not be acquired/pressed. Drag picks up the
67
+ * source with the same smart click as {@link CloudBrowser.click}, so a pre-drag
68
+ * failure is a click failure: `code` mirrors it and the full click diagnostics
69
+ * live under `clickError`.
70
+ */
71
+ export class DragError extends BrowserScaleError {
72
+ constructor(init) {
73
+ super(formatMessage("drag", init.code, init.message));
74
+ this.name = "DragError";
75
+ this.code = init.code;
76
+ this.clickError = init.clickError;
77
+ this.result = init.result;
78
+ }
79
+ }
80
+ /**
81
+ * ScrollError is thrown by {@link CloudBrowser.scrollTo} when the target could
82
+ * not be located/scrolled.
83
+ */
84
+ export class ScrollError extends BrowserScaleError {
85
+ constructor(init) {
86
+ super(formatMessage("scrollTo", init.code, init.message));
87
+ this.name = "ScrollError";
88
+ this.code = init.code;
89
+ this.result = init.result;
90
+ }
91
+ }
92
+ /**
93
+ * MoveError is thrown by {@link CloudBrowser.moveTo} when the target could not
94
+ * be located. A move has no occlusion notion, so this is the only semantic
95
+ * failure.
96
+ */
97
+ export class MoveError extends BrowserScaleError {
98
+ constructor(init) {
99
+ super(formatMessage("moveTo", init.code, init.message));
100
+ this.name = "MoveError";
101
+ this.code = init.code;
102
+ this.result = init.result;
103
+ }
104
+ }
105
+ /**
106
+ * SelectOptionError is thrown by the {@link CloudBrowser.selectByIndex} /
107
+ * `selectByValue` / `selectByText` calls when the option could not be selected.
108
+ * selectOption is programmatic (no pointer gate), so it only reports semantic
109
+ * failures.
110
+ */
111
+ export class SelectOptionError extends BrowserScaleError {
112
+ constructor(init) {
113
+ super(formatMessage("selectOption", init.code, init.message));
114
+ this.name = "SelectOptionError";
115
+ this.code = init.code;
116
+ this.result = init.result;
117
+ }
118
+ }
119
+ /**
120
+ * WaitError is thrown by {@link CloudBrowser.wait} / {@link CloudBrowser.waitAny}
121
+ * when no condition matched before the deadline. `conditions` holds the
122
+ * per-condition breakdown (same order/length as the conditions passed in)
123
+ * explaining why each one never matched.
124
+ */
125
+ export class WaitError extends BrowserScaleError {
126
+ constructor(init) {
127
+ super(formatMessage("wait", init.code, init.message));
128
+ this.name = "WaitError";
129
+ this.code = init.code;
130
+ this.conditions = init.conditions;
131
+ this.result = init.result;
132
+ }
133
+ }
134
+ function formatMessage(action, code, message) {
135
+ const base = `${action} failed: ${code}`;
136
+ return message ? `${base}: ${message}` : base;
137
+ }