Skip to content

Commit

Permalink
test: Editor tests for renaming, copying, moving, and deleting APIs (#…
Browse files Browse the repository at this point in the history
…38896)

## Description
This PR adds set of tests for API-related operations in the editor,
including renaming, copying, moving, and validating tab behaviors
triggered from debugger logs.

## Automation

/ok-to-test tags="@tag.Datasource, @tag.Git, @tag.Sanity"

### 🔍 Cypress test results
<!-- This is an auto-generated comment: Cypress test results  -->
> [!TIP]
> 🟢 🟢 🟢 All cypress tests have passed! 🎉 🎉 🎉
> Workflow run:
<https://github.com/appsmithorg/appsmith/actions/runs/13047527270>
> Commit: 09e3929
> <a
href="https://internal.appsmith.com/app/cypress-dashboard/rundetails-65890b3c81d7400d08fa9ee5?branch=master&workflowId=13047527270&attempt=2"
target="_blank">Cypress dashboard</a>.
> Tags: `@tag.Datasource, @tag.Git, @tag.Sanity`
> Spec:
> <hr>Thu, 30 Jan 2025 08:38:58 UTC
<!-- end of auto-generated comment: Cypress test results  -->


## Communication
Should the DevRel and Marketing teams inform users about this change?
- [ ] Yes
- [x] No


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

## Release Notes

- **New Features**
	- Enhanced API management testing capabilities
	- Added support for renaming, copying, and moving APIs
	- Improved log-based tab navigation and reopening functionality

- **Tests**
	- Introduced comprehensive test suite for API operations
	- Added test cases for API renaming, copying, moving, and deletion
	- Implemented log-based tab interaction tests

These updates improve the testing infrastructure and validate key API
management features in the application.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
  • Loading branch information
shadabbuchh authored Jan 30, 2025
1 parent 01cda23 commit 213db55
Show file tree
Hide file tree
Showing 3 changed files with 183 additions and 1 deletion.
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
import {
agHelper,
debuggerHelper,
homePage,
} from "../../../../support/Objects/ObjectsCore";
import { apiPage } from "../../../../support/Objects/ObjectsCore";
import {
PageLeftPane,
PagePaneSegment,
} from "../../../../support/Pages/EditorNavigation";
import FileTabs from "../../../../support/Pages/IDE/FileTabs";
import PageList from "../../../../support/Pages/PageList";

describe(
"Additional API tests",
{ tags: ["@tag.Datasource", "@tag.Git"] },
() => {
it("1. Validate renaming & copying API from editor", () => {
// Create first API
apiPage.CreateApi();
// Rename the API
apiPage.renameFromEditor("changedName");
// Create second API
apiPage.CreateApi("secondApi", "GET");
// Add a new blank page to the application
PageList.AddNewPage("New blank page");
// Copy the API to the same page
apiPage.performActionFromEditor("copy", "changedName", "Page1", "Page1");
// Copy the API to a different page
apiPage.performActionFromEditor("copy", "secondApi", "Page1", "Page2");
});

it("2. Validate moving & deleting API from editor", () => {
// Create a new application
homePage.NavigateToHome();
homePage.CreateNewApplication();
// Create first API
apiPage.CreateApi("ApiToBeMoved", "GET");
apiPage.CreateApi("ApiNotToBeMoved", "GET");
// Having only one page in the app, check if the API is moved to the same page
apiPage.performActionFromEditor("move", "ApiToBeMoved", "Page1", "Page1");
// Add a new blank page to the application
PageList.AddNewPage("New blank page");
// Move the API to a different page & check if the source page does not have the API anymore
apiPage.performActionFromEditor("move", "ApiToBeMoved", "Page1", "Page2");
apiPage.performActionFromEditor("move", "ApiToBeMoved", "Page2", "Page1");
apiPage.deleteAPIFromEditor("ApiToBeMoved", "Page1");
});

it("3. Validate whether correct tab opens up after clicking on link from logs", () => {
// Create a new application
homePage.NavigateToHome();
homePage.CreateNewApplication();
for (let i = 0; i < 4; i++) {
apiPage.CreateApi(``, "GET");
}
debuggerHelper.OpenDebugger();
//Navigate to the "Logs" tab in the debugger
debuggerHelper.ClickLogsTab();
// Click on the entity link in the log entry at index 2
debuggerHelper.ClicklogEntityLink(false, 2);
// Assert that the correct tab ("Api3") opens
agHelper.AssertClassExists(FileTabs.locators.tabName("Api3"), "active");
});

it("4. Validate whether closed tab opens up after clicking on link from logs", () => {
// Close all the tabs (Api1 to Api4)
for (let i = 1; i < 5; i++) {
FileTabs.closeTab(`Api${i}`);
}
// Switch to the "UI" segment in the page left pane
PageLeftPane.switchSegment(PagePaneSegment.UI);
debuggerHelper.OpenDebugger();
// Navigate to the "Logs" tab in the debugger
debuggerHelper.ClickLogsTab();
// Click on the entity link in the log entry at index 1
debuggerHelper.ClicklogEntityLink(false, 1);
// Assert that the correct tab ("Api2") reopens
agHelper.AssertClassExists(FileTabs.locators.tabName("Api2"), "active");
});
},
);
101 changes: 100 additions & 1 deletion app/client/cypress/support/Pages/ApiPage.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { ObjectsRegistry } from "../Objects/Registry";
import {
import EditorNavigation, {
AppSidebar,
AppSidebarButton,
PageLeftPane,
Expand All @@ -9,6 +9,8 @@ import * as _ from "../Objects/ObjectsCore";
import ApiEditor from "../../locators/ApiEditor";
import { PluginActionForm } from "./PluginActionForm";
import BottomTabs from "./IDE/BottomTabs";
import PageList from "./PageList";
import FileTabs from "./IDE/FileTabs";

type RightPaneTabs = "datasources" | "connections";

Expand Down Expand Up @@ -102,6 +104,9 @@ export class ApiPage {
"input[name^='execute-on-page-load'][type='checkbox']";
public settingsTriggerLocator = "[data-testid='t--js-settings-trigger']";
public splitPaneContextMenuTrigger = ".entity-context-menu";
public moreActionsTrigger = "[data-testid='t--more-action-trigger']";
private apiNameInput = ".editor-tab.active > .ads-v2-text input";
public pageList = ".ads-v2-sub-menu > .ads-v2-menu__menu-item";

CreateApi(
apiName = "",
Expand Down Expand Up @@ -509,4 +514,98 @@ export class ApiPage {
if (enable) this.agHelper.CheckUncheck(this.runOnPageLoadJSObject, true);
else this.agHelper.CheckUncheck(this.runOnPageLoadJSObject, false);
}

public renameFromEditor(renameVal: string) {
cy.get(this.moreActionsTrigger).click();
cy.contains("Rename").should("be.visible").click();

cy.get(this.apiNameInput).clear().type(renameVal, { force: true }).blur();

PageLeftPane.assertPresence(renameVal);
}

public performActionFromEditor(
action: "copy" | "move",
apiName: string,
sourcePage: string,
targetPage: string,
) {
// Navigate to the source page and select the API item
EditorNavigation.NavigateToPage(sourcePage);
PageLeftPane.selectItem(apiName);
this.agHelper.AssertClassExists(
FileTabs.locators.tabName(apiName),
"active",
);

PageList.ShowList();
cy.get(PageList.numberOfPages).then(($el) => {
// Open the 'More Actions' menu and select the action
cy.get(this.moreActionsTrigger).should("be.visible").click(); // Open the 'More Actions' dropdown
cy.contains(action === "copy" ? "Copy to page" : "Move to page")
.should("be.visible")
.trigger("click", { force: true });
if (action === "move" && $el.text().includes("All Pages (1)")) {
// Handle case where the target page list is empty during move operation
cy.get(this.pageList).should("have.text", "No pages");
} else if (action === "move" && /All Pages \(\d+\)/.test($el.text())) {
cy.get(this.pageList)
.should("be.visible")
.should("not.have.text", sourcePage)
.contains(targetPage)
.should("be.visible")
.trigger("click", { force: true });

this.agHelper.ValidateToastMessage(
apiName + " action moved to page " + targetPage + " successfully",
);
PageList.VerifyIsCurrentPage(targetPage); // Verify the target page is active
PageLeftPane.assertPresence(apiName); // Assert the API is present on the target page
EditorNavigation.NavigateToPage(sourcePage);
PageLeftPane.assertAbsence(apiName); // Assert the API is removed from the source page
} else {
// Select the target page from the page list
cy.get(this.pageList)
.should("be.visible")
.contains(targetPage)
.should("be.visible")
.trigger("click", { force: true });

// Validate the toast message and the current page
this.agHelper.ValidateToastMessage(
`${apiName} action ${action === "copy" ? "copied" : "moved"} to page ${targetPage} successfully`,
);
PageList.VerifyIsCurrentPage(targetPage); // Verify the target page is active

// Assert the presence of the API on the target page
apiName =
action === "copy" && sourcePage === targetPage
? `${apiName}Copy`
: apiName;
PageLeftPane.assertPresence(apiName);

if (action === "move") {
EditorNavigation.NavigateToPage(sourcePage);
PageLeftPane.assertAbsence(apiName); // Assert the API is removed from the source page
}
}
});
}

public deleteAPIFromEditor(apiName: string, sourcePage: string) {
// Navigate to the source page and select the API item
EditorNavigation.NavigateToPage(sourcePage);
PageLeftPane.selectItem(apiName);
this.agHelper.AssertClassExists(
FileTabs.locators.tabName(apiName),
"active",
);

this.agHelper.GetNClick(this.moreActionsTrigger);
this.agHelper.ContainsNClick("Delete", 0, true);
this.agHelper.ContainsNClick("Are you sure?", 0, true);

// Validate the absence of the API from the source page
PageLeftPane.assertAbsence(apiName);
}
}
1 change: 1 addition & 0 deletions app/client/cypress/support/Pages/PageList.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ class PageList {
};

public DefaultPageName = PAGE_ENTITY_NAME + "1";
public numberOfPages = `.pages > .ads-v2-text`;

public AddNewPage(
option:
Expand Down

0 comments on commit 213db55

Please sign in to comment.