Make web document navigation survive live-updating pages
Recreated-node caret recovery, tolerant caret validation, per-root retained document trees and cursors across tab switches, document warm-up, coalesced structural moves, and hung-provider fast-fail with an 'Application is not responding' announcement.
This commit is contained in:
1 parent
8ce5e5cdad
commit
7eef6e8be6
30 files changed
+1484
-174
No files matched your search
@@ -110,6 +110,43 @@ func TestNavigationDocumentValidatesOnlyTraversedBranches(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// Caret moves read text and line bounds live from the provider, so text,
|
||||
// geometry, or child-order staleness along the traversed range must not
|
||||
// force a recapture first: on ticking pages some counter between caret and
|
||||
// target is always mid-update, and strict validation traps the caret no
|
||||
// matter how often it recaptures. Identity and semantics stay strict, and
|
||||
// the strict range validation used by structural navigation is unchanged.
|
||||
func TestValidateDocumentCaretRangeToleratesTextAndGeometryStaleness(t *testing.T) {
|
||||
for _, test := range []struct {
|
||||
name string
|
||||
invalidate func(*AccessibleTree)
|
||||
want error
|
||||
wantStrict error
|
||||
}{
|
||||
{"text", func(tree *AccessibleTree) { tree.InvalidateText(testID("/link")) }, nil, ErrStaleText},
|
||||
{"geometry", func(tree *AccessibleTree) { tree.InvalidateGeometry(testID("/inner")) }, nil, ErrStaleGeometry},
|
||||
{"semantics", func(tree *AccessibleTree) { tree.InvalidateSnapshot(testID("/link")) }, ErrStaleSnapshot, ErrStaleSnapshot},
|
||||
{"children", func(tree *AccessibleTree) { tree.MarkChildrenChanged(testID("/inner")) }, nil, ErrIncompleteTree},
|
||||
} {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
tree, _ := NewAccessibleTree(testID("/root"), documentTestNodes())
|
||||
ref, _ := tree.Reference(testID("/heading"))
|
||||
view, err := tree.NavigationDocument(context.Background(), ref)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
test.invalidate(tree)
|
||||
heading, _ := view.Index(ref.ID())
|
||||
if err := tree.ValidateDocumentCaretRange(context.Background(), view, heading, len(view.Nodes)-1); !errors.Is(err, test.want) {
|
||||
t.Fatalf("caret validation: %v, want %v", err, test.want)
|
||||
}
|
||||
if err := tree.ValidateDocumentRange(context.Background(), view, heading, len(view.Nodes)-1); !errors.Is(err, test.wantStrict) {
|
||||
t.Fatalf("strict validation changed: %v, want %v", err, test.wantStrict)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestNavigationDocumentRejectsRetiredViewsAndCanceledMoves(t *testing.T) {
|
||||
tree, _ := NewAccessibleTree(testID("/root"), documentTestNodes())
|
||||
ref, _ := tree.Reference(testID("/heading"))
|
||||
|
||||
Reference in new issue
Block a user