mirror of
https://github.com/priyanshujain/sanderling.git
synced 2026-10-04 12:07:09 +00:00
refactor(spec): actions.ts returns pure GeneratorNode data trees
This commit is contained in:
1 parent
b34f73f3f7
commit
fe3ebd0484
2 files changed
+60
-78
No files matched your search
+51
-45
@@ -1,7 +1,13 @@
|
||||
// Author-facing action factories. Each returns plain GeneratorNode /
|
||||
// ActionDescriptor DATA (see action-tree.ts); the shared picker (pick.ts) walks
|
||||
// the tree and the runtime entry (runtime-entry.ts) serializes the result. No
|
||||
// factory forwards to globalThis.__sanderling__ anymore: the same data tree
|
||||
// drives both the goja verifier and the V8 web runtime.
|
||||
|
||||
import type { Pcg } from "./pcg.ts";
|
||||
import type {
|
||||
AccessibilityElement,
|
||||
Action,
|
||||
ActionGenerator,
|
||||
Direction,
|
||||
DoubleTapAction,
|
||||
InputTextAction,
|
||||
@@ -16,16 +22,17 @@ import type {
|
||||
WaitAction,
|
||||
WeightedEntry,
|
||||
} from "./types.ts";
|
||||
import type { ActionDescriptor, GeneratorNode } from "./action-tree.ts";
|
||||
|
||||
export function actions(generator: () => Action[]): ActionGenerator {
|
||||
return globalThis.__sanderling__.actions(generator);
|
||||
export function actions(generator: () => Action[]): GeneratorNode {
|
||||
return { kind: "actions", generate: generator as () => ActionDescriptor[] };
|
||||
}
|
||||
|
||||
export function whenRoute(
|
||||
routeExtractor: { readonly current: string | null },
|
||||
routes: string | readonly string[],
|
||||
body: () => Action[],
|
||||
): ActionGenerator {
|
||||
): GeneratorNode {
|
||||
const allowed = typeof routes === "string" ? [routes] : routes;
|
||||
return actions(() => {
|
||||
const current = routeExtractor.current;
|
||||
@@ -34,38 +41,54 @@ export function whenRoute(
|
||||
});
|
||||
}
|
||||
|
||||
export function weighted(...entries: WeightedEntry[]): ActionGenerator {
|
||||
return globalThis.__sanderling__.weighted(...entries);
|
||||
export function weighted(...entries: WeightedEntry[]): GeneratorNode {
|
||||
return { kind: "weighted", branches: entries };
|
||||
}
|
||||
|
||||
// samplerRng is the picker's Pcg while it evaluates an `actions` node's
|
||||
// generator (set by pick.ts walkActions). `from(...).generate()` draws from it
|
||||
// so sampling shares the single deterministic stream. It is null outside a
|
||||
// walk; eager spec-time generate() calls then fall back to the first item.
|
||||
let samplerRng: Pcg | null = null;
|
||||
|
||||
export function setSamplerRng(rng: Pcg | null): void {
|
||||
samplerRng = rng;
|
||||
}
|
||||
|
||||
export function from<T>(items: readonly T[]): Sampler<T> {
|
||||
return globalThis.__sanderling__.from(items);
|
||||
return {
|
||||
generate(): T {
|
||||
if (items.length <= 1) return items[0] as T;
|
||||
const index = samplerRng ? samplerRng.intN(items.length) : 0;
|
||||
return items[index] as T;
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
export function Tap(parameters: { on: string | AccessibilityElement }): TapAction {
|
||||
return globalThis.__sanderling__.tap(parameters);
|
||||
return { kind: "Tap", on: parameters.on };
|
||||
}
|
||||
|
||||
export function DoubleTap(parameters: { on: string | AccessibilityElement }): DoubleTapAction {
|
||||
return globalThis.__sanderling__.doubleTap(parameters);
|
||||
return { kind: "DoubleTap", on: parameters.on };
|
||||
}
|
||||
|
||||
export function LongPress(parameters: { on: string | AccessibilityElement }): LongPressAction {
|
||||
return globalThis.__sanderling__.longPress(parameters);
|
||||
return { kind: "LongPress", on: parameters.on };
|
||||
}
|
||||
|
||||
export function Scroll(parameters: {
|
||||
direction: Direction;
|
||||
in?: string | AccessibilityElement;
|
||||
}): ScrollAction {
|
||||
return globalThis.__sanderling__.scroll(parameters);
|
||||
return { kind: "Scroll", direction: parameters.direction, in: parameters.in };
|
||||
}
|
||||
|
||||
export function InputText(parameters: {
|
||||
into: string | AccessibilityElement;
|
||||
text: string;
|
||||
}): InputTextAction {
|
||||
return globalThis.__sanderling__.inputText(parameters);
|
||||
return { kind: "InputText", into: parameters.into, text: parameters.text };
|
||||
}
|
||||
|
||||
export function Swipe(parameters: {
|
||||
@@ -73,44 +96,27 @@ export function Swipe(parameters: {
|
||||
to: Point | AccessibilityElement;
|
||||
durationMillis?: number;
|
||||
}): SwipeAction {
|
||||
return globalThis.__sanderling__.swipe(parameters);
|
||||
return {
|
||||
kind: "Swipe",
|
||||
from: parameters.from,
|
||||
to: parameters.to,
|
||||
durationMillis: parameters.durationMillis,
|
||||
};
|
||||
}
|
||||
|
||||
export function PressKey(parameters: { key: Key }): PressKeyAction {
|
||||
return globalThis.__sanderling__.pressKey(parameters);
|
||||
return { kind: "PressKey", key: parameters.key };
|
||||
}
|
||||
|
||||
export function Wait(parameters: { durationMillis: number }): WaitAction {
|
||||
return globalThis.__sanderling__.wait(parameters);
|
||||
return { kind: "Wait", durationMillis: parameters.durationMillis };
|
||||
}
|
||||
|
||||
function builtinGenerator(
|
||||
name:
|
||||
| "taps"
|
||||
| "doubleTaps"
|
||||
| "longPresses"
|
||||
| "scrolls"
|
||||
| "typing"
|
||||
| "swipes"
|
||||
| "waitOnce"
|
||||
| "pressKeys",
|
||||
): ActionGenerator {
|
||||
return new Proxy({} as ActionGenerator, {
|
||||
get(_target, property) {
|
||||
const runtime = globalThis.__sanderling__[name] as unknown as Record<
|
||||
string | symbol,
|
||||
unknown
|
||||
>;
|
||||
return runtime[property];
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
export const taps: ActionGenerator = builtinGenerator("taps");
|
||||
export const doubleTaps: ActionGenerator = builtinGenerator("doubleTaps");
|
||||
export const longPresses: ActionGenerator = builtinGenerator("longPresses");
|
||||
export const scrolls: ActionGenerator = builtinGenerator("scrolls");
|
||||
export const typing: ActionGenerator = builtinGenerator("typing");
|
||||
export const swipes: ActionGenerator = builtinGenerator("swipes");
|
||||
export const waitOnce: ActionGenerator = builtinGenerator("waitOnce");
|
||||
export const pressKey: ActionGenerator = builtinGenerator("pressKeys");
|
||||
export const taps: GeneratorNode = { kind: "builtin", verb: "taps" };
|
||||
export const doubleTaps: GeneratorNode = { kind: "builtin", verb: "doubleTaps" };
|
||||
export const longPresses: GeneratorNode = { kind: "builtin", verb: "longPresses" };
|
||||
export const scrolls: GeneratorNode = { kind: "builtin", verb: "scrolls" };
|
||||
export const typing: GeneratorNode = { kind: "builtin", verb: "typing" };
|
||||
export const swipes: GeneratorNode = { kind: "builtin", verb: "swipes" };
|
||||
export const waitOnce: GeneratorNode = { kind: "builtin", verb: "waitOnce" };
|
||||
export const pressKey: GeneratorNode = { kind: "builtin", verb: "pressKeys" };
|
||||
Reference in new issue
Block a user