diff --git a/app/client/cypress/e2e/Regression/ClientSide/IDE/Tabs_Navigation_spec.ts b/app/client/cypress/e2e/Regression/ClientSide/IDE/Tabs_Navigation_spec.ts new file mode 100644 index 0000000000..1e56f501e1 --- /dev/null +++ b/app/client/cypress/e2e/Regression/ClientSide/IDE/Tabs_Navigation_spec.ts @@ -0,0 +1,148 @@ +import { ObjectsRegistry } from "../../../../support/Objects/Registry"; +import { + agHelper, + dataSources, + locators, + jsEditor, +} from "../../../../support/Objects/ObjectsCore"; +import PageList from "../../../../support/Pages/PageList"; +import EditorNavigation, { + editorTabSelector, + PageLeftPane, + PagePaneSegment, +} from "../../../../support/Pages/EditorNavigation"; + +let dsName = "MongoDB"; + +describe("Tabs Navigation", { tags: ["@tag.IDE"] }, () => { + before(() => { + dataSources.CreateDataSource("Mongo"); + cy.renameDatasource(dsName); + }); + + it("should create and switch between JS files", () => { + // Create first JS file + jsEditor.CreateJSObject("", { prettify: false, toRun: false }); + jsEditor.RenameJSObjFromPane("Page1_JS1"); + + // Create second JS file + jsEditor.CreateJSObject("", { prettify: false, toRun: false }); + jsEditor.RenameJSObjFromPane("Page1_JS2"); + + agHelper.GetNClick(editorTabSelector("page1_js1")); + + jsEditor.currentJSObjectName().then((jsObjName) => { + expect(jsObjName).equal("Page1_JS1"); + }); + + agHelper.GetNClick(editorTabSelector("page1_js2")); + + jsEditor.currentJSObjectName().then((jsObjName) => { + expect(jsObjName).equal("Page1_JS2"); + }); + }); + + it("should create and switch between queries", () => { + dataSources.CreateQueryFromOverlay(dsName, "", "Page1_Query1"); + agHelper + .GetElement("[data-testid='t--ide-tab-page1_query1']") + .should("be.visible"); + dataSources.CreateQueryFromOverlay(dsName, "", "Page1_Query2"); + + // Switch between tabs + agHelper.GetNClick(editorTabSelector("page1_query1")); + + agHelper + .GetElement(locators._queryName) + .should("have.text", "Page1_Query1"); + + agHelper.GetNClick(editorTabSelector("page1_query2")); + + agHelper + .GetElement(locators._queryName) + .should("have.text", "Page1_Query2"); + }); + + it("should create items in the next page and navigate", () => { + // Create first page + PageList.AddNewPage("New blank page"); + + // Create first JS file + jsEditor.CreateJSObject("", { prettify: false, toRun: false }); + jsEditor.RenameJSObjFromPane("Page2_JS1"); + + // Create second JS file + jsEditor.CreateJSObject("", { prettify: false, toRun: false }); + jsEditor.RenameJSObjFromPane("Page2_JS2"); + + agHelper.GetNClick(editorTabSelector("page2_js1")); + + jsEditor.currentJSObjectName().then((jsObjName) => { + expect(jsObjName).equal("Page2_JS1"); + }); + + agHelper.GetNClick(editorTabSelector("page2_js2")); + + jsEditor.currentJSObjectName().then((jsObjName) => { + expect(jsObjName).equal("Page2_JS2"); + }); + + dataSources.CreateQueryFromOverlay(dsName, "", "Page2_Query1"); + dataSources.CreateQueryFromOverlay(dsName, "", "Page2_Query2"); + + agHelper.GetNClick(editorTabSelector("page2_query1")); + + agHelper + .GetElement(locators._queryName) + .should("have.text", "Page2_Query1"); + + agHelper.GetNClick(editorTabSelector("page2_query2")); + + agHelper + .GetElement(locators._queryName) + .should("have.text", "Page2_Query2"); + }); + + it("Use tabs navigation with multiple pages", () => { + EditorNavigation.NavigateToPage("Page1"); + agHelper.GetNClick(editorTabSelector("page1_query1")); + + agHelper + .GetElement(locators._queryName) + .should("have.text", "Page1_Query1"); + + agHelper.GetNClick(editorTabSelector("page1_query2")); + + agHelper + .GetElement(locators._queryName) + .should("have.text", "Page1_Query2"); + + PageLeftPane.switchSegment(PagePaneSegment.JS); + + agHelper.GetNClick(editorTabSelector("page1_js1")); + + jsEditor.currentJSObjectName().then((jsObjName) => { + expect(jsObjName).equal("Page1_JS1"); + }); + + agHelper.GetNClick(editorTabSelector("page1_js2")); + + jsEditor.currentJSObjectName().then((jsObjName) => { + expect(jsObjName).equal("Page1_JS2"); + }); + + EditorNavigation.NavigateToPage("Page2"); + PageLeftPane.switchSegment(PagePaneSegment.JS); + agHelper.GetNClick(editorTabSelector("page2_js1")); + + jsEditor.currentJSObjectName().then((jsObjName) => { + expect(jsObjName).equal("Page2_JS1"); + }); + + agHelper.GetNClick(editorTabSelector("page2_js2")); + + jsEditor.currentJSObjectName().then((jsObjName) => { + expect(jsObjName).equal("Page2_JS2"); + }); + }); +}); diff --git a/app/client/cypress/support/Pages/EditorNavigation.ts b/app/client/cypress/support/Pages/EditorNavigation.ts index 971b607b19..38fc48ad3f 100644 --- a/app/client/cypress/support/Pages/EditorNavigation.ts +++ b/app/client/cypress/support/Pages/EditorNavigation.ts @@ -20,6 +20,9 @@ export enum PagePaneSegment { JS = "JS", } +export const editorTabSelector = (name: string) => + `[data-testid='t--ide-tab-${name.toLowerCase()}']`; + export enum EditorViewMode { FullScreen = "FullScreen", SplitScreen = "SplitScreen", diff --git a/app/client/src/pages/Editor/IDE/EditorTabs/index.tsx b/app/client/src/pages/Editor/IDE/EditorTabs/index.tsx index eeea9f8e7e..0f07bf982c 100644 --- a/app/client/src/pages/Editor/IDE/EditorTabs/index.tsx +++ b/app/client/src/pages/Editor/IDE/EditorTabs/index.tsx @@ -1,4 +1,4 @@ -import React, { useEffect } from "react"; +import React, { useCallback, useEffect } from "react"; import { shallowEqual, useDispatch, useSelector } from "react-redux"; import { Flex, ScrollArea, ToggleButton } from "@appsmith/ads"; import { @@ -86,10 +86,13 @@ const EditorTabs = () => { }); // TODO: this returns a new function every time, needs to be recomposed - const handleTabClick = useEventCallback((tab: EntityItem) => () => { - dispatch(setListViewActiveState(false)); - tabClickHandler(tab); - }); + const handleTabClick = useCallback( + (tab: EntityItem) => () => { + dispatch(setListViewActiveState(false)); + tabClickHandler(tab); + }, + [dispatch, tabClickHandler], + ); const handleNewTabClick = useEventCallback(() => { dispatch(setListViewActiveState(false));