browser_accessibility_print_to_json.js (6175B)
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 = "<h1>Top level header</h1>"; 7 8 function getMenuItems(toolbox) { 9 const menuDoc = toolbox.doc.defaultView.windowRoot.ownerGlobal.document; 10 const menu = menuDoc.getElementById("accessibility-row-contextmenu"); 11 return { 12 menu, 13 items: [...menu.getElementsByTagName("menuitem")], 14 }; 15 } 16 17 async function newTabSelected(tab) { 18 info("Waiting for the JSON viewer tab."); 19 await BrowserTestUtils.waitForCondition( 20 () => gBrowser.selectedTab !== tab, 21 "Current tab updated." 22 ); 23 return gBrowser.selectedTab; 24 } 25 26 function parseSnapshotFromTabURI(tab) { 27 let snapshot = tab.label.split("data:application/json;charset=UTF-8,")[1]; 28 snapshot = decodeURIComponent(snapshot); 29 return JSON.parse(snapshot); 30 } 31 32 async function checkJSONSnapshotForRow({ doc, tab, toolbox }, index, expected) { 33 info(`Triggering context menu for row #${index}.`); 34 EventUtils.synthesizeMouseAtCenter( 35 doc.querySelectorAll(".treeRow")[index], 36 { type: "contextmenu" }, 37 doc.defaultView 38 ); 39 40 info(`Triggering "Print To JSON" menu item for row ${index}.`); 41 const { 42 menu, 43 items: [printToJSON], 44 } = getMenuItems(toolbox); 45 46 await BrowserTestUtils.waitForPopupEvent(menu, "shown"); 47 48 menu.activateItem(printToJSON); 49 50 const jsonViewTab = await newTabSelected(tab); 51 Assert.deepEqual( 52 parseSnapshotFromTabURI(jsonViewTab), 53 expected, 54 "JSON snapshot for the whole document is correct" 55 ); 56 57 await removeTab(jsonViewTab); 58 } 59 60 const OOP_FRAME_DOCUMENT_SNAPSHOT = { 61 childCount: 1, 62 description: "", 63 indexInParent: 0, 64 keyboardShortcut: "", 65 name: "Accessibility Panel Test (OOP)", 66 nodeCssSelector: "", 67 nodeType: 9, 68 role: "document", 69 value: "", 70 actions: [], 71 attributes: { 72 display: "block", 73 "explicit-name": "true", 74 "margin-bottom": "8px", 75 "margin-left": "8px", 76 "margin-right": "8px", 77 "margin-top": "8px", 78 tag: "body", 79 "text-align": "start", 80 "text-indent": "0px", 81 }, 82 states: [ 83 "readonly", 84 "focusable", 85 "selectable text", 86 "opaque", 87 "enabled", 88 "sensitive", 89 ], 90 children: [ 91 { 92 childCount: 1, 93 description: "", 94 indexInParent: 0, 95 keyboardShortcut: "", 96 name: "Top level header", 97 nodeCssSelector: "body > h1:nth-child(1)", 98 nodeType: 1, 99 role: "heading", 100 value: "", 101 actions: [], 102 attributes: { 103 display: "block", 104 formatting: "block", 105 level: "1", 106 "margin-bottom": "21.44px", 107 "margin-left": "0px", 108 "margin-right": "0px", 109 "margin-top": "0px", 110 tag: "h1", 111 "text-align": "start", 112 "text-indent": "0px", 113 }, 114 states: ["selectable text", "opaque", "enabled", "sensitive"], 115 children: [ 116 { 117 childCount: 0, 118 description: "", 119 indexInParent: 0, 120 keyboardShortcut: "", 121 name: "Top level header", 122 nodeCssSelector: "body > h1:nth-child(1)#text", 123 nodeType: 3, 124 role: "text leaf", 125 value: "", 126 actions: [], 127 attributes: { 128 "explicit-name": "true", 129 }, 130 states: ["opaque", "enabled", "sensitive"], 131 children: [], 132 }, 133 ], 134 }, 135 ], 136 }; 137 138 const OOP_FRAME_SNAPSHOT = { 139 childCount: 1, 140 description: "", 141 indexInParent: 0, 142 keyboardShortcut: "", 143 name: "Accessibility Panel Test (OOP)", 144 nodeCssSelector: "body > iframe:nth-child(1)", 145 nodeType: 1, 146 role: "internal frame", 147 value: "", 148 actions: [], 149 attributes: { 150 display: "inline", 151 "explicit-name": "true", 152 "margin-bottom": "0px", 153 "margin-left": "0px", 154 "margin-right": "0px", 155 "margin-top": "0px", 156 tag: "iframe", 157 "text-align": "start", 158 "text-indent": "0px", 159 }, 160 states: ["focusable", "opaque", "enabled", "sensitive"], 161 children: [OOP_FRAME_DOCUMENT_SNAPSHOT], 162 }; 163 164 const EXPECTED_SNAPSHOT = { 165 childCount: 1, 166 description: "", 167 indexInParent: 0, 168 keyboardShortcut: "", 169 name: null, 170 nodeCssSelector: "", 171 nodeType: 9, 172 role: "document", 173 value: "", 174 actions: [], 175 attributes: { 176 display: "block", 177 "margin-bottom": "8px", 178 "margin-left": "8px", 179 "margin-right": "8px", 180 "margin-top": "8px", 181 tag: "body", 182 "text-align": "start", 183 "text-indent": "0px", 184 }, 185 states: [ 186 "readonly", 187 "focusable", 188 "selectable text", 189 "opaque", 190 "enabled", 191 "sensitive", 192 ], 193 children: [OOP_FRAME_SNAPSHOT], 194 }; 195 196 addA11YPanelTask( 197 "Test print to JSON functionality.", 198 TEST_URI, 199 async env => { 200 const { doc } = env; 201 await runA11yPanelTests( 202 [ 203 { 204 desc: "Test the initial accessibility tree.", 205 expected: { 206 tree: [ 207 { 208 role: "document", 209 name: `""text label`, 210 badges: ["text label"], 211 }, 212 ], 213 }, 214 }, 215 ], 216 env 217 ); 218 219 await toggleRow(doc, 0); 220 await toggleRow(doc, 1); 221 222 await runA11yPanelTests( 223 [ 224 { 225 desc: "Test expanded accessibility tree.", 226 expected: { 227 tree: [ 228 { 229 role: "document", 230 name: `""text label`, 231 badges: ["text label"], 232 }, 233 { 234 role: "internal frame", 235 name: `"Accessibility Panel Test (OOP)"`, 236 }, 237 { 238 role: "document", 239 name: `"Accessibility Panel Test (OOP)"`, 240 }, 241 ], 242 }, 243 }, 244 ], 245 env 246 ); 247 248 // Complete snapshot that includes OOP frame document (crossing process boundry). 249 await checkJSONSnapshotForRow(env, 0, EXPECTED_SNAPSHOT); 250 // Snapshot of an OOP frame (crossing process boundry). 251 await checkJSONSnapshotForRow(env, 1, OOP_FRAME_SNAPSHOT); 252 // Snapshot of an OOP frame document (not crossing process boundry). 253 await checkJSONSnapshotForRow(env, 2, OOP_FRAME_DOCUMENT_SNAPSHOT); 254 }, 255 { 256 remoteIframe: true, 257 } 258 );