browser_boxmodel_navigation.js (6607B)
1 /* Any copyright is dedicated to the Public Domain. 2 http://creativecommons.org/publicdomain/zero/1.0/ */ 3 4 "use strict"; 5 6 // Tests that keyboard and mouse navigation updates aria-active and focus 7 // of elements. 8 9 const TEST_URI = ` 10 <style> 11 div { position: absolute; top: 42px; left: 42px; 12 height: 100.111px; width: 100px; border: 10px solid black; 13 padding: 20px; margin: 30px auto;} 14 </style><div></div> 15 `; 16 17 add_task(async function () { 18 await addTab("data:text/html," + encodeURIComponent(TEST_URI)); 19 const { inspector, boxmodel } = await openLayoutView(); 20 await selectNode("div", inspector); 21 22 await testInitialFocus(inspector, boxmodel); 23 await testChangingLevels(inspector, boxmodel); 24 await testTabbingThroughItems(inspector, boxmodel); 25 await testChangingLevelsByClicking(inspector, boxmodel); 26 }); 27 28 function testInitialFocus(inspector, boxmodel) { 29 info("Test that the focus is(on margin layout."); 30 const doc = boxmodel.document; 31 const container = doc.querySelector(".boxmodel-container"); 32 container.focus(); 33 EventUtils.synthesizeKey("KEY_Enter"); 34 35 is( 36 container.dataset.activeDescendantClassName, 37 "boxmodel-main devtools-monospace", 38 "Should be set to the position layout." 39 ); 40 } 41 42 function testChangingLevels(inspector, boxmodel) { 43 info("Test that using arrow keys updates level."); 44 const doc = boxmodel.document; 45 const container = doc.querySelector(".boxmodel-container"); 46 container.focus(); 47 EventUtils.synthesizeKey("KEY_Enter"); 48 EventUtils.synthesizeKey("KEY_Escape"); 49 50 EventUtils.synthesizeKey("KEY_ArrowDown"); 51 is( 52 container.dataset.activeDescendantClassName, 53 "boxmodel-margins", 54 "Should be set to the margin layout." 55 ); 56 57 EventUtils.synthesizeKey("KEY_ArrowDown"); 58 is( 59 container.dataset.activeDescendantClassName, 60 "boxmodel-borders", 61 "Should be set to the border layout." 62 ); 63 64 EventUtils.synthesizeKey("KEY_ArrowDown"); 65 is( 66 container.dataset.activeDescendantClassName, 67 "boxmodel-paddings", 68 "Should be set to the padding layout." 69 ); 70 71 EventUtils.synthesizeKey("KEY_ArrowDown"); 72 is( 73 container.dataset.activeDescendantClassName, 74 "boxmodel-contents", 75 "Should be set to the content layout." 76 ); 77 78 EventUtils.synthesizeKey("KEY_ArrowUp"); 79 is( 80 container.dataset.activeDescendantClassName, 81 "boxmodel-paddings", 82 "Should be set to the padding layout." 83 ); 84 85 EventUtils.synthesizeKey("KEY_ArrowUp"); 86 is( 87 container.dataset.activeDescendantClassName, 88 "boxmodel-borders", 89 "Should be set to the border layout." 90 ); 91 92 EventUtils.synthesizeKey("KEY_ArrowUp"); 93 is( 94 container.dataset.activeDescendantClassName, 95 "boxmodel-margins", 96 "Should be set to the margin layout." 97 ); 98 99 EventUtils.synthesizeKey("KEY_ArrowUp"); 100 is( 101 container.dataset.activeDescendantClassName, 102 "boxmodel-main devtools-monospace", 103 "Should be set to the position layout." 104 ); 105 } 106 107 function testTabbingThroughItems(inspector, boxmodel) { 108 info("Test that using Tab key moves focus to next/previous input field."); 109 const doc = boxmodel.document; 110 const container = doc.querySelector(".boxmodel-container"); 111 container.focus(); 112 EventUtils.synthesizeKey("KEY_Enter"); 113 114 const editBoxes = [...doc.querySelectorAll("[data-box].boxmodel-editable")]; 115 116 const editBoxesInfo = [ 117 { name: "position-top", itemId: "position-top-id" }, 118 { name: "position-right", itemId: "position-right-id" }, 119 { name: "position-bottom", itemId: "position-bottom-id" }, 120 { name: "position-left", itemId: "position-left-id" }, 121 { name: "margin-top", itemId: "margin-top-id" }, 122 { name: "margin-right", itemId: "margin-right-id" }, 123 { name: "margin-bottom", itemId: "margin-bottom-id" }, 124 { name: "margin-left", itemId: "margin-left-id" }, 125 { name: "border-top-width", itemId: "border-top-width-id" }, 126 { name: "border-right-width", itemId: "border-right-width-id" }, 127 { name: "border-bottom-width", itemId: "border-bottom-width-id" }, 128 { name: "border-left-width", itemId: "border-left-width-id" }, 129 { name: "padding-top", itemId: "padding-top-id" }, 130 { name: "padding-right", itemId: "padding-right-id" }, 131 { name: "padding-bottom", itemId: "padding-bottom-id" }, 132 { name: "padding-left", itemId: "padding-left-id" }, 133 { name: "width", itemId: "width-id" }, 134 { name: "height", itemId: "height-id" }, 135 ]; 136 137 // Check whether tabbing through box model items works 138 // Note that the test checks whether wrapping around the box model works 139 // by letting the loop run beyond the number of indexes to start with 140 // the first item again. 141 for (let i = 0; i <= editBoxesInfo.length; i++) { 142 const itemIndex = i % editBoxesInfo.length; 143 const editBoxInfo = editBoxesInfo[itemIndex]; 144 is( 145 editBoxes[itemIndex].parentElement.id, 146 editBoxInfo.itemId, 147 `${editBoxInfo.name} item is current` 148 ); 149 is( 150 editBoxes[itemIndex].previousElementSibling?.localName, 151 "input", 152 `Input shown for ${editBoxInfo.name} item` 153 ); 154 155 // Pressing Tab should not be synthesized for the last item to 156 // wrap to the very last item again when tabbing in reversed order. 157 if (i < editBoxesInfo.length) { 158 EventUtils.synthesizeKey("KEY_Tab"); 159 } 160 } 161 162 // Check whether reversed tabbing through box model items works 163 for (let i = editBoxesInfo.length; i >= 0; i--) { 164 const itemIndex = i % editBoxesInfo.length; 165 const editBoxInfo = editBoxesInfo[itemIndex]; 166 is( 167 editBoxes[itemIndex].parentElement.id, 168 editBoxInfo.itemId, 169 `${editBoxInfo.name} item is current` 170 ); 171 is( 172 editBoxes[itemIndex].previousElementSibling?.localName, 173 "input", 174 `Input shown for ${editBoxInfo.name} item` 175 ); 176 EventUtils.synthesizeKey("KEY_Tab", { shiftKey: true }); 177 } 178 } 179 180 function testChangingLevelsByClicking(inspector, boxmodel) { 181 info("Test that clicking on levels updates level."); 182 const doc = boxmodel.document; 183 const container = doc.querySelector(".boxmodel-container"); 184 container.focus(); 185 186 const marginLayout = doc.querySelector(".boxmodel-margins"); 187 const borderLayout = doc.querySelector(".boxmodel-borders"); 188 const paddingLayout = doc.querySelector(".boxmodel-paddings"); 189 const contentLayout = doc.querySelector(".boxmodel-contents"); 190 const layouts = [contentLayout, paddingLayout, borderLayout, marginLayout]; 191 192 layouts.forEach(layout => { 193 layout.click(); 194 is( 195 container.dataset.activeDescendantClassName, 196 layout.className, 197 `Should be set to ${layout.getAttribute("data-box")} layout.` 198 ); 199 }); 200 }