Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

test: Editor tests for renaming, copying, moving, and deleting APIs #38896

Merged
merged 3 commits into from
Jan 30, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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");
});
Comment on lines +18 to +31
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codebase verification

Add PageLeftPane assertions after API copy operations

Add the following verifications:

  • After copying "changedName" API within Page1:
    PageLeftPane.assertPresence("changedName");
    PageLeftPane.assertPresence("changedName_Copy");
  • After copying "secondApi" to Page2:
    PageLeftPane.assertPresence("secondApi");
    PageLeftPane.assertPresence("secondApi_Copy");
🔗 Analysis chain

Add assertions for API presence after copy operations.

The test should verify that the copied API exists in both source and target pages.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Verify the presence of API-related assertions in the test file
rg -A 2 "assertPresence.*Api" app/client/cypress/e2e/Regression/ServerSide/ApiTests/API_Additional_Tests_spec.ts

Length of output: 114


Script:

#!/bin/bash
# Search for any assertions in the test file
rg "expect|should|assert" app/client/cypress/e2e/Regression/ServerSide/ApiTests/API_Additional_Tests_spec.ts

# Look for apiPage method implementations
ast-grep --pattern 'apiPage.$_($$$)' app/client/cypress/e2e/Regression/ServerSide/ApiTests/API_Additional_Tests_spec.ts

# Search for verification methods in apiPage definition
fd -e ts -e js apiPage

Length of output: 2086


Script:

#!/bin/bash
# Search for apiPage class implementation
fd -t f -e ts -e js -H -I "apiPage" app/client/cypress/

# Search for performActionFromEditor implementation
rg -A 5 "performActionFromEditor.*{" app/client/cypress/

Length of output: 230


Script:

#!/bin/bash
# Search for performActionFromEditor implementation with fixed pattern
rg -A 5 "performActionFromEditor" app/client/cypress/

# Search for any verification methods in apiPage
rg -A 5 "verify.*Api|assert.*Api" app/client/cypress/

Length of output: 13943


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");
});
Comment on lines +33 to +48
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Add assertions to verify API move and delete operations.

Add assertions after each operation to verify the expected state:

// After moving API within same page
PageLeftPane.assertPresence("ApiToBeMoved");

// After moving API to different page
PageLeftPane.assertNotPresence("ApiToBeMoved", "Page1");
PageLeftPane.assertPresence("ApiToBeMoved", "Page2");

// After deleting API
PageLeftPane.assertNotPresence("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");
Comment on lines +61 to +63
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Avoid hardcoded index in log selection.

The test relies on a hardcoded index (2) which makes it brittle. Consider using a more reliable way to identify the correct log entry, such as searching for specific content or using test data attributes.

});

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");
Comment on lines +77 to +79
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Avoid hardcoded index in log selection.

Similar to the previous test, using a hardcoded index (1) makes the test brittle. Consider a more reliable way to identify the correct log entry.

});
},
);
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
Loading