mirror of
https://github.com/priyanshujain/sanderling.git
synced 2026-10-02 11:07:10 +00:00
fix(hierarchy): bounds is a raw attribute, not a cross-platform key
Every native dump writes the rectangle out as a string under bounds, and no DOM element carries an attribute of that name, so the key resolved against the dump and matched nothing on web on every page there is. It is accepted, so no unknown-key error said so, and no mapping can be invented for it: there is no DOM fact to map it to. Off the accepted list the web runtime raises the unknown-key error instead of matching nothing in silence, and the key still resolves wherever a producer writes it, through the escape hatch every other raw attribute already uses: a key some element carries is a key that can match, on both sides.
This commit is contained in:
1 parent
77ee3fc31e
commit
48425e113f
5 files changed
+47
-4
No files matched your search
@@ -302,7 +302,6 @@ var selectorKeys = []string{
|
|||||||
"accessibilityText",
|
"accessibilityText",
|
||||||
"aria-label",
|
"aria-label",
|
||||||
"ariaLabel",
|
"ariaLabel",
|
||||||
"bounds",
|
|
||||||
"checked",
|
"checked",
|
||||||
"class",
|
"class",
|
||||||
"className",
|
"className",
|
||||||
|
|||||||
@@ -690,6 +690,31 @@ func TestTestTagStillReachesTheIdentifierKeys(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// bounds is a raw driver attribute rather than a cross-platform key: every dump
|
||||||
|
// writes the rectangle out as a string and no DOM element carries an attribute
|
||||||
|
// of that name, so the key resolved here and matched nothing on web on every
|
||||||
|
// page there is, with no unknown-key error to say so and no mapping to invent
|
||||||
|
// for it. Off the accepted list the web runtime raises that error, and the
|
||||||
|
// escape hatch for an attribute the tree carries is what keeps it resolving
|
||||||
|
// where a producer writes it.
|
||||||
|
func TestBoundsIsAReachableRawAttributeAndNotAnAcceptedKey(t *testing.T) {
|
||||||
|
if slices.Contains(SelectorKeys(), "bounds") {
|
||||||
|
t.Error("bounds names no fact a DOM carries, so it cannot be a cross-platform key")
|
||||||
|
}
|
||||||
|
tree, _ := Parse(androidAttrDump)
|
||||||
|
selector := Selector{Filters: []AttrFilter{{Attr: "bounds", Value: "[0,0,1080,200]"}}}
|
||||||
|
if unknown := tree.UnknownSelectorKeys(selector); len(unknown) != 0 {
|
||||||
|
t.Errorf("bounds is an attribute this dump carries, got unknown %v", unknown)
|
||||||
|
}
|
||||||
|
node := tree.FindBySelector(selector)
|
||||||
|
if node == nil {
|
||||||
|
t.Fatal("expected bounds to match the raw attribute the dump writes")
|
||||||
|
}
|
||||||
|
if node.ResourceID != "com.app:id/row1" {
|
||||||
|
t.Fatalf("bounds matched %q, want row1", node.ResourceID)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestContentDescAliasOnIOS(t *testing.T) {
|
func TestContentDescAliasOnIOS(t *testing.T) {
|
||||||
tree, _ := Parse(iosAttrDump)
|
tree, _ := Parse(iosAttrDump)
|
||||||
el := tree.Find("content-desc:Close")
|
el := tree.Find("content-desc:Close")
|
||||||
|
|||||||
@@ -248,7 +248,6 @@ const SELECTOR_KEYS: readonly string[] = [
|
|||||||
"accessibilityText",
|
"accessibilityText",
|
||||||
"aria-label",
|
"aria-label",
|
||||||
"ariaLabel",
|
"ariaLabel",
|
||||||
"bounds",
|
|
||||||
"checked",
|
"checked",
|
||||||
"class",
|
"class",
|
||||||
"className",
|
"className",
|
||||||
|
|||||||
+1
-2
@@ -5,7 +5,6 @@
|
|||||||
"accessibilityText",
|
"accessibilityText",
|
||||||
"aria-label",
|
"aria-label",
|
||||||
"ariaLabel",
|
"ariaLabel",
|
||||||
"bounds",
|
|
||||||
"checked",
|
"checked",
|
||||||
"class",
|
"class",
|
||||||
"className",
|
"className",
|
||||||
@@ -41,5 +40,5 @@
|
|||||||
"unknownKeyExample": [
|
"unknownKeyExample": [
|
||||||
"descripton"
|
"descripton"
|
||||||
],
|
],
|
||||||
"unknownKeyMessage": "selector key \"descripton\" cannot match: no element carries that attribute, and it is not one of the accepted keys: accessibilityIdentifier, accessibilityLabel, accessibilityText, aria-label, ariaLabel, bounds, checked, class, className, clickable, content-desc, contentDescription, data-testid, desc, descPrefix, editable, elementType, enabled, focused, hintText, id, idPrefix, identifier, label, package, placeholder, placeholderValue, resource-id, scrollable, secure, selected, tag, testID, testTag, text, title, value"
|
"unknownKeyMessage": "selector key \"descripton\" cannot match: no element carries that attribute, and it is not one of the accepted keys: accessibilityIdentifier, accessibilityLabel, accessibilityText, aria-label, ariaLabel, checked, class, className, clickable, content-desc, contentDescription, data-testid, desc, descPrefix, editable, elementType, enabled, focused, hintText, id, idPrefix, identifier, label, package, placeholder, placeholderValue, resource-id, scrollable, secure, selected, tag, testID, testTag, text, title, value"
|
||||||
}
|
}
|
||||||
@@ -597,6 +597,27 @@ test("selectorFromObject accepts a raw attribute the page carries", () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// bounds is a raw driver attribute rather than a cross-platform key: every
|
||||||
|
// native dump writes the rectangle out as a string and no DOM element carries an
|
||||||
|
// attribute of that name, so the key resolved against the dump and matched
|
||||||
|
// nothing here on every page there is. Being on the accepted list is what kept
|
||||||
|
// that silent, and no mapping can be invented for it. Off the list it raises the
|
||||||
|
// unknown-key error here, and it still resolves wherever a producer writes it,
|
||||||
|
// through the escape hatch every other raw attribute uses.
|
||||||
|
test("bounds is a raw attribute rather than an accepted key", () => {
|
||||||
|
assert.equal(__testing__.SELECTOR_KEYS.includes("bounds"), false);
|
||||||
|
withDocumentCarrying([], () => {
|
||||||
|
assert.throws(
|
||||||
|
() => selectorFromObject({ bounds: "[0,0,120,40]" }),
|
||||||
|
(error: Error) =>
|
||||||
|
error.message.includes('"bounds"') && error.message.includes("accepted keys"),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
withDocumentCarrying(["bounds"], () => {
|
||||||
|
assert.doesNotThrow(() => selectorFromObject({ bounds: "[0,0,120,40]" }));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
// The string form's kind space stays open on both sides: "<attr>:<value>" is
|
// The string form's kind space stays open on both sides: "<attr>:<value>" is
|
||||||
// the documented way to reach a raw driver attribute, and internal/hierarchy
|
// the documented way to reach a raw driver attribute, and internal/hierarchy
|
||||||
// resolves an unknown kind to an empty result rather than an error.
|
// resolves an unknown kind to an empty result rather than an error.
|
||||||
|
|||||||
Reference in new issue
Block a user