browser_tableWidget_keyboard_interaction.js (4804B)
1 /* Any copyright is dedicated to the Public Domain. 2 http://creativecommons.org/publicdomain/zero/1.0/ */ 3 4 // Tests that keyboard interaction works fine with the table widget 5 6 "use strict"; 7 8 const TEST_URI = CHROME_URL_ROOT + "doc_tableWidget_keyboard_interaction.xhtml"; 9 const TEST_OPT = "chrome,titlebar,toolbar,centerscreen,resizable,dialog=no"; 10 11 const { 12 TableWidget, 13 } = require("resource://devtools/client/shared/widgets/TableWidget.js"); 14 15 var doc, table; 16 17 function test() { 18 waitForExplicitFinish(); 19 const win = Services.ww.openWindow(null, TEST_URI, "_blank", TEST_OPT, null); 20 21 win.addEventListener( 22 "load", 23 function () { 24 waitForFocus(function () { 25 doc = win.document; 26 table = new TableWidget(doc.querySelector("box"), { 27 initialColumns: { 28 col1: "Column 1", 29 col2: "Column 2", 30 col3: "Column 3", 31 col4: "Column 4", 32 }, 33 uniqueId: "col1", 34 emptyText: "dummy-text", 35 highlightUpdated: true, 36 removableColumns: true, 37 l10n: { 38 setAttributes() {}, 39 }, 40 }); 41 startTests(); 42 }); 43 }, 44 { once: true } 45 ); 46 } 47 48 function endTests() { 49 table.destroy(); 50 doc.defaultView.close(); 51 doc = table = null; 52 finish(); 53 } 54 55 var startTests = async function () { 56 populateTable(); 57 await testKeyboardInteraction(); 58 endTests(); 59 }; 60 61 function populateTable() { 62 table.push({ 63 col1: "id1", 64 col2: "value10", 65 col3: "value20", 66 col4: "value30", 67 }); 68 table.push({ 69 col1: "id2", 70 col2: "value14", 71 col3: "value29", 72 col4: "value32", 73 }); 74 table.push({ 75 col1: "id3", 76 col2: "value17", 77 col3: "value21", 78 col4: "value31", 79 extraData: "foobar", 80 extraData2: 42, 81 }); 82 table.push({ 83 col1: "id4", 84 col2: "value12", 85 col3: "value26", 86 col4: "value33", 87 }); 88 table.push({ 89 col1: "id5", 90 col2: "value19", 91 col3: "value26", 92 col4: "value37", 93 }); 94 table.push({ 95 col1: "id6", 96 col2: "value15", 97 col3: "value25", 98 col4: "value37", 99 }); 100 table.push({ 101 col1: "id7", 102 col2: "value18", 103 col3: "value21", 104 col4: "value36", 105 somethingExtra: "Hello World!", 106 }); 107 table.push({ 108 col1: "id8", 109 col2: "value11", 110 col3: "value27", 111 col4: "value34", 112 }); 113 table.push({ 114 col1: "id9", 115 col2: "value11", 116 col3: "value23", 117 col4: "value38", 118 }); 119 } 120 121 // Sends a click event on the passed DOM node in an async manner 122 function click(node, button = 0) { 123 if (button == 0) { 124 executeSoon(() => 125 EventUtils.synthesizeMouseAtCenter(node, {}, doc.defaultView) 126 ); 127 } else { 128 executeSoon(() => 129 EventUtils.synthesizeMouseAtCenter( 130 node, 131 { 132 button, 133 type: "contextmenu", 134 }, 135 doc.defaultView 136 ) 137 ); 138 } 139 } 140 141 function getNodeByValue(value) { 142 return table.tbody.querySelector("[value=" + value + "]"); 143 } 144 145 /** 146 * Tests if pressing navigation keys on the table items does the expected 147 * behavior. 148 */ 149 var testKeyboardInteraction = async function () { 150 info("Testing keyboard interaction with the table"); 151 info("clicking on the row containing id2"); 152 const node = getNodeByValue("id2"); 153 const event = table.once(TableWidget.EVENTS.ROW_SELECTED); 154 click(node); 155 await event; 156 157 await testRow("id3", "DOWN", "next row"); 158 await testRow("id4", "DOWN", "next row"); 159 await testRow("id3", "UP", "previous row"); 160 await testRow("id4", "DOWN", "next row"); 161 await testRow("id5", "DOWN", "next row"); 162 await testRow("id6", "DOWN", "next row"); 163 await testRow("id5", "UP", "previous row"); 164 await testRow("id4", "UP", "previous row"); 165 await testRow("id3", "UP", "previous row"); 166 167 // selecting last item node to test edge navigation cycling case 168 table.selectedRow = "id9"; 169 170 // pressing down on last row should move to first row. 171 await testRow("id1", "DOWN", "first row"); 172 173 // pressing up now should move to last row. 174 await testRow("id9", "UP", "last row"); 175 }; 176 177 async function testRow(id, key, destination) { 178 const node = getNodeByValue(id); 179 // node should not have selected class 180 ok( 181 !node.classList.contains("theme-selected"), 182 "Row should not have selected class" 183 ); 184 info(`Pressing ${key} to select ${destination}`); 185 186 const event = table.once(TableWidget.EVENTS.ROW_SELECTED); 187 EventUtils.sendKey(key, doc.defaultView); 188 189 const uniqueId = await event; 190 is(id, uniqueId, `Correct row was selected after pressing ${key}`); 191 192 ok(node.classList.contains("theme-selected"), "row has selected class"); 193 194 const nodes = doc.querySelectorAll(".theme-selected"); 195 for (let i = 0; i < nodes.length; i++) { 196 is( 197 nodes[i].getAttribute("data-id"), 198 id, 199 "Correct cell selected in all columns" 200 ); 201 } 202 }