Portals: Extract name from child tree root
This CL adds a change similar to https://crrev.com/c/2024110, but for the automation API. Bug: 1057598, 1045608 Change-Id: Ib27c661a6fda9c1ac0c952abf727367d9f0a79b9 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2112512 Commit-Queue: Adithya Srinivasan <adithyas@chromium.org> Reviewed-by: David Tseng <dtseng@chromium.org> Cr-Commit-Position: refs/heads/master@{#757999}
This commit is contained in:

committed by
Commit Bot

parent
8dfb00f1c2
commit
7d22c5843a
chrome
browser
resources
chromeos
accessibility
chromevox
background
test
extensions/renderer
@ -41,6 +41,45 @@ ChromeVoxPortalsTest = class extends ChromeVoxNextE2ETest {
|
||||
CommandHandler.onCommand(cmd);
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Waits for |portal|'s tree to be ready.
|
||||
* @param {chrome.automation.AutomationNode} portal
|
||||
* @return {Promise}
|
||||
*/
|
||||
async waitForPortal(portal) {
|
||||
const waitForChildren = () => new Promise(r => {
|
||||
const hasChildren = () => portal.children.length > 0;
|
||||
if (hasChildren()) {
|
||||
r();
|
||||
return;
|
||||
}
|
||||
const onChildrenChanged = () => {
|
||||
portal.removeEventListener(
|
||||
EventType.CHILDREN_CHANGED, onChildrenChanged, true);
|
||||
r();
|
||||
};
|
||||
portal.addEventListener(
|
||||
EventType.CHILDREN_CHANGED, onChildrenChanged, true);
|
||||
});
|
||||
|
||||
const waitForLoaded = () => new Promise(r => {
|
||||
const hasLoaded = () => portal.children[0].docLoaded;
|
||||
if (hasLoaded()) {
|
||||
r();
|
||||
return;
|
||||
}
|
||||
const onLoadComplete = () => {
|
||||
portal.removeEventListener(
|
||||
EventType.LOAD_COMPLETE, onLoadComplete, true);
|
||||
r();
|
||||
};
|
||||
portal.addEventListener(EventType.LOAD_COMPLETE, onLoadComplete, true);
|
||||
});
|
||||
|
||||
await waitForChildren();
|
||||
await waitForLoaded();
|
||||
}
|
||||
};
|
||||
|
||||
TEST_F('ChromeVoxPortalsTest', 'ShouldFocusPortal', function() {
|
||||
@ -62,23 +101,24 @@ TEST_F('ChromeVoxPortalsTest', 'ShouldFocusPortal', function() {
|
||||
doCmd('nextObject')();
|
||||
});
|
||||
|
||||
const onChildrenChanged = evt => {
|
||||
if (portal.children.length) {
|
||||
portal.removeEventListener(
|
||||
EventType.CHILDREN_CHANGED, onChildrenChanged, true);
|
||||
afterPortalIsReady();
|
||||
}
|
||||
};
|
||||
|
||||
button.focus();
|
||||
button.addEventListener(EventType.FOCUS, this.newCallback(function() {
|
||||
if (!portal.children.length) {
|
||||
portal.addEventListener(
|
||||
EventType.CHILDREN_CHANGED, onChildrenChanged, true);
|
||||
return;
|
||||
}
|
||||
afterPortalIsReady();
|
||||
}));
|
||||
button.addEventListener(
|
||||
EventType.FOCUS,
|
||||
() => this.waitForPortal(portal).then(afterPortalIsReady));
|
||||
}.bind(this),
|
||||
`${testRunnerParams.testServerBaseUrl}portal/portal-and-button.html`);
|
||||
});
|
||||
|
||||
TEST_F('ChromeVoxPortalsTest', 'PortalName', function() {
|
||||
this.runWithLoadedTree(
|
||||
undefined,
|
||||
function(root) {
|
||||
const portal = root.find({role: RoleType.PORTAL});
|
||||
assertEquals(RoleType.PORTAL, portal.role);
|
||||
this.waitForPortal(portal).then(this.newCallback(() => {
|
||||
assertTrue(portal.firstChild.docLoaded);
|
||||
assertEquals(portal.name, 'some text');
|
||||
}));
|
||||
}.bind(this),
|
||||
`${testRunnerParams.testServerBaseUrl}portal/portal-with-text.html`);
|
||||
});
|
||||
|
4
chrome/test/data/portal/portal-with-text-portal.html
Normal file
4
chrome/test/data/portal/portal-with-text-portal.html
Normal file
@ -0,0 +1,4 @@
|
||||
<!DOCTYPE html>
|
||||
<body>
|
||||
<text>some text</text>
|
||||
</body>
|
4
chrome/test/data/portal/portal-with-text.html
Normal file
4
chrome/test/data/portal/portal-with-text.html
Normal file
@ -0,0 +1,4 @@
|
||||
<!DOCTYPE html>
|
||||
<body>
|
||||
<portal src="portal-with-text-portal.html"></portal>
|
||||
</body>
|
@ -1151,6 +1151,25 @@ void AutomationInternalCustomBindings::AddRoutes() {
|
||||
v8::NewStringType::kNormal)
|
||||
.ToLocalChecked());
|
||||
});
|
||||
RouteNodeIDFunction("GetName", [this](v8::Isolate* isolate,
|
||||
v8::ReturnValue<v8::Value> result,
|
||||
AutomationAXTreeWrapper* tree_wrapper,
|
||||
ui::AXNode* node) {
|
||||
const ui::AXNodeData& node_data = node->data();
|
||||
const char* name =
|
||||
node_data.GetStringAttribute(ax::mojom::StringAttribute::kName).c_str();
|
||||
if (node_data.role == ax::mojom::Role::kPortal &&
|
||||
node_data.GetNameFrom() == ax::mojom::NameFrom::kNone) {
|
||||
if (GetRootOfChildTree(&node, &tree_wrapper)) {
|
||||
name = node->data()
|
||||
.GetStringAttribute(ax::mojom::StringAttribute::kName)
|
||||
.c_str();
|
||||
}
|
||||
}
|
||||
result.Set(
|
||||
v8::String::NewFromUtf8(isolate, name, v8::NewStringType::kNormal)
|
||||
.ToLocalChecked());
|
||||
});
|
||||
RouteNodeIDFunction(
|
||||
"GetDescriptionFrom",
|
||||
[](v8::Isolate* isolate, v8::ReturnValue<v8::Value> result,
|
||||
|
@ -262,6 +262,13 @@ var GetUnclippedLocation = natives.GetUnclippedLocation;
|
||||
var GetLineStartOffsets = requireNative(
|
||||
'automationInternal').GetLineStartOffsets;
|
||||
|
||||
/**
|
||||
* @param {string} axTreeID The id of the accessibility tree.
|
||||
* @param {number} nodeID The id of the node.
|
||||
* @return {?string} The computed name of this node.
|
||||
*/
|
||||
var GetName = natives.GetName;
|
||||
|
||||
/**
|
||||
* @param {string} axTreeID The id of the accessibility tree.
|
||||
* @param {number} nodeID The id of a node.
|
||||
@ -700,6 +707,9 @@ AutomationNodeImpl.prototype = {
|
||||
return GetNameFrom(this.treeID, this.id);
|
||||
},
|
||||
|
||||
get name() {
|
||||
return GetName(this.treeID, this.id);
|
||||
},
|
||||
|
||||
get descriptionFrom() {
|
||||
return GetDescriptionFrom(this.treeID, this.id);
|
||||
@ -1036,7 +1046,7 @@ AutomationNodeImpl.prototype = {
|
||||
var childID = GetChildIDAtIndex(this.treeID, this.id, i).nodeId;
|
||||
$Array.push(childIDs, childID);
|
||||
}
|
||||
var name = GetStringAttribute(this.treeID, this.id, 'name');
|
||||
var name = GetName(this.treeID, this.id);
|
||||
|
||||
var result = 'node id=' + this.id +
|
||||
' role=' + this.role +
|
||||
@ -1231,7 +1241,6 @@ var stringAttributes = [
|
||||
'language',
|
||||
'liveRelevant',
|
||||
'liveStatus',
|
||||
'name',
|
||||
'placeholder',
|
||||
'roleDescription',
|
||||
'textInputType',
|
||||
@ -1815,6 +1824,7 @@ utils.expose(AutomationNode, AutomationNodeImpl, {
|
||||
'lineThrough',
|
||||
'location',
|
||||
'markers',
|
||||
'name',
|
||||
'nameFrom',
|
||||
'nextSibling',
|
||||
'nonInlineTextWordEnds',
|
||||
|
Reference in New Issue
Block a user