Skip to content

Commit

Permalink
#2117 Use React Testing Library for common-properties tests - Part 1 …
Browse files Browse the repository at this point in the history
…- Controls + conditions (#2118)

Signed-off-by: Michael Pavlik <[email protected]>
Signed-off-by: Michael Pavlik <[email protected]>
Co-authored-by: Michael Pavlik <[email protected]>
Co-authored-by: Michael Pavlik <[email protected]>
Co-authored-by: Matt Howard <[email protected]>
  • Loading branch information
4 people authored Sep 12, 2024
1 parent 212e6fe commit 15caeba
Show file tree
Hide file tree
Showing 31 changed files with 4,300 additions and 3,481 deletions.
31 changes: 31 additions & 0 deletions canvas_modules/common-canvas/__tests__/_utils_/control-utilsRTL.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/*
* Copyright 2017-2023 Elyra Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

const { fireEvent } = require("@testing-library/react");

// Retrieve the dropdown items from a non-filterable dropdown control
function getDropdownItems(container, parameterId) {
let dropdownWrapper = container.querySelector(`div[data-id='properties-${parameterId}']`);
const dropdownButton = dropdownWrapper.querySelector("button");
fireEvent.click(dropdownButton);
dropdownWrapper = container.querySelector(`div[data-id='properties-${parameterId}']`);
const dropdownList = dropdownWrapper.querySelectorAll("li.cds--list-box__menu-item");
return dropdownList;
}

module.exports = {
getDropdownItems: getDropdownItems
};
85 changes: 83 additions & 2 deletions canvas_modules/common-canvas/__tests__/_utils_/table-utilsRTL.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,14 @@ function openFieldPicker(container, dataIdName) {
return container.querySelector("div.properties-fp-table");
}

// When table has 0 rows, click on Add columns button to open FieldPicker
function openFieldPickerForEmptyTable(container, dataIdName) {
const tableWrapper = container.querySelector("div[data-id=\"" + dataIdName + "\"]");
const emptyTableButton = tableWrapper.querySelector("button.properties-empty-table-button");
fireEvent.click(emptyTableButton); // open field picker
return container.querySelector("div.properties-fp-table");
}

// expectedFields is optional
// fieldsToSelect is an array of field names or objects with name and schema. ex: { "name": "age", "schema": "schema1" }
function fieldPicker(fieldpickerContainer, fieldsToSelect, expectedFields) {
Expand Down Expand Up @@ -108,6 +116,18 @@ function clickTableRows(container, rows) {
}
}

/*
* @param wrapper
* @param rows - array of row numbers to check
*/
function dblClickTableRows(container, rows) {
const tableRows = container.querySelectorAll(".properties-vt-double-click");
for (const row of rows) {
fireEvent.dblClick(tableRows[row]);
}
}


/*
* @param wrapper
* @param col - index of column to sort
Expand All @@ -133,6 +153,17 @@ function selectCheckboxes(container, rows) {
}
}

// Select checkbox using space or enter keys
function selectCheckboxesUsingKeyboard(container, rows) {
const checkboxes = getTableRows(container);
for (const row of rows) {
const checkbox = checkboxes[row].querySelector(".properties-vt-row-checkbox");
fireEvent.focus(checkbox);
fireEvent.keyDown(checkbox, { code: "Enter" });
fireEvent.blur(checkbox);
}
}

function selectCheckboxesRows(tableRows, rows) {
for (const row of rows) {
const checkbox = tableRows[row].querySelector(".properties-vt-row-checkbox");
Expand All @@ -142,7 +173,24 @@ function selectCheckboxesRows(tableRows, rows) {
}
}

function shiftSelectCheckbox(rows, rowNumber) {
/*
* Select/deselect multiple rows by shift + selecting row number
* @param wrapper
* @param rows - single row number.
*/
function shiftSelectCheckbox(container, rowNumber) {
const rows = getTableRows(container);
const checkboxes = [];
rows.forEach((row) => {
checkboxes.push(row.querySelector(".properties-vt-row-checkbox"));
});
// row index start from 0 instead of 1 so subtract 1 from rowNumber
fireEvent.mouseEnter(checkboxes[rowNumber - 1]);
fireEvent.mouseDown(checkboxes[rowNumber - 1], { shiftKey: true });
fireEvent.mouseLeave(checkboxes[rowNumber - 1]);
}

function shiftSelectCheckboxRows(rows, rowNumber) {
const checkboxes = [];
for (const row of rows) {
checkboxes.push(row.querySelector(".properties-vt-row-checkbox"));
Expand All @@ -153,6 +201,23 @@ function shiftSelectCheckbox(rows, rowNumber) {
fireEvent.mouseLeave(checkboxes[rowNumber - 1]);
}

/*
* Select the checkbox from the table header that is not the `Select row` column
* @param wrapper
* @param index - the column index that contains a checkbox to select
* @param checked - true to select the checkbox, false to deselect checkbox
*/
function selectHeaderColumnCheckbox(container, index, checked) {
const columns = getTableHeaderRows(container)[0]
.querySelectorAll(".properties-vt-column");
const column = columns[index];
const tableCheckboxHeader = column.querySelector(".tooltip-trigger").querySelector("input");
fireEvent.click(tableCheckboxHeader);
if (!checked) {
fireEvent.click(tableCheckboxHeader);
}
}

function selectFieldPickerHeaderCheckbox(container) {
const checkboxes = getTableHeaderRows(container);
const checkbox = checkboxes[0].querySelector(".properties-vt-header-checkbox").querySelector("input");
Expand Down Expand Up @@ -181,18 +246,34 @@ function validateSelectedRowNumRows(rows) {
return res;
}

function validateSelectedCheckbox(checkboxes) {
const res = [];
for (const checkbox of checkboxes) {
if (checkbox.checked === true) {
res.push(checkbox);
}
}
return res;
}

module.exports = {
openFieldPicker: openFieldPicker,
openFieldPickerForEmptyTable: openFieldPickerForEmptyTable,
fieldPicker: fieldPicker,
verifyFieldPickerRow: verifyFieldPickerRow,
getTableHeaderRows: getTableHeaderRows,
getTableRows: getTableRows,
clickTableRows: clickTableRows,
dblClickTableRows: dblClickTableRows,
clickHeaderColumnSort: clickHeaderColumnSort,
selectCheckboxes: selectCheckboxes,
selectCheckboxesUsingKeyboard: selectCheckboxesUsingKeyboard,
selectCheckboxesRows: selectCheckboxesRows,
shiftSelectCheckbox: shiftSelectCheckbox,
shiftSelectCheckboxRows: shiftSelectCheckboxRows,
selectHeaderColumnCheckbox: selectHeaderColumnCheckbox,
selectFieldPickerHeaderCheckbox: selectFieldPickerHeaderCheckbox,
validateSelectedRowNum: validateSelectedRowNum,
validateSelectedRowNumRows: validateSelectedRowNumRows
validateSelectedRowNumRows: validateSelectedRowNumRows,
validateSelectedCheckbox: validateSelectedCheckbox,
};
Original file line number Diff line number Diff line change
Expand Up @@ -924,35 +924,35 @@ describe("field-picker control multiple rows selection", () => {
expect(selected).to.have.length(0);

// Shift + select 8th row
tableUtilsRTL.shiftSelectCheckbox(tableRows, 8);
tableUtilsRTL.shiftSelectCheckboxRows(tableRows, 8);
fieldPicker = container.querySelector("div.properties-fp-table");
tableRows = tableUtilsRTL.getTableRows(fieldPicker);
// Verify 1-8 rows are selected
expect(tableUtilsRTL.validateSelectedRowNumRows(tableRows)).to.have.length(8);

// shift + select 15th row
tableUtilsRTL.shiftSelectCheckbox(tableRows, 15);
tableUtilsRTL.shiftSelectCheckboxRows(tableRows, 15);
fieldPicker = container.querySelector("div.properties-fp-table");
tableRows = tableUtilsRTL.getTableRows(fieldPicker);
// Verify 1-15 rows are selected
expect(tableUtilsRTL.validateSelectedRowNumRows(tableRows)).to.have.length(15);

// shift + select 5th row -- this will deselect 5-15 rows.
tableUtilsRTL.shiftSelectCheckbox(tableRows, 5);
tableUtilsRTL.shiftSelectCheckboxRows(tableRows, 5);
fieldPicker = container.querySelector("div.properties-fp-table");
tableRows = tableUtilsRTL.getTableRows(fieldPicker);
// 5-15 rows will be deselected. And 1-4 rows will remain selected
expect(tableUtilsRTL.validateSelectedRowNumRows(tableRows)).to.have.length(4);

// shift + select 1st row -- this will deselect all rows
tableUtilsRTL.shiftSelectCheckbox(tableRows, 1);
tableUtilsRTL.shiftSelectCheckboxRows(tableRows, 1);
fieldPicker = container.querySelector("div.properties-fp-table");
tableRows = tableUtilsRTL.getTableRows(fieldPicker);
// Verify all rows are deselected
expect(tableUtilsRTL.validateSelectedRowNumRows(tableRows)).to.have.length(0);

// shift + select 29th row -- this will select all rows
tableUtilsRTL.shiftSelectCheckbox(tableRows, 29);
tableUtilsRTL.shiftSelectCheckboxRows(tableRows, 29);
fieldPicker = container.querySelector("div.properties-fp-table");
tableRows = tableUtilsRTL.getTableRows(fieldPicker);
// Verify all rows are selected
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,17 @@
* limitations under the License.
*/

import propertyUtils from "../../_utils_/property-utils";
import tableUtils from "./../../_utils_/table-utils";
import propertyUtilsRTL from "../../_utils_/property-utilsRTL";
import tableUtilsRTL from "./../../_utils_/table-utilsRTL";
import { expect } from "chai";
import sharedFieldsParamDef from "../../test_resources/paramDefs/sharedFields_paramDef.json";
import { fireEvent } from "@testing-library/react";


describe("Condition dmSharedFields test cases", () => {
let wrapper;
beforeEach(() => {
const renderedObject = propertyUtils.flyoutEditorForm(sharedFieldsParamDef);
const renderedObject = propertyUtilsRTL.flyoutEditorForm(sharedFieldsParamDef);
wrapper = renderedObject.wrapper;
});
afterEach(() => {
Expand All @@ -32,86 +33,94 @@ describe("Condition dmSharedFields test cases", () => {


it("Test the available fields.", () => {
const { container } = wrapper;
// Validate the available fields in the selectColumns control
let fieldPicker = tableUtils.openFieldPicker(wrapper, "properties-ft-input_fields");
tableUtils.fieldPicker(fieldPicker, [], ["Age", "BP", "Cholesterol"]);
let fieldPicker = tableUtilsRTL.openFieldPicker(container, "properties-ft-input_fields");
tableUtilsRTL.fieldPicker(fieldPicker, [], ["Age", "BP", "Cholesterol"]);

// Validate the available fields in the table control
const summaryPanel = propertyUtils.openSummaryPanel(wrapper, "structuretable_filter-summary-panel");
fieldPicker = tableUtils.openFieldPicker(wrapper, "properties-ft-structuretable_filter");
const tableRows = tableUtils.getTableRows(fieldPicker);
const summaryPanel = propertyUtilsRTL.openSummaryPanel(wrapper, "structuretable_filter-summary-panel");
fieldPicker = tableUtilsRTL.openFieldPicker(container, "properties-ft-structuretable_filter");
const tableRows = tableUtilsRTL.getTableRows(fieldPicker);
expect(tableRows).to.have.length(3); // Other fields should be filtered out
// close summary panel
summaryPanel.find("button.properties-apply-button").simulate("click");
fireEvent.click(summaryPanel.querySelector("button.properties-apply-button"));

// Check the available fields in the weight dropdown
const weightDropDown = wrapper.find("div[data-id='properties-regression_weight_field'] Dropdown");
let options = weightDropDown.prop("items"); // by Type
let expectedOptions = [
{ label: "...", value: "" },
{ label: "K", value: "K" },
{ label: "BP", value: "BP" }
];
const weightDropDown = container.querySelector("div[data-id='properties-regression_weight_field']");
const weightDropDownButton = weightDropDown.querySelector("button.cds--list-box__field");
fireEvent.click(weightDropDownButton);
const weightDropDownItems = container.querySelectorAll(".cds--list-box__menu-item__option");
let options = [];
weightDropDownItems.forEach((element) => {
options.push(element.textContent);
});
let expectedOptions = ["...", "K", "BP"];
expect(options).to.eql(expectedOptions);

// Check the available fields in the offset dropdown
const offsetDropDown = wrapper.find("div[data-id='properties-offset_field'] Dropdown");
options = offsetDropDown.prop("items"); // by Type
expectedOptions = [
{ label: "...", value: "" },
{ label: "Na", value: "Na" }
];
const offsetDropDown = container.querySelector("div[data-id='properties-offset_field']");
const offSetDropDownButton = offsetDropDown.querySelector("button.cds--list-box__field");
fireEvent.click(offSetDropDownButton);
const offsetDropDownItems = offsetDropDown.querySelectorAll(".cds--list-box__menu-item__option");
options = [];
offsetDropDownItems.forEach((element) => {
options.push(element.textContent);
});
expectedOptions = ["...", "Na"];
expect(options).to.eql(expectedOptions);
});

it("Test allow a change to a field to filter another field's choices.", () => {
let selectedFields = tableUtils.getTableRows(wrapper.find("div[data-id='properties-input_fields']"));
const { container } = wrapper;
let selectedFields = tableUtilsRTL.getTableRows(container.querySelector("div[data-id='properties-input_fields']"));
expect(selectedFields).to.have.length(2); // Age and Cholesterol already selected
// Select another field `BP` in the selectColumns control
const fieldPicker = tableUtils.openFieldPicker(wrapper, "properties-ft-input_fields");
tableUtils.fieldPicker(fieldPicker, ["BP"], ["Age", "BP", "Cholesterol"]);
selectedFields = tableUtils.getTableRows(wrapper.find("div[data-id='properties-input_fields']"));
const fieldPicker = tableUtilsRTL.openFieldPicker(container, "properties-ft-input_fields");
tableUtilsRTL.fieldPicker(fieldPicker, ["BP"], ["Age", "BP", "Cholesterol"]);
selectedFields = tableUtilsRTL.getTableRows(container.querySelector("div[data-id='properties-input_fields']"));
expect(selectedFields).to.have.length(3); // Age, BP, and Cholesterol selected

const weightDropDown = wrapper.find("div[data-id='properties-regression_weight_field'] Dropdown");
const options = weightDropDown.prop("items"); // by Type
const expectedOptions = [
{ label: "...", value: "" },
{ label: "K", value: "K" }
];
const weightDropDown = container.querySelector("div[data-id='properties-regression_weight_field']");
const weightDropDownButton = weightDropDown.querySelector("button.cds--list-box__field");
fireEvent.click(weightDropDownButton);
const weightDropDownItems = container.querySelectorAll(".cds--list-box__menu-item__option");
const options = [];
weightDropDownItems.forEach((element) => {
options.push(element.textContent);
});
const expectedOptions = ["...", "K"];
expect(options).to.eql(expectedOptions);
});

it("Shares fields between dmSharedFields and columnSelection panel", () => {
const { container } = wrapper;
// Validate the available fields in the selectColumns control
const fieldPicker = tableUtils.openFieldPicker(wrapper, "properties-column_selection_fields");
tableUtils.fieldPicker(fieldPicker, [], ["Age", "Sex", "BP", "Na", "K", "Drug"]);
const fieldPicker = tableUtilsRTL.openFieldPicker(container, "properties-column_selection_fields");
tableUtilsRTL.fieldPicker(fieldPicker, [], ["Age", "Sex", "BP", "Na", "K", "Drug"]);

// Check the available fields in the single chooser dropdown
const weightDropDown = wrapper.find("div[data-id='properties-column_selection_chooser'] Dropdown");
let options = weightDropDown.prop("items"); // by Type
let expectedOptions = [
{ label: "...", value: "" },
{ label: "Sex", value: "Sex" },
{ label: "Cholesterol", value: "Cholesterol" },
{ label: "Na", value: "Na" },
{ label: "K", value: "K" },
{ label: "Drug", value: "Drug" }
];
const weightDropDown = container.querySelector("div[data-id='properties-column_selection_chooser']");
const weightDropDownButton = weightDropDown.querySelector("button.cds--list-box__field");
fireEvent.click(weightDropDownButton);
const weightDropDownItems = container.querySelectorAll(".cds--list-box__menu-item__option");
let options = [];
weightDropDownItems.forEach((element) => {
options.push(element.textContent);
});
let expectedOptions = ["...", "Sex", "Cholesterol", "Na", "K", "Drug"];
expect(options).to.eql(expectedOptions);

// Check the available fields in the offset dropdown
const offsetDropDown = wrapper.find("div[data-id='properties-dmSharedFields_chooser'] Dropdown");
options = offsetDropDown.prop("items"); // by Type
expectedOptions = [
{ label: "...", value: "" },
{ label: "Age", value: "Age" },
{ label: "Sex", value: "Sex" },
{ label: "BP", value: "BP" },
{ label: "Na", value: "Na" },
{ label: "K", value: "K" },
{ label: "Drug", value: "Drug" }
];
const offsetDropDown = container.querySelector("div[data-id='properties-dmSharedFields_chooser']");
const offSetDropDownButton = offsetDropDown.querySelector("button.cds--list-box__field");
fireEvent.click(offSetDropDownButton);
const offsetDropDownItems = offsetDropDown.querySelectorAll(".cds--list-box__menu-item__option");
options = [];
offsetDropDownItems.forEach((element) => {
options.push(element.textContent);
});
expectedOptions = ["...", "Age", "Sex", "BP", "Na", "K", "Drug"];
expect(options).to.eql(expectedOptions);
});
});
Loading

0 comments on commit 15caeba

Please sign in to comment.