diff --git a/app/client/cypress/e2e/Regression/ClientSide/IDE/IDE_Add_Pane_Interactions_spec.ts b/app/client/cypress/e2e/Regression/ClientSide/IDE/IDE_Add_Pane_Interactions_spec.ts new file mode 100644 index 0000000000..2429a21669 --- /dev/null +++ b/app/client/cypress/e2e/Regression/ClientSide/IDE/IDE_Add_Pane_Interactions_spec.ts @@ -0,0 +1,106 @@ +import EditorNavigation, { + EditorViewMode, + PageLeftPane, + PagePaneSegment, +} from "../../../../support/Pages/EditorNavigation"; +import { ObjectsRegistry } from "../../../../support/Objects/Registry"; +import FileTabs from "../../../../support/Pages/IDE/FileTabs"; + +const agHelper = ObjectsRegistry.AggregateHelper; +const commonLocators = ObjectsRegistry.CommonLocators; + +describe("IDE add pane interactions", { tags: ["@tag.IDE"] }, () => { + it("1. UI tab add interactions", () => { + // check add pane is open + PageLeftPane.assertInAddView(); + // close add pane to show blank state + PageLeftPane.closeAddView(); + // click on add button and check add state + PageLeftPane.switchToAddNew(); + // check add pane + PageLeftPane.assertInAddView(); + // drag and drop a widget and list view should be opened + cy.dragAndDropToCanvas("textwidget", { x: 300, y: 200 }); + // check listing ui + PageLeftPane.selectedItem().contains("Text1"); + // click add button + PageLeftPane.switchToAddNew(); + // check add pane is open + PageLeftPane.assertInAddView(); + // close add pane + PageLeftPane.closeAddView(); + // click on canvas and check add pane visible or not + agHelper.GetNClick(commonLocators._canvas).click(); + // check add pane + PageLeftPane.assertInAddView(); + }); + + it("2. JS tab add interactions", () => { + /** Fullscreen */ + // switch to JS tab from UI + PageLeftPane.switchSegment(PagePaneSegment.JS); + // check and click on blank state add button + PageLeftPane.switchToAddNew(); + // check listing UI + PageLeftPane.assertInListView(); + // click on add btn in the listing UI + PageLeftPane.switchToAddNew(); + // check item got added or not + PageLeftPane.assertInListView(); + PageLeftPane.assertItemCount(2); + /** Splitscreen */ + // switch to splitscreen + EditorNavigation.SwitchScreenMode(EditorViewMode.SplitScreen); + // click on add + FileTabs.switchToAddNew(); + // check tabs count to verify js added or not + FileTabs.assertTabCount(3); + // switch back to full screen + EditorNavigation.SwitchScreenMode(EditorViewMode.FullScreen); + // delete all js objects and check add screen + cy.get(".editor-tab").each(($ele) => { + cy.selectByTestId("more-action-trigger").click(); + cy.get(".t--apiFormDeleteBtn").click(); + cy.get(".t--apiFormDeleteBtn").click(); + }); + PageLeftPane.assertInAddView(); + }); + + it("3. Queries tab add interactions", () => { + /** Fullscreen */ + // switch to Query tab from JS + PageLeftPane.switchSegment(PagePaneSegment.Queries); + // check and click on blank state add button + PageLeftPane.switchToAddNew(); + // check add pane + PageLeftPane.assertInAddView(); + // close add pane + PageLeftPane.closeAddView(); + // open add pane to add item + PageLeftPane.switchToAddNew(); + // add item + cy.get(".t--new-blank-api").children("div").first().click(); + // check item added or not + PageLeftPane.assertPresence("Api1"); + /** Splitscreen */ + // switch to splitscreen + EditorNavigation.SwitchScreenMode(EditorViewMode.SplitScreen); + // click on add + FileTabs.switchToAddNew(); + // check add pane + PageLeftPane.assertInAddView(); + // add item + cy.get(".t--new-blank-api").children("div").first().click(); + // check tabs count to verify js added or not + FileTabs.assertTabCount(2); + // switch back to full screen + EditorNavigation.SwitchScreenMode(EditorViewMode.FullScreen); + // delete all queries and check add screen + cy.get(".editor-tab").each(($ele) => { + cy.selectByTestId("more-action-trigger").click(); + cy.get(".t--apiFormDeleteBtn").click(); + cy.get(".t--apiFormDeleteBtn").click(); + }); + PageLeftPane.assertInAddView(); + }); +}); diff --git a/app/client/cypress/support/Pages/EditorNavigation.ts b/app/client/cypress/support/Pages/EditorNavigation.ts index 74a49f2fcb..ced98a547c 100644 --- a/app/client/cypress/support/Pages/EditorNavigation.ts +++ b/app/client/cypress/support/Pages/EditorNavigation.ts @@ -19,6 +19,11 @@ export enum PagePaneSegment { JS = "JS", } +export enum EditorViewMode { + FullScreen = "FullScreen", + SplitScreen = "SplitScreen", +} + const pagePaneListItemSelector = (name: string) => "//div[contains(@class, 't--entity-name')][text()='" + name + "']"; @@ -38,6 +43,12 @@ export enum EntityType { Page = "Page", } class EditorNavigation { + public locators = { + MaximizeBtn: "[data-testid='t--ide-maximize']", + MinimizeBtn: "[data-testid='t--ide-minimize']", + announcementCloseButton: "[data-testid='t--ide-close-announcement']", + }; + NavigateToDatasource(name: string) { AppSidebar.navigate(AppSidebarButton.Data); cy.get(datasource.datasourceCard) @@ -119,6 +130,23 @@ class EditorNavigation { AppSidebar.navigate(AppSidebarButton.Editor); PageLeftPane.switchSegment(PagePaneSegment.UI); } + + SwitchScreenMode(mode: EditorViewMode) { + if (mode === EditorViewMode.FullScreen) { + _.AggregateHelper.GetNClick(this.locators.MaximizeBtn); + } else { + _.AggregateHelper.GetNClick(this.locators.MinimizeBtn); + cy.get("body").then(($body) => { + if ($body.find(this.locators.announcementCloseButton).length > 0) { + _.AggregateHelper.GetNClick( + this.locators.announcementCloseButton, + 0, + true, + ); + } + }); + } + } } export default new EditorNavigation(); diff --git a/app/client/cypress/support/Pages/IDE/AddView.ts b/app/client/cypress/support/Pages/IDE/AddView.ts new file mode 100644 index 0000000000..cedba70bec --- /dev/null +++ b/app/client/cypress/support/Pages/IDE/AddView.ts @@ -0,0 +1,28 @@ +import { ObjectsRegistry } from "../../Objects/Registry"; + +class AddView { + public locators = { + closePaneButton: "[data-testid='t--add-pane-close-icon']", + createOption: "[data-testid='t--create-option']", + }; + + constructor() { + // + } + + public assertInAddView() { + ObjectsRegistry.AggregateHelper.AssertElementVisibility( + this.locators.closePaneButton, + ); + } + + public closeAddView() { + ObjectsRegistry.AggregateHelper.GetNClick(this.locators.closePaneButton); + } + + public getCreateOptions(): Cypress.Chainable { + return cy.get(this.locators.createOption); + } +} + +export default AddView; diff --git a/app/client/cypress/support/Pages/IDE/FileTabs.ts b/app/client/cypress/support/Pages/IDE/FileTabs.ts new file mode 100644 index 0000000000..7eb9570211 --- /dev/null +++ b/app/client/cypress/support/Pages/IDE/FileTabs.ts @@ -0,0 +1,37 @@ +import { ObjectsRegistry } from "../../Objects/Registry"; +class FileTabs { + locators = { + container: "[data-testid='t--editor-tabs']", + tabName: (name: string) => `[data-testid='t--ide-tab-${name}']`, + tabs: ".editor-tab", + addItem: "[data-testid='t--ide-split-screen-add-button']", + }; + + assertVisibility() { + ObjectsRegistry.AggregateHelper.AssertElementVisibility( + this.locators.container, + ); + } + + assertTabCount(count: number) { + ObjectsRegistry.AggregateHelper.GetElement(this.locators.tabs).should( + "have.length", + count, + ); + } + + switchToAddNew() { + // for js it will directly add a new file + cy.get("body").then(($body) => { + if ($body.find(this.locators.addItem).length > 0) { + ObjectsRegistry.AggregateHelper.GetNClick( + this.locators.addItem, + 0, + true, + ); + } + }); + } +} + +export default new FileTabs(); diff --git a/app/client/cypress/support/Pages/IDE/LeftPane.ts b/app/client/cypress/support/Pages/IDE/LeftPane.ts index 9648d21af6..0ada0f1fff 100644 --- a/app/client/cypress/support/Pages/IDE/LeftPane.ts +++ b/app/client/cypress/support/Pages/IDE/LeftPane.ts @@ -1,4 +1,6 @@ import { ObjectsRegistry } from "../../Objects/Registry"; +import AddView from "./AddView"; +import ListView from "./ListView"; export class LeftPane { segments?: string[]; @@ -10,11 +12,13 @@ export class LeftPane { "//div[text()='" + name + "']/ancestor::div/span[contains(@class, 't--entity-collapse-toggle')]", - addItem: "button.t--add-item", activeItemSelector: "", selector: "", }; + private addView: AddView; + private listView: ListView; + constructor( listItemSelector: (name: string) => string, selector: string, @@ -25,6 +29,8 @@ export class LeftPane { this.segments = segments; this.locators.selector = selector; this.locators.activeItemSelector = activeItemSelector; + this.addView = new AddView(); + this.listView = new ListView(); } public assertAbsence(name: string) { @@ -96,15 +102,26 @@ export class LeftPane { } public switchToAddNew() { - // for js it will directly add a new file - cy.get("body").then(($body) => { - if ($body.find(this.locators.addItem).length > 0) { - ObjectsRegistry.AggregateHelper.GetNClick( - this.locators.addItem, - 0, - true, - ); - } - }); + this.listView.switchToAddNew(); + } + + public assertInAddView() { + this.addView.assertInAddView(); + } + + public closeAddView() { + this.addView.closeAddView(); + } + + public getCreateOptions() { + return this.addView.getCreateOptions(); + } + + public assertInListView() { + this.listView.assertListVisibility(); + } + + public assertItemCount(count: number) { + this.listView.assertItemCount(count); } } diff --git a/app/client/cypress/support/Pages/IDE/ListView.ts b/app/client/cypress/support/Pages/IDE/ListView.ts new file mode 100644 index 0000000000..0da47d2b26 --- /dev/null +++ b/app/client/cypress/support/Pages/IDE/ListView.ts @@ -0,0 +1,47 @@ +import { ObjectsRegistry } from "../../Objects/Registry"; + +class ListView { + public locators = { + list: "[data-testid='t--ide-list']", + listItem: "[data-testid='t--ide-list-item']", + addItem: "button.t--add-item", + }; + + public assertListVisibility() { + ObjectsRegistry.AggregateHelper.AssertElementVisibility(this.locators.list); + } + + public assertItemVisibility(name: string) { + ObjectsRegistry.AggregateHelper.GetNAssertElementText( + this.locators.listItem, + name, + ); + } + + public getItem(name: string) { + return ObjectsRegistry.AggregateHelper.GetElement( + this.locators.listItem, + ).should("have.text", name); + } + + public assertItemCount(count: number) { + return ObjectsRegistry.AggregateHelper.GetElement( + this.locators.listItem, + ).should("have.length", count); + } + + switchToAddNew() { + // for js it will directly add a new file + cy.get("body").then(($body) => { + if ($body.find(this.locators.addItem).length > 0) { + ObjectsRegistry.AggregateHelper.GetNClick( + this.locators.addItem, + 0, + true, + ); + } + }); + } +} + +export default ListView; diff --git a/app/client/cypress/support/commands.js b/app/client/cypress/support/commands.js index f1b567e9d9..50f197b23c 100644 --- a/app/client/cypress/support/commands.js +++ b/app/client/cypress/support/commands.js @@ -2077,3 +2077,16 @@ Cypress.Commands.add("stubPricingPage", () => { }).as("pricingPage"); }); }); + +/** + * @param testID + * @returns + * + * This function act as a data-testid selector. In + * any case it is decided to rename the data-testid, + * it's thing single function that needs to be updated. + * + */ +Cypress.Commands.add("selectByTestId", (testId) => { + return cy.get(`[data-testid="${testId}"]`); +}); diff --git a/app/client/cypress/support/index.d.ts b/app/client/cypress/support/index.d.ts index 2126de3a5b..5e8f574a06 100644 --- a/app/client/cypress/support/index.d.ts +++ b/app/client/cypress/support/index.d.ts @@ -175,5 +175,6 @@ declare namespace Cypress { skipSignposting(); stubPricingPage(); validateEvaluatedValue(value: string); + selectByTestId(value: string): Chainable>; } } diff --git a/app/client/src/ce/pages/Editor/IDE/EditorPane/JS/ListItem.tsx b/app/client/src/ce/pages/Editor/IDE/EditorPane/JS/ListItem.tsx index 178e7c56a6..cbf027d8db 100644 --- a/app/client/src/ce/pages/Editor/IDE/EditorPane/JS/ListItem.tsx +++ b/app/client/src/ce/pages/Editor/IDE/EditorPane/JS/ListItem.tsx @@ -14,7 +14,7 @@ export interface JSListItemProps { export const JSListItem = (props: JSListItemProps) => { const { isActive, item, parentEntityId, parentEntityType } = props; return ( - + { parentEntityType={ActionParentEntityType.PAGE} > { ) : null} {widgetsExist ? ( - + {widgets?.children?.map((child) => ( { const modalFooter = () => ( <> -