diff options
Diffstat (limited to 'devtools/client/shared/test/browser_tableWidget_keyboard_interaction.js')
-rw-r--r-- | devtools/client/shared/test/browser_tableWidget_keyboard_interaction.js | 202 |
1 files changed, 202 insertions, 0 deletions
diff --git a/devtools/client/shared/test/browser_tableWidget_keyboard_interaction.js b/devtools/client/shared/test/browser_tableWidget_keyboard_interaction.js new file mode 100644 index 0000000000..293ac71e7f --- /dev/null +++ b/devtools/client/shared/test/browser_tableWidget_keyboard_interaction.js @@ -0,0 +1,202 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +// Tests that keyboard interaction works fine with the table widget + +"use strict"; + +const TEST_URI = CHROME_URL_ROOT + "doc_tableWidget_keyboard_interaction.xhtml"; +const TEST_OPT = "chrome,titlebar,toolbar,centerscreen,resizable,dialog=no"; + +const { + TableWidget, +} = require("resource://devtools/client/shared/widgets/TableWidget.js"); + +var doc, table; + +function test() { + waitForExplicitFinish(); + const win = Services.ww.openWindow(null, TEST_URI, "_blank", TEST_OPT, null); + + win.addEventListener( + "load", + function () { + waitForFocus(function () { + doc = win.document; + table = new TableWidget(doc.querySelector("box"), { + initialColumns: { + col1: "Column 1", + col2: "Column 2", + col3: "Column 3", + col4: "Column 4", + }, + uniqueId: "col1", + emptyText: "dummy-text", + highlightUpdated: true, + removableColumns: true, + l10n: { + setAttributes() {}, + }, + }); + startTests(); + }); + }, + { once: true } + ); +} + +function endTests() { + table.destroy(); + doc.defaultView.close(); + doc = table = null; + finish(); +} + +var startTests = async function () { + populateTable(); + await testKeyboardInteraction(); + endTests(); +}; + +function populateTable() { + table.push({ + col1: "id1", + col2: "value10", + col3: "value20", + col4: "value30", + }); + table.push({ + col1: "id2", + col2: "value14", + col3: "value29", + col4: "value32", + }); + table.push({ + col1: "id3", + col2: "value17", + col3: "value21", + col4: "value31", + extraData: "foobar", + extraData2: 42, + }); + table.push({ + col1: "id4", + col2: "value12", + col3: "value26", + col4: "value33", + }); + table.push({ + col1: "id5", + col2: "value19", + col3: "value26", + col4: "value37", + }); + table.push({ + col1: "id6", + col2: "value15", + col3: "value25", + col4: "value37", + }); + table.push({ + col1: "id7", + col2: "value18", + col3: "value21", + col4: "value36", + somethingExtra: "Hello World!", + }); + table.push({ + col1: "id8", + col2: "value11", + col3: "value27", + col4: "value34", + }); + table.push({ + col1: "id9", + col2: "value11", + col3: "value23", + col4: "value38", + }); +} + +// Sends a click event on the passed DOM node in an async manner +function click(node, button = 0) { + if (button == 0) { + executeSoon(() => + EventUtils.synthesizeMouseAtCenter(node, {}, doc.defaultView) + ); + } else { + executeSoon(() => + EventUtils.synthesizeMouseAtCenter( + node, + { + button, + type: "contextmenu", + }, + doc.defaultView + ) + ); + } +} + +function getNodeByValue(value) { + return table.tbody.querySelector("[value=" + value + "]"); +} + +/** + * Tests if pressing navigation keys on the table items does the expected + * behavior. + */ +var testKeyboardInteraction = async function () { + info("Testing keyboard interaction with the table"); + info("clicking on the row containing id2"); + const node = getNodeByValue("id2"); + const event = table.once(TableWidget.EVENTS.ROW_SELECTED); + click(node); + await event; + + await testRow("id3", "DOWN", "next row"); + await testRow("id4", "DOWN", "next row"); + await testRow("id3", "UP", "previous row"); + await testRow("id4", "DOWN", "next row"); + await testRow("id5", "DOWN", "next row"); + await testRow("id6", "DOWN", "next row"); + await testRow("id5", "UP", "previous row"); + await testRow("id4", "UP", "previous row"); + await testRow("id3", "UP", "previous row"); + + // selecting last item node to test edge navigation cycling case + table.selectedRow = "id9"; + + // pressing down on last row should move to first row. + await testRow("id1", "DOWN", "first row"); + + // pressing up now should move to last row. + await testRow("id9", "UP", "last row"); +}; + +async function testRow(id, key, destination) { + const node = getNodeByValue(id); + // node should not have selected class + ok( + !node.classList.contains("theme-selected"), + "Row should not have selected class" + ); + info(`Pressing ${key} to select ${destination}`); + + const event = table.once(TableWidget.EVENTS.ROW_SELECTED); + EventUtils.sendKey(key, doc.defaultView); + + const uniqueId = await event; + is(id, uniqueId, `Correct row was selected after pressing ${key}`); + + ok(node.classList.contains("theme-selected"), "row has selected class"); + + const nodes = doc.querySelectorAll(".theme-selected"); + for (let i = 0; i < nodes.length; i++) { + is( + nodes[i].getAttribute("data-id"), + id, + "Correct cell selected in all columns" + ); + } +} |