mirror of
https://github.com/priyanshujain/sanderling.git
synced 2026-10-04 20:17:09 +00:00
feat(spec): serialize selector-only string targets for the runner to re-resolve
This commit is contained in:
1 parent
1a9d82711f
commit
50cb9e98cb
2 files changed
+23
-7
No files matched your search
@@ -34,16 +34,23 @@ export type SerializedAction =
|
|||||||
|
|
||||||
const DEFAULT_SWIPE_DURATION = 250;
|
const DEFAULT_SWIPE_DURATION = 250;
|
||||||
|
|
||||||
// pointOf resolves a target to {x, y, selector?}. Builtins already supply a
|
// pointOf resolves a target to {x, y, selector?}. Builtins and resolved ax
|
||||||
// Point; author targets that carry numeric x/y (or a resolved element handle)
|
// elements carry numeric x/y; a bare selector string carries no geometry, so it
|
||||||
// collapse the same way. A string/selector target the host could not resolve
|
// serializes with (0, 0) and the selector, leaving the native runner to
|
||||||
// returns undefined so the action is dropped.
|
// re-resolve coordinates by id/text. A target with neither shape (null, an
|
||||||
|
// unrecognized object) returns undefined so the action is dropped.
|
||||||
function pointOf(target: unknown): (Point & { selector?: string }) | undefined {
|
function pointOf(target: unknown): (Point & { selector?: string }) | undefined {
|
||||||
|
if (typeof target === "string") {
|
||||||
|
return target.length > 0 ? { x: 0, y: 0, selector: target } : undefined;
|
||||||
|
}
|
||||||
if (!target || typeof target !== "object") return undefined;
|
if (!target || typeof target !== "object") return undefined;
|
||||||
const obj = target as Record<string, unknown>;
|
const obj = target as Record<string, unknown>;
|
||||||
if (typeof obj.x === "number" && typeof obj.y === "number") {
|
if (typeof obj.x === "number" && typeof obj.y === "number") {
|
||||||
const point: Point & { selector?: string } = { x: obj.x, y: obj.y };
|
const point: Point & { selector?: string } = { x: obj.x, y: obj.y };
|
||||||
if (typeof obj.selector === "string") point.selector = obj.selector;
|
// The picker's builtin candidates carry `selector`; a goja ax element
|
||||||
|
// carries it under the runtime tag. Either lets the runner re-resolve.
|
||||||
|
const selector = obj.selector ?? obj.__sanderlingSelector;
|
||||||
|
if (typeof selector === "string" && selector.length > 0) point.selector = selector;
|
||||||
return point;
|
return point;
|
||||||
}
|
}
|
||||||
return undefined;
|
return undefined;
|
||||||
|
|||||||
@@ -119,8 +119,17 @@ test("builtin Scroll carries the pre-computed to endpoint", () => {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
test("an unresolved (string) target drops the action", () => {
|
test("a string target serializes selector-only for the runner to re-resolve", () => {
|
||||||
assert.equal(serializeAction({ kind: "Tap", on: "id:never-resolved" }), null);
|
assert.deepEqual(serializeAction({ kind: "Tap", on: "id:save" }), {
|
||||||
|
kind: "Tap",
|
||||||
|
x: 0,
|
||||||
|
y: 0,
|
||||||
|
selector: "id:save",
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
test("an empty target or null action is dropped", () => {
|
||||||
|
assert.equal(serializeAction({ kind: "Tap", on: "" }), null);
|
||||||
assert.equal(serializeAction(null), null);
|
assert.equal(serializeAction(null), null);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
Reference in new issue
Block a user