diff --git a/cypress-tests/cypress/constants/selectors/common.js b/cypress-tests/cypress/constants/selectors/common.js index 1f0a54bc9b..275f68d9cf 100644 --- a/cypress-tests/cypress/constants/selectors/common.js +++ b/cypress-tests/cypress/constants/selectors/common.js @@ -158,7 +158,7 @@ export const commonWidgetSelector = { boxShadowDefaultParam: ["x", "y", "blur", "spread"], colourPickerParent: "[data-cy='color-picker-parent']", inputBoxShadow: "[data-cy= 'input-box-shadow']", - boxShadowColorPicker: "[data-cy='box-shadow-color-picker']", + boxShadowColorPicker: "[data-cy='box-shadow-picker']", textInputWidget: '[data-cy="draggable-widget-textinput1"]', previewButton: `[data-cy="preview-link-button"]`, }; diff --git a/cypress-tests/cypress/constants/selectors/listview.js b/cypress-tests/cypress/constants/selectors/listview.js new file mode 100644 index 0000000000..e69de29bb2 diff --git a/cypress-tests/cypress/constants/texts/common.js b/cypress-tests/cypress/constants/texts/common.js index e1f7dae903..8d88faf46d 100644 --- a/cypress-tests/cypress/constants/texts/common.js +++ b/cypress-tests/cypress/constants/texts/common.js @@ -64,7 +64,7 @@ export const commonWidgetText = { parameterShowOnMobile: "Show on mobile", parameterVisibility: "Visibility", parameterDisable: "Disable", - parameterBorderRadius: "Border radius", + parameterBorderRadius: "Border Radius", borderRadiusInput: ["{{", "20}}"], parameterOptionLabels: "Option labels", parameterBoxShadow: "Box Shadow", @@ -81,17 +81,22 @@ export const commonWidgetText = { addEventHandlerLink: "+ Add event handler", inspectorComponentLabel: "components", componentValueLabel: "Value", - labelDefaultValue: "Default value", + labelDefaultValue: "Default Value", parameterLabel: "Label", datepickerDocumentationLink: "Datepicker documentation", text1: "text1", + textinput1: "textinput1", toggleswitch1: "toggleswitch1", toggleSwitch: "Toggle Switch", + button1: "button1", + image1: "image1", }; export const createBackspaceText = (text) => { let backspace = "{end}"; - [...text].forEach((c) => (backspace += "{backspace}")); + [...text].forEach((c) => { + backspace += "{backspace}{del}"; + }); return backspace; }; diff --git a/cypress-tests/cypress/constants/texts/listview.js b/cypress-tests/cypress/constants/texts/listview.js new file mode 100644 index 0000000000..8e77128f1d --- /dev/null +++ b/cypress-tests/cypress/constants/texts/listview.js @@ -0,0 +1,7 @@ +export const listviewText = { + defaultWidgetName: "Listview1", + showBottomBorder: "Show bottom border", + rowHeight: "Row height", + noEventHandlerMessage: "This listview doesn't have any event handlers", + listData: "List data", +}; diff --git a/cypress-tests/cypress/e2e/editor/widget/listViewHappyPath.cy.js b/cypress-tests/cypress/e2e/editor/widget/listViewHappyPath.cy.js new file mode 100644 index 0000000000..c17d2066af --- /dev/null +++ b/cypress-tests/cypress/e2e/editor/widget/listViewHappyPath.cy.js @@ -0,0 +1,381 @@ +import { listviewSelector } from "Selectors/listview"; +import { listviewText } from "Texts/listview"; +import { + commonText, + commonWidgetText, + codeMirrorInputLabel, +} from "Texts/common"; +import { commonSelectors, commonWidgetSelector } from "Selectors/common"; +import { fake } from "Fixtures/fake"; + +import { + deleteInnerWidget, + dropWidgetToListview, + verifyMultipleComponentValuesFromInspector, + addDataToListViewInputs, + verifyValuesOnList, + verifyExposedValueByToast, + textArrayOfLength, +} from "Support/utils/listviewWidget"; +import { + openAccordion, + verifyAndModifyParameter, + openEditorSidebar, + verifyAndModifyToggleFx, + addDefaultEventHandler, + addAndVerifyTooltip, + verifyTooltip, + editAndVerifyWidgetName, + pushIntoArrayOfObject, + selectColourFromColourPicker, + fillBoxShadowParams, + verifyBoxShadowCss, +} from "Support/utils/commonWidget"; + +describe("List view widget", () => { + beforeEach(() => { + cy.appUILogin(); + cy.createApp(); + cy.dragAndDropWidget("List View"); + cy.modifyCanvasSize(1800, 780); + }); + + it("should verify the properties of the list view widget", () => { + const data = {}; + data.marks = textArrayOfLength(3); + data.names = textArrayOfLength(3); + data.widgetName = fake.widgetName; + data.customMessage = fake.randomSentence; + + openEditorSidebar(listviewText.defaultWidgetName); + editAndVerifyWidgetName(data.widgetName); + + openEditorSidebar(data.widgetName); + openAccordion(commonWidgetText.accordionEvents); + deleteInnerWidget(data.widgetName, commonWidgetText.text1); + deleteInnerWidget(data.widgetName, commonWidgetText.button1); + deleteInnerWidget(data.widgetName, commonWidgetText.image1); + + dropWidgetToListview("Text", 50, 50, data.widgetName); + + dropWidgetToListview("Text Input", 250, 50, data.widgetName); + addDataToListViewInputs( + data.widgetName, + commonWidgetText.textinput1, + data.names + ); + verifyMultipleComponentValuesFromInspector( + data.widgetName, + commonWidgetText.textinput1, + data.names + ); + + openEditorSidebar(data.widgetName); + verifyAndModifyParameter( + "List data", + codeMirrorInputLabel(pushIntoArrayOfObject(data.names, data.marks)) + ); + + cy.get( + `${commonWidgetSelector.draggableWidget(commonWidgetText.text1)}:eq(0)` + ).click(); + verifyAndModifyParameter("Text", codeMirrorInputLabel("listItem.name")); + cy.forceClickOnCanvas(); + cy.get( + `${commonWidgetSelector.draggableWidget( + commonWidgetText.textinput1 + )}:eq(0)` + ).click(); + verifyAndModifyParameter( + commonWidgetText.labelDefaultValue, + codeMirrorInputLabel("listItem.mark") + ); + cy.forceClickOnCanvas(); + verifyValuesOnList( + data.widgetName, + commonWidgetText.text1, + "text", + data.names + ); + verifyValuesOnList( + data.widgetName, + commonWidgetText.textinput1, + "value", + data.marks + ); + + verifyMultipleComponentValuesFromInspector( + data.widgetName, + commonWidgetText.textinput1, + data.marks, + "open" + ); + + cy.forceClickOnCanvas(); + openEditorSidebar(data.widgetName); + verifyAndModifyParameter(listviewText.rowHeight, "99"); + + openEditorSidebar(data.widgetName); + verifyAndModifyParameter( + listviewText.showBottomBorder, + codeMirrorInputLabel("false") + ); + + cy.forceClickOnCanvas(); + cy.get(`[data-cy=${data.widgetName.toLowerCase()}-row-1]`) + .should("have.css", "height", "99px") + .invoke("attr", "class") + .and("not.contain", "border-bottom"); + + openEditorSidebar(data.widgetName); + openAccordion(commonWidgetText.accordionEvents); + cy.get(commonWidgetSelector.noEventHandlerMessage).should( + "have.text", + listviewText.noEventHandlerMessage + ); + addDefaultEventHandler( + codeMirrorInputLabel( + `components.${data.widgetName}.selectedRow.${commonWidgetText.textinput1}.value` + ) + ); + cy.get(commonWidgetSelector.buttonCloseEditorSideBar).click(); + cy.get(`[data-cy=${data.widgetName.toLowerCase()}-row-1]`).click(); + cy.verifyToastMessage(commonSelectors.toastMessage, data.marks[1]); + + openEditorSidebar(data.widgetName); + openAccordion(commonWidgetText.accordionGenaral); + addAndVerifyTooltip( + commonWidgetSelector.draggableWidget(data.widgetName), + data.customMessage + ); + + openEditorSidebar(data.widgetName); + openAccordion(commonWidgetText.accordionLayout); + verifyAndModifyToggleFx( + commonWidgetText.parameterShowOnDesktop, + commonWidgetText.codeMirrorLabelTrue + ); + cy.get(commonWidgetSelector.draggableWidget(data.widgetName)).should( + "not.exist" + ); + + verifyAndModifyToggleFx( + commonWidgetText.parameterShowOnMobile, + commonWidgetText.codeMirrorLabelFalse + ); + cy.get(commonWidgetSelector.changeLayoutButton).click(); + cy.get(commonWidgetSelector.draggableWidget(data.widgetName)).should( + "exist" + ); + }); + + it("should verify the styles of the list view widget", () => { + const data = {}; + data.colour = fake.randomRgba; + data.boxShadowParam = fake.boxShadowParam; + + openEditorSidebar(listviewText.defaultWidgetName); + cy.get(commonWidgetSelector.buttonStylesEditorSideBar).click(); + + verifyAndModifyToggleFx( + commonWidgetText.parameterVisibility, + commonWidgetText.codeMirrorLabelTrue + ); + cy.get( + commonWidgetSelector.draggableWidget(listviewText.defaultWidgetName) + ).should("not.be.visible"); + cy.get( + commonWidgetSelector.parameterTogglebutton( + commonWidgetText.parameterVisibility + ) + ).click(); + verifyAndModifyToggleFx( + commonWidgetText.parameterDisable, + commonWidgetText.codeMirrorLabelFalse + ); + cy.get(commonSelectors.autoSave, { timeout: 9000 }).should( + "have.text", + commonText.autoSave + ); + cy.get( + commonWidgetSelector.draggableWidget(listviewText.defaultWidgetName) + ).should("have.attr", "data-disabled", "true"); + cy.get("[data-cy='disable-toggle-button']").click(); + + cy.get("[data-cy='border-radius-fx-button']:eq(1)").click(); + verifyAndModifyParameter( + commonWidgetText.parameterBorderRadius, + commonWidgetText.borderRadiusInput + ); + cy.get(commonWidgetSelector.buttonCloseEditorSideBar).click(); + cy.get( + commonWidgetSelector.draggableWidget(listviewText.defaultWidgetName) + ).should("have.css", "border-radius", "20px"); + + openEditorSidebar(listviewText.defaultWidgetName); + cy.get(commonWidgetSelector.buttonStylesEditorSideBar).click(); + openAccordion(commonWidgetText.accordionGenaral, "1"); + + verifyAndModifyToggleFx( + commonWidgetText.parameterBoxShadow, + commonWidgetText.boxShadowDefaultValue, + false + ); + + cy.get('[data-cy="border-radius-fx-button"]').click(); + cy.get(commonWidgetSelector.boxShadowColorPicker).click(); + + fillBoxShadowParams( + commonWidgetSelector.boxShadowDefaultParam, + data.boxShadowParam + ); + + selectColourFromColourPicker(commonWidgetText.boxShadowColor, data.colour); + verifyBoxShadowCss( + listviewText.defaultWidgetName, + data.colour, + data.boxShadowParam + ); + }); + + it("should verify listview widget in preview", () => { + const data = {}; + data.marks = textArrayOfLength(3); + data.names = textArrayOfLength(3); + data.widgetName = listviewText.defaultWidgetName; + data.customMessage = fake.randomSentence; + data.colour = fake.randomRgba; + data.boxShadowParam = fake.boxShadowParam; + + openEditorSidebar(data.widgetName); + editAndVerifyWidgetName(data.widgetName); + + openEditorSidebar(data.widgetName); + openAccordion(commonWidgetText.accordionEvents); + deleteInnerWidget(data.widgetName, "button1"); + deleteInnerWidget(data.widgetName, "image1"); + + dropWidgetToListview("Text Input", 250, 50, data.widgetName); + + cy.forceClickOnCanvas(); + openEditorSidebar(data.widgetName); + verifyAndModifyParameter( + "List data", + codeMirrorInputLabel(pushIntoArrayOfObject(data.names, data.marks)) + ); + + cy.get( + `${commonWidgetSelector.draggableWidget(commonWidgetText.text1)}:eq(0)` + ).click(); + verifyAndModifyParameter("Text", codeMirrorInputLabel("listItem.name")); + cy.forceClickOnCanvas(); + cy.get( + `${commonWidgetSelector.draggableWidget( + commonWidgetText.textinput1 + )}:eq(0)` + ).click(); + verifyAndModifyParameter( + commonWidgetText.labelDefaultValue, + codeMirrorInputLabel("listItem.mark") + ); + + cy.forceClickOnCanvas(); + openEditorSidebar(data.widgetName); + verifyAndModifyParameter("Row height", "99"); + + openEditorSidebar(data.widgetName); + verifyAndModifyParameter( + "Show bottom border", + codeMirrorInputLabel("false") + ); + + cy.forceClickOnCanvas(); + openEditorSidebar(data.widgetName); + openAccordion(commonWidgetText.accordionEvents); + addDefaultEventHandler( + codeMirrorInputLabel( + `components.${data.widgetName}.selectedRow.${commonWidgetText.textinput1}.value` + ) + ); + + openEditorSidebar(data.widgetName); + openAccordion(commonWidgetText.accordionGenaral); + addAndVerifyTooltip( + commonWidgetSelector.draggableWidget(data.widgetName), + data.customMessage + ); + + openEditorSidebar(listviewText.defaultWidgetName); + cy.get(commonWidgetSelector.buttonStylesEditorSideBar).click(); + + verifyAndModifyToggleFx( + commonWidgetText.parameterVisibility, + commonWidgetText.codeMirrorLabelTrue + ); + cy.get( + commonWidgetSelector.draggableWidget(listviewText.defaultWidgetName) + ).should("not.be.visible"); + cy.get( + commonWidgetSelector.parameterTogglebutton( + commonWidgetText.parameterVisibility + ) + ).click(); + + cy.get("[data-cy='border-radius-fx-button']:eq(1)").click(); + verifyAndModifyParameter( + commonWidgetText.parameterBorderRadius, + commonWidgetText.borderRadiusInput + ); + + cy.get(commonWidgetSelector.buttonCloseEditorSideBar).click(); + cy.get( + commonWidgetSelector.draggableWidget(listviewText.defaultWidgetName) + ).should("have.css", "border-radius", "20px"); + + openEditorSidebar(listviewText.defaultWidgetName); + cy.get(commonWidgetSelector.buttonStylesEditorSideBar).click(); + openAccordion(commonWidgetText.accordionGenaral, "1"); + + verifyAndModifyToggleFx( + commonWidgetText.parameterBoxShadow, + commonWidgetText.boxShadowDefaultValue, + false + ); + + cy.get(commonWidgetSelector.boxShadowColorPicker).click(); + fillBoxShadowParams( + commonWidgetSelector.boxShadowDefaultParam, + data.boxShadowParam + ); + selectColourFromColourPicker(commonWidgetText.boxShadowColor, data.colour); + + cy.openInCurrentTab(commonWidgetSelector.previewButton); + + verifyTooltip( + commonWidgetSelector.draggableWidget(data.widgetName), + data.customMessage + ); + + cy.get(`[data-cy=${data.widgetName.toLowerCase()}-row-1]`).click(); + cy.verifyToastMessage(commonSelectors.toastMessage, data.marks[1]); + + verifyBoxShadowCss( + listviewText.defaultWidgetName, + data.colour, + data.boxShadowParam + ); + + cy.get(`[data-cy=${data.widgetName.toLowerCase()}-row-1]`) + .should("have.css", "height", "99px") + .invoke("attr", "class") + .and("not.contain", "border-bottom"); + + data.names = textArrayOfLength(3); + addDataToListViewInputs( + data.widgetName, + commonWidgetText.textinput1, + data.names + ); + verifyExposedValueByToast(data.widgetName, data.names); + }); +}); diff --git a/cypress-tests/cypress/support/utils/commonWidget.js b/cypress-tests/cypress/support/utils/commonWidget.js index 00ba474f27..ec19f6d318 100644 --- a/cypress-tests/cypress/support/utils/commonWidget.js +++ b/cypress-tests/cypress/support/utils/commonWidget.js @@ -27,7 +27,9 @@ export const verifyAndModifyParameter = (paramName, value) => { }; export const openEditorSidebar = (widgetName = "") => { - cy.get(commonWidgetSelector.draggableWidget(widgetName)).trigger("mouseover"); + cy.get(`${commonWidgetSelector.draggableWidget(widgetName)}:eq(0)`).trigger( + "mouseover" + ); cy.get(commonWidgetSelector.widgetConfigHandle(widgetName)).click(); }; @@ -289,3 +291,11 @@ export const verifyWidgetText = (widgetName, text) => { text ); }; + +export const pushIntoArrayOfObject = (arrayOne, arrayTwo) => { + let arrayOfObj = "["; + arrayOne.forEach((element, index) => { + arrayOfObj += `{name: "${element}", mark: "${arrayTwo[index]}" },`; + }); + return arrayOfObj + "]"; +}; diff --git a/cypress-tests/cypress/support/utils/listviewWidget.js b/cypress-tests/cypress/support/utils/listviewWidget.js new file mode 100644 index 0000000000..feca37df26 --- /dev/null +++ b/cypress-tests/cypress/support/utils/listviewWidget.js @@ -0,0 +1,110 @@ +import { commonSelectors, commonWidgetSelector } from "Selectors/common"; +import { fake } from "Fixtures/fake"; + +export const deleteInnerWidget = (widgetName, innerWidgetName) => { + cy.get(commonSelectors.canvas).click({ force: true }); + cy.get(commonWidgetSelector.draggableWidget(widgetName)).within(() => { + cy.get(commonWidgetSelector.draggableWidget(innerWidgetName)).as( + "innerWidget" + ); + cy.get("@innerWidget").first().click(); + cy.get(`[data-cy="${innerWidgetName}-delete-button"]`) + .click() + .should("not.exist"); + }); +}; + +export const dropWidgetToListview = ( + widgetName, + positionX = 250, + positionY = 45, + listviewName +) => { + const dataTransfer = new DataTransfer(); + + cy.forceClickOnCanvas(); + cy.clearAndType(commonSelectors.searchField, widgetName); + cy.get(commonWidgetSelector.widgetBox(widgetName)).trigger( + "dragstart", + { dataTransfer }, + { force: true } + ); + cy.get(commonWidgetSelector.draggableWidget(listviewName)).within(() => { + // .click({ force: true }) + cy.get(`[data-cy="${listviewName.toLowerCase()}-row-0"]`) + .children(".real-canvas") + .click() + .trigger("mouseover") + .trigger("mouseenter") + .trigger("drop", positionX, positionY, { + dataTransfer, + force: true, + scrollBehavior: top, + delay: 2000, + }); + }); + cy.get(`[data-cy="${listviewName.toLowerCase()}-row-0"]`).trigger("dragend"); + cy.waitForAutoSave(); +}; + +export const verifyMultipleComponentValuesFromInspector = ( + listviewName, + componentName, + values = [], + openStatus = "closed" +) => { + cy.get(commonWidgetSelector.sidebarinspector).click(); + if (openStatus == "closed") { + cy.get(commonWidgetSelector.inspectorNodeComponents).click(); + cy.get(commonWidgetSelector.nodeComponent(listviewName)).click(); + cy.get(commonWidgetSelector.nodeComponent("data")).click(); + } + values.forEach((value, i) => { + if (openStatus == "closed") { + cy.get(commonWidgetSelector.nodeComponent(`${i}`)).click(); + cy.get( + `${commonWidgetSelector.nodeComponent(componentName)}:eq(${i})` + ).click(); + } + cy.get(`${commonWidgetSelector.nodeComponentValue}:eq(${i})`).should( + "contain.text", + `${value}` + ); + }); + cy.forceClickOnCanvas(); +}; + +export const addDataToListViewInputs = (listviewName, childName, data) => { + cy.get(commonWidgetSelector.draggableWidget(listviewName)).within(() => { + cy.get(commonWidgetSelector.draggableWidget(childName)).each( + ($element, i) => { + cy.wrap($element).type(`{selectAll}${data[i]}`); + } + ); + }); +}; + +export const verifyValuesOnList = (listviewName, childName, type, value) => { + cy.get(commonWidgetSelector.draggableWidget(listviewName)).within(() => { + cy.get(commonWidgetSelector.draggableWidget(childName)).each( + ($element, i) => { + cy.wrap($element).should(`have.${type}`, value[i]); + } + ); + }); +}; + +export const verifyExposedValueByToast = (widgetName, datas) => { + datas.forEach((data, i) => { + cy.get(`[data-cy=${widgetName.toLowerCase()}-row-${i}]`).click(); + cy.verifyToastMessage(`${commonSelectors.toastMessage}:eq(0)`, data); + }); +}; + +export const textArrayOfLength = (index) => { + const labels = []; + for (let i = 0; i < index; i++) { + labels.push(`${fake.firstName}`); + } + return labels; +}; diff --git a/frontend/src/Editor/Components/Datepicker.jsx b/frontend/src/Editor/Components/Datepicker.jsx index 6ad9591d29..b67b542879 100644 --- a/frontend/src/Editor/Components/Datepicker.jsx +++ b/frontend/src/Editor/Components/Datepicker.jsx @@ -80,7 +80,7 @@ export const Datepicker = function Datepicker({