| OLD | NEW |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 function initialize_DumpAccessibilityNodesTest() { | 5 function initialize_DumpAccessibilityNodesTest() { |
| 6 | 6 |
| 7 var nodeInfo = {}; | 7 var nodeInfo = {}; |
| 8 InspectorTest.trackGetChildNodesEvents(nodeInfo); | 8 InspectorTest.trackGetChildNodesEvents(nodeInfo); |
| 9 | 9 |
| 10 InspectorTest.dumpAccessibilityNodesBySelectorAndCompleteTest = function(selecto
r, msg) { | 10 InspectorTest.dumpAccessibilityNodesBySelectorAndCompleteTest = function(selecto
r, fetchRelatives, msg) { |
| 11 if (msg.error) { | 11 if (msg.error) { |
| 12 InspectorTest.log(msg.error.message); | 12 InspectorTest.log(msg.error.message); |
| 13 InspectorTest.completeTest(); | 13 InspectorTest.completeTest(); |
| 14 return; | 14 return; |
| 15 } | 15 } |
| 16 | 16 |
| 17 var rootNode = msg.result.root; | 17 var rootNode = msg.result.root; |
| 18 sendQuerySelectorAll(rootNode.nodeId, selector) | 18 var rootNodeId = rootNode.nodeId; |
| 19 .then((msg) => { return getAXNodes(msg) } ) | 19 InspectorTest.addNode(nodeInfo, rootNode); |
| 20 |
| 21 sendQuerySelectorAll(rootNodeId, selector) |
| 22 .then((msg) => { return getAXNodes(msg, fetchRelatives || false) } ) |
| 20 .then(() => { done(); }) | 23 .then(() => { done(); }) |
| 21 .then(() => { | 24 .then(() => { |
| 22 InspectorTest.completeTest(); | 25 InspectorTest.completeTest(); |
| 23 }) | 26 }) |
| 24 .catch((msg) => { InspectorTest.log("Error: " + JSON.stringify(msg)); }) | 27 .catch((msg) => { InspectorTest.log("Error: " + JSON.stringify(msg)); }) |
| 25 } | 28 } |
| 26 | 29 |
| 27 function sendCommandPromise(command, params) | 30 function sendCommandPromise(command, params) |
| 28 { | 31 { |
| 29 return new Promise(function(resolve, reject) { | 32 return new Promise(function(resolve, reject) { |
| (...skipping 12 matching lines...) Expand all Loading... |
| 42 { | 45 { |
| 43 sendCommandPromise("Runtime.evaluate", { expression: "done();" }); | 46 sendCommandPromise("Runtime.evaluate", { expression: "done();" }); |
| 44 } | 47 } |
| 45 | 48 |
| 46 function sendQuerySelectorAll(nodeId, selector) | 49 function sendQuerySelectorAll(nodeId, selector) |
| 47 { | 50 { |
| 48 return sendCommandPromise("DOM.querySelectorAll", { "nodeId": nodeId, "selec
tor": | 51 return sendCommandPromise("DOM.querySelectorAll", { "nodeId": nodeId, "selec
tor": |
| 49 selector }); | 52 selector }); |
| 50 } | 53 } |
| 51 | 54 |
| 52 function getAXNodes(msg) | 55 function getAXNodes(msg, fetchRelatives) |
| 53 { | 56 { |
| 54 var promise; | 57 var promise = Promise.resolve(); |
| 58 if (!msg.result || !msg.result.nodeIds) { |
| 59 InspectorTest.log("Unexpected result: " + JSON.stringify(msg)); |
| 60 InspectorTest.completeTest(); |
| 61 } |
| 55 msg.result.nodeIds.forEach((id) => { | 62 msg.result.nodeIds.forEach((id) => { |
| 56 if (promise) | 63 if (fetchRelatives) { |
| 57 promise = promise.then(() => { return sendCommandPromise("Accessibil
ity.getAXNodeChain", { "nodeId": id, "fetchAncestors": false }); }); | 64 promise = promise.then(() => { |
| 58 else | 65 return sendCommandPromise("Accessibility.getPartialAXTree", { "n
odeId": id, "fetchRelatives": true }); |
| 59 promise = sendCommandPromise("Accessibility.getAXNodeChain", { "node
Id": id, "fetchAncestors": false }); | 66 }); |
| 60 promise = promise.then((msg) => { return rewriteRelatedNodes(msg); }) | 67 promise = promise.then((msg) => { return rewriteRelatedNodes(msg, id
); }) |
| 61 .then((msg) => { return dumpNode(null, msg); }); | 68 .then((msg) => { return dumpTreeStructure(msg); }); |
| 69 |
| 70 } |
| 71 promise = promise.then(() => { return sendCommandPromise("Accessibility.
getPartialAXTree", { "nodeId": id, "fetchRelatives": false }); }) |
| 72 .then((msg) => { return rewriteRelatedNodes(msg, id); }
) |
| 73 .then((msg) => { return dumpNode(msg); }); |
| 74 |
| 62 }); | 75 }); |
| 63 return promise; | 76 return promise; |
| 64 } | 77 } |
| 65 | 78 |
| 66 function describeRelatedNode(nodeData) | 79 function describeDomNode(nodeData) |
| 67 { | 80 { |
| 68 var description = nodeData.nodeName.toLowerCase(); | 81 var description = nodeData.nodeName.toLowerCase(); |
| 69 switch (nodeData.nodeType) { | 82 switch (nodeData.nodeType) { |
| 70 case Node.ELEMENT_NODE: | 83 case Node.ELEMENT_NODE: |
| 71 var p = nodeData.attributes.indexOf("id"); | 84 var p = nodeData.attributes.indexOf("id"); |
| 72 if (p >= 0) | 85 if (p >= 0) |
| 73 description += "#" + nodeData.attributes[p + 1]; | 86 description += "#" + nodeData.attributes[p + 1]; |
| 74 } | 87 } |
| 75 return description; | 88 return description; |
| 76 } | 89 } |
| 77 | 90 |
| 91 function rewriteBackendDomNodeId(axNode, selectedNodeId, promises) |
| 92 { |
| 93 if (!("backendDOMNodeId" in axNode)) |
| 94 return; |
| 95 |
| 96 function rewriteBackendDomNodeIdPromise(resolve, reject) |
| 97 { |
| 98 if (!("backendDOMNodeId" in axNode)) { |
| 99 resolve(); |
| 100 return; |
| 101 } |
| 102 var backendDOMNodeId = axNode.backendDOMNodeId; |
| 103 |
| 104 function onDomNodeResolved(backendDOMNodeId, message) |
| 105 { |
| 106 if (!message.result || !message.result.nodeIds) { |
| 107 InspectorTest.log("Unexpected result for pushNodesByBackendIdsTo
Frontend: " + JSON.stringify(message)); |
| 108 InspectorTest.completeTest(); |
| 109 return; |
| 110 } |
| 111 var nodeId = message.result.nodeIds[0]; |
| 112 if (!(nodeId in nodeInfo)) { |
| 113 axNode.domNode = "[NODE NOT FOUND]"; |
| 114 resolve(); |
| 115 return; |
| 116 } |
| 117 var domNode = nodeInfo[nodeId]; |
| 118 delete axNode.backendDOMNodeId; |
| 119 axNode.domNode = describeDomNode(domNode); |
| 120 if (nodeId === selectedNodeId) |
| 121 axNode.selected = true; |
| 122 resolve(); |
| 123 } |
| 124 |
| 125 var params = { "backendNodeIds": [ backendDOMNodeId ] }; |
| 126 InspectorTest.sendCommand("DOM.pushNodesByBackendIdsToFrontend", params
, onDomNodeResolved.bind(null, backendDOMNodeId)); |
| 127 } |
| 128 promises.push(new Promise(rewriteBackendDomNodeIdPromise)); |
| 129 } |
| 130 |
| 78 function rewriteRelatedNode(relatedNode) | 131 function rewriteRelatedNode(relatedNode) |
| 79 { | 132 { |
| 80 function rewriteRelatedNodePromise(resolve, reject) | 133 function rewriteRelatedNodePromise(resolve, reject) |
| 81 { | 134 { |
| 82 if (!("backendNodeId" in relatedNode)) { | 135 if (!("backendDOMNodeId" in relatedNode)) { |
| 83 reject("Could not find backendNodeId in " + JSON.stringify(relatedNo
de)); | 136 reject("Could not find backendDOMNodeId in " + JSON.stringify(relate
dNode)); |
| 84 return; | 137 return; |
| 85 } | 138 } |
| 86 var backendNodeId = relatedNode.backendNodeId; | 139 var backendDOMNodeId = relatedNode.backendDOMNodeId; |
| 87 | 140 |
| 88 function onNodeResolved(backendNodeId, message) | 141 function onNodeResolved(backendDOMNodeId, message) |
| 89 { | 142 { |
| 143 if (!message.result || !message.result.nodeIds) { |
| 144 InspectorTest.log("Unexpected result for pushNodesByBackendIdsTo
Frontend: " + JSON.stringify(message)); |
| 145 InspectorTest.completeTest(); |
| 146 return; |
| 147 } |
| 90 var nodeId = message.result.nodeIds[0]; | 148 var nodeId = message.result.nodeIds[0]; |
| 91 if (!(nodeId in nodeInfo)) { | 149 if (!(nodeId in nodeInfo)) { |
| 92 relatedNode.nodeResult = "[NODE NOT FOUND]"; | 150 relatedNode.nodeResult = "[NODE NOT FOUND]"; |
| 93 resolve(); | 151 resolve(); |
| 94 return; | 152 return; |
| 95 } | 153 } |
| 96 var node = nodeInfo[nodeId]; | 154 var domNode = nodeInfo[nodeId]; |
| 97 delete relatedNode.backendNodeId; | 155 delete relatedNode.backendDOMNodeId; |
| 98 relatedNode.nodeResult = describeRelatedNode(node); | 156 relatedNode.nodeResult = describeDomNode(domNode); |
| 99 resolve(); | 157 resolve(); |
| 100 } | 158 } |
| 101 InspectorTest.sendCommand("DOM.pushNodesByBackendIdsToFrontend", { "back
endNodeIds": [ backendNodeId ] }, onNodeResolved.bind(null, backendNodeId)); | 159 var params = { "backendNodeIds": [ backendDOMNodeId ] }; |
| 160 InspectorTest.sendCommand("DOM.pushNodesByBackendIdsToFrontend", params,
onNodeResolved.bind(null, backendDOMNodeId)); |
| 161 |
| 102 } | 162 } |
| 103 return new Promise(rewriteRelatedNodePromise); | 163 return new Promise(rewriteRelatedNodePromise); |
| 104 } | 164 } |
| 105 | 165 |
| 106 function checkExists(path, obj) | 166 function checkExists(path, obj) |
| 107 { | 167 { |
| 108 var pathComponents = path.split("."); | 168 var pathComponents = path.split("."); |
| 109 var currentPath = []; | 169 var currentPath = []; |
| 110 var currentObject = obj; | 170 var currentObject = obj; |
| 111 for (var component of pathComponents) { | 171 for (var component of pathComponents) { |
| (...skipping 28 matching lines...) Expand all Loading... |
| 140 function rewriteRelatedNodeValue(value, promises) | 200 function rewriteRelatedNodeValue(value, promises) |
| 141 { | 201 { |
| 142 checkExists("relatedNodes", value); | 202 checkExists("relatedNodes", value); |
| 143 var relatedNodeArray = value.relatedNodes; | 203 var relatedNodeArray = value.relatedNodes; |
| 144 check(Array.isArray(relatedNodeArray), "relatedNodes should be an array", JS
ON.stringify(value)); | 204 check(Array.isArray(relatedNodeArray), "relatedNodes should be an array", JS
ON.stringify(value)); |
| 145 for (var relatedNode of relatedNodeArray) { | 205 for (var relatedNode of relatedNodeArray) { |
| 146 promises.push(rewriteRelatedNode(relatedNode)); | 206 promises.push(rewriteRelatedNode(relatedNode)); |
| 147 } | 207 } |
| 148 } | 208 } |
| 149 | 209 |
| 150 function rewriteRelatedNodes(msg) | 210 function rewriteRelatedNodes(msg, nodeId) |
| 151 { | 211 { |
| 152 if (msg.error) { | 212 if (msg.error) { |
| 153 throw new Error(msg.error.message); | 213 throw new Error(msg.error.message); |
| 154 } | 214 } |
| 155 | 215 |
| 156 var node = msg.result.nodes[0]; | |
| 157 | |
| 158 if (node.ignored) { | |
| 159 checkExists("result.nodes[0].ignoredReasons", msg); | |
| 160 var properties = node.ignoredReasons; | |
| 161 } else { | |
| 162 checkExists("result.nodes[0].properties", msg); | |
| 163 var properties = node.properties; | |
| 164 } | |
| 165 var promises = []; | 216 var promises = []; |
| 166 if (node.name && node.name.sources) { | 217 for (var node of msg.result.nodes) { |
| 167 for (var source of node.name.sources) { | 218 if (node.ignored) { |
| 219 checkExists("ignoredReasons", node); |
| 220 var properties = node.ignoredReasons; |
| 221 } else { |
| 222 checkExists("properties", node); |
| 223 var properties = node.properties; |
| 224 } |
| 225 if (node.name && node.name.sources) { |
| 226 for (var source of node.name.sources) { |
| 168 var value; | 227 var value; |
| 169 if (source.value) | 228 if (source.value) |
| 170 value = source.value; | 229 value = source.value; |
| 171 if (source.attributeValue) | 230 if (source.attributeValue) |
| 172 value = source.attributeValue; | 231 value = source.attributeValue; |
| 173 if (!value) | 232 if (!value) |
| 174 continue; | 233 continue; |
| 175 if (value.type === "idrefList" || | 234 if (value.type === "idrefList" || |
| 176 value.type === "idref" || | 235 value.type === "idref" || |
| 177 value.type === "nodeList") | 236 value.type === "nodeList") |
| 178 rewriteRelatedNodeValue(value, promises); | 237 rewriteRelatedNodeValue(value, promises); |
| 238 } |
| 179 } | 239 } |
| 180 } | 240 for (var property of properties) { |
| 181 for (var property of properties) { | 241 if (property.value.type === "idrefList" || |
| 182 if (property.value.type === "idrefList" || | 242 property.value.type === "idref" || |
| 183 property.value.type === "idref" || | 243 property.value.type === "nodeList") |
| 184 property.value.type === "nodeList") | 244 rewriteRelatedNodeValue(property.value, promises); |
| 185 rewriteRelatedNodeValue(property.value, promises); | 245 } |
| 246 rewriteBackendDomNodeId(node, nodeId, promises); |
| 186 } | 247 } |
| 187 return Promise.all(promises).then(() => { return msg; }); | 248 return Promise.all(promises).then(() => { return msg; }); |
| 188 } | 249 } |
| 189 | 250 |
| 190 function dumpNode(selector, msg) | 251 function dumpNode(msg) |
| 191 { | 252 { |
| 192 function stripIds(key, value) | 253 function stripIds(key, value) |
| 193 { | 254 { |
| 194 if (key == "id") | 255 var stripKeys = ["id", "backendDOMNodeId", "nodeId", "parentId"]; |
| 195 return "<int>" | 256 if (stripKeys.indexOf(key) !== -1) |
| 196 if (key == "backendNodeId") | 257 return "<" + typeof(value) + ">"; |
| 197 return "<string>" | 258 var deleteKeys = ["selected"]; |
| 198 if (key == "nodeId") | 259 if (deleteKeys.indexOf(key) !== -1) |
| 199 return "<string>" | 260 return undefined; |
| 200 return value; | 261 return value; |
| 201 } | 262 } |
| 202 InspectorTest.log((selector ? selector + ": " : "") + JSON.stringify(msg, st
ripIds, " ")); | 263 if (!msg.result || !msg.result.nodes || msg.result.nodes.length !== 1) { |
| 264 InspectorTest.log("Expected exactly one node in " + JSON.stringify(msg,
null, " ")); |
| 265 return; |
| 266 } |
| 267 InspectorTest.log(JSON.stringify(msg.result.nodes[0], stripIds, " ")); |
| 203 } | 268 } |
| 269 |
| 270 function dumpTreeStructure(msg) |
| 271 { |
| 272 function printNodeAndChildren(node, leadingSpace) |
| 273 { |
| 274 leadingSpace = leadingSpace || ""; |
| 275 var string = leadingSpace; |
| 276 if (node.selected) |
| 277 string += "*"; |
| 278 if (node.role) |
| 279 string += node.role.value; |
| 280 else |
| 281 string += "<no role>"; |
| 282 string += (node.name && node.name.value !== "" ? " \"" + node.name.value
+ "\"" : ""); |
| 283 if (node.children) { |
| 284 for (var child of node.children) |
| 285 string += "\n" + printNodeAndChildren(child, leadingSpace + " "
); |
| 286 } |
| 287 return string; |
| 288 } |
| 289 |
| 290 var rawMsg = JSON.stringify(msg, null, " "); |
| 291 var nodeMap = {}; |
| 292 if ("result" in msg && "nodes" in msg.result) { |
| 293 for (var node of msg.result.nodes) |
| 294 nodeMap[node.nodeId] = node; |
| 295 } |
| 296 for (var nodeId in nodeMap) { |
| 297 var node = nodeMap[nodeId]; |
| 298 if (node.childIds) { |
| 299 node.children = []; |
| 300 for (var i = 0; i < node.childIds.length && node.childIds.length > 0
;) { |
| 301 var childId = node.childIds[i]; |
| 302 if (childId in nodeMap) { |
| 303 var child = nodeMap[childId]; |
| 304 child.parentId = nodeId; |
| 305 node.children.push(child); |
| 306 |
| 307 node.childIds.splice(i, 1); |
| 308 } else { |
| 309 node.childIds[i] = "<string>"; |
| 310 i++; |
| 311 } |
| 312 } |
| 313 if (!node.childIds.length) |
| 314 delete node.childIds; |
| 315 if (!node.children.length) |
| 316 delete node.children; |
| 317 } |
| 318 } |
| 319 var rootNode = Object.values(nodeMap).find((node) => !("parentId" in node)); |
| 320 for (var node of Object.values(nodeMap)) |
| 321 delete node.parentId; |
| 322 |
| 323 InspectorTest.log("\n" + printNodeAndChildren(rootNode)); |
| 204 } | 324 } |
| 325 |
| 326 } |
| OLD | NEW |