craftdriver 1.3.0 → 1.5.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.
Files changed (132) hide show
  1. package/CHANGELOG.md +17 -3
  2. package/README.md +4 -1
  3. package/dist/cli/dispatcher.js +1 -1
  4. package/dist/cli/dispatcher.js.map +1 -1
  5. package/dist/cli/parseArgs.d.ts +2 -2
  6. package/dist/cli/parseArgs.d.ts.map +1 -1
  7. package/dist/cli/parseArgs.js +1 -1
  8. package/dist/index.d.ts +7 -1
  9. package/dist/index.d.ts.map +1 -1
  10. package/dist/index.js +5 -0
  11. package/dist/index.js.map +1 -1
  12. package/dist/lib/bidi/storage.d.ts +13 -0
  13. package/dist/lib/bidi/storage.d.ts.map +1 -1
  14. package/dist/lib/bidi/storage.js +81 -32
  15. package/dist/lib/bidi/storage.js.map +1 -1
  16. package/dist/lib/browser.d.ts +173 -21
  17. package/dist/lib/browser.d.ts.map +1 -1
  18. package/dist/lib/browser.js +519 -210
  19. package/dist/lib/browser.js.map +1 -1
  20. package/dist/lib/browserContext.d.ts +2 -2
  21. package/dist/lib/browserContext.d.ts.map +1 -1
  22. package/dist/lib/browserContext.js +1 -1
  23. package/dist/lib/builder.d.ts +4 -1
  24. package/dist/lib/builder.d.ts.map +1 -1
  25. package/dist/lib/builder.js +20 -2
  26. package/dist/lib/builder.js.map +1 -1
  27. package/dist/lib/capabilities.d.ts +45 -0
  28. package/dist/lib/capabilities.d.ts.map +1 -0
  29. package/dist/lib/capabilities.js +103 -0
  30. package/dist/lib/capabilities.js.map +1 -0
  31. package/dist/lib/chrome.d.ts +7 -2
  32. package/dist/lib/chrome.d.ts.map +1 -1
  33. package/dist/lib/chrome.js +10 -1
  34. package/dist/lib/chrome.js.map +1 -1
  35. package/dist/lib/driver.d.ts +16 -1
  36. package/dist/lib/driver.d.ts.map +1 -1
  37. package/dist/lib/driver.js +64 -0
  38. package/dist/lib/driver.js.map +1 -1
  39. package/dist/lib/driverManager.d.ts +120 -0
  40. package/dist/lib/driverManager.d.ts.map +1 -1
  41. package/dist/lib/driverManager.js +289 -10
  42. package/dist/lib/driverManager.js.map +1 -1
  43. package/dist/lib/electron.d.ts +60 -0
  44. package/dist/lib/electron.d.ts.map +1 -0
  45. package/dist/lib/electron.js +85 -0
  46. package/dist/lib/electron.js.map +1 -0
  47. package/dist/lib/electronDeeplink.d.ts +22 -0
  48. package/dist/lib/electronDeeplink.d.ts.map +1 -0
  49. package/dist/lib/electronDeeplink.js +118 -0
  50. package/dist/lib/electronDeeplink.js.map +1 -0
  51. package/dist/lib/electronDiagnostics.d.ts +49 -0
  52. package/dist/lib/electronDiagnostics.d.ts.map +1 -0
  53. package/dist/lib/electronDiagnostics.js +195 -0
  54. package/dist/lib/electronDiagnostics.js.map +1 -0
  55. package/dist/lib/electronDialogMock.d.ts +51 -0
  56. package/dist/lib/electronDialogMock.d.ts.map +1 -0
  57. package/dist/lib/electronDialogMock.js +106 -0
  58. package/dist/lib/electronDialogMock.js.map +1 -0
  59. package/dist/lib/electronFuses.d.ts +13 -0
  60. package/dist/lib/electronFuses.d.ts.map +1 -0
  61. package/dist/lib/electronFuses.js +118 -0
  62. package/dist/lib/electronFuses.js.map +1 -0
  63. package/dist/lib/electronMainBridge.d.ts +28 -0
  64. package/dist/lib/electronMainBridge.d.ts.map +1 -0
  65. package/dist/lib/electronMainBridge.js +270 -0
  66. package/dist/lib/electronMainBridge.js.map +1 -0
  67. package/dist/lib/electronMainLogs.d.ts +81 -0
  68. package/dist/lib/electronMainLogs.d.ts.map +1 -0
  69. package/dist/lib/electronMainLogs.js +176 -0
  70. package/dist/lib/electronMainLogs.js.map +1 -0
  71. package/dist/lib/electronMock.d.ts +52 -0
  72. package/dist/lib/electronMock.d.ts.map +1 -0
  73. package/dist/lib/electronMock.js +96 -0
  74. package/dist/lib/electronMock.js.map +1 -0
  75. package/dist/lib/electronRemote.d.ts +106 -0
  76. package/dist/lib/electronRemote.d.ts.map +1 -0
  77. package/dist/lib/electronRemote.js +406 -0
  78. package/dist/lib/electronRemote.js.map +1 -0
  79. package/dist/lib/electronVersions.d.ts +34 -0
  80. package/dist/lib/electronVersions.d.ts.map +1 -0
  81. package/dist/lib/electronVersions.js +90 -0
  82. package/dist/lib/electronVersions.js.map +1 -0
  83. package/dist/lib/errors.d.ts +27 -0
  84. package/dist/lib/errors.d.ts.map +1 -1
  85. package/dist/lib/errors.js +27 -0
  86. package/dist/lib/errors.js.map +1 -1
  87. package/dist/lib/launchTarget.d.ts +30 -0
  88. package/dist/lib/launchTarget.d.ts.map +1 -0
  89. package/dist/lib/launchTarget.js +174 -0
  90. package/dist/lib/launchTarget.js.map +1 -0
  91. package/dist/lib/page.d.ts +1 -0
  92. package/dist/lib/page.d.ts.map +1 -1
  93. package/dist/lib/page.js +1 -1
  94. package/dist/lib/page.js.map +1 -1
  95. package/dist/lib/safari.d.ts +90 -0
  96. package/dist/lib/safari.d.ts.map +1 -0
  97. package/dist/lib/safari.js +136 -0
  98. package/dist/lib/safari.js.map +1 -0
  99. package/dist/lib/service.d.ts +21 -0
  100. package/dist/lib/service.d.ts.map +1 -1
  101. package/dist/lib/service.js +94 -6
  102. package/dist/lib/service.js.map +1 -1
  103. package/dist/lib/tracing.d.ts +1 -1
  104. package/dist/lib/tracing.d.ts.map +1 -1
  105. package/dist/lib/tracing.js.map +1 -1
  106. package/dist/lib/types.d.ts +41 -0
  107. package/dist/lib/types.d.ts.map +1 -1
  108. package/dist/lib/vibiumTrace.d.ts +1 -1
  109. package/dist/lib/vibiumTrace.d.ts.map +1 -1
  110. package/dist/lib/webelement.d.ts.map +1 -1
  111. package/dist/lib/webelement.js +118 -2
  112. package/dist/lib/webelement.js.map +1 -1
  113. package/docs/api-reference.md +39 -2
  114. package/docs/browser-api.md +7 -1
  115. package/docs/driver-configuration.md +54 -0
  116. package/docs/electron.md +419 -0
  117. package/docs/error-codes.md +5 -0
  118. package/docs/getting-started.md +30 -10
  119. package/docs/index.md +5 -1
  120. package/docs/public/examples/displayed.html +86 -0
  121. package/docs/recipes/electron-app-from-another-repo.md +136 -0
  122. package/docs/recipes/electron-deep-link.md +117 -0
  123. package/docs/recipes/electron-mock-apis.md +88 -0
  124. package/docs/recipes/electron-native-dialog.md +105 -0
  125. package/docs/recipes.md +28 -9
  126. package/docs/safari.md +118 -0
  127. package/docs/standards.md +13 -0
  128. package/docs/why-craftdriver.md +1 -1
  129. package/docs/zero-config-drivers.md +12 -0
  130. package/package.json +7 -1
  131. package/skills/craftdriver/SKILL.md +4 -1
  132. package/skills/craftdriver/cheatsheet.md +4 -1
@@ -0,0 +1,406 @@
1
+ /**
2
+ * `browser.electron` — the optional Electron **main-process** capability
3
+ * namespace. Deliberately not an `ElectronApp` class: the renderer stays on the
4
+ * ordinary `Browser` API; this adds only what the DOM surface can't reach.
5
+ *
6
+ * `executeMain(fn, ...args)` runs `fn(electron, ...args)` in the app's main
7
+ * process (Node context, full `electron` module) and returns its JSON-
8
+ * serializable result. It's named `executeMain` — not `execute` — so the process
9
+ * boundary is loud at every call site: `browser.evaluate()` runs in the renderer,
10
+ * `browser.electron.executeMain()` in the powerful main process. (WDIO calls this
11
+ * `browser.electron.execute`; the rename is a one-time migration cost.)
12
+ */
13
+ import { CraftdriverError, ErrorCode } from './errors.js';
14
+ import { ElectronMainBridge } from './electronMainBridge.js';
15
+ import { ElectronMainLogMonitor, } from './electronMainLogs.js';
16
+ import { ElectronDialogMockHandle, validateDialogResult, } from './electronDialogMock.js';
17
+ import { ElectronMockHandle, validateMockTarget, } from './electronMock.js';
18
+ import { executeDeeplinkCommand, getPlatformCommand, resolveDeeplinkUrl, validateDeeplinkUrl, } from './electronDeeplink.js';
19
+ import { readInspectArgumentsFuse } from './electronFuses.js';
20
+ function assertJsonSerializable(value, path = 'arg', stack = new Set()) {
21
+ if (value === null || typeof value === 'string' || typeof value === 'boolean')
22
+ return;
23
+ if (typeof value === 'number') {
24
+ if (Number.isFinite(value))
25
+ return;
26
+ throw new CraftdriverError(ErrorCode.EVAL_BAD_ARG, `executeMain(fn, ...args): ${path} must be a finite JSON number.`, { detail: { path, argType: 'number' } });
27
+ }
28
+ if (Array.isArray(value)) {
29
+ if (stack.has(value)) {
30
+ throw new CraftdriverError(ErrorCode.EVAL_BAD_ARG, `executeMain(fn, ...args): ${path} contains a circular reference.`, { detail: { path, argType: 'array' } });
31
+ }
32
+ stack.add(value);
33
+ try {
34
+ value.forEach((item, index) => assertJsonSerializable(item, `${path}[${index}]`, stack));
35
+ }
36
+ finally {
37
+ stack.delete(value);
38
+ }
39
+ return;
40
+ }
41
+ if (typeof value === 'object') {
42
+ const proto = Object.getPrototypeOf(value);
43
+ if (proto !== Object.prototype && proto !== null) {
44
+ throw new CraftdriverError(ErrorCode.EVAL_BAD_ARG, `executeMain(fn, ...args): ${path} must be a plain JSON object.`, { detail: { path, argType: proto?.constructor?.name ?? 'object' } });
45
+ }
46
+ const obj = value;
47
+ if (stack.has(obj)) {
48
+ throw new CraftdriverError(ErrorCode.EVAL_BAD_ARG, `executeMain(fn, ...args): ${path} contains a circular reference.`, { detail: { path, argType: 'object' } });
49
+ }
50
+ stack.add(obj);
51
+ try {
52
+ for (const [key, item] of Object.entries(obj)) {
53
+ assertJsonSerializable(item, `${path}.${key}`, stack);
54
+ }
55
+ }
56
+ finally {
57
+ stack.delete(obj);
58
+ }
59
+ return;
60
+ }
61
+ throw new CraftdriverError(ErrorCode.EVAL_BAD_ARG, `executeMain(fn, ...args): ${path} of type "${typeof value}" is not JSON-serializable.`, { detail: { path, argType: typeof value } });
62
+ }
63
+ /**
64
+ * Run code in the Electron main process via `browser.electron.executeMain`.
65
+ * Named `executeMain` (not WDIO's `execute`) so the process boundary is loud:
66
+ * `browser.evaluate()` is the renderer, `executeMain()` the main process.
67
+ */
68
+ export class ElectronRemote {
69
+ #bridge;
70
+ #connect;
71
+ #appBinaryPath;
72
+ #userDataDir;
73
+ #mainLogs = new ElectronMainLogMonitor();
74
+ #dialogMocks = new Map();
75
+ #apiMocks = new Map();
76
+ /** `connect` is undefined for non-Electron sessions or when `mainProcess` wasn't enabled. */
77
+ constructor(connect, options) {
78
+ this.#connect = connect;
79
+ this.#appBinaryPath = options?.appBinaryPath;
80
+ }
81
+ /**
82
+ * Captured **main-process** console output and errors — the main-process
83
+ * counterpart to `browser.logs`. Populated from launch when the session was
84
+ * started with `electron: { mainProcess: true }` (empty otherwise). See
85
+ * {@link ElectronMainLogMonitor}.
86
+ *
87
+ * ```ts
88
+ * await browser.electron.executeMain((electron) => console.log('ready', electron.app.getName()));
89
+ * const [entry] = browser.electron.mainLogs.getLogs();
90
+ * ```
91
+ */
92
+ get mainLogs() {
93
+ return this.#mainLogs;
94
+ }
95
+ /**
96
+ * Open the main-process bridge now (rather than lazily on first `executeMain`)
97
+ * so `mainLogs` captures from launch. No-op without a main-process inspector;
98
+ * best-effort — the caller (Browser.launch) swallows failures so a disabled
99
+ * inspector fuse never breaks renderer automation.
100
+ */
101
+ async connect() {
102
+ if (!this.#connect)
103
+ return;
104
+ await this.#ensureConnected();
105
+ }
106
+ /**
107
+ * Run `fn` in the Electron **main process**. `fn` receives the `electron`
108
+ * module first, then your `args` (which must be JSON-serializable). The return
109
+ * value is passed back by value, so it must be JSON-serializable too.
110
+ *
111
+ * ```ts
112
+ * const version = await browser.electron.executeMain(
113
+ * (electron) => electron.app.getVersion(),
114
+ * );
115
+ * ```
116
+ */
117
+ async executeMain(fn, ...args) {
118
+ if (!this.#connect) {
119
+ throw new CraftdriverError(ErrorCode.ELECTRON_MAIN_UNAVAILABLE, 'Electron main-process access is not available for this session.', {
120
+ hint: 'Launch with `electron: { mainProcess: true }` to enable it. Browser sessions, and ' +
121
+ 'Electron launches without that flag, do not expose the main process.',
122
+ });
123
+ }
124
+ if (typeof fn !== 'function') {
125
+ throw new CraftdriverError(ErrorCode.INVALID_ARGUMENT, 'executeMain(fn, ...args): fn must be a function.');
126
+ }
127
+ // Args cross the wire as a JSON literal. Validate recursively instead of
128
+ // relying on JSON.stringify(), which silently turns values like undefined,
129
+ // functions, Symbols, NaN, and Infinity into null inside arrays/objects.
130
+ args.forEach((arg, index) => assertJsonSerializable(arg, `arg[${index}]`));
131
+ const bridge = await this.#ensureConnected();
132
+ return bridge.executeMain(fn.toString(), args);
133
+ }
134
+ /**
135
+ * Replace any `electron.<api>.<fn>` **main-process** method with a scripted
136
+ * return value and call recorder. The general primitive behind the typed
137
+ * {@link mockDialog} convenience — reach for it for `shell.openExternal`,
138
+ * `app.getPath`, `safeStorage.encryptString`, and other Electron APIs.
139
+ *
140
+ * The app is not modified: the replacement lives in its main process for this
141
+ * session and is restored by `mock.restore()` or `browser.quit()`. The scripted
142
+ * value is returned **as-is** (not wrapped in a Promise), so it works for both
143
+ * synchronous methods and `await`ed asynchronous ones. Provide the resolved
144
+ * value for an async method; recorded call args and the return value must be
145
+ * JSON-serializable.
146
+ *
147
+ * ```ts
148
+ * const openExternal = await browser.electron.mock('shell', 'openExternal', true);
149
+ * await browser.click(By.testId('open-docs'));
150
+ * expect(await openExternal.getCalls()).toEqual([{ args: ['https://example.com/docs'] }]);
151
+ * ```
152
+ */
153
+ async mock(api, fn, returnValue) {
154
+ validateMockTarget(api, fn);
155
+ const key = `${api}.${fn}`;
156
+ if (this.#apiMocks.has(key)) {
157
+ throw new CraftdriverError(ErrorCode.STATE_INVALID, `electron.${key} is already mocked. Restore that mock before replacing it.`);
158
+ }
159
+ const id = `${Date.now()}-${Math.random().toString(36).slice(2)}`;
160
+ // `undefined` can't cross executeMain's JSON-arg validation, so carry a
161
+ // presence flag and a JSON-safe placeholder; the callback restores undefined.
162
+ const hasResult = returnValue !== undefined;
163
+ await this.executeMain((electron, apiName, funcName, mockId, resultPresent, scriptedResult) => {
164
+ const registryKey = Symbol.for('craftdriver.electron.apiMocks');
165
+ const globals = globalThis;
166
+ const registry = (globals[registryKey] ??= Object.create(null));
167
+ const entryKey = `${apiName}.${funcName}`;
168
+ if (registry[entryKey])
169
+ throw new Error(`Mock ${entryKey} is already active.`);
170
+ const namespace = electron[apiName];
171
+ if (!namespace || typeof namespace !== 'object') {
172
+ throw new Error(`electron.${apiName} is not available in this Electron build.`);
173
+ }
174
+ const original = namespace[funcName];
175
+ if (typeof original !== 'function') {
176
+ throw new Error(`electron.${entryKey} is not a function in this Electron build.`);
177
+ }
178
+ const jsonSafe = (value, seen = new WeakSet()) => {
179
+ if (value === null || typeof value === 'string' || typeof value === 'boolean')
180
+ return value;
181
+ if (typeof value === 'number')
182
+ return Number.isFinite(value) ? value : String(value);
183
+ if (typeof value !== 'object')
184
+ return `[${typeof value}]`;
185
+ if (seen.has(value))
186
+ return '[Circular]';
187
+ seen.add(value);
188
+ try {
189
+ if (Array.isArray(value))
190
+ return value.map((item) => jsonSafe(item, seen));
191
+ const proto = Object.getPrototypeOf(value);
192
+ if (proto !== Object.prototype && proto !== null) {
193
+ return `[${proto?.constructor?.name ?? 'Object'}]`;
194
+ }
195
+ const copy = {};
196
+ for (const [name, item] of Object.entries(value))
197
+ copy[name] = jsonSafe(item, seen);
198
+ return copy;
199
+ }
200
+ finally {
201
+ seen.delete(value);
202
+ }
203
+ };
204
+ const entry = {
205
+ id: mockId,
206
+ original: original,
207
+ calls: [],
208
+ result: resultPresent ? scriptedResult : undefined,
209
+ replacement: undefined,
210
+ };
211
+ const replacement = (...args) => {
212
+ entry.calls.push({ args: args.map((a) => jsonSafe(a)) });
213
+ // Return a fresh clone so a caller mutating the result can't corrupt the
214
+ // scripted value for later calls. Returned as-is (sync), so both sync and
215
+ // awaited-async callers see the value.
216
+ return entry.result === undefined ? undefined : JSON.parse(JSON.stringify(entry.result));
217
+ };
218
+ entry.replacement = replacement;
219
+ registry[entryKey] = entry;
220
+ namespace[funcName] = replacement;
221
+ }, api, fn, id, hasResult, hasResult ? returnValue : null);
222
+ const mock = new ElectronMockHandle(this, api, fn, id, () => {
223
+ this.#apiMocks.delete(key);
224
+ });
225
+ this.#apiMocks.set(key, mock);
226
+ return mock;
227
+ }
228
+ /**
229
+ * Open a custom-protocol **deep link** (`myapp://…`) against the running app,
230
+ * exactly as the OS would when another app or the browser hands off the URL —
231
+ * so your app's real `open-url` (macOS) / `second-instance` (Windows, Linux)
232
+ * handler runs. Fire-and-forget: it resolves once the OS launcher is spawned;
233
+ * assert the effect through your app afterwards (e.g. `waitForLog`, a renderer
234
+ * assertion, or `executeMain`).
235
+ *
236
+ * Your app must register the protocol (`app.setAsDefaultProtocolClient(...)`)
237
+ * and take the single-instance lock. On Windows and Linux a raw deep link would
238
+ * spawn a *second* instance; craftdriver appends the running app's user-data dir
239
+ * as a `userData` query parameter so the second instance can route the URL to
240
+ * the test instance (auto-detected via the main process when available).
241
+ *
242
+ * ```ts
243
+ * await browser.electron.triggerDeeplink('myapp://open?file=test.txt');
244
+ * const entry = await browser.electron.mainLogs.waitForLog((l) => l.text.includes('open-url'));
245
+ * ```
246
+ */
247
+ async triggerDeeplink(url) {
248
+ const platform = process.platform;
249
+ // Validate before any detection work so a bad URL fails fast and identically
250
+ // on every platform.
251
+ validateDeeplinkUrl(url);
252
+ // Windows/Linux need the running app's user-data dir to route the URL to this
253
+ // instance; detect it once (best-effort) via the main process, then cache it.
254
+ let userDataDir = this.#userDataDir;
255
+ if (!userDataDir && (platform === 'win32' || platform === 'linux') && this.#connect) {
256
+ try {
257
+ userDataDir = await this.executeMain((electron) => electron.app.getPath('userData'));
258
+ this.#userDataDir = userDataDir;
259
+ }
260
+ catch {
261
+ // Fall through: without it the deep link may open a fresh instance. The
262
+ // command still runs; the caller's post-assertion will reveal a miss.
263
+ }
264
+ }
265
+ const finalUrl = resolveDeeplinkUrl(url, platform, userDataDir);
266
+ const { command, args } = getPlatformCommand(finalUrl, platform, this.#appBinaryPath);
267
+ await executeDeeplinkCommand(command, args);
268
+ }
269
+ async mockDialog(method, result) {
270
+ if (!['showOpenDialog', 'showSaveDialog', 'showMessageBox'].includes(method)) {
271
+ throw new CraftdriverError(ErrorCode.INVALID_ARGUMENT, `Unsupported Electron dialog method "${String(method)}".`, {
272
+ hint: 'Use showOpenDialog, showSaveDialog, or showMessageBox.',
273
+ detail: { method },
274
+ });
275
+ }
276
+ validateDialogResult(method, result);
277
+ if (this.#dialogMocks.has(method)) {
278
+ throw new CraftdriverError(ErrorCode.STATE_INVALID, `electron.dialog.${method} is already mocked. Restore that mock before replacing it.`);
279
+ }
280
+ const id = `${Date.now()}-${Math.random().toString(36).slice(2)}`;
281
+ await this.executeMain((electron, dialogMethod, mockId, scriptedResult) => {
282
+ const methodName = dialogMethod;
283
+ const key = Symbol.for('craftdriver.electron.dialogMocks');
284
+ const globals = globalThis;
285
+ const registry = (globals[key] ??= Object.create(null));
286
+ if (registry[methodName])
287
+ throw new Error(`Dialog mock ${methodName} is already active.`);
288
+ const dialog = electron
289
+ .dialog;
290
+ const original = dialog[methodName];
291
+ if (typeof original !== 'function') {
292
+ throw new Error(`electron.dialog.${methodName} is not available in this Electron build.`);
293
+ }
294
+ const entry = {
295
+ id: mockId,
296
+ original,
297
+ calls: [],
298
+ result: scriptedResult,
299
+ replacement: undefined,
300
+ };
301
+ const jsonSafe = (value, seen = new WeakSet()) => {
302
+ if (value === null || typeof value === 'string' || typeof value === 'boolean')
303
+ return value;
304
+ if (typeof value === 'number')
305
+ return Number.isFinite(value) ? value : String(value);
306
+ if (typeof value !== 'object')
307
+ return `[${typeof value}]`;
308
+ if (seen.has(value))
309
+ return '[Circular]';
310
+ seen.add(value);
311
+ try {
312
+ if (Array.isArray(value))
313
+ return value.map((item) => jsonSafe(item, seen));
314
+ const proto = Object.getPrototypeOf(value);
315
+ if (proto !== Object.prototype && proto !== null) {
316
+ return `[${proto?.constructor?.name ?? 'Object'}]`;
317
+ }
318
+ const copy = {};
319
+ for (const [name, item] of Object.entries(value))
320
+ copy[name] = jsonSafe(item, seen);
321
+ return copy;
322
+ }
323
+ finally {
324
+ seen.delete(value);
325
+ }
326
+ };
327
+ const replacement = (...args) => {
328
+ const options = args.length > 1 ? args[1] : args[0];
329
+ entry.calls.push({ options: jsonSafe(options) });
330
+ return Promise.resolve(JSON.parse(JSON.stringify(entry.result)));
331
+ };
332
+ entry.replacement = replacement;
333
+ registry[methodName] = entry;
334
+ dialog[methodName] = replacement;
335
+ }, method, id, result);
336
+ const mock = new ElectronDialogMockHandle(this, method, id, () => {
337
+ this.#dialogMocks.delete(method);
338
+ });
339
+ this.#dialogMocks.set(method, mock);
340
+ return mock;
341
+ }
342
+ async #ensureConnected() {
343
+ if (!this.#bridge) {
344
+ const bridge = new ElectronMainBridge(this.#connect.host, this.#connect.port);
345
+ try {
346
+ await bridge.connect();
347
+ // Route CDP Runtime events into the log monitor, then enable the domain.
348
+ // Order matters: the listener must be armed before Runtime.enable so the
349
+ // inspector's replayed console backlog is captured, not dropped.
350
+ bridge.onEvent((method, params) => {
351
+ if (method === 'Runtime.consoleAPICalled') {
352
+ this.#mainLogs.ingestConsoleEvent(params);
353
+ }
354
+ else if (method === 'Runtime.exceptionThrown') {
355
+ this.#mainLogs.ingestExceptionEvent(params);
356
+ }
357
+ });
358
+ await bridge.enableRuntime();
359
+ }
360
+ catch (error) {
361
+ await bridge.close().catch(() => { });
362
+ throw this.#enrichUnreachable(error);
363
+ }
364
+ this.#bridge = bridge;
365
+ }
366
+ return this.#bridge;
367
+ }
368
+ /**
369
+ * When the main-process inspector is unreachable, read the app's
370
+ * `EnableNodeCliInspectArguments` fuse: if it's provably disabled/removed, upgrade
371
+ * the generic "inspector unreachable" into a precise, actionable error. Any other
372
+ * status (enabled, or unreadable) leaves the original error — which already names
373
+ * the fuse as the likely cause — untouched.
374
+ */
375
+ #enrichUnreachable(error) {
376
+ if (!CraftdriverError.is(error, ErrorCode.ELECTRON_MAIN_UNAVAILABLE))
377
+ return error;
378
+ const status = readInspectArgumentsFuse(this.#appBinaryPath);
379
+ if (status !== 'disabled' && status !== 'removed')
380
+ return error;
381
+ return new CraftdriverError(ErrorCode.ELECTRON_MAIN_UNAVAILABLE, `This Electron build has the EnableNodeCliInspectArguments fuse ${status}, so its main ` +
382
+ 'process cannot be reached — browser.electron.executeMain / mock / mockDialog / mainLogs ' +
383
+ 'are unavailable. Renderer automation is unaffected.', {
384
+ cause: error,
385
+ hint: 'Package a test build with the EnableNodeCliInspectArguments fuse enabled (the default) ' +
386
+ 'before code signing; a disabled fuse cannot be changed after signing.',
387
+ detail: {
388
+ fuse: 'EnableNodeCliInspectArguments',
389
+ fuseStatus: status,
390
+ appBinaryPath: this.#appBinaryPath,
391
+ },
392
+ });
393
+ }
394
+ /** Close the underlying inspector connection. Called from `Browser.quit()`. */
395
+ async close() {
396
+ for (const mock of [...this.#dialogMocks.values(), ...this.#apiMocks.values()]) {
397
+ await mock.restore().catch(() => { });
398
+ }
399
+ this.#dialogMocks.clear();
400
+ this.#apiMocks.clear();
401
+ const bridge = this.#bridge;
402
+ this.#bridge = undefined;
403
+ await bridge?.close();
404
+ }
405
+ }
406
+ //# sourceMappingURL=electronRemote.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"electronRemote.js","sourceRoot":"","sources":["../../src/lib/electronRemote.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Electron → Chromium major-version map, used to resolve a matching
3
+ * Chrome-for-Testing chromedriver from an app's Electron version — so an Electron
4
+ * user can drop the `electron-chromedriver` dependency (see
5
+ * {@link resolveElectronChromeDriverInfo}).
6
+ *
7
+ * WHY A VENDORED MAP (not the `electron-to-chromium` package WDIO uses):
8
+ * craftdriver ships an intentionally tiny dependency surface, and Electron is an
9
+ * optional target — pulling a data package into every install (or making users
10
+ * install one) to serve a niche feature isn't worth it. The chromedriver
11
+ * downloader only needs the Chromium **major** to pick a compatible driver
12
+ * (`downloadChromedriver` matches within a major), and Electron bumps its
13
+ * Chromium major roughly quarterly, so this table is small and slow-moving.
14
+ *
15
+ * MAINTENANCE: add one row per new Electron major. Source of truth for a pair is
16
+ * the `electron-to-chromium` package or https://electronjs.org/headers/index.json
17
+ * (both list the exact Chromium each Electron release bundles). An unmapped
18
+ * version fails with actionable guidance rather than guessing, so a missing row
19
+ * is a clear error, never a wrong driver.
20
+ *
21
+ * COVERAGE NOTE: Chrome for Testing only publishes chromedriver for Chromium
22
+ * >= 115 (Electron >= 26), and a brand-new Chromium major can lag CfT by weeks.
23
+ * Mapping a version whose Chromium isn't in CfT yet still fails at download with
24
+ * CfT's own "no chromedriver found" error — pin `electron-chromedriver` or an
25
+ * explicit `chromedriverPath` for those.
26
+ */
27
+ /**
28
+ * Map an Electron version to the Chromium **major** it bundles, or `undefined`
29
+ * when the version is malformed or not in the vendored table. Pure — no I/O.
30
+ */
31
+ export declare function chromiumMajorForElectron(electronVersion: string): number | undefined;
32
+ /** The Electron majors this build knows how to map, ascending — for diagnostics. */
33
+ export declare function knownElectronMajors(): number[];
34
+ //# sourceMappingURL=electronVersions.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"electronVersions.d.ts","sourceRoot":"","sources":["../../src/lib/electronVersions.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAkDH;;;GAGG;AACH,wBAAgB,wBAAwB,CAAC,eAAe,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAIpF;AAED,oFAAoF;AACpF,wBAAgB,mBAAmB,IAAI,MAAM,EAAE,CAI9C"}
@@ -0,0 +1,90 @@
1
+ /**
2
+ * Electron → Chromium major-version map, used to resolve a matching
3
+ * Chrome-for-Testing chromedriver from an app's Electron version — so an Electron
4
+ * user can drop the `electron-chromedriver` dependency (see
5
+ * {@link resolveElectronChromeDriverInfo}).
6
+ *
7
+ * WHY A VENDORED MAP (not the `electron-to-chromium` package WDIO uses):
8
+ * craftdriver ships an intentionally tiny dependency surface, and Electron is an
9
+ * optional target — pulling a data package into every install (or making users
10
+ * install one) to serve a niche feature isn't worth it. The chromedriver
11
+ * downloader only needs the Chromium **major** to pick a compatible driver
12
+ * (`downloadChromedriver` matches within a major), and Electron bumps its
13
+ * Chromium major roughly quarterly, so this table is small and slow-moving.
14
+ *
15
+ * MAINTENANCE: add one row per new Electron major. Source of truth for a pair is
16
+ * the `electron-to-chromium` package or https://electronjs.org/headers/index.json
17
+ * (both list the exact Chromium each Electron release bundles). An unmapped
18
+ * version fails with actionable guidance rather than guessing, so a missing row
19
+ * is a clear error, never a wrong driver.
20
+ *
21
+ * COVERAGE NOTE: Chrome for Testing only publishes chromedriver for Chromium
22
+ * >= 115 (Electron >= 26), and a brand-new Chromium major can lag CfT by weeks.
23
+ * Mapping a version whose Chromium isn't in CfT yet still fails at download with
24
+ * CfT's own "no chromedriver found" error — pin `electron-chromedriver` or an
25
+ * explicit `chromedriverPath` for those.
26
+ */
27
+ /**
28
+ * Electron major → bundled Chromium major. Kept as majors because the CfT
29
+ * chromedriver selection is major-scoped; a driver is compatible across a
30
+ * Chromium major, so the exact build isn't needed to pick the right one.
31
+ */
32
+ const ELECTRON_MAJOR_TO_CHROMIUM_MAJOR = {
33
+ // Historical, CfT-covered range (Chromium >= 115). Verified against
34
+ // electron-to-chromium.
35
+ 26: 116,
36
+ 27: 118,
37
+ 28: 120,
38
+ 29: 122,
39
+ 30: 124,
40
+ 31: 126,
41
+ 32: 128,
42
+ 33: 130,
43
+ 34: 132,
44
+ 35: 134,
45
+ 36: 136,
46
+ 37: 138,
47
+ 38: 140,
48
+ // 39 verified live: Fiddler Everywhere 7.8 is Electron 39.8.6 / Chromium 142
49
+ // (read from its Electron Framework), driven end-to-end. 40–42 follow the exact
50
+ // +2-Chromium-major-per-Electron-major cadence this table holds across 26→43
51
+ // (37→138, 38→140, 39→142, … 43→150); re-verify against electron-to-chromium
52
+ // when an app pins one.
53
+ 39: 142,
54
+ 40: 144,
55
+ 41: 146,
56
+ 42: 148,
57
+ // craftdriver's own compatibility target (see docs/electron.md): Electron
58
+ // 43.1.0 bundles Chromium 150. Verified end-to-end: CfT publishes a matching
59
+ // chromedriver (150.0.7871.115), so `electron: { version: '43.1.0' }` resolves
60
+ // a matching driver with no electron-chromedriver dependency.
61
+ 43: 150,
62
+ };
63
+ /**
64
+ * Parse the leading integer major from an Electron version string
65
+ * (`'43.1.0'` → 43, `'37'` → 37). Returns `undefined` for anything without a
66
+ * numeric leading component.
67
+ */
68
+ function electronMajor(version) {
69
+ const match = /^\s*(\d+)/.exec(version);
70
+ if (!match)
71
+ return undefined;
72
+ return Number.parseInt(match[1], 10);
73
+ }
74
+ /**
75
+ * Map an Electron version to the Chromium **major** it bundles, or `undefined`
76
+ * when the version is malformed or not in the vendored table. Pure — no I/O.
77
+ */
78
+ export function chromiumMajorForElectron(electronVersion) {
79
+ const major = electronMajor(electronVersion);
80
+ if (major === undefined)
81
+ return undefined;
82
+ return ELECTRON_MAJOR_TO_CHROMIUM_MAJOR[major];
83
+ }
84
+ /** The Electron majors this build knows how to map, ascending — for diagnostics. */
85
+ export function knownElectronMajors() {
86
+ return Object.keys(ELECTRON_MAJOR_TO_CHROMIUM_MAJOR)
87
+ .map((k) => Number.parseInt(k, 10))
88
+ .sort((a, b) => a - b);
89
+ }
90
+ //# sourceMappingURL=electronVersions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"electronVersions.js","sourceRoot":"","sources":["../../src/lib/electronVersions.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAEH;;;;GAIG;AACH,MAAM,gCAAgC,GAAqC;IACzE,oEAAoE;IACpE,wBAAwB;IACxB,EAAE,EAAE,GAAG;IACP,EAAE,EAAE,GAAG;IACP,EAAE,EAAE,GAAG;IACP,EAAE,EAAE,GAAG;IACP,EAAE,EAAE,GAAG;IACP,EAAE,EAAE,GAAG;IACP,EAAE,EAAE,GAAG;IACP,EAAE,EAAE,GAAG;IACP,EAAE,EAAE,GAAG;IACP,EAAE,EAAE,GAAG;IACP,EAAE,EAAE,GAAG;IACP,EAAE,EAAE,GAAG;IACP,EAAE,EAAE,GAAG;IACP,6EAA6E;IAC7E,gFAAgF;IAChF,6EAA6E;IAC7E,6EAA6E;IAC7E,wBAAwB;IACxB,EAAE,EAAE,GAAG;IACP,EAAE,EAAE,GAAG;IACP,EAAE,EAAE,GAAG;IACP,EAAE,EAAE,GAAG;IACP,0EAA0E;IAC1E,6EAA6E;IAC7E,+EAA+E;IAC/E,8DAA8D;IAC9D,EAAE,EAAE,GAAG;CACR,CAAC;AAEF;;;;GAIG;AACH,SAAS,aAAa,CAAC,OAAe;IACpC,MAAM,KAAK,GAAG,WAAW,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACxC,IAAI,CAAC,KAAK;QAAE,OAAO,SAAS,CAAC;IAC7B,OAAO,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;AACvC,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,wBAAwB,CAAC,eAAuB;IAC9D,MAAM,KAAK,GAAG,aAAa,CAAC,eAAe,CAAC,CAAC;IAC7C,IAAI,KAAK,KAAK,SAAS;QAAE,OAAO,SAAS,CAAC;IAC1C,OAAO,gCAAgC,CAAC,KAAK,CAAC,CAAC;AACjD,CAAC;AAED,oFAAoF;AACpF,MAAM,UAAU,mBAAmB;IACjC,OAAO,MAAM,CAAC,IAAI,CAAC,gCAAgC,CAAC;SACjD,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;SAClC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;AAC3B,CAAC"}
@@ -39,6 +39,33 @@ export declare const ErrorCode: {
39
39
  readonly STATE_INVALID: "STATE_INVALID";
40
40
  /** Driver-level / transport-level failure surfaced to the caller. */
41
41
  readonly DRIVER_ERROR: "DRIVER_ERROR";
42
+ /**
43
+ * The resolved chromedriver doesn't match the Electron app before a session is
44
+ * created — wrong bundled-Chromium major or wrong CPU arch. `detail.kind`
45
+ * distinguishes `'chromium-major'` from `'arch'`.
46
+ */
47
+ readonly ELECTRON_DRIVER_MISMATCH: "ELECTRON_DRIVER_MISMATCH";
48
+ /**
49
+ * The Electron app process exited during session creation ("Chrome instance
50
+ * exited"). `detail`/`hint` carry the diagnosed likely cause (macOS
51
+ * signing/Gatekeeper, Linux sandbox) plus the chromedriver output tail.
52
+ */
53
+ readonly ELECTRON_LAUNCH_FAILED: "ELECTRON_LAUNCH_FAILED";
54
+ /**
55
+ * `browser.electron.executeMain(...)` couldn't reach the app's main process —
56
+ * main-process access wasn't enabled (`electron: { mainProcess: true }`), the
57
+ * session isn't an Electron one, or the Node inspector is unavailable (e.g. the
58
+ * `EnableNodeCliInspectArguments` fuse is disabled). `hint` names the fix.
59
+ */
60
+ readonly ELECTRON_MAIN_UNAVAILABLE: "ELECTRON_MAIN_UNAVAILABLE";
61
+ /** The `executeMain(...)` callback threw inside the Electron main process. */
62
+ readonly ELECTRON_MAIN_THREW: "ELECTRON_MAIN_THREW";
63
+ /**
64
+ * `browser.electron.triggerDeeplink(url)` could not open the custom-protocol URL —
65
+ * an invalid/`http(s)`/`file` URL (use {@link INVALID_ARGUMENT}'s sibling check),
66
+ * an unsupported platform, or the OS `open`/`gio`/`rundll32` launcher failed.
67
+ */
68
+ readonly ELECTRON_DEEPLINK_FAILED: "ELECTRON_DEEPLINK_FAILED";
42
69
  };
43
70
  export type ErrorCodeName = keyof typeof ErrorCode;
44
71
  export type ErrorCodeValue = (typeof ErrorCode)[ErrorCodeName];
@@ -1 +1 @@
1
- {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/lib/errors.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,eAAO,MAAM,SAAS;IACpB,+DAA+D;;IAE/D,yEAAyE;;IAEzE,wGAAwG;;IAExG,kEAAkE;;IAElE,0EAA0E;;IAE1E,kEAAkE;;IAElE,2DAA2D;;IAE3D,4DAA4D;;IAE5D,2DAA2D;;IAE3D,iDAAiD;;IAEjD,iFAAiF;;IAEjF,6EAA6E;;IAE7E,uGAAuG;;IAEvG,kFAAkF;;IAElF,qEAAqE;;CAE7D,CAAC;AAEX,MAAM,MAAM,aAAa,GAAG,MAAM,OAAO,SAAS,CAAC;AACnD,MAAM,MAAM,cAAc,GAAG,CAAC,OAAO,SAAS,CAAC,CAAC,aAAa,CAAC,CAAC;AAE/D,MAAM,WAAW,uBAAuB;IACtC,wDAAwD;IACxD,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACjC,8DAA8D;IAC9D,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,kEAAkE;IAClE,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED;;;;;;;;;GASG;AACH,qBAAa,gBAAiB,SAAQ,KAAK;IACzC,QAAQ,CAAC,IAAI,EAAE,cAAc,CAAC;IAC9B,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC1C,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;gBAEX,IAAI,EAAE,cAAc,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,uBAAuB;IAQpF,wDAAwD;IACxD,MAAM,CAAC,EAAE,CAAC,GAAG,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,cAAc,GAAG,GAAG,IAAI,gBAAgB;CAIxE;AAqBD,wBAAsB,gBAAgB,CAAC,CAAC,EACtC,QAAQ,EAAE,QAAQ,EAClB,MAAM,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GACvB,OAAO,CAAC,CAAC,CAAC,CAQZ"}
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/lib/errors.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,eAAO,MAAM,SAAS;IACpB,+DAA+D;;IAE/D,yEAAyE;;IAEzE,wGAAwG;;IAExG,kEAAkE;;IAElE,0EAA0E;;IAE1E,kEAAkE;;IAElE,2DAA2D;;IAE3D,4DAA4D;;IAE5D,2DAA2D;;IAE3D,iDAAiD;;IAEjD,iFAAiF;;IAEjF,6EAA6E;;IAE7E,uGAAuG;;IAEvG,kFAAkF;;IAElF,qEAAqE;;IAErE;;;;OAIG;;IAEH;;;;OAIG;;IAEH;;;;;OAKG;;IAEH,8EAA8E;;IAE9E;;;;OAIG;;CAEK,CAAC;AAEX,MAAM,MAAM,aAAa,GAAG,MAAM,OAAO,SAAS,CAAC;AACnD,MAAM,MAAM,cAAc,GAAG,CAAC,OAAO,SAAS,CAAC,CAAC,aAAa,CAAC,CAAC;AAE/D,MAAM,WAAW,uBAAuB;IACtC,wDAAwD;IACxD,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACjC,8DAA8D;IAC9D,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,kEAAkE;IAClE,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED;;;;;;;;;GASG;AACH,qBAAa,gBAAiB,SAAQ,KAAK;IACzC,QAAQ,CAAC,IAAI,EAAE,cAAc,CAAC;IAC9B,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC1C,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;gBAEX,IAAI,EAAE,cAAc,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,uBAAuB;IAQpF,wDAAwD;IACxD,MAAM,CAAC,EAAE,CAAC,GAAG,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,cAAc,GAAG,GAAG,IAAI,gBAAgB;CAIxE;AAqBD,wBAAsB,gBAAgB,CAAC,CAAC,EACtC,QAAQ,EAAE,QAAQ,EAClB,MAAM,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GACvB,OAAO,CAAC,CAAC,CAAC,CAQZ"}
@@ -39,6 +39,33 @@ export const ErrorCode = {
39
39
  STATE_INVALID: 'STATE_INVALID',
40
40
  /** Driver-level / transport-level failure surfaced to the caller. */
41
41
  DRIVER_ERROR: 'DRIVER_ERROR',
42
+ /**
43
+ * The resolved chromedriver doesn't match the Electron app before a session is
44
+ * created — wrong bundled-Chromium major or wrong CPU arch. `detail.kind`
45
+ * distinguishes `'chromium-major'` from `'arch'`.
46
+ */
47
+ ELECTRON_DRIVER_MISMATCH: 'ELECTRON_DRIVER_MISMATCH',
48
+ /**
49
+ * The Electron app process exited during session creation ("Chrome instance
50
+ * exited"). `detail`/`hint` carry the diagnosed likely cause (macOS
51
+ * signing/Gatekeeper, Linux sandbox) plus the chromedriver output tail.
52
+ */
53
+ ELECTRON_LAUNCH_FAILED: 'ELECTRON_LAUNCH_FAILED',
54
+ /**
55
+ * `browser.electron.executeMain(...)` couldn't reach the app's main process —
56
+ * main-process access wasn't enabled (`electron: { mainProcess: true }`), the
57
+ * session isn't an Electron one, or the Node inspector is unavailable (e.g. the
58
+ * `EnableNodeCliInspectArguments` fuse is disabled). `hint` names the fix.
59
+ */
60
+ ELECTRON_MAIN_UNAVAILABLE: 'ELECTRON_MAIN_UNAVAILABLE',
61
+ /** The `executeMain(...)` callback threw inside the Electron main process. */
62
+ ELECTRON_MAIN_THREW: 'ELECTRON_MAIN_THREW',
63
+ /**
64
+ * `browser.electron.triggerDeeplink(url)` could not open the custom-protocol URL —
65
+ * an invalid/`http(s)`/`file` URL (use {@link INVALID_ARGUMENT}'s sibling check),
66
+ * an unsupported platform, or the OS `open`/`gio`/`rundll32` launcher failed.
67
+ */
68
+ ELECTRON_DEEPLINK_FAILED: 'ELECTRON_DEEPLINK_FAILED',
42
69
  };
43
70
  /**
44
71
  * Base class for every error thrown from the public API.