@allwright.dev/core 0.1.19 → 0.1.21

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -51,7 +51,7 @@ Paths passed to `setFiles` and `saveAs` belong to the test process, even when
51
51
  the Allwright server is remote. Android apps support the same `fileChooser` and
52
52
  `download` hook shape; Android `newPage` hooks are not applicable.
53
53
 
54
- Runnable examples live in [examples/web-basic.ts](./examples/web-basic.ts) and [examples/android-basic.ts](./examples/android-basic.ts).
54
+ Runnable examples live in [examples/web-basic.ts](./examples/web-basic.ts), [examples/android-basic.ts](./examples/android-basic.ts), and [examples/ios-basic.ts](./examples/ios-basic.ts).
55
55
 
56
56
  Shared config files are stack-agnostic and can live in `allwright.config.yaml` or `allwright.config.json`.
57
57
  The shared schema lives at the repo root in `allwright.schema.json`.
@@ -104,7 +104,7 @@ const value = await page.locator('input, textarea').inputValue();
104
104
  const options = await page.locator('select').selectedOptions(); // [{ value, label, index }]
105
105
  const selectedText = await page.locator('textarea').selectedText();
106
106
  const checked = await page.locator('input[type=checkbox]').isChecked();
107
- const text = await page.locator('h1').innerText(); // { selector, text, note }
107
+ const text = await page.locator('h1').innerText(); // string
108
108
  const attribute = await page.locator('a').getAttribute('href');
109
109
  const box = await page.locator('button').boundingBox(); // { x, y, width, height }
110
110
  ```
package/dist/bootstrap.js CHANGED
@@ -12,7 +12,7 @@ const ALLWRIGHT_HOME_ENV_VAR = "ALLWRIGHT_HOME";
12
12
  const ALLWRIGHT_REPOSITORY_ENV_VAR = "ALLWRIGHT_REPOSITORY";
13
13
  const ALLWRIGHT_VERSION_ENV_VAR = "ALLWRIGHT_VERSION";
14
14
  const DEFAULT_RELEASE_REPOSITORY = "allwright-dev/allwright";
15
- const DEFAULT_RELEASE_VERSION = "0.1.19";
15
+ const DEFAULT_RELEASE_VERSION = "0.1.21";
16
16
  const STARTUP_TIMEOUT_MS = 20_000;
17
17
  const PING_TIMEOUT_MS = 1_000;
18
18
  const PROTO_ROOT = fileURLToPath(new URL("../proto/", import.meta.url));
@@ -0,0 +1,2 @@
1
+ import type { DesktopSurfaceNamespace } from "./types.js";
2
+ export declare const desktop: DesktopSurfaceNamespace;
@@ -0,0 +1,73 @@
1
+ import { createBrowserSessionHandle, getRuntime } from "./runtime.js";
2
+ import { MobileAndroidAppImpl } from "./mobile.js";
3
+ function retryOptions(timeoutMs) {
4
+ return timeoutMs === undefined ? undefined : { timeoutMs };
5
+ }
6
+ class DesktopMacImpl {
7
+ sessionId;
8
+ surfaceSessionId;
9
+ runtime;
10
+ stream;
11
+ queue;
12
+ #closed = false;
13
+ #currentApp;
14
+ constructor(sessionId, surfaceSessionId, runtime, stream, queue, initialAppSessionId) {
15
+ this.sessionId = sessionId;
16
+ this.surfaceSessionId = surfaceSessionId;
17
+ this.runtime = runtime;
18
+ this.stream = stream;
19
+ this.queue = queue;
20
+ this.#currentApp = new MobileAndroidAppImpl(runtime, surfaceSessionId, initialAppSessionId);
21
+ }
22
+ app() {
23
+ return this.#currentApp;
24
+ }
25
+ async launch(options) {
26
+ if (this.#closed)
27
+ throw new Error(`macOS desktop session ${this.sessionId} is closed`);
28
+ this.stream.write({
29
+ launchDesktopApp: {
30
+ appId: options.appId,
31
+ terminateRunning: options.terminateRunning ?? false,
32
+ retryOptions: retryOptions(options.timeoutMs),
33
+ },
34
+ });
35
+ while (true) {
36
+ const event = await this.queue.next();
37
+ if (event.desktopAppLaunched?.appSessionId) {
38
+ this.#currentApp = new MobileAndroidAppImpl(this.runtime, this.surfaceSessionId, event.desktopAppLaunched.appSessionId);
39
+ return this.#currentApp;
40
+ }
41
+ if (event.error?.message)
42
+ throw new Error(event.error.message);
43
+ if (event.closed) {
44
+ this.#closed = true;
45
+ throw new Error(`macOS desktop session ${this.sessionId} closed while launching app`);
46
+ }
47
+ }
48
+ }
49
+ }
50
+ class DesktopMacSurfaceImpl {
51
+ async connect(options = {}) {
52
+ const runtime = await getRuntime();
53
+ const { stream, queue } = await createBrowserSessionHandle(runtime);
54
+ stream.write({
55
+ connectDesktop: {
56
+ platform: 1,
57
+ agentEndpoint: options.agentEndpoint,
58
+ retryOptions: retryOptions(options.timeoutMs),
59
+ },
60
+ });
61
+ while (true) {
62
+ const event = await queue.next();
63
+ if (event.desktopConnected?.initialAppSessionId) {
64
+ return new DesktopMacImpl(event.desktopConnected.desktopSessionId ?? event.sessionId ?? "", event.sessionId ?? "", runtime, stream, queue, event.desktopConnected.initialAppSessionId);
65
+ }
66
+ if (event.error?.message)
67
+ throw new Error(event.error.message);
68
+ }
69
+ }
70
+ }
71
+ export const desktop = {
72
+ mac: new DesktopMacSurfaceImpl(),
73
+ };
package/dist/index.d.ts CHANGED
@@ -1,11 +1,12 @@
1
1
  import { BrowserImpl, BrowserTypeImpl } from "./browser.js";
2
2
  import { findConfigFile, loadConfigFile, resolveConfig } from "./config.js";
3
3
  import { mobile } from "./mobile.js";
4
+ import { desktop } from "./desktop.js";
4
5
  import { PageImpl } from "./page.js";
5
6
  import { setServerAddr, shutdown } from "./runtime.js";
6
7
  import type { Browser, BrowserKind, BrowserType, LaunchOptions, Page, Dialog, FileChooser, Download, HookType, ResolveConfigOptions, ResolvedAllwrightConfig } from "./types.js";
7
8
  export { findConfigFile, loadConfigFile, resolveConfig, setServerAddr, shutdown };
8
- export type { CapturedOption, BoundingBox, AccessibilitySnapshotOptions, AllwrightConfig, Browser, BrowserInfo, BrowserKind, BrowserType, Hook, HookType, Dialog, FileChooser, Download, ClickResult, CommandOptions, CountResult, ElementResult, FillResult, HighlightOptions, HighlightResult, LaunchOptions, MobileAndroidConnectOptions, MobileAndroidDevice, MobileAndroidLaunchOptions, MobileAndroidLocator, MobileAndroidApp, MobileIosConnectOptions, MobileIosDevice, MobileIosLaunchOptions, MobileIosLocator, MobileIosApp, Locator, LocatorInfo, MobileSurfaceNamespace, NavigateResult, Page, PageInfo, PressOptions, PressResult, ResolveConfigOptions, ResolvedAllwrightConfig, RetryConfig, ScreenshotOptions, ScreenshotResult, TextResult, WaitForSelectorOptions, WaitForSelectorResult, } from "./types.js";
9
+ export type { CapturedOption, BoundingBox, AccessibilitySnapshotOptions, AllwrightConfig, Browser, BrowserInfo, BrowserKind, BrowserType, Hook, HookType, Dialog, FileChooser, Download, ClickResult, CommandOptions, CountResult, ElementResult, FillResult, HighlightOptions, HighlightResult, LaunchOptions, MobileAndroidConnectOptions, MobileAndroidDevice, MobileAndroidLaunchOptions, MobileAndroidLocator, MobileAndroidApp, MobileIosConnectOptions, MobileIosDevice, MobileIosLaunchOptions, MobileIosLocator, MobileIosApp, Locator, LocatorInfo, MobileSurfaceNamespace, DesktopMacApp, DesktopMacConnectOptions, DesktopMacDesktop, DesktopMacLaunchOptions, DesktopMacLocator, DesktopSurfaceNamespace, NavigateResult, Page, PageInfo, PressOptions, PressResult, ResolveConfigOptions, ResolvedAllwrightConfig, RetryConfig, ScreenshotOptions, ScreenshotResult, TextResult, WaitForSelectorOptions, WaitForSelectorResult, } from "./types.js";
9
10
  export declare const chromium: BrowserType;
10
11
  export declare const firefox: BrowserType;
11
12
  export declare const hooks: {
@@ -15,6 +16,7 @@ export declare const hooks: {
15
16
  download: HookType<Download>;
16
17
  };
17
18
  export { mobile };
19
+ export { desktop };
18
20
  export type Tab = Page;
19
21
  export declare function ping(): Promise<string>;
20
22
  export declare function launchChrome(options?: LaunchOptions): Promise<Browser>;
package/dist/index.js CHANGED
@@ -2,6 +2,7 @@ import { BrowserImpl, BrowserTypeImpl } from "./browser.js";
2
2
  import { formatActionError } from "./errors.js";
3
3
  import { findConfigFile, loadConfigFile, resolveConfig } from "./config.js";
4
4
  import { mobile } from "./mobile.js";
5
+ import { desktop } from "./desktop.js";
5
6
  import { PageImpl } from "./page.js";
6
7
  import { createBrowserSessionHandle, getRuntime, launchConfiguredBrowser as launchConfiguredBrowserWithResolver, ping as runtimePing, resolveLaunchBrowserArgs, setServerAddr, shutdown, } from "./runtime.js";
7
8
  export { findConfigFile, loadConfigFile, resolveConfig, setServerAddr, shutdown };
@@ -14,6 +15,7 @@ export const hooks = {
14
15
  download: Object.freeze({ name: "download" }),
15
16
  };
16
17
  export { mobile };
18
+ export { desktop };
17
19
  export async function ping() {
18
20
  return runtimePing();
19
21
  }
package/dist/locator.d.ts CHANGED
@@ -1,27 +1,27 @@
1
1
  import { WebLocatorBuilders, type LocatorFilterOptions } from "./web-locators.js";
2
- import type { BoundingBox, CapturedOption, ClickResult, CommandOptions, CountResult, ElementResult, FillResult, HighlightOptions, HighlightResult, Locator, LocatorInfo, Page, PressOptions, PressResult, TextResult, WaitForSelectorOptions, WaitForSelectorResult } from "./types.js";
2
+ import type { BoundingBox, CapturedOption, CommandOptions, HighlightOptions, Locator, LocatorInfo, Page, PressOptions, WaitForSelectorOptions } from "./types.js";
3
3
  export declare class LocatorImpl extends WebLocatorBuilders implements Locator {
4
4
  readonly page: Page;
5
5
  readonly selector: string;
6
6
  constructor(input: LocatorInfo);
7
7
  frame(options?: CommandOptions): Promise<Page>;
8
8
  Frame(options?: CommandOptions): Promise<Page>;
9
- click(options?: CommandOptions): Promise<ClickResult>;
10
- count(options?: CommandOptions): Promise<CountResult>;
11
- highlight(options?: HighlightOptions): Promise<HighlightResult>;
12
- focus(options?: CommandOptions): Promise<ElementResult>;
13
- fill(value: string, options?: CommandOptions): Promise<FillResult>;
14
- hover(options?: CommandOptions): Promise<ElementResult>;
15
- press(key: string, options?: PressOptions): Promise<PressResult>;
9
+ click(options?: CommandOptions): Promise<void>;
10
+ count(options?: CommandOptions): Promise<number>;
11
+ highlight(options?: HighlightOptions): Promise<void>;
12
+ focus(options?: CommandOptions): Promise<void>;
13
+ fill(value: string, options?: CommandOptions): Promise<void>;
14
+ hover(options?: CommandOptions): Promise<void>;
15
+ press(key: string, options?: PressOptions): Promise<void>;
16
16
  inputValue(options?: CommandOptions): Promise<string>;
17
17
  selectedOptions(options?: CommandOptions): Promise<CapturedOption[]>;
18
18
  selectedText(options?: CommandOptions): Promise<string | null>;
19
19
  isChecked(options?: CommandOptions): Promise<boolean>;
20
20
  getAttribute(name: string, options?: CommandOptions): Promise<string | null>;
21
21
  boundingBox(options?: CommandOptions): Promise<BoundingBox | null>;
22
- textContent(options?: CommandOptions): Promise<TextResult>;
23
- innerText(options?: CommandOptions): Promise<TextResult>;
24
- waitFor(options?: WaitForSelectorOptions): Promise<WaitForSelectorResult>;
22
+ textContent(options?: CommandOptions): Promise<string | null>;
23
+ innerText(options?: CommandOptions): Promise<string>;
24
+ waitFor(options?: WaitForSelectorOptions): Promise<void>;
25
25
  not(other: Locator): Locator;
26
26
  filter(options?: LocatorFilterOptions): Locator;
27
27
  nth(index: number): Locator;
package/dist/mobile.d.ts CHANGED
@@ -1,2 +1,28 @@
1
- import type { MobileSurfaceNamespace } from "./types.js";
1
+ import { type RoleOptions, type TextMatcher, type TextOptions } from "./web-locators.js";
2
+ import type { AccessibilitySnapshotOptions, CommandOptions, Hook, HookType, MobileAndroidLocator, MobileAndroidApp, MobileSurfaceNamespace, PressOptions, RuntimeClient, ScreenshotOptions, WaitForSelectorOptions } from "./types.js";
3
+ export declare class MobileAndroidAppImpl implements MobileAndroidApp {
4
+ #private;
5
+ readonly sessionId: string;
6
+ constructor(runtime: RuntimeClient, surfaceSessionId: string, sessionId: string);
7
+ locator(selector: string): MobileAndroidLocator;
8
+ getByRole(role: string, options?: RoleOptions): MobileAndroidLocator;
9
+ getByText(text: TextMatcher, options?: TextOptions): MobileAndroidLocator;
10
+ getByLabel(text: TextMatcher, options?: TextOptions): MobileAndroidLocator;
11
+ getByTestId(text: TextMatcher): MobileAndroidLocator;
12
+ registerHook<T>(type: HookType<T>): Promise<Hook<T>>;
13
+ setChooserFiles(fileChooserId: string, files: string[], options: CommandOptions): Promise<void>;
14
+ saveMobileDownload(downloadId: string, path: string, options: CommandOptions): Promise<void>;
15
+ click(selector: string, options?: CommandOptions): Promise<void>;
16
+ goto(url: string, options?: CommandOptions): Promise<void>;
17
+ navigate(url: string, options?: CommandOptions): Promise<void>;
18
+ count(selector: string, options?: CommandOptions): Promise<number>;
19
+ focus(selector: string, options?: CommandOptions): Promise<void>;
20
+ fill(selector: string, value: string, options?: CommandOptions): Promise<void>;
21
+ press(selector: string, key: string, options?: PressOptions): Promise<void>;
22
+ textContent(selector: string, options?: CommandOptions): Promise<string | null>;
23
+ innerText(selector: string, options?: CommandOptions): Promise<string>;
24
+ waitForSelector(selector: string, options?: WaitForSelectorOptions): Promise<void>;
25
+ accessibilitySnapshot(options?: AccessibilitySnapshotOptions): Promise<string>;
26
+ screenshot(options?: ScreenshotOptions): Promise<Uint8Array>;
27
+ }
2
28
  export declare const mobile: MobileSurfaceNamespace;
package/dist/mobile.js CHANGED
@@ -7,7 +7,7 @@ import { semanticSelector } from "./web-locators.js";
7
7
  function retryOptions(timeoutMs) {
8
8
  return timeoutMs ? { timeoutMs } : undefined;
9
9
  }
10
- class MobileAndroidAppImpl {
10
+ export class MobileAndroidAppImpl {
11
11
  sessionId;
12
12
  #runtime;
13
13
  #surfaceSessionId;
@@ -204,11 +204,7 @@ class MobileAndroidAppImpl {
204
204
  while (true) {
205
205
  const event = await handle.queue.next();
206
206
  if (event.elementClicked) {
207
- return {
208
- selector: event.elementClicked.cssSelector ?? "",
209
- note: event.elementClicked.note ?? "",
210
- bidiSessionId: event.elementClicked.bidiSessionId ?? "",
211
- };
207
+ return;
212
208
  }
213
209
  if (event.error?.message) {
214
210
  throw new Error(event.error.message);
@@ -219,6 +215,30 @@ class MobileAndroidAppImpl {
219
215
  }
220
216
  }
221
217
  }
218
+ async goto(url, options = {}) {
219
+ return this.navigate(url, options);
220
+ }
221
+ async navigate(url, options = {}) {
222
+ const handle = await this.#getHandle();
223
+ this.#ensureOpen(handle);
224
+ handle.stream.write({
225
+ surfaceSessionId: this.#surfaceSessionId,
226
+ contextSessionId: this.sessionId,
227
+ navigate: { url, retryOptions: retryOptions(options.timeoutMs) },
228
+ });
229
+ while (true) {
230
+ const event = await handle.queue.next();
231
+ if (event.navigated) {
232
+ return;
233
+ }
234
+ if (event.error?.message)
235
+ throw new Error(event.error.message);
236
+ if (event.closed) {
237
+ handle.closed = true;
238
+ throw new Error(`mobile app session ${this.sessionId} closed while opening deep link`);
239
+ }
240
+ }
241
+ }
222
242
  async count(selector, options = {}) {
223
243
  const handle = await this.#getHandle();
224
244
  this.#ensureOpen(handle);
@@ -233,11 +253,7 @@ class MobileAndroidAppImpl {
233
253
  while (true) {
234
254
  const event = await handle.queue.next();
235
255
  if (event.elementCounted) {
236
- return {
237
- selector: event.elementCounted.cssSelector ?? "",
238
- count: event.elementCounted.count ?? 0,
239
- note: event.elementCounted.note ?? "",
240
- };
256
+ return event.elementCounted.count ?? 0;
241
257
  }
242
258
  if (event.error?.message) {
243
259
  throw new Error(event.error.message);
@@ -262,10 +278,7 @@ class MobileAndroidAppImpl {
262
278
  while (true) {
263
279
  const event = await handle.queue.next();
264
280
  if (event.elementFocused) {
265
- return {
266
- selector: event.elementFocused.cssSelector ?? "",
267
- note: event.elementFocused.note ?? "",
268
- };
281
+ return;
269
282
  }
270
283
  if (event.error?.message) {
271
284
  throw new Error(event.error.message);
@@ -291,11 +304,7 @@ class MobileAndroidAppImpl {
291
304
  while (true) {
292
305
  const event = await handle.queue.next();
293
306
  if (event.elementFilled) {
294
- return {
295
- selector: event.elementFilled.cssSelector ?? "",
296
- value: event.elementFilled.value ?? "",
297
- note: event.elementFilled.note ?? "",
298
- };
307
+ return;
299
308
  }
300
309
  if (event.error?.message) {
301
310
  throw new Error(event.error.message);
@@ -322,11 +331,7 @@ class MobileAndroidAppImpl {
322
331
  while (true) {
323
332
  const event = await handle.queue.next();
324
333
  if (event.keyPressed) {
325
- return {
326
- selector: event.keyPressed.cssSelector ?? "",
327
- key: event.keyPressed.key ?? "",
328
- note: event.keyPressed.note ?? "",
329
- };
334
+ return;
330
335
  }
331
336
  if (event.error?.message) {
332
337
  throw new Error(event.error.message);
@@ -338,10 +343,10 @@ class MobileAndroidAppImpl {
338
343
  }
339
344
  }
340
345
  async textContent(selector, options = {}) {
341
- return this.#readText(selector, options, true);
346
+ return (await this.#readText(selector, options, true)).text;
342
347
  }
343
348
  async innerText(selector, options = {}) {
344
- return this.#readText(selector, options, false);
349
+ return (await this.#readText(selector, options, false)).text;
345
350
  }
346
351
  async waitForSelector(selector, options = {}) {
347
352
  const handle = await this.#getHandle();
@@ -358,11 +363,7 @@ class MobileAndroidAppImpl {
358
363
  while (true) {
359
364
  const event = await handle.queue.next();
360
365
  if (event.selectorWaitSatisfied) {
361
- return {
362
- selector: event.selectorWaitSatisfied.cssSelector ?? "",
363
- visible: event.selectorWaitSatisfied.visible ?? false,
364
- note: event.selectorWaitSatisfied.note ?? "",
365
- };
366
+ return;
366
367
  }
367
368
  if (event.error?.message) {
368
369
  throw new Error(event.error.message);
@@ -426,7 +427,7 @@ class MobileAndroidAppImpl {
426
427
  if (options.path) {
427
428
  await writeFile(options.path, screenshot.pngData);
428
429
  }
429
- return screenshot;
430
+ return screenshot.pngData;
430
431
  }
431
432
  if (event.error?.message) {
432
433
  throw new Error(event.error.message);
@@ -152,6 +152,9 @@ export function normalizeMobileSelectorForTransport(selector) {
152
152
  if (!trimmed) {
153
153
  return "";
154
154
  }
155
+ if (/^ref[=:]/i.test(trimmed)) {
156
+ return `ref=${decodeSelectorBody(trimmed.slice(4))}`;
157
+ }
155
158
  if (isNormalizedTransportSelector(trimmed)) {
156
159
  return trimmed;
157
160
  }
package/dist/page.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { WebLocatorBuilders, type LocatorFilterOptions } from "./web-locators.js";
2
- import type { BoundingBox, CapturedOption, AccessibilitySnapshotOptions, ClickResult, CommandOptions, CountResult, ElementResult, FillResult, FileChooser, Download, HighlightOptions, HighlightResult, Hook, HookType, Locator, NavigateResult, Page, PageInfo, PressOptions, PressResult, RuntimeClient, ScreenshotOptions, ScreenshotResult, TextResult, WaitForSelectorOptions, WaitForSelectorResult } from "./types.js";
2
+ import type { BoundingBox, CapturedOption, AccessibilitySnapshotOptions, CommandOptions, FileChooser, Download, HighlightOptions, Hook, HookType, Locator, Page, PageInfo, PressOptions, RuntimeClient, ScreenshotOptions, WaitForSelectorOptions } from "./types.js";
3
3
  export declare class PageImpl extends WebLocatorBuilders implements Page {
4
4
  #private;
5
5
  constructor(input: PageInfo & {
@@ -13,14 +13,14 @@ export declare class PageImpl extends WebLocatorBuilders implements Page {
13
13
  setFileChooserFiles(fileChooserId: string, files: string[], options?: CommandOptions): Promise<void>;
14
14
  saveDownload(downloadId: string, path: string, options?: CommandOptions): Promise<void>;
15
15
  locator(selector: string, options?: LocatorFilterOptions): Locator;
16
- goto(url: string, options?: CommandOptions): Promise<NavigateResult>;
17
- click(selector: string, options?: CommandOptions): Promise<ClickResult>;
18
- count(selector: string, options?: CommandOptions): Promise<CountResult>;
19
- highlight(selector: string, options?: HighlightOptions): Promise<HighlightResult>;
20
- focus(selector: string, options?: CommandOptions): Promise<ElementResult>;
21
- fill(selector: string, value: string, options?: CommandOptions): Promise<FillResult>;
22
- hover(selector: string, options?: CommandOptions): Promise<ElementResult>;
23
- press(selector: string, key: string, options?: PressOptions): Promise<PressResult>;
16
+ goto(url: string, options?: CommandOptions): Promise<void>;
17
+ click(selector: string, options?: CommandOptions): Promise<void>;
18
+ count(selector: string, options?: CommandOptions): Promise<number>;
19
+ highlight(selector: string, options?: HighlightOptions): Promise<void>;
20
+ focus(selector: string, options?: CommandOptions): Promise<void>;
21
+ fill(selector: string, value: string, options?: CommandOptions): Promise<void>;
22
+ hover(selector: string, options?: CommandOptions): Promise<void>;
23
+ press(selector: string, key: string, options?: PressOptions): Promise<void>;
24
24
  url(options?: CommandOptions): Promise<string>;
25
25
  inputValue(selector: string, options?: CommandOptions): Promise<string>;
26
26
  selectedOptions(selector: string, options?: CommandOptions): Promise<CapturedOption[]>;
@@ -28,15 +28,15 @@ export declare class PageImpl extends WebLocatorBuilders implements Page {
28
28
  isChecked(selector: string, options?: CommandOptions): Promise<boolean>;
29
29
  getAttribute(selector: string, name: string, options?: CommandOptions): Promise<string | null>;
30
30
  boundingBox(selector: string, options?: CommandOptions): Promise<BoundingBox | null>;
31
- textContent(selector: string, options?: CommandOptions): Promise<TextResult>;
32
- innerText(selector: string, options?: CommandOptions): Promise<TextResult>;
33
- waitForSelector(selector: string, options?: WaitForSelectorOptions): Promise<WaitForSelectorResult>;
31
+ textContent(selector: string, options?: CommandOptions): Promise<string | null>;
32
+ innerText(selector: string, options?: CommandOptions): Promise<string>;
33
+ waitForSelector(selector: string, options?: WaitForSelectorOptions): Promise<void>;
34
34
  accessibilitySnapshot(options?: AccessibilitySnapshotOptions): Promise<string>;
35
- screenshot(options?: ScreenshotOptions): Promise<ScreenshotResult>;
35
+ screenshot(options?: ScreenshotOptions): Promise<Uint8Array>;
36
36
  close(): Promise<void>;
37
37
  ping(message?: string): Promise<string>;
38
38
  pageInfo(): PageInfo;
39
- navigate(url: string, options?: CommandOptions): Promise<NavigateResult>;
39
+ navigate(url: string, options?: CommandOptions): Promise<void>;
40
40
  dispose(): void;
41
41
  }
42
42
  export declare class FileChooserImpl implements FileChooser {
package/dist/page.js CHANGED
@@ -278,14 +278,7 @@ export class PageImpl extends WebLocatorBuilders {
278
278
  throw new Error(`page session ${this.sessionId} closed while navigating`);
279
279
  }
280
280
  if (navigated && injection) {
281
- return {
282
- url: navigated.url ?? "",
283
- note: navigated.note ?? "",
284
- bidiSessionId: injection.bidiSessionId ?? "",
285
- mapperTargetId: injection.mapperTargetId ?? "",
286
- mapperSessionId: injection.mapperSessionId ?? "",
287
- packageVersion: injection.packageVersion ?? "",
288
- };
281
+ return;
289
282
  }
290
283
  }
291
284
  }
@@ -304,11 +297,7 @@ export class PageImpl extends WebLocatorBuilders {
304
297
  while (true) {
305
298
  const event = await handle.queue.next();
306
299
  if (event.elementClicked) {
307
- return {
308
- selector: event.elementClicked.cssSelector ?? "",
309
- note: event.elementClicked.note ?? "",
310
- bidiSessionId: event.elementClicked.bidiSessionId ?? "",
311
- };
300
+ return;
312
301
  }
313
302
  if (event.error?.message) {
314
303
  throw formatActionError("click", event.error.message, selector);
@@ -334,11 +323,7 @@ export class PageImpl extends WebLocatorBuilders {
334
323
  while (true) {
335
324
  const event = await handle.queue.next();
336
325
  if (event.elementCounted) {
337
- return {
338
- selector: event.elementCounted.cssSelector ?? "",
339
- count: event.elementCounted.count ?? 0,
340
- note: event.elementCounted.note ?? "",
341
- };
326
+ return event.elementCounted.count ?? 0;
342
327
  }
343
328
  if (event.error?.message) {
344
329
  throw formatActionError("count elements", event.error.message, selector);
@@ -365,11 +350,7 @@ export class PageImpl extends WebLocatorBuilders {
365
350
  while (true) {
366
351
  const event = await handle.queue.next();
367
352
  if (event.elementsHighlighted) {
368
- return {
369
- selector: event.elementsHighlighted.cssSelector ?? "",
370
- count: event.elementsHighlighted.count ?? 0,
371
- note: event.elementsHighlighted.note ?? "",
372
- };
353
+ return;
373
354
  }
374
355
  if (event.error?.message) {
375
356
  throw formatActionError("highlight elements", event.error.message, selector);
@@ -395,10 +376,7 @@ export class PageImpl extends WebLocatorBuilders {
395
376
  while (true) {
396
377
  const event = await handle.queue.next();
397
378
  if (event.elementFocused) {
398
- return {
399
- selector: event.elementFocused.cssSelector ?? "",
400
- note: event.elementFocused.note ?? "",
401
- };
379
+ return;
402
380
  }
403
381
  if (event.error?.message) {
404
382
  throw formatActionError("focus", event.error.message, selector);
@@ -425,11 +403,7 @@ export class PageImpl extends WebLocatorBuilders {
425
403
  while (true) {
426
404
  const event = await handle.queue.next();
427
405
  if (event.elementFilled) {
428
- return {
429
- selector: event.elementFilled.cssSelector ?? "",
430
- value: event.elementFilled.value ?? "",
431
- note: event.elementFilled.note ?? "",
432
- };
406
+ return;
433
407
  }
434
408
  if (event.error?.message) {
435
409
  throw formatActionError("fill", event.error.message, selector);
@@ -455,10 +429,7 @@ export class PageImpl extends WebLocatorBuilders {
455
429
  while (true) {
456
430
  const event = await handle.queue.next();
457
431
  if (event.elementHovered) {
458
- return {
459
- selector: event.elementHovered.cssSelector ?? "",
460
- note: event.elementHovered.note ?? "",
461
- };
432
+ return;
462
433
  }
463
434
  if (event.error?.message) {
464
435
  throw formatActionError("hover", event.error.message, selector);
@@ -486,11 +457,7 @@ export class PageImpl extends WebLocatorBuilders {
486
457
  while (true) {
487
458
  const event = await handle.queue.next();
488
459
  if (event.keyPressed) {
489
- return {
490
- selector: event.keyPressed.cssSelector ?? "",
491
- key: event.keyPressed.key ?? "",
492
- note: event.keyPressed.note ?? "",
493
- };
460
+ return;
494
461
  }
495
462
  if (event.error?.message) {
496
463
  throw formatActionError("press key", event.error.message, selector);
@@ -548,10 +515,10 @@ export class PageImpl extends WebLocatorBuilders {
548
515
  return r.boundingBox ?? null;
549
516
  }
550
517
  async textContent(selector, options = {}) {
551
- return this.#readText(selector, options, true);
518
+ return (await this.#readText(selector, options, true)).text;
552
519
  }
553
520
  async innerText(selector, options = {}) {
554
- return this.#readText(selector, options, false);
521
+ return (await this.#readText(selector, options, false)).text;
555
522
  }
556
523
  async waitForSelector(selector, options = {}) {
557
524
  const handle = await this.#getHandle();
@@ -569,11 +536,7 @@ export class PageImpl extends WebLocatorBuilders {
569
536
  while (true) {
570
537
  const event = await handle.queue.next();
571
538
  if (event.selectorWaitSatisfied) {
572
- return {
573
- selector: event.selectorWaitSatisfied.cssSelector ?? "",
574
- visible: event.selectorWaitSatisfied.visible ?? false,
575
- note: event.selectorWaitSatisfied.note ?? "",
576
- };
539
+ return;
577
540
  }
578
541
  if (event.error?.message) {
579
542
  throw formatActionError("wait for selector", event.error.message, selector);
@@ -637,7 +600,7 @@ export class PageImpl extends WebLocatorBuilders {
637
600
  if (options.path) {
638
601
  await writeFile(options.path, screenshot.pngData);
639
602
  }
640
- return screenshot;
603
+ return screenshot.pngData;
641
604
  }
642
605
  if (event.error?.message) {
643
606
  throw formatActionError("screenshot", event.error.message);
package/dist/types.d.ts CHANGED
@@ -153,19 +153,19 @@ export interface Page extends PageInfo, WebLocators {
153
153
  registerHook<T>(type: HookType<T>): Promise<Hook<T>>;
154
154
  accessibilitySnapshot(options?: AccessibilitySnapshotOptions): Promise<string>;
155
155
  locator(selector: string, options?: LocatorFilterOptions): Locator;
156
- goto(url: string, options?: CommandOptions): Promise<NavigateResult>;
157
- navigate(url: string, options?: CommandOptions): Promise<NavigateResult>;
158
- click(selector: string, options?: CommandOptions): Promise<ClickResult>;
159
- count(selector: string, options?: CommandOptions): Promise<CountResult>;
160
- highlight(selector: string, options?: HighlightOptions): Promise<HighlightResult>;
161
- focus(selector: string, options?: CommandOptions): Promise<ElementResult>;
162
- fill(selector: string, value: string, options?: CommandOptions): Promise<FillResult>;
163
- hover(selector: string, options?: CommandOptions): Promise<ElementResult>;
164
- press(selector: string, key: string, options?: PressOptions): Promise<PressResult>;
165
- textContent(selector: string, options?: CommandOptions): Promise<TextResult>;
166
- innerText(selector: string, options?: CommandOptions): Promise<TextResult>;
167
- waitForSelector(selector: string, options?: WaitForSelectorOptions): Promise<WaitForSelectorResult>;
168
- screenshot(options?: ScreenshotOptions): Promise<ScreenshotResult>;
156
+ goto(url: string, options?: CommandOptions): Promise<void>;
157
+ navigate(url: string, options?: CommandOptions): Promise<void>;
158
+ click(selector: string, options?: CommandOptions): Promise<void>;
159
+ count(selector: string, options?: CommandOptions): Promise<number>;
160
+ highlight(selector: string, options?: HighlightOptions): Promise<void>;
161
+ focus(selector: string, options?: CommandOptions): Promise<void>;
162
+ fill(selector: string, value: string, options?: CommandOptions): Promise<void>;
163
+ hover(selector: string, options?: CommandOptions): Promise<void>;
164
+ press(selector: string, key: string, options?: PressOptions): Promise<void>;
165
+ textContent(selector: string, options?: CommandOptions): Promise<string | null>;
166
+ innerText(selector: string, options?: CommandOptions): Promise<string>;
167
+ waitForSelector(selector: string, options?: WaitForSelectorOptions): Promise<void>;
168
+ screenshot(options?: ScreenshotOptions): Promise<Uint8Array>;
169
169
  close(): Promise<void>;
170
170
  ping(message?: string): Promise<string>;
171
171
  pageInfo(): PageInfo;
@@ -186,14 +186,14 @@ export interface MobileAndroidLaunchOptions {
186
186
  export interface MobileAndroidLocator {
187
187
  readonly page: MobileAndroidApp;
188
188
  readonly selector: string;
189
- click(options?: CommandOptions): Promise<ClickResult>;
190
- count(options?: CommandOptions): Promise<CountResult>;
191
- focus(options?: CommandOptions): Promise<ElementResult>;
192
- fill(value: string, options?: CommandOptions): Promise<FillResult>;
193
- press(key: string, options?: PressOptions): Promise<PressResult>;
194
- textContent(options?: CommandOptions): Promise<TextResult>;
195
- innerText(options?: CommandOptions): Promise<TextResult>;
196
- waitFor(options?: WaitForSelectorOptions): Promise<WaitForSelectorResult>;
189
+ click(options?: CommandOptions): Promise<void>;
190
+ count(options?: CommandOptions): Promise<number>;
191
+ focus(options?: CommandOptions): Promise<void>;
192
+ fill(value: string, options?: CommandOptions): Promise<void>;
193
+ press(key: string, options?: PressOptions): Promise<void>;
194
+ textContent(options?: CommandOptions): Promise<string | null>;
195
+ innerText(options?: CommandOptions): Promise<string>;
196
+ waitFor(options?: WaitForSelectorOptions): Promise<void>;
197
197
  locator(selector: string): MobileAndroidLocator;
198
198
  getByRole(role: string, options?: RoleOptions): MobileAndroidLocator;
199
199
  getByText(text: TextMatcher, options?: TextOptions): MobileAndroidLocator;
@@ -203,20 +203,22 @@ export interface MobileAndroidLocator {
203
203
  export interface MobileAndroidApp {
204
204
  accessibilitySnapshot(options?: AccessibilitySnapshotOptions): Promise<string>;
205
205
  readonly sessionId: string;
206
+ goto(url: string, options?: CommandOptions): Promise<void>;
207
+ navigate(url: string, options?: CommandOptions): Promise<void>;
206
208
  locator(selector: string): MobileAndroidLocator;
207
209
  getByRole(role: string, options?: RoleOptions): MobileAndroidLocator;
208
210
  getByText(text: TextMatcher, options?: TextOptions): MobileAndroidLocator;
209
211
  getByLabel(text: TextMatcher, options?: TextOptions): MobileAndroidLocator;
210
212
  getByTestId(text: TextMatcher): MobileAndroidLocator;
211
- click(selector: string, options?: CommandOptions): Promise<ClickResult>;
212
- count(selector: string, options?: CommandOptions): Promise<CountResult>;
213
- focus(selector: string, options?: CommandOptions): Promise<ElementResult>;
214
- fill(selector: string, value: string, options?: CommandOptions): Promise<FillResult>;
215
- press(selector: string, key: string, options?: PressOptions): Promise<PressResult>;
216
- textContent(selector: string, options?: CommandOptions): Promise<TextResult>;
217
- innerText(selector: string, options?: CommandOptions): Promise<TextResult>;
218
- waitForSelector(selector: string, options?: WaitForSelectorOptions): Promise<WaitForSelectorResult>;
219
- screenshot(options?: ScreenshotOptions): Promise<ScreenshotResult>;
213
+ click(selector: string, options?: CommandOptions): Promise<void>;
214
+ count(selector: string, options?: CommandOptions): Promise<number>;
215
+ focus(selector: string, options?: CommandOptions): Promise<void>;
216
+ fill(selector: string, value: string, options?: CommandOptions): Promise<void>;
217
+ press(selector: string, key: string, options?: PressOptions): Promise<void>;
218
+ textContent(selector: string, options?: CommandOptions): Promise<string | null>;
219
+ innerText(selector: string, options?: CommandOptions): Promise<string>;
220
+ waitForSelector(selector: string, options?: WaitForSelectorOptions): Promise<void>;
221
+ screenshot(options?: ScreenshotOptions): Promise<Uint8Array>;
220
222
  registerHook<T>(type: HookType<T>): Promise<Hook<T>>;
221
223
  }
222
224
  export interface MobileAndroidDevice {
@@ -253,6 +255,27 @@ export interface MobileSurfaceNamespace {
253
255
  connect(options?: MobileIosConnectOptions): Promise<MobileIosDevice>;
254
256
  };
255
257
  }
258
+ export interface DesktopMacConnectOptions {
259
+ agentEndpoint?: string;
260
+ timeoutMs?: number;
261
+ }
262
+ export interface DesktopMacLaunchOptions {
263
+ appId: string;
264
+ terminateRunning?: boolean;
265
+ timeoutMs?: number;
266
+ }
267
+ export type DesktopMacApp = MobileAndroidApp;
268
+ export type DesktopMacLocator = MobileAndroidLocator;
269
+ export interface DesktopMacDesktop {
270
+ readonly sessionId: string;
271
+ app(): DesktopMacApp;
272
+ launch(options: DesktopMacLaunchOptions): Promise<DesktopMacApp>;
273
+ }
274
+ export interface DesktopSurfaceNamespace {
275
+ mac: {
276
+ connect(options?: DesktopMacConnectOptions): Promise<DesktopMacDesktop>;
277
+ };
278
+ }
256
279
  export interface Locator extends WebLocators {
257
280
  inputValue(options?: CommandOptions): Promise<string>;
258
281
  selectedOptions(options?: CommandOptions): Promise<CapturedOption[]>;
@@ -269,16 +292,16 @@ export interface Locator extends WebLocators {
269
292
  last(): Locator;
270
293
  readonly page: Page;
271
294
  readonly selector: string;
272
- click(options?: CommandOptions): Promise<ClickResult>;
273
- count(options?: CommandOptions): Promise<CountResult>;
274
- highlight(options?: HighlightOptions): Promise<HighlightResult>;
275
- focus(options?: CommandOptions): Promise<ElementResult>;
276
- fill(value: string, options?: CommandOptions): Promise<FillResult>;
277
- hover(options?: CommandOptions): Promise<ElementResult>;
278
- press(key: string, options?: PressOptions): Promise<PressResult>;
279
- textContent(options?: CommandOptions): Promise<TextResult>;
280
- innerText(options?: CommandOptions): Promise<TextResult>;
281
- waitFor(options?: WaitForSelectorOptions): Promise<WaitForSelectorResult>;
295
+ click(options?: CommandOptions): Promise<void>;
296
+ count(options?: CommandOptions): Promise<number>;
297
+ highlight(options?: HighlightOptions): Promise<void>;
298
+ focus(options?: CommandOptions): Promise<void>;
299
+ fill(value: string, options?: CommandOptions): Promise<void>;
300
+ hover(options?: CommandOptions): Promise<void>;
301
+ press(key: string, options?: PressOptions): Promise<void>;
302
+ textContent(options?: CommandOptions): Promise<string | null>;
303
+ innerText(options?: CommandOptions): Promise<string>;
304
+ waitFor(options?: WaitForSelectorOptions): Promise<void>;
282
305
  locator(selector: string, options?: LocatorFilterOptions): Locator;
283
306
  }
284
307
  export interface AllwrightConfig {
@@ -415,6 +438,19 @@ export interface SurfaceSessionEvent {
415
438
  activityName?: string;
416
439
  webviewContext?: string;
417
440
  };
441
+ desktopConnected?: {
442
+ platform?: number | string;
443
+ hostName?: string;
444
+ note?: string;
445
+ backend?: string;
446
+ desktopSessionId?: string;
447
+ initialAppSessionId?: string;
448
+ };
449
+ desktopAppLaunched?: {
450
+ appSessionId?: string;
451
+ appId?: string;
452
+ note?: string;
453
+ };
418
454
  contextOpened?: {
419
455
  contextSessionId?: string;
420
456
  note?: string;
@@ -734,6 +770,24 @@ export interface LaunchAppRequest {
734
770
  };
735
771
  };
736
772
  }
773
+ export interface ConnectDesktopRequest {
774
+ connectDesktop: {
775
+ platform: number;
776
+ agentEndpoint?: string;
777
+ retryOptions?: {
778
+ timeoutMs?: number;
779
+ };
780
+ };
781
+ }
782
+ export interface LaunchDesktopAppRequest {
783
+ launchDesktopApp: {
784
+ appId: string;
785
+ terminateRunning?: boolean;
786
+ retryOptions?: {
787
+ timeoutMs?: number;
788
+ };
789
+ };
790
+ }
737
791
  export interface SurfacePingRequest {
738
792
  ping: {
739
793
  message: string;
@@ -890,7 +944,7 @@ export interface CloseContextRequest {
890
944
  contextSessionId: string;
891
945
  close: Record<string, never>;
892
946
  }
893
- export type SurfaceSessionRequest = LaunchBrowserRequest | LaunchChromeRequest | OpenContextRequest | ConnectMobileRequest | LaunchAppRequest | SurfacePingRequest | CloseSurfaceRequest;
947
+ export type SurfaceSessionRequest = LaunchBrowserRequest | LaunchChromeRequest | OpenContextRequest | ConnectMobileRequest | LaunchAppRequest | ConnectDesktopRequest | LaunchDesktopAppRequest | SurfacePingRequest | CloseSurfaceRequest;
894
948
  export type ContextSessionRequest = {
895
949
  surfaceSessionId: string;
896
950
  contextSessionId: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@allwright.dev/core",
3
- "version": "0.1.19",
3
+ "version": "0.1.21",
4
4
  "description": "High-level TypeScript client for the allwright automation engine.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -6,6 +6,7 @@ option java_package = "dev.allwright.engine.v1";
6
6
  option java_multiple_files = true;
7
7
 
8
8
  import "core/v1/common.proto";
9
+ import "surfaces/desktop/v1/desktop.proto";
9
10
  import "surfaces/mobile/v1/mobile.proto";
10
11
  import "surfaces/web/v1/web.proto";
11
12
 
@@ -18,6 +19,8 @@ message SurfaceSessionCommand {
18
19
  LaunchBrowserCommand launch_browser = 5;
19
20
  ConnectMobileCommand connect_mobile = 6;
20
21
  LaunchAppCommand launch_app = 7;
22
+ ConnectDesktopCommand connect_desktop = 8;
23
+ LaunchDesktopAppCommand launch_desktop_app = 9;
21
24
  }
22
25
  }
23
26
 
@@ -43,6 +46,8 @@ message SurfaceSessionEvent {
43
46
  BrowserLaunchedEvent browser_launched = 7;
44
47
  MobileConnectedEvent mobile_connected = 8;
45
48
  AppLaunchedEvent app_launched = 9;
49
+ DesktopConnectedEvent desktop_connected = 10;
50
+ DesktopAppLaunchedEvent desktop_app_launched = 11;
46
51
  }
47
52
  }
48
53
 
@@ -0,0 +1,40 @@
1
+ syntax = "proto3";
2
+
3
+ package allwright.engine.v1;
4
+ option go_package = "allwright.dev/gen/allwright/engine/v1;enginev1";
5
+ option java_package = "dev.allwright.engine.v1";
6
+ option java_multiple_files = true;
7
+
8
+ import "core/v1/common.proto";
9
+
10
+ enum DesktopPlatform {
11
+ DESKTOP_PLATFORM_UNSPECIFIED = 0;
12
+ DESKTOP_PLATFORM_MAC = 1;
13
+ }
14
+
15
+ message ConnectDesktopCommand {
16
+ DesktopPlatform platform = 1;
17
+ optional string agent_endpoint = 2;
18
+ optional CommandRetryOptions retry_options = 3;
19
+ }
20
+
21
+ message DesktopConnectedEvent {
22
+ DesktopPlatform platform = 1;
23
+ string host_name = 2;
24
+ string note = 3;
25
+ string backend = 4;
26
+ string desktop_session_id = 5;
27
+ string initial_app_session_id = 6;
28
+ }
29
+
30
+ message LaunchDesktopAppCommand {
31
+ string app_id = 1;
32
+ bool terminate_running = 2;
33
+ optional CommandRetryOptions retry_options = 3;
34
+ }
35
+
36
+ message DesktopAppLaunchedEvent {
37
+ string app_session_id = 1;
38
+ string app_id = 2;
39
+ string note = 3;
40
+ }