mirror of
https://github.com/priyanshujain/sanderling.git
synced 2026-10-04 03:57:09 +00:00
feat(runner): re-fetch on transitional hierarchy capture
Some actions trigger async work (DB write, ViewModel coroutine) whose navigation transition begins after the sidecar settle poll has already exited. Without intervention, the next iteration's hierarchy fetch lands mid cross-fade and the verifier observes a partial extractor state which then surfaces as a false-positive violation at the step where the transition completes. fetchSyncedState pairs hierarchy + screenshot in one goroutine and retries the pair (up to 4 times, 200ms apart) while the captured tree contains more than one route-level *Screen tag. Steps that observe no transition get no added cost; steps that catch a transition pay up to ~600ms extra wall time but record a tree that matches the post-transition state the property language expects to compare.
This commit is contained in:
1 parent
8deef1a425
commit
ddec95a2c5
2 files changed
+118
-20
No files matched your search
@@ -17,6 +17,7 @@ import (
|
||||
|
||||
"github.com/priyanshujain/sanderling/internal/driver"
|
||||
mockdriver "github.com/priyanshujain/sanderling/internal/driver/mock"
|
||||
"github.com/priyanshujain/sanderling/internal/hierarchy"
|
||||
"github.com/priyanshujain/sanderling/internal/trace"
|
||||
"github.com/priyanshujain/sanderling/internal/verifier"
|
||||
)
|
||||
@@ -493,6 +494,34 @@ func TestRunner_OneScreenshotPerStep(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// TestIsTransitionalHierarchy_DetectsMultipleScreens covers the runner-side
|
||||
// guard that re-fetches when the hierarchy still carries two route-level
|
||||
// *Screen ids - the NavHost cross-fade signature.
|
||||
func TestIsTransitionalHierarchy_DetectsMultipleScreens(t *testing.T) {
|
||||
multi, err := hierarchy.Parse(`{"attributes":{"resource-id":"root"},"children":[
|
||||
{"attributes":{"resource-id":"AddAccountScreen"},"children":[]},
|
||||
{"attributes":{"resource-id":"HomeScreen"},"children":[]}
|
||||
]}`)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if !isTransitionalHierarchy(multi) {
|
||||
t.Error("expected multi-screen tree to be flagged as transitional")
|
||||
}
|
||||
|
||||
single, err := hierarchy.Parse(`{"attributes":{"resource-id":"HomeScreen"},"children":[]}`)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if isTransitionalHierarchy(single) {
|
||||
t.Error("single-screen tree must not be flagged as transitional")
|
||||
}
|
||||
|
||||
if isTransitionalHierarchy(nil) {
|
||||
t.Error("nil tree must not be flagged as transitional")
|
||||
}
|
||||
}
|
||||
|
||||
// TestRunner_WaitActionSkipsIdle ensures the runner does not call WaitForIdle
|
||||
// after a Wait action - the action already provides settling time.
|
||||
func TestRunner_WaitActionSkipsIdle(t *testing.T) {
|
||||
|
||||
Reference in new issue
Block a user