Source code

Revision control

Copy as Markdown

Other Tools

Test Info: Warnings

  • This test gets skipped with pattern: os == 'linux' && os_version == '18.04' && processor == 'x86_64' && opt OR os == 'linux' && os_version == '18.04' && processor == 'x86_64' && tsan OR os == 'linux' && os_version == '18.04' && processor == 'x86_64' && ccov
  • Manifest: devtools/client/shared/test/browser.toml
/* Any copyright is dedicated to the Public Domain.
// Tests that mosue interaction works fine with the table widget
"use strict";
const TEST_URI = CHROME_URL_ROOT + "doc_tableWidget_mouse_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: "This is dummy empty text",
highlightUpdated: true,
removableColumns: true,
wrapTextInElements: true,
l10n: {
setAttributes() {},
},
});
startTests();
});
},
{ once: true }
);
}
function endTests() {
table.destroy();
doc.defaultView.close();
doc = table = null;
finish();
}
var startTests = async function () {
populateTable();
await testMouseInteraction();
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
)
);
}
}
async function showCol(id) {
const onPopupHidden = once(table.menupopup, "popuphidden");
const event = table.once(TableWidget.EVENTS.HEADER_CONTEXT_MENU);
const menuItem = table.menupopup.querySelector(`[data-id='${id}']`);
const column = table.tbody.querySelector(`#${id}`);
info(`Showing ${id}`);
ok(BrowserTestUtils.isHidden(column), "Column is hidden before showing it");
table.menupopup.activateItem(menuItem);
const toShow = await event;
await onPopupHidden;
is(toShow, id, `#${id} was selected to be shown`);
ok(
BrowserTestUtils.isVisible(column),
"Column is not hidden after showing it"
);
}
async function hideCol(id) {
const onPopupHidden = once(table.menupopup, "popuphidden");
const event = table.once(TableWidget.EVENTS.HEADER_CONTEXT_MENU);
const menuItem = table.menupopup.querySelector(`[data-id='${id}']`);
const column = table.tbody.querySelector(`#${id}`);
info(`selecting to hide #${id}`);
ok(
BrowserTestUtils.isVisible(column),
`Column #${id} is not hidden before hiding it`
);
table.menupopup.activateItem(menuItem);
const toHide = await event;
await onPopupHidden;
is(toHide, id, `#${id} was selected to be hidden`);
ok(
BrowserTestUtils.isHidden(column),
`Column #${id} is hidden after hiding it`
);
}
/**
* Tests if clicking the table items does the expected behavior
*/
var testMouseInteraction = async function () {
info("Testing mouse interaction with the table");
ok(!table.selectedRow, "Nothing should be selected beforehand");
let event = table.once(TableWidget.EVENTS.ROW_SELECTED);
const firstColumnFirstRowCell = table.tbody.querySelector("[data-id=id1]");
info("clicking on the first row");
ok(
!firstColumnFirstRowCell.classList.contains("theme-selected"),
"Node should not have selected class before clicking"
);
click(firstColumnFirstRowCell);
let id = await event;
ok(
firstColumnFirstRowCell.classList.contains("theme-selected"),
"Node has selected class after click"
);
is(id, "id1", "Correct row was selected");
info("clicking on second row to select it");
event = table.once(TableWidget.EVENTS.ROW_SELECTED);
const firstColumnSecondRowCell = table.tbody.firstChild.children[2];
// node should not have selected class
ok(
!firstColumnSecondRowCell.classList.contains("theme-selected"),
"New node should not have selected class before clicking"
);
click(firstColumnSecondRowCell);
id = await event;
ok(
firstColumnSecondRowCell.classList.contains("theme-selected"),
"New node has selected class after clicking"
);
is(id, "id2", "Correct table path is emitted for new node");
isnot(
firstColumnFirstRowCell,
firstColumnSecondRowCell,
"Old and new node are different"
);
ok(
!firstColumnFirstRowCell.classList.contains("theme-selected"),
"Old node should not have selected class after the click on new node"
);
info("clicking on the third row cell content to select third row");
event = table.once(TableWidget.EVENTS.ROW_SELECTED);
const firstColumnThirdRowCell = table.tbody.firstChild.children[3];
const firstColumnThirdRowCellInnerNode =
firstColumnThirdRowCell.querySelector("span");
// node should not have selected class
ok(
!firstColumnThirdRowCell.classList.contains("theme-selected"),
"New node should not have selected class before clicking"
);
click(firstColumnThirdRowCellInnerNode);
id = await event;
ok(
firstColumnThirdRowCell.classList.contains("theme-selected"),
"New node has selected class after clicking the cell content"
);
is(id, "id3", "Correct table path is emitted for new node");
// clicking on table header to sort by it
event = table.once(TableWidget.EVENTS.COLUMN_SORTED);
let node = table.tbody.children[6].children[0];
info("clicking on the 4th coulmn header to sort the table by it");
ok(
!node.hasAttribute("sorted"),
"Node should not have sorted attribute before clicking"
);
ok(
doc.querySelector("[sorted]"),
"Although, something else should be sorted on"
);
isnot(doc.querySelector("[sorted]"), node, "Which is not equal to this node");
click(node);
id = await event;
is(id, "col4", "Correct column was sorted on");
ok(
node.hasAttribute("sorted"),
"Node should now have sorted attribute after clicking"
);
is(
doc.querySelectorAll("[sorted]").length,
1,
"Now only one column should be sorted on"
);
is(doc.querySelector("[sorted]"), node, "Which should be this column");
// test context menu opening.
// hiding second column
// event listener for popupshown
info("right click on the first column header");
node = table.tbody.firstChild.firstChild;
let onPopupShown = once(table.menupopup, "popupshown");
click(node, 2);
await onPopupShown;
is(
table.menupopup.querySelectorAll("menuitem[disabled]").length,
1,
"Only 1 menuitem is disabled"
);
is(
table.menupopup.querySelector("menuitem[disabled]"),
table.menupopup.querySelector("[data-id='col1']"),
"Which is the unique column"
);
// popup should be open now
// clicking on second column label
await hideCol("col2");
// hiding third column
// event listener for popupshown
info("right clicking on the first column header");
node = table.tbody.firstChild.firstChild;
onPopupShown = once(table.menupopup, "popupshown");
click(node, 2);
await onPopupShown;
is(
table.menupopup.querySelectorAll("menuitem[disabled]").length,
1,
"Only 1 menuitem is disabled"
);
await hideCol("col3");
// opening again to see if 2 items are disabled now
// event listener for popupshown
info("right clicking on the first column header");
node = table.tbody.firstChild.firstChild;
onPopupShown = once(table.menupopup, "popupshown");
click(node, 2);
await onPopupShown;
is(
table.menupopup.querySelectorAll("menuitem[disabled]").length,
2,
"2 menuitems are disabled now as only 2 columns remain visible"
);
is(
table.menupopup.querySelectorAll("menuitem[disabled]")[0],
table.menupopup.querySelector("[data-id='col1']"),
"First is the unique column"
);
is(
table.menupopup.querySelectorAll("menuitem[disabled]")[1],
table.menupopup.querySelector("[data-id='col4']"),
"Second is the last column"
);
// showing back 2nd column
// popup should be open now
// clicking on second column label
await showCol("col2");
// showing back 3rd column
// event listener for popupshown
info("right clicking on the first column header");
node = table.tbody.firstChild.firstChild;
onPopupShown = once(table.menupopup, "popupshown");
click(node, 2);
await onPopupShown;
// popup should be open now
// clicking on second column label
await showCol("col3");
// reset table state
table.clearSelection();
table.sortBy("col1");
};