@allwright.dev/core 0.1.4 → 0.1.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +13 -0
- package/dist/bootstrap.js +1 -1
- package/dist/browser.js +1 -0
- package/dist/index.d.ts +5 -2
- package/dist/index.js +3 -0
- package/dist/page.d.ts +3 -1
- package/dist/page.js +57 -0
- package/dist/types.d.ts +39 -1
- package/package.json +1 -1
- package/proto/core/v1/context.proto +28 -0
- package/proto/surfaces/web/v1/web.proto +7 -0
package/README.md
CHANGED
|
@@ -20,6 +20,19 @@ await page.click(
|
|
|
20
20
|
await browser.close();
|
|
21
21
|
```
|
|
22
22
|
|
|
23
|
+
Register a typed hook before an action that opens a tab, then wait for its
|
|
24
|
+
typed result afterward:
|
|
25
|
+
|
|
26
|
+
```ts
|
|
27
|
+
import { firefox, hooks } from "@allwright.dev/core";
|
|
28
|
+
|
|
29
|
+
const browser = await firefox.launch();
|
|
30
|
+
const page = browser.page();
|
|
31
|
+
const hook = await page.registerHook(hooks.newPage);
|
|
32
|
+
await page.click("a[target=_blank]");
|
|
33
|
+
const newPage = await hook.wait();
|
|
34
|
+
```
|
|
35
|
+
|
|
23
36
|
Runnable examples live in [examples/web-basic.ts](./examples/web-basic.ts) and [examples/android-basic.ts](./examples/android-basic.ts).
|
|
24
37
|
|
|
25
38
|
Shared config files are stack-agnostic and can live in `allwright.config.yaml` or `allwright.config.json`.
|
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.
|
|
15
|
+
const DEFAULT_RELEASE_VERSION = "0.1.6";
|
|
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));
|
package/dist/browser.js
CHANGED
package/dist/index.d.ts
CHANGED
|
@@ -3,11 +3,14 @@ import { findConfigFile, loadConfigFile, resolveConfig } from "./config.js";
|
|
|
3
3
|
import { mobile } from "./mobile.js";
|
|
4
4
|
import { PageImpl } from "./page.js";
|
|
5
5
|
import { setServerAddr, shutdown } from "./runtime.js";
|
|
6
|
-
import type { Browser, BrowserKind, BrowserType, LaunchOptions, Page, ResolveConfigOptions, ResolvedAllwrightConfig } from "./types.js";
|
|
6
|
+
import type { Browser, BrowserKind, BrowserType, LaunchOptions, Page, HookType, ResolveConfigOptions, ResolvedAllwrightConfig } from "./types.js";
|
|
7
7
|
export { findConfigFile, loadConfigFile, resolveConfig, setServerAddr, shutdown };
|
|
8
|
-
export type { AccessibilitySnapshotOptions, AllwrightConfig, Browser, BrowserInfo, BrowserKind, BrowserType, ClickResult, CommandOptions, CountResult, ElementResult, FillResult, HighlightOptions, HighlightResult, LaunchOptions, MobileAndroidConnectOptions, MobileAndroidDevice, MobileAndroidLaunchOptions, MobileAndroidLocator, MobileAndroidApp, Locator, LocatorInfo, MobileSurfaceNamespace, NavigateResult, Page, PageInfo, PressOptions, PressResult, ResolveConfigOptions, ResolvedAllwrightConfig, RetryConfig, ScreenshotOptions, ScreenshotResult, TextResult, WaitForSelectorOptions, WaitForSelectorResult, } from "./types.js";
|
|
8
|
+
export type { AccessibilitySnapshotOptions, AllwrightConfig, Browser, BrowserInfo, BrowserKind, BrowserType, Hook, HookType, ClickResult, CommandOptions, CountResult, ElementResult, FillResult, HighlightOptions, HighlightResult, LaunchOptions, MobileAndroidConnectOptions, MobileAndroidDevice, MobileAndroidLaunchOptions, MobileAndroidLocator, MobileAndroidApp, Locator, LocatorInfo, MobileSurfaceNamespace, NavigateResult, Page, PageInfo, PressOptions, PressResult, ResolveConfigOptions, ResolvedAllwrightConfig, RetryConfig, ScreenshotOptions, ScreenshotResult, TextResult, WaitForSelectorOptions, WaitForSelectorResult, } from "./types.js";
|
|
9
9
|
export declare const chromium: BrowserType;
|
|
10
10
|
export declare const firefox: BrowserType;
|
|
11
|
+
export declare const hooks: {
|
|
12
|
+
newPage: HookType<Page>;
|
|
13
|
+
};
|
|
11
14
|
export { mobile };
|
|
12
15
|
export type Tab = Page;
|
|
13
16
|
export declare function ping(): Promise<string>;
|
package/dist/index.js
CHANGED
|
@@ -7,6 +7,9 @@ import { createBrowserSessionHandle, getRuntime, launchConfiguredBrowser as laun
|
|
|
7
7
|
export { findConfigFile, loadConfigFile, resolveConfig, setServerAddr, shutdown };
|
|
8
8
|
export const chromium = new BrowserTypeImpl("chromium");
|
|
9
9
|
export const firefox = new BrowserTypeImpl("firefox");
|
|
10
|
+
export const hooks = {
|
|
11
|
+
newPage: Object.freeze({ name: "newPage" }),
|
|
12
|
+
};
|
|
10
13
|
export { mobile };
|
|
11
14
|
export async function ping() {
|
|
12
15
|
return runtimePing();
|
package/dist/page.d.ts
CHANGED
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
import { WebLocatorBuilders, type LocatorFilterOptions } from "./web-locators.js";
|
|
2
|
-
import type { AccessibilitySnapshotOptions, ClickResult, CommandOptions, CountResult, ElementResult, FillResult, HighlightOptions, HighlightResult, Locator, NavigateResult, Page, PageInfo, PressOptions, PressResult, RuntimeClient, ScreenshotOptions, ScreenshotResult, TextResult, WaitForSelectorOptions, WaitForSelectorResult } from "./types.js";
|
|
2
|
+
import type { AccessibilitySnapshotOptions, ClickResult, CommandOptions, CountResult, ElementResult, FillResult, HighlightOptions, HighlightResult, Hook, HookType, Locator, NavigateResult, Page, PageInfo, PressOptions, PressResult, RuntimeClient, ScreenshotOptions, ScreenshotResult, TextResult, WaitForSelectorOptions, WaitForSelectorResult } from "./types.js";
|
|
3
3
|
export declare class PageImpl extends WebLocatorBuilders implements Page {
|
|
4
4
|
#private;
|
|
5
5
|
constructor(input: PageInfo & {
|
|
6
6
|
runtime: RuntimeClient;
|
|
7
|
+
createPage?: (sessionId: string) => Page;
|
|
7
8
|
});
|
|
8
9
|
readonly sessionId: string;
|
|
9
10
|
readonly browserSessionId: string;
|
|
11
|
+
registerHook<T>(type: HookType<T>): Promise<Hook<T>>;
|
|
10
12
|
locator(selector: string, options?: LocatorFilterOptions): Locator;
|
|
11
13
|
goto(url: string, options?: CommandOptions): Promise<NavigateResult>;
|
|
12
14
|
click(selector: string, options?: CommandOptions): Promise<ClickResult>;
|
package/dist/page.js
CHANGED
|
@@ -7,14 +7,71 @@ import { createPageHandle } from "./runtime.js";
|
|
|
7
7
|
export class PageImpl extends WebLocatorBuilders {
|
|
8
8
|
#runtime;
|
|
9
9
|
#handlePromise = null;
|
|
10
|
+
#createPage;
|
|
10
11
|
constructor(input) {
|
|
11
12
|
super();
|
|
12
13
|
this.#runtime = input.runtime;
|
|
13
14
|
this.sessionId = input.sessionId;
|
|
14
15
|
this.browserSessionId = input.browserSessionId;
|
|
16
|
+
this.#createPage = input.createPage ?? ((sessionId) => new PageImpl({
|
|
17
|
+
runtime: this.#runtime,
|
|
18
|
+
browserSessionId: this.browserSessionId,
|
|
19
|
+
sessionId,
|
|
20
|
+
createPage: this.#createPage,
|
|
21
|
+
}));
|
|
15
22
|
}
|
|
16
23
|
sessionId;
|
|
17
24
|
browserSessionId;
|
|
25
|
+
async registerHook(type) {
|
|
26
|
+
if (type.name !== "newPage") {
|
|
27
|
+
throw formatActionError("register hook", `unsupported hook type: ${type.name}`);
|
|
28
|
+
}
|
|
29
|
+
const handle = await this.#getHandle();
|
|
30
|
+
this.#ensureOpen(handle);
|
|
31
|
+
handle.stream.write({
|
|
32
|
+
surfaceSessionId: this.browserSessionId,
|
|
33
|
+
contextSessionId: this.sessionId,
|
|
34
|
+
registerHook: { newPage: {} },
|
|
35
|
+
});
|
|
36
|
+
while (true) {
|
|
37
|
+
const event = await handle.queue.next();
|
|
38
|
+
if (event.hookRegistered?.hookId) {
|
|
39
|
+
const hookId = event.hookRegistered.hookId;
|
|
40
|
+
return {
|
|
41
|
+
id: hookId,
|
|
42
|
+
type,
|
|
43
|
+
wait: (options = {}) => this.#waitForHook(hookId, type, options),
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
if (event.error?.message) {
|
|
47
|
+
throw formatActionError(`register ${type.name} hook`, event.error.message);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
async #waitForHook(hookId, type, options) {
|
|
52
|
+
const handle = await this.#getHandle();
|
|
53
|
+
this.#ensureOpen(handle);
|
|
54
|
+
handle.stream.write({
|
|
55
|
+
surfaceSessionId: this.browserSessionId,
|
|
56
|
+
contextSessionId: this.sessionId,
|
|
57
|
+
waitForHook: {
|
|
58
|
+
hookId,
|
|
59
|
+
retryOptions: options.timeoutMs ? { timeoutMs: options.timeoutMs } : undefined,
|
|
60
|
+
},
|
|
61
|
+
});
|
|
62
|
+
while (true) {
|
|
63
|
+
const event = await handle.queue.next();
|
|
64
|
+
if (event.hookCompleted?.hookId === hookId) {
|
|
65
|
+
if (type.name === "newPage" && event.hookCompleted.newPage?.contextSessionId) {
|
|
66
|
+
return this.#createPage(event.hookCompleted.newPage.contextSessionId);
|
|
67
|
+
}
|
|
68
|
+
throw formatActionError(`wait for ${type.name} hook`, "hook returned an invalid result");
|
|
69
|
+
}
|
|
70
|
+
if (event.error?.message) {
|
|
71
|
+
throw formatActionError(`wait for ${type.name} hook`, event.error.message);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
18
75
|
locator(selector, options) {
|
|
19
76
|
const result = new LocatorImpl({ page: this, selector: normalizeSelectorForTransport(selector) });
|
|
20
77
|
return options ? result.filter(options) : result;
|
package/dist/types.d.ts
CHANGED
|
@@ -98,6 +98,16 @@ export interface LocatorInfo {
|
|
|
98
98
|
export interface BrowserType {
|
|
99
99
|
launch(options?: LaunchOptions): Promise<Browser>;
|
|
100
100
|
}
|
|
101
|
+
declare const hookOutput: unique symbol;
|
|
102
|
+
export interface HookType<T> {
|
|
103
|
+
readonly name: string;
|
|
104
|
+
readonly [hookOutput]: T;
|
|
105
|
+
}
|
|
106
|
+
export interface Hook<T> {
|
|
107
|
+
readonly id: string;
|
|
108
|
+
readonly type: HookType<T>;
|
|
109
|
+
wait(options?: CommandOptions): Promise<T>;
|
|
110
|
+
}
|
|
101
111
|
export interface Browser extends BrowserInfo {
|
|
102
112
|
page(): Page;
|
|
103
113
|
initialPage(): Page;
|
|
@@ -110,6 +120,7 @@ export interface Browser extends BrowserInfo {
|
|
|
110
120
|
browserInfo(): BrowserInfo;
|
|
111
121
|
}
|
|
112
122
|
export interface Page extends PageInfo, WebLocators {
|
|
123
|
+
registerHook<T>(type: HookType<T>): Promise<Hook<T>>;
|
|
113
124
|
accessibilitySnapshot(options?: AccessibilitySnapshotOptions): Promise<string>;
|
|
114
125
|
locator(selector: string, options?: LocatorFilterOptions): Locator;
|
|
115
126
|
goto(url: string, options?: CommandOptions): Promise<NavigateResult>;
|
|
@@ -367,6 +378,16 @@ export interface ContextSessionEvent {
|
|
|
367
378
|
error?: {
|
|
368
379
|
message?: string;
|
|
369
380
|
};
|
|
381
|
+
hookRegistered?: {
|
|
382
|
+
hookId?: string;
|
|
383
|
+
};
|
|
384
|
+
hookCompleted?: {
|
|
385
|
+
hookId?: string;
|
|
386
|
+
newPage?: {
|
|
387
|
+
contextSessionId?: string;
|
|
388
|
+
note?: string;
|
|
389
|
+
};
|
|
390
|
+
};
|
|
370
391
|
navigated?: {
|
|
371
392
|
url?: string;
|
|
372
393
|
note?: string;
|
|
@@ -455,6 +476,23 @@ export interface OpenContextRequest {
|
|
|
455
476
|
};
|
|
456
477
|
};
|
|
457
478
|
}
|
|
479
|
+
export interface RegisterHookRequest {
|
|
480
|
+
surfaceSessionId: string;
|
|
481
|
+
contextSessionId: string;
|
|
482
|
+
registerHook: {
|
|
483
|
+
newPage?: Record<string, never>;
|
|
484
|
+
};
|
|
485
|
+
}
|
|
486
|
+
export interface WaitForHookRequest {
|
|
487
|
+
surfaceSessionId: string;
|
|
488
|
+
contextSessionId: string;
|
|
489
|
+
waitForHook: {
|
|
490
|
+
hookId: string;
|
|
491
|
+
retryOptions?: {
|
|
492
|
+
timeoutMs?: number;
|
|
493
|
+
};
|
|
494
|
+
};
|
|
495
|
+
}
|
|
458
496
|
export interface ConnectMobileRequest {
|
|
459
497
|
connectMobile: {
|
|
460
498
|
platform: number;
|
|
@@ -634,7 +672,7 @@ export interface CloseContextRequest {
|
|
|
634
672
|
close: Record<string, never>;
|
|
635
673
|
}
|
|
636
674
|
export type SurfaceSessionRequest = LaunchBrowserRequest | LaunchChromeRequest | OpenContextRequest | ConnectMobileRequest | LaunchAppRequest | SurfacePingRequest | CloseSurfaceRequest;
|
|
637
|
-
export type ContextSessionRequest = ContextPingRequest | NavigateRequest | ClickRequest | CountRequest | HighlightRequest | FocusRequest | FillRequest | HoverRequest | PressRequest | TextContentRequest | InnerTextRequest | WaitForSelectorRequest | AccessibilitySnapshotRequest | ScreenshotRequest | CloseContextRequest;
|
|
675
|
+
export type ContextSessionRequest = ContextPingRequest | RegisterHookRequest | WaitForHookRequest | NavigateRequest | ClickRequest | CountRequest | HighlightRequest | FocusRequest | FillRequest | HoverRequest | PressRequest | TextContentRequest | InnerTextRequest | WaitForSelectorRequest | AccessibilitySnapshotRequest | ScreenshotRequest | CloseContextRequest;
|
|
638
676
|
export type SurfaceSessionStream = grpc.ClientDuplexStream<SurfaceSessionRequest, SurfaceSessionEvent>;
|
|
639
677
|
export type ContextSessionStream = grpc.ClientDuplexStream<ContextSessionRequest, ContextSessionEvent>;
|
|
640
678
|
export interface EngineServiceClientShape {
|
package/package.json
CHANGED
|
@@ -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/web/v1/web.proto";
|
|
9
10
|
|
|
10
11
|
message ContextSessionCommand {
|
|
11
12
|
string surface_session_id = 1;
|
|
@@ -27,6 +28,8 @@ message ContextSessionCommand {
|
|
|
27
28
|
WaitForSelectorCommand wait_for_selector = 15;
|
|
28
29
|
ScreenshotCommand screenshot = 16;
|
|
29
30
|
AccessibilitySnapshotCommand accessibility_snapshot = 17;
|
|
31
|
+
RegisterHookCommand register_hook = 18;
|
|
32
|
+
WaitForHookCommand wait_for_hook = 19;
|
|
30
33
|
}
|
|
31
34
|
}
|
|
32
35
|
|
|
@@ -58,6 +61,8 @@ message ContextSessionEvent {
|
|
|
58
61
|
SelectorWaitSatisfiedEvent selector_wait_satisfied = 17;
|
|
59
62
|
ScreenshotCapturedEvent screenshot_captured = 18;
|
|
60
63
|
AccessibilitySnapshotCapturedEvent accessibility_snapshot_captured = 19;
|
|
64
|
+
HookRegisteredEvent hook_registered = 20;
|
|
65
|
+
HookCompletedEvent hook_completed = 21;
|
|
61
66
|
}
|
|
62
67
|
}
|
|
63
68
|
|
|
@@ -77,6 +82,29 @@ message ContextSessionErrorEvent {
|
|
|
77
82
|
string message = 1;
|
|
78
83
|
}
|
|
79
84
|
|
|
85
|
+
message RegisterHookCommand {
|
|
86
|
+
oneof hook {
|
|
87
|
+
RegisterNewPageHook new_page = 1;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
message WaitForHookCommand {
|
|
92
|
+
string hook_id = 1;
|
|
93
|
+
optional CommandRetryOptions retry_options = 2;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
message HookRegisteredEvent {
|
|
97
|
+
string hook_id = 1;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
message HookCompletedEvent {
|
|
101
|
+
string hook_id = 1;
|
|
102
|
+
|
|
103
|
+
oneof result {
|
|
104
|
+
NewPageHookResult new_page = 2;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
80
108
|
message NavigatePageCommand {
|
|
81
109
|
string url = 1;
|
|
82
110
|
optional CommandRetryOptions retry_options = 2;
|