browser_accessibility_mutations.js (4910B)
1 /* Any copyright is dedicated to the Public Domain. 2 * http://creativecommons.org/publicdomain/zero/1.0/ */ 3 4 "use strict"; 5 6 const TEST_URI = `<html> 7 <head> 8 <meta charset="utf-8"/> 9 <title>Accessibility Panel Test</title> 10 </head> 11 <body> 12 <h1 id="h1">Top level header</h1> 13 <p id="p">This is a paragraph.</p> 14 </body> 15 </html>`; 16 17 const documentRow = { 18 role: "document", 19 name: `"Accessibility Panel Test"`, 20 }; 21 const documentRowOOP = { 22 role: "document", 23 name: `""text label`, 24 badges: ["text label"], 25 }; 26 const subtree = [ 27 { 28 role: "heading", 29 name: `"Top level header"`, 30 }, 31 { 32 role: "text leaf", 33 name: `"Top level header"`, 34 }, 35 { 36 role: "paragraph", 37 name: `""`, 38 }, 39 ]; 40 const frameSubtree = [ 41 { role: "internal frame", name: `"Accessibility Panel Test (OOP)"` }, 42 { 43 role: "document", 44 name: `"Accessibility Panel Test (OOP)"`, 45 }, 46 ]; 47 const subtreeOOP = [...frameSubtree, ...subtree]; 48 const renamed = [ 49 { 50 role: "heading", 51 name: `"New Header"`, 52 }, 53 { 54 role: "text leaf", 55 name: `"New Header"`, 56 }, 57 ]; 58 const paragraphSidebar = { 59 name: null, 60 role: "paragraph", 61 actions: [], 62 value: "", 63 description: "", 64 keyboardShortcut: "", 65 childCount: 1, 66 indexInParent: 1, 67 states: ["selectable text", "opaque", "enabled", "sensitive"], 68 }; 69 const headerSidebar = { 70 name: "Top level header", 71 role: "text leaf", 72 }; 73 const newHeaderSidebar = { 74 name: "New Header", 75 }; 76 77 function removeRow(rowNumber) { 78 return async ({ doc, browser }) => { 79 is( 80 doc.querySelectorAll(".treeRow").length, 81 rowNumber, 82 "Tree size is correct." 83 ); 84 await SpecialPowers.spawn(browser, [], async () => { 85 const iframe = content.document.getElementsByTagName("iframe")[0]; 86 if (iframe) { 87 await SpecialPowers.spawn(iframe, [], () => 88 content.document.getElementById("p").remove() 89 ); 90 return; 91 } 92 93 content.document.getElementById("p").remove(); 94 }); 95 await BrowserTestUtils.waitForCondition( 96 () => doc.querySelectorAll(".treeRow").length === rowNumber - 1, 97 "Tree updated." 98 ); 99 }; 100 } 101 102 async function rename({ browser }) { 103 await SpecialPowers.spawn(browser, [], async () => { 104 const iframe = content.document.getElementsByTagName("iframe")[0]; 105 if (iframe) { 106 await SpecialPowers.spawn( 107 iframe, 108 [], 109 () => (content.document.getElementById("h1").textContent = "New Header") 110 ); 111 return; 112 } 113 114 content.document.getElementById("h1").textContent = "New Header"; 115 }); 116 } 117 118 /** 119 * Test data has the format of: 120 * { 121 * desc {String} description for better logging 122 * setup {Function} An optional setup that needs to be performed before 123 * the state of the tree and the sidebar can be checked. 124 * expected {JSON} An expected states for the tree and the sidebar. 125 * } 126 */ 127 const testsTopLevel = [ 128 { 129 desc: "Expand first and second rows, select third row.", 130 setup: async ({ doc }) => { 131 await toggleRow(doc, 0); 132 await toggleRow(doc, 1); 133 selectRow(doc, 3); 134 }, 135 expected: { 136 tree: [documentRow, ...subtree], 137 sidebar: paragraphSidebar, 138 }, 139 }, 140 { 141 desc: "Remove a child from a document.", 142 setup: removeRow(4), 143 expected: { 144 tree: [documentRow, ...subtree.slice(0, -1)], 145 sidebar: headerSidebar, 146 }, 147 }, 148 { 149 desc: "Update child's text content.", 150 setup: rename, 151 expected: { 152 tree: [documentRow, ...renamed], 153 }, 154 }, 155 { 156 desc: "Select third row in the tree.", 157 setup: ({ doc }) => selectRow(doc, 1), 158 expected: { 159 sidebar: newHeaderSidebar, 160 }, 161 }, 162 ]; 163 164 const testsOOP = [ 165 { 166 desc: "Expand rows until we reach an internal OOP frame.", 167 setup: async ({ doc }) => { 168 await toggleRow(doc, 0); 169 await toggleRow(doc, 1); 170 await toggleRow(doc, 2); 171 await toggleRow(doc, 3); 172 selectRow(doc, 5); 173 }, 174 expected: { 175 tree: [documentRowOOP, ...subtreeOOP], 176 sidebar: paragraphSidebar, 177 }, 178 }, 179 { 180 desc: "Remove a child from a document.", 181 setup: removeRow(6), 182 expected: { 183 tree: [documentRowOOP, ...subtreeOOP.slice(0, -1)], 184 sidebar: headerSidebar, 185 }, 186 }, 187 { 188 desc: "Update child's text content.", 189 setup: rename, 190 expected: { 191 tree: [documentRowOOP, ...frameSubtree, ...renamed], 192 }, 193 }, 194 { 195 desc: "Select third row in the tree.", 196 setup: ({ doc }) => selectRow(doc, 1), 197 expected: { 198 sidebar: newHeaderSidebar, 199 }, 200 }, 201 ]; 202 203 /** 204 * Tests that checks the Accessibility panel after DOM tree mutations. 205 */ 206 addA11yPanelTestsTask( 207 testsTopLevel, 208 TEST_URI, 209 "Test Accessibility panel after DOM tree mutations." 210 ); 211 212 addA11yPanelTestsTask( 213 testsOOP, 214 TEST_URI, 215 "Test Accessibility panel after DOM tree mutations in the OOP frame.", 216 { remoteIframe: true } 217 );