mirror of
https://github.com/priyanshujain/sanderling.git
synced 2026-10-02 11:07:10 +00:00
feat(spec-api): typed surface for spec authors
Thin wrappers over a globalThis.__uatu__ runtime that the verifier provides as host bindings. Spec authors get IntelliSense for extract/always/Tap/InputText/actions/weighted/taps/swipes, but the bundle stays small because runtime logic lives in goja.
This commit is contained in:
1 parent
5988e93057
commit
4a1f8cb522
5 files changed
+116
No files matched your search
@@ -0,0 +1,36 @@
|
||||
import type {
|
||||
AccessibilityElement,
|
||||
Action,
|
||||
ActionGenerator,
|
||||
InputTextAction,
|
||||
TapAction,
|
||||
WeightedEntry,
|
||||
} from "./types.ts";
|
||||
|
||||
export function actions(generator: () => Action[]): ActionGenerator {
|
||||
return globalThis.__uatu__.actions(generator);
|
||||
}
|
||||
|
||||
export function weighted(...entries: WeightedEntry[]): ActionGenerator {
|
||||
return globalThis.__uatu__.weighted(...entries);
|
||||
}
|
||||
|
||||
export function Tap(parameters: { on: string | AccessibilityElement }): TapAction {
|
||||
return globalThis.__uatu__.tap(parameters);
|
||||
}
|
||||
|
||||
export function InputText(parameters: { into: string | AccessibilityElement; text: string }): InputTextAction {
|
||||
return globalThis.__uatu__.inputText(parameters);
|
||||
}
|
||||
|
||||
export const taps: ActionGenerator = new Proxy({} as ActionGenerator, {
|
||||
get(_target, property) {
|
||||
return (globalThis.__uatu__.taps as unknown as Record<string | symbol, unknown>)[property];
|
||||
},
|
||||
});
|
||||
|
||||
export const swipes: ActionGenerator = new Proxy({} as ActionGenerator, {
|
||||
get(_target, property) {
|
||||
return (globalThis.__uatu__.swipes as unknown as Record<string | symbol, unknown>)[property];
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,5 @@
|
||||
import type { Extracted, State } from "./types.ts";
|
||||
|
||||
export function extract<T>(getter: (state: State) => T): Extracted<T> {
|
||||
return globalThis.__uatu__.extract(getter);
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
export type {
|
||||
AccessibilityElement,
|
||||
AccessibilityTree,
|
||||
Action,
|
||||
ActionGenerator,
|
||||
Extracted,
|
||||
Formula,
|
||||
InputTextAction,
|
||||
Snapshots,
|
||||
State,
|
||||
TapAction,
|
||||
WeightedEntry,
|
||||
} from "./types.ts";
|
||||
|
||||
export { extract } from "./extract.ts";
|
||||
export { always } from "./ltl.ts";
|
||||
export { Tap, InputText, actions, weighted, taps, swipes } from "./actions.ts";
|
||||
@@ -0,0 +1,5 @@
|
||||
import type { Formula } from "./types.ts";
|
||||
|
||||
export function always(predicate: () => boolean): Formula {
|
||||
return globalThis.__uatu__.always(predicate);
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
export type Snapshots = Record<string, unknown>;
|
||||
|
||||
export interface AccessibilityElement {
|
||||
id?: string;
|
||||
text?: string;
|
||||
bounds?: { left: number; top: number; right: number; bottom: number };
|
||||
}
|
||||
|
||||
export interface AccessibilityTree {
|
||||
find(selector: string): AccessibilityElement | undefined;
|
||||
findAll(selector: string): AccessibilityElement[];
|
||||
}
|
||||
|
||||
export interface State {
|
||||
snapshots: Snapshots;
|
||||
ax: AccessibilityTree;
|
||||
}
|
||||
|
||||
export interface Extracted<T> {
|
||||
readonly current: T;
|
||||
readonly previous: T | undefined;
|
||||
}
|
||||
|
||||
export type TapAction = { kind: "Tap"; on: string | AccessibilityElement };
|
||||
export type InputTextAction = { kind: "InputText"; into: string | AccessibilityElement; text: string };
|
||||
export type Action = TapAction | InputTextAction;
|
||||
|
||||
export interface ActionGenerator {
|
||||
readonly __uatuActionGenerator: true;
|
||||
generate(): Action[];
|
||||
}
|
||||
|
||||
export interface Formula {
|
||||
readonly __uatuFormula: true;
|
||||
}
|
||||
|
||||
export interface UatuRuntime {
|
||||
extract: <T>(getter: (state: State) => T) => Extracted<T>;
|
||||
always: (predicate: () => boolean) => Formula;
|
||||
actions: (generator: () => Action[]) => ActionGenerator;
|
||||
weighted: (...entries: WeightedEntry[]) => ActionGenerator;
|
||||
tap: (parameters: { on: string | AccessibilityElement }) => TapAction;
|
||||
inputText: (parameters: { into: string | AccessibilityElement; text: string }) => InputTextAction;
|
||||
taps: ActionGenerator;
|
||||
swipes: ActionGenerator;
|
||||
}
|
||||
|
||||
export type WeightedEntry = readonly [number, ActionGenerator];
|
||||
|
||||
declare global {
|
||||
// eslint-disable-next-line no-var
|
||||
var __uatu__: UatuRuntime;
|
||||
}
|
||||
Reference in new issue
Block a user