mirror of
https://github.com/priyanshujain/sanderling.git
synced 2026-10-02 11:07:10 +00:00
feat: --clear-data flag + typed attribute selectors (#48)
* feat(test): add --clear-data flag to clear app data on launch * test+docs: cover --clear-data flag in CLI parser test and reference * feat(spec): type AttrSelector with known attribute names Replace AttrSelector = Record<string, string> with KnownAttrSelectors plus a string|boolean index signature, so authors get autocomplete and type-checking on testTag / focused / clickable / etc. while raw driver attributes still type-check via the fallback. Boolean state attributes accept native booleans; goja stringifies them at the marshal boundary. AccessibilityElement.attrs becomes RawAttrs (typed string-valued shape of the same canonical names) so element.attrs.testTag autocompletes. * test(verifier): native boolean selector value matches focused=true * docs+folio: use native boolean for focused selector and document typed attrs
This commit is contained in:
10 files changed
+112
-5
No files matched your search
@@ -29,6 +29,7 @@ type Options struct {
|
||||
Duration time.Duration
|
||||
Seed int64
|
||||
Output string
|
||||
ClearData bool
|
||||
}
|
||||
|
||||
// Execute runs the full test pipeline: bundle, launch app, verify properties.
|
||||
@@ -68,7 +69,7 @@ func Execute(ctx context.Context, options Options, stdout io.Writer) error {
|
||||
}
|
||||
defer cleanup()
|
||||
|
||||
if err := activeDriver.Launch(ctx, options.BundleID, false, nil); err != nil {
|
||||
if err := activeDriver.Launch(ctx, options.BundleID, options.ClearData, nil); err != nil {
|
||||
return fmt.Errorf("launch app: %w", err)
|
||||
}
|
||||
|
||||
|
||||
@@ -428,6 +428,36 @@ func TestSelectorPath_ScopedDescent(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// TestSelector_BooleanValue ensures a native JS boolean in the selector
|
||||
// (e.g. `find({ focused: true })`) matches the "true"/"false" string
|
||||
// serialization the hierarchy uses for boolean state attributes.
|
||||
func TestSelector_BooleanValue(t *testing.T) {
|
||||
const treeJSON = `{
|
||||
"attributes": {"resource-id": "root", "bounds": "[0,0,100,100]"},
|
||||
"children": [
|
||||
{"attributes": {"testTag": "EmailField", "bounds": "[0,0,100,40]"}, "focused": true, "children": []},
|
||||
{"attributes": {"testTag": "PasswordField", "bounds": "[0,40,100,80]"}, "focused": false, "children": []}
|
||||
]
|
||||
}`
|
||||
verifier := newVerifier(t)
|
||||
mustLoad(t, verifier, `
|
||||
globalThis.focusedTag = __sanderling__.extract(state =>
|
||||
state.ax.find({ focused: true })?.attrs?.testTag ?? null
|
||||
);
|
||||
`)
|
||||
tree, err := hierarchy.Parse(treeJSON)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := verifier.PushSnapshot(SnapshotInput{Snapshots: Snapshots{}, Tree: tree}); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
got := verifier.runtime.GlobalObject().Get("focusedTag").ToObject(verifier.runtime).Get("current")
|
||||
if got == nil || got.String() != "EmailField" {
|
||||
t.Fatalf("expected EmailField, got %v", got)
|
||||
}
|
||||
}
|
||||
|
||||
// TestFrom_SeededReplayIsDeterministic guarantees `from()` over a per-step
|
||||
// dynamic array picks the same element under the same seed across runs. The
|
||||
// folio spec relies on this to replace Math.random() in account-card taps.
|
||||
|
||||
Reference in new issue
Block a user