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:
pj committed 2026-08-19 10:13:52 +05:30
1 parent 77ee3fc31e
commit 48425e113f
5 files changed
+47 -4

No files matched your search

-1
View File
@@ -248,7 +248,6 @@ const SELECTOR_KEYS: readonly string[] = [
"accessibilityText",
"aria-label",
"ariaLabel",
"bounds",
"checked",
"class",
"className",
+1 -2
View File
@@ -5,7 +5,6 @@
"accessibilityText",
"aria-label",
"ariaLabel",
"bounds",
"checked",
"class",
"className",
@@ -41,5 +40,5 @@
"unknownKeyExample": [
"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"
}
+21
View File
@@ -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 documented way to reach a raw driver attribute, and internal/hierarchy
// resolves an unknown kind to an empty result rather than an error.