test_general.html (7080B)
1 <!DOCTYPE HTML> 2 <html> 3 <head> 4 <meta charset="utf-8"> 5 <title>Accessibility API: generic</title> 6 <link rel="stylesheet" type="text/css" 7 href="chrome://mochikit/content/tests/SimpleTest/test.css"> 8 <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> 9 <script> 10 "use strict"; 11 12 SimpleTest.waitForExplicitFinish(); 13 const finish = SimpleTest.finish.bind(SimpleTest); 14 enablePref() 15 .then(createIframe) 16 .then(checkImplementation) 17 .catch(err => { 18 dump(`${err}: ${err.stack}`); 19 finish(); 20 }); 21 22 function enablePref() { 23 const ops = { 24 "set": [ 25 [ "accessibility.AOM.enabled", true ], 26 ], 27 }; 28 return SpecialPowers.pushPrefEnv(ops); 29 } 30 31 // WebIDL conditional annotations for an interface are evaluated once per 32 // global, so we need to create an iframe to see the effects of calling 33 // enablePref(). 34 function createIframe() { 35 return new Promise((resolve) => { 36 let iframe = document.createElement("iframe"); 37 iframe.src = `data:text/html,<html><title>hello</title><body>hey</body></html>`; 38 iframe.onload = () => resolve(iframe.contentDocument); 39 document.body.appendChild(iframe); 40 document.body.offsetTop; // We rely on the a11y tree being created 41 // already, and it's created off layout. 42 }); 43 } 44 45 function testStringProp(anode, prop) { 46 is(anode[prop], null, `anode.${prop} should be null`); 47 let text = "This is a string test"; 48 anode[prop] = text; 49 is(anode[prop], text, `anode.${prop} was assigned "${text}"`); 50 anode[prop] = null; 51 is(anode[prop], null, `anode.${prop} was assigned null`); 52 } 53 54 function testBoolProp(anode, prop) { 55 is(anode[prop], null, `anode.${prop} should be null`); 56 anode[prop] = true; 57 is(anode[prop], true, `anode.${prop} was assigned true`); 58 anode[prop] = false; 59 is(anode[prop], false, `anode.${prop} was assigned false`); 60 anode[prop] = null; 61 is(anode[prop], null, `anode.${prop} was assigned null`); 62 } 63 64 function testDoubleProp(anode, prop) { 65 is(anode[prop], null, `anode.${prop} should be null`); 66 anode[prop] = Number.MAX_VALUE; 67 is(anode[prop], Number.MAX_VALUE, `anode.${prop} was assigned ${Number.MAX_VALUE}`); 68 anode[prop] = null; 69 is(anode[prop], null, `anode.${prop} was assigned null`); 70 } 71 72 function testIntProp(anode, prop) { 73 is(anode[prop], null, `anode.${prop} should be null`); 74 anode[prop] = -1; 75 is(anode[prop], -1, `anode.${prop} was assigned -1`); 76 anode[prop] = null; 77 is(anode[prop], null, `anode.${prop} was assigned null`); 78 } 79 80 function testUIntProp(anode, prop) { 81 is(anode[prop], null, `anode.${prop} should be null`); 82 anode[prop] = 4294967295; 83 is(anode[prop], 4294967295, `anode.${prop} was assigned 4294967295`); 84 anode[prop] = null; 85 is(anode[prop], null, `anode.${prop} was assigned null`); 86 } 87 88 function testRelationProp(anode, node, prop) { 89 is(anode[prop], null, `anode.${prop} should be null`); 90 anode[prop] = node.accessibleNode; 91 is(anode[prop], node.accessibleNode, `anode.${prop} was assigned AccessibleNode`); 92 anode[prop] = null; 93 is(anode[prop], null, `anode.${prop} was assigned null`); 94 } 95 // Check that the WebIDL is as expected. 96 function checkImplementation(ifrDoc) { 97 let anode = ifrDoc.accessibleNode; 98 ok(anode, "DOM document has accessible node"); 99 100 is(anode.computedRole, "document", "correct role of a document accessible node"); 101 is(anode.DOMNode, ifrDoc, "correct DOM Node of a document accessible node"); 102 103 // States may differ depending on the document state, for example, if it is 104 // loaded or is loading still. 105 var states = null; 106 switch (anode.states.length) { 107 case 5: 108 states = [ 109 "readonly", "focusable", "opaque", "enabled", "sensitive", 110 ]; 111 break; 112 case 6: 113 states = [ 114 "readonly", "busy", "focusable", "opaque", "enabled", "sensitive", 115 ]; 116 break; 117 case 7: 118 states = [ 119 "readonly", "busy", "focusable", "opaque", "stale", "enabled", "sensitive", 120 ]; 121 break; 122 default: 123 ok(false, "Unexpected amount of states: " + JSON.stringify(anode.states)); 124 } 125 if (states) { 126 for (let i = 0; i < states.length; i++) { 127 is(anode.states[i], states[i], `${states[i]} state is expected at ${i}th index`); 128 } 129 } 130 131 ok(anode.is("document", "focusable"), 132 "correct role and state on an accessible node"); 133 134 is(anode.get("explicit-name"), "true", 135 "correct object attribute value on an accessible node"); 136 137 ok(anode.has("explicit-name"), 138 "object attributes are present"); 139 140 var attrs = [ "explicit-name" ]; 141 if (anode.attributes.length > 1) { 142 attrs = [ 143 "margin-left", "text-align", "text-indent", "margin-right", 144 "tag", "margin-top", "margin-bottom", "display", 145 "explicit-name", 146 ]; 147 } 148 149 is(anode.attributes.length, attrs.length, "correct number of attributes"); 150 for (let i = 0; i < attrs.length; i++) { 151 ok(attrs.includes(anode.attributes[i]), 152 `${anode.attributes[i]} attribute is expected and found`); 153 } 154 155 const strProps = ["autocomplete", "checked", "current", "hasPopUp", "invalid", 156 "keyShortcuts", "label", "live", "orientation", "placeholder", 157 "pressed", "relevant", "role", "roleDescription", "sort", 158 "valueText"]; 159 160 for (const strProp of strProps) { 161 testStringProp(anode, strProp); 162 } 163 164 const boolProps = ["atomic", "busy", "disabled", "expanded", "hidden", "modal", 165 "multiline", "multiselectable", "readOnly", "required", "selected"]; 166 167 for (const boolProp of boolProps) { 168 testBoolProp(anode, boolProp); 169 } 170 171 const doubleProps = ["valueMax", "valueMin", "valueNow"]; 172 173 for (const doubleProp of doubleProps) { 174 testDoubleProp(anode, doubleProp); 175 } 176 177 const intProps = ["colCount", "rowCount", "setSize"]; 178 179 for (const intProp of intProps) { 180 testIntProp(anode, intProp); 181 } 182 183 const uintProps = ["colIndex", "colSpan", "level", "posInSet", "rowIndex", "rowSpan"]; 184 185 for (const uintProp of uintProps) { 186 testUIntProp(anode, uintProp); 187 } 188 189 // Check if an AccessibleNode is properly cached. 190 let node = ifrDoc.createElement("div"); 191 anode = node.accessibleNode; 192 is(anode, node.accessibleNode, "an AccessibleNode is properly cached"); 193 194 // Adopting node to another document doesn't change .accessibleNode 195 let anotherDoc = ifrDoc.implementation.createDocument("", "", null); 196 let adopted_node = anotherDoc.adoptNode(node); 197 is(anode, adopted_node.accessibleNode, "adopting node to another document doesn't change node.accessibleNode"); 198 199 const relationProps = ["activeDescendant", "details", "errorMessage"]; 200 201 for (const relationProp of relationProps) { 202 testRelationProp(anode, node, relationProp); 203 } 204 205 finish(); 206 } 207 </script> 208 </head>