diff --git a/app/client/cypress/integration/Regression_TestSuite/ClientSideTests/Widgets/ListV2/ListV2_max_nested_List_widget_spec.js b/app/client/cypress/integration/Regression_TestSuite/ClientSideTests/Widgets/ListV2/ListV2_max_nested_List_widget_spec.js deleted file mode 100644 index 2007ed6e82..0000000000 --- a/app/client/cypress/integration/Regression_TestSuite/ClientSideTests/Widgets/ListV2/ListV2_max_nested_List_widget_spec.js +++ /dev/null @@ -1,49 +0,0 @@ -const dsl = require("../../../../../fixtures/Listv2/copy_paste_listv2_dsl.json"); - -const widgetSelector = (name) => `[data-widgetname-cy="${name}"]`; - -describe(" Nested List Widgets ", function() { - const modifierKey = Cypress.platform === "darwin" ? "meta" : "ctrl"; - before(() => { - cy.addDsl(dsl); - }); - - it("a. Pasting - should show toast when nesting is greater than 3", function() { - cy.openPropertyPaneByWidgetName("List1", "listwidgetv2"); - // Copy List1 - cy.get(".t--copy-widget").click({ force: true }); - cy.wait(500); - //Paste inside List 1 - cy.get(`${widgetSelector("List1")} [type="CONTAINER_WIDGET"]`) - .first() - .click({ force: true }) - .type(`{${modifierKey}}{v}`); - cy.wait(500); - - //Copy List 2 and Paste inside list 2 - cy.openPropertyPaneByWidgetName("List2", "listwidgetv2"); - cy.get(".t--copy-widget").click({ force: true }); - cy.wait(500); - // Paste inside list 2 - cy.get(`${widgetSelector("List2")} [type="CONTAINER_WIDGET"]`) - .first() - .click({ force: true }) - .type(`{${modifierKey}}{v}`); - cy.wait(500); - - //Now Both List1 and List2 are n-2 levels - - //Copy List2 and Past in List 1 - cy.openPropertyPaneByWidgetName("List2", "listwidgetv2"); - cy.get(".t--copy-widget").click({ force: true }); - cy.wait(500); - cy.get(`${widgetSelector("List1Copy")} [type="CONTAINER_WIDGET"]`) - .first() - .click({ force: true }) - .type(`{${modifierKey}}{v}`); - - cy.wait(500); - cy.validateToastMessage("Cannot have more than 3 levels of nesting"); - cy.get(`${widgetSelector("List2Copy1")}`).should("not.exist"); - }); -}); diff --git a/app/client/cypress/integration/Regression_TestSuite/ClientSideTests/Widgets/ListV2/ListV2_nested_List_widget_spec.js b/app/client/cypress/integration/Regression_TestSuite/ClientSideTests/Widgets/ListV2/ListV2_nested_List_widget_spec.js new file mode 100644 index 0000000000..3fdad4cb2c --- /dev/null +++ b/app/client/cypress/integration/Regression_TestSuite/ClientSideTests/Widgets/ListV2/ListV2_nested_List_widget_spec.js @@ -0,0 +1,128 @@ +const dsl = require("../../../../../fixtures/Listv2/copy_paste_listv2_dsl.json"); + +const widgetSelector = (name) => `[data-widgetname-cy="${name}"]`; + +function checkAutosuggestion(label, type) { + cy.get(".CodeMirror-hints") + .contains(label) + .then(($el) => { + const after = getComputedStyle($el[0], "::after"); + const afterContent = after.getPropertyValue("content"); + expect(afterContent).eq(`"${type}"`); + }); +} +describe(" Nested List Widgets ", function() { + const modifierKey = Cypress.platform === "darwin" ? "meta" : "ctrl"; + before(() => { + cy.addDsl(dsl); + }); + + it("a. Pasting - should show toast when nesting is greater than 3", function() { + cy.openPropertyPaneByWidgetName("List1", "listwidgetv2"); + // Copy List1 + cy.get(".t--copy-widget").click({ force: true }); + cy.wait(500); + //Paste inside List 1 + cy.get(`${widgetSelector("List1")} [type="CONTAINER_WIDGET"]`) + .first() + .click({ force: true }) + .type(`{${modifierKey}}{v}`); + cy.wait(500); + + //Copy List 2 and Paste inside list 2 + cy.openPropertyPaneByWidgetName("List2", "listwidgetv2"); + cy.get(".t--copy-widget").click({ force: true }); + cy.wait(500); + // Paste inside list 2 + cy.get(`${widgetSelector("List2")} [type="CONTAINER_WIDGET"]`) + .first() + .click({ force: true }) + .type(`{${modifierKey}}{v}`); + cy.wait(500); + + //Now Both List1 and List2 are n-2 levels + + //Copy List2 and Past in List 1 + cy.openPropertyPaneByWidgetName("List2", "listwidgetv2"); + cy.get(".t--copy-widget").click({ force: true }); + cy.wait(500); + cy.get(`${widgetSelector("List1Copy")} [type="CONTAINER_WIDGET"]`) + .first() + .click({ force: true }) + .type(`{${modifierKey}}{v}`); + + cy.wait(500); + cy.validateToastMessage("Cannot have more than 3 levels of nesting"); + cy.get(`${widgetSelector("List2Copy1")}`).should("not.exist"); + }); + + it("b. No cyclic dependency when using levelData in a child widget", () => { + cy.dragAndDropToWidgetBySelector( + "textwidget", + '[data-widgetname-cy="List1"] [type="CONTAINER_WIDGET"]', + { + x: 150, + y: 50, + }, + ); + cy.openPropertyPane("textwidget"); + + cy.updateCodeInput(".t--property-control-text", `{{currentItem.name}}`); + + cy.dragAndDropToWidgetBySelector( + "textwidget", + '[data-widgetname-cy="List1Copy"]', + { + x: 150, + y: 100, + }, + ); + cy.testJsontextclear("text"); + + cy.get(".t--property-control-text .CodeMirror textarea").type( + "{{level_1.currentView.", + { + force: true, + }, + ); + checkAutosuggestion("Text1", "Object"); + checkAutosuggestion("List1Copy", "Object"); + + cy.testJsontextclear("text"); + + cy.get(".t--property-control-text .CodeMirror textarea").type( + "{{level_1.currentView.List1Copy.", + { + force: true, + }, + ); + checkAutosuggestion("backgroundColor", "String"); + checkAutosuggestion("itemSpacing", "Number"); + checkAutosuggestion("isVisible", "Boolean"); + checkAutosuggestion("listData", "Array"); + checkAutosuggestion("pageNo", "Number"); + checkAutosuggestion("pageSize", "Number"); + + cy.get(".CodeMirror-hints").each(($el) => { + cy.wrap($el).should("not.have.text", "currentViewItems"); + }); + + cy.get(".CodeMirror-hints").each(($el) => { + cy.wrap($el).should("not.have.text", "selectedItemView"); + }); + + cy.get(".CodeMirror-hints").each(($el) => { + cy.wrap($el).should("not.have.text", "triggeredItemView"); + }); + + cy.get(".CodeMirror-hints") + .contains("pageNo") + .first() + .click({ force: true }); + + cy.get(`${widgetSelector("Text2")} .bp3-ui-text span`).should( + "have.text", + "1", + ); + }); +}); diff --git a/app/client/cypress/integration/Regression_TestSuite/ClientSideTests/Widgets/ListV2/Listv2_BasicChildWidgetInteraction_spec.js b/app/client/cypress/integration/Regression_TestSuite/ClientSideTests/Widgets/ListV2/Listv2_BasicChildWidgetInteraction_spec.js index b9b9fedadd..dd7d8740a3 100644 --- a/app/client/cypress/integration/Regression_TestSuite/ClientSideTests/Widgets/ListV2/Listv2_BasicChildWidgetInteraction_spec.js +++ b/app/client/cypress/integration/Regression_TestSuite/ClientSideTests/Widgets/ListV2/Listv2_BasicChildWidgetInteraction_spec.js @@ -93,7 +93,15 @@ describe("List widget v2 - Basic Child Widget Interaction", () => { cy.PublishtheApp(); - cy.wait(3000); + cy.waitUntil(() => + cy + .get( + `${widgetSelector("List1")} ${containerWidgetSelector} ${ + publishLocators.selectwidget + }`, + ) + .should("have.length", 3), + ); // open the select widget cy.get(publishLocators.selectwidget) @@ -122,7 +130,15 @@ describe("List widget v2 - Basic Child Widget Interaction", () => { cy.PublishtheApp(); - cy.wait(3000); + cy.waitUntil(() => + cy + .get( + `${widgetSelector("List1")} ${containerWidgetSelector} ${ + publishLocators.checkboxGroupWidget + }`, + ) + .should("have.length", 3), + ); // select green cy.get(publishLocators.checkboxGroupWidget) @@ -157,7 +173,15 @@ describe("List widget v2 - Basic Child Widget Interaction", () => { cy.PublishtheApp(); - cy.wait(3000); + cy.waitUntil(() => + cy + .get( + `${widgetSelector("List1")} ${containerWidgetSelector} ${ + publishLocators.switchwidget + }`, + ) + .should("have.length", 3), + ); // Verify checked cy.get(publishLocators.switchwidget) @@ -189,7 +213,15 @@ describe("List widget v2 - Basic Child Widget Interaction", () => { cy.PublishtheApp(); - cy.wait(3000); + cy.waitUntil(() => + cy + .get( + `${widgetSelector("List1")} ${containerWidgetSelector} ${ + publishLocators.radioWidget + }`, + ) + .should("have.length", 3), + ); // Check radio with value=1 is selected checkSelectedRadioValue(publishLocators.radioWidget, "Y"); diff --git a/app/client/cypress/integration/Regression_TestSuite/ClientSideTests/Widgets/ListV2/Listv2_Meta_Hydration_ClientSide_spec.js b/app/client/cypress/integration/Regression_TestSuite/ClientSideTests/Widgets/ListV2/Listv2_Meta_Hydration_ClientSide_spec.js index ab2ea3f954..6c218942c0 100644 --- a/app/client/cypress/integration/Regression_TestSuite/ClientSideTests/Widgets/ListV2/Listv2_Meta_Hydration_ClientSide_spec.js +++ b/app/client/cypress/integration/Regression_TestSuite/ClientSideTests/Widgets/ListV2/Listv2_Meta_Hydration_ClientSide_spec.js @@ -99,7 +99,17 @@ describe("List widget v2 - meta hydration tests", () => { cy.get(commonlocators.listPaginateNextButton).click({ force: true, }); - cy.wait(2000); + cy.wait(200); + + cy.waitUntil(() => + cy + .get( + `${widgetSelector( + "List1", + )} ${containerWidgetSelector} .t--widget-selectwidget button`, + ) + .should("have.length", 3), + ); // SecondPage // First Row @@ -122,7 +132,30 @@ describe("List widget v2 - meta hydration tests", () => { cy.get(commonlocators.listPaginatePrevButton).click({ force: true, }); - cy.wait(3000); + cy.wait(300); + cy.waitUntil(() => + cy + .get( + `${widgetSelector( + "List1", + )} ${containerWidgetSelector} .t--widget-selectwidget button`, + ) + .should("have.length", 3), + ); + + cy.waitUntil(() => + cy + .get( + `${widgetSelector( + "List1", + )} ${containerWidgetSelector} .t--widget-selectwidget button span.bp3-button-text`, + ) + .first() + .invoke("text") + .then(($selectedValue) => { + expect($selectedValue).to.eq("Green"); + }), + ); //Validate values in FirstPage // First Row @@ -146,7 +179,30 @@ describe("List widget v2 - meta hydration tests", () => { cy.get(commonlocators.listPaginateNextButton).click({ force: true, }); - cy.wait(3000); + cy.wait(300); + cy.waitUntil(() => + cy + .get( + `${widgetSelector( + "List1", + )} ${containerWidgetSelector} .t--widget-selectwidget button`, + ) + .should("have.length", 3), + ); + + cy.waitUntil(() => + cy + .get( + `${widgetSelector( + "List1", + )} ${containerWidgetSelector} .t--widget-selectwidget button span.bp3-button-text`, + ) + .first() + .invoke("text") + .then(($selectedValue) => { + expect($selectedValue).to.eq("Blue"); + }), + ); //Validate values in SecondPage // First Row @@ -194,7 +250,16 @@ describe("List widget v2 - meta hydration tests", () => { cy.get(commonlocators.listPaginateNextButton).click({ force: true, }); - cy.wait(2000); + cy.wait(300); + cy.waitUntil(() => + cy + .get( + `${widgetSelector( + "List1", + )} ${containerWidgetSelector} .t--widget-selectwidget button`, + ) + .should("have.length", 3), + ); // SecondPage // First Row @@ -216,10 +281,34 @@ describe("List widget v2 - meta hydration tests", () => { cy.get(commonlocators.listPaginatePrevButton).click({ force: true, }); - cy.wait(3000); //Validate values in FirstPage // First Row + cy.wait(300); + cy.waitUntil(() => + cy + .get( + `${widgetSelector( + "List1", + )} ${containerWidgetSelector} .t--widget-selectwidget button`, + ) + .should("have.length", 3), + ); + + cy.waitUntil(() => + cy + .get( + `${widgetSelector( + "List1", + )} ${containerWidgetSelector} .t--widget-selectwidget button span.bp3-button-text`, + ) + .first() + .invoke("text") + .then(($selectedValue) => { + expect($selectedValue).to.eq("Green"); + }), + ); + cy.get(`${widgetSelector("List1")}`).scrollIntoView(); verifyValueOfWidget("selectwidget", "Green", 0); @@ -240,10 +329,34 @@ describe("List widget v2 - meta hydration tests", () => { cy.get(commonlocators.listPaginateNextButton).click({ force: true, }); - cy.wait(3000); //Validate values in SecondPage // First Row + cy.wait(300); + cy.waitUntil(() => + cy + .get( + `${widgetSelector( + "List1", + )} ${containerWidgetSelector} .t--widget-selectwidget button`, + ) + .should("have.length", 3), + ); + + cy.waitUntil(() => + cy + .get( + `${widgetSelector( + "List1", + )} ${containerWidgetSelector} .t--widget-selectwidget button span.bp3-button-text`, + ) + .first() + .invoke("text") + .then(($selectedValue) => { + expect($selectedValue).to.eq("Blue"); + }), + ); + cy.get(`${widgetSelector("List1")}`).scrollIntoView(); verifyValueOfWidget("selectwidget", "Blue", 0); diff --git a/app/client/cypress/integration/Regression_TestSuite/ClientSideTests/Widgets/ListV2/Listv2_Meta_Hydration_ServerSide_spec.js b/app/client/cypress/integration/Regression_TestSuite/ClientSideTests/Widgets/ListV2/Listv2_Meta_Hydration_ServerSide_spec.js index bdf224d915..5935dc01dd 100644 --- a/app/client/cypress/integration/Regression_TestSuite/ClientSideTests/Widgets/ListV2/Listv2_Meta_Hydration_ServerSide_spec.js +++ b/app/client/cypress/integration/Regression_TestSuite/ClientSideTests/Widgets/ListV2/Listv2_Meta_Hydration_ServerSide_spec.js @@ -176,7 +176,17 @@ describe("List widget v2 - meta hydration tests", () => { cy.get(commonlocators.listPaginateNextButton).click({ force: true, }); - cy.wait(2000); + cy.wait(200); + + cy.waitUntil(() => + cy + .get( + `${widgetSelector( + "List1", + )} ${containerWidgetSelector} .t--widget-selectwidget button`, + ) + .should("have.length", 3), + ); // SecondPage // First Row @@ -202,7 +212,34 @@ describe("List widget v2 - meta hydration tests", () => { //Validate values in FirstPage // First Row - cy.wait(10000); + cy.wait(300); + cy.waitUntil(() => + cy + .get( + `${widgetSelector( + "List1", + )} ${containerWidgetSelector} .t--widget-selectwidget button`, + ) + .should("have.length", 3), + ); + + cy.waitUntil( + () => + cy + .get( + `${widgetSelector( + "List1", + )} ${containerWidgetSelector} .t--widget-selectwidget button span.bp3-button-text`, + ) + .first() + .invoke("text") + .then(($selectedValue) => { + expect($selectedValue).to.eq("Green"); + }), + { + timeout: 10000, + }, + ); cy.get(`${widgetSelector("List1")}`).scrollIntoView(); verifyValueOfWidget("selectwidget", "Green", 0); verifyValueOfWidget("inputwidgetv2", "First", 0); @@ -222,10 +259,37 @@ describe("List widget v2 - meta hydration tests", () => { cy.get(commonlocators.listPaginateNextButton).click({ force: true, }); + cy.wait(300); //Validate values in SecondPage // First Row - cy.wait(10000); + cy.waitUntil(() => + cy + .get( + `${widgetSelector( + "List1", + )} ${containerWidgetSelector} .t--widget-selectwidget button`, + ) + .should("have.length", 3), + ); + + cy.waitUntil( + () => + cy + .get( + `${widgetSelector( + "List1", + )} ${containerWidgetSelector} .t--widget-selectwidget button span.bp3-button-text`, + ) + .first() + .invoke("text") + .then(($selectedValue) => { + expect($selectedValue).to.eq("Blue"); + }), + { + timeout: 10000, + }, + ); cy.get(`${widgetSelector("List1")}`).scrollIntoView(); verifyValueOfWidget("selectwidget", "Blue", 0); verifyValueOfWidget("inputwidgetv2", "Fourth", 0); @@ -268,7 +332,17 @@ describe("List widget v2 - meta hydration tests", () => { cy.get(commonlocators.listPaginateNextButton).click({ force: true, }); - cy.wait(2000); + cy.wait(200); + + cy.waitUntil(() => + cy + .get( + `${widgetSelector( + "List1", + )} ${containerWidgetSelector} .t--widget-selectwidget button`, + ) + .should("have.length", 3), + ); // SecondPage // First Row @@ -293,7 +367,34 @@ describe("List widget v2 - meta hydration tests", () => { //Validate values in FirstPage // First Row - cy.wait(10000); + cy.wait(300); + cy.waitUntil(() => + cy + .get( + `${widgetSelector( + "List1", + )} ${containerWidgetSelector} .t--widget-selectwidget button`, + ) + .should("have.length", 3), + ); + + cy.waitUntil( + () => + cy + .get( + `${widgetSelector( + "List1", + )} ${containerWidgetSelector} .t--widget-selectwidget button span.bp3-button-text`, + ) + .first() + .invoke("text") + .then(($selectedValue) => { + expect($selectedValue).to.eq("Green"); + }), + { + timeout: 10000, + }, + ); cy.get(`${widgetSelector("List1")}`).scrollIntoView(); verifyValueOfWidget("selectwidget", "Green", 0); verifyValueOfWidget("inputwidgetv2", "First", 0); @@ -316,7 +417,34 @@ describe("List widget v2 - meta hydration tests", () => { //Validate values in SecondPage // First Row - cy.wait(10000); + cy.wait(300); + cy.waitUntil(() => + cy + .get( + `${widgetSelector( + "List1", + )} ${containerWidgetSelector} .t--widget-selectwidget button`, + ) + .should("have.length", 3), + ); + + cy.waitUntil( + () => + cy + .get( + `${widgetSelector( + "List1", + )} ${containerWidgetSelector} .t--widget-selectwidget button span.bp3-button-text`, + ) + .first() + .invoke("text") + .then(($selectedValue) => { + expect($selectedValue).to.eq("Blue"); + }), + { + timeout: 10000, + }, + ); cy.get(`${widgetSelector("List1")}`).scrollIntoView(); verifyValueOfWidget("selectwidget", "Blue", 0); verifyValueOfWidget("inputwidgetv2", "Fourth", 0); diff --git a/app/client/cypress/support/commands.js b/app/client/cypress/support/commands.js index a38a6c2f92..340f545b2e 100644 --- a/app/client/cypress/support/commands.js +++ b/app/client/cypress/support/commands.js @@ -785,6 +785,25 @@ Cypress.Commands.add( }, ); +Cypress.Commands.add( + "dragAndDropToWidgetBySelector", + (widgetType, destinationSelector, { x, y }) => { + const selector = `.t--widget-card-draggable-${widgetType}`; + cy.wait(800); + cy.get(selector) + .scrollIntoView() + .trigger("dragstart", { force: true }) + .trigger("mousemove", x, y, { force: true }); + cy.get(destinationSelector) + .first() + .scrollIntoView() + .scrollTo("top", { ensureScrollable: false }) + .trigger("mousemove", x, y, { eventConstructor: "MouseEvent" }) + .trigger("mousemove", x, y, { eventConstructor: "MouseEvent" }) + .trigger("mouseup", x, y, { eventConstructor: "MouseEvent" }); + }, +); + Cypress.Commands.add("changeButtonColor", (buttonColor) => { cy.get(widgetsPage.buttonColor) .click({ force: true }) diff --git a/app/client/src/widgets/ListWidgetV2/MetaWidgetGenerator.test.ts b/app/client/src/widgets/ListWidgetV2/MetaWidgetGenerator.test.ts index 35b6de8732..cbec08d7a1 100644 --- a/app/client/src/widgets/ListWidgetV2/MetaWidgetGenerator.test.ts +++ b/app/client/src/widgets/ListWidgetV2/MetaWidgetGenerator.test.ts @@ -727,7 +727,7 @@ describe("#generate", () => { }, List6: { entityDefinition: - "backgroundColor: List6.backgroundColor,isVisible: List6.isVisible,itemSpacing: List6.itemSpacing,selectedItem: List6.selectedItem,selectedItemView: List6.selectedItemView,triggeredItem: List6.triggeredItem,triggeredItemView: List6.triggeredItemView,listData: List6.listData,pageNo: List6.pageNo,pageSize: List6.pageSize", + "backgroundColor: List6.backgroundColor,isVisible: List6.isVisible,itemSpacing: List6.itemSpacing,selectedItem: List6.selectedItem,triggeredItem: List6.triggeredItem,listData: List6.listData,pageNo: List6.pageNo,pageSize: List6.pageSize", rowIndex: 0, metaWidgetId: "fs2d2lqjgd", metaWidgetName: "List6", @@ -927,7 +927,7 @@ describe("#generate", () => { }; const expectedDataBinding = - "{{\n {\n \n Image1: { image: Image1.image,isVisible: Image1.isVisible }\n ,\n Text1: { isVisible: Text1.isVisible,text: Text1.text }\n ,\n Text2: { isVisible: Text2.isVisible,text: Text2.text }\n ,\n List6: { backgroundColor: List6.backgroundColor,isVisible: List6.isVisible,itemSpacing: List6.itemSpacing,selectedItem: List6.selectedItem,selectedItemView: List6.selectedItemView,triggeredItem: List6.triggeredItem,triggeredItemView: List6.triggeredItemView,listData: List6.listData,pageNo: List6.pageNo,pageSize: List6.pageSize }\n \n }\n }}"; + "{{\n {\n \n Image1: { image: Image1.image,isVisible: Image1.isVisible }\n ,\n Text1: { isVisible: Text1.isVisible,text: Text1.text }\n ,\n Text2: { isVisible: Text2.isVisible,text: Text2.text }\n ,\n List6: { backgroundColor: List6.backgroundColor,isVisible: List6.isVisible,itemSpacing: List6.itemSpacing,selectedItem: List6.selectedItem,triggeredItem: List6.triggeredItem,listData: List6.listData,pageNo: List6.pageNo,pageSize: List6.pageSize }\n \n }\n }}"; const count = Object.keys(metaWidgets).length; expect(count).toEqual(18); diff --git a/app/client/src/widgets/ListWidgetV2/MetaWidgetGenerator.ts b/app/client/src/widgets/ListWidgetV2/MetaWidgetGenerator.ts index 6303b527ab..e2c0d5f5be 100644 --- a/app/client/src/widgets/ListWidgetV2/MetaWidgetGenerator.ts +++ b/app/client/src/widgets/ListWidgetV2/MetaWidgetGenerator.ts @@ -181,7 +181,7 @@ enum MODIFICATION_TYPE { const ROOT_CONTAINER_PARENT_KEY = "__$ROOT_CONTAINER_PARENT$__"; const ROOT_ROW_KEY = "__$ROOT_KEY$__"; const BLACKLISTED_ENTITY_DEFINITION: Record = { - LIST_WIDGET_V2: ["currentItemsView"], + LIST_WIDGET_V2: ["currentItemsView", "selectedItemView", "triggeredItemView"], }; /** * LEVEL_PATH_REGEX gives out following matches: