-
Notifications
You must be signed in to change notification settings - Fork 3.9k
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
Changes from 2 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
@@ -0,0 +1,83 @@ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
import { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
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"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
let repoName; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
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"); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
}); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Comment on lines
+33
to
+48
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
FileTabs.assertActiveTab("Api3"); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
}); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Improve test isolation and avoid hardcoded indices. The test relies on hardcoded index (2) for log entry selection, which could make the test brittle. - debuggerHelper.ClicklogEntityLink(false, 2);
+ const LOG_INDEX = 2;
+ debuggerHelper.ClicklogEntityLink(false, LOG_INDEX); 📝 Committable suggestion
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
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 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
FileTabs.assertActiveTab("Api2"); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
}); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
}, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
); |
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, | ||
|
@@ -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"; | ||
|
||
|
@@ -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 = "", | ||
|
@@ -509,4 +514,97 @@ 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); | ||
FileTabs.assertActiveTab(apiName); | ||
|
||
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)")) { | ||
shadabbuchh marked this conversation as resolved.
Show resolved
Hide resolved
|
||
// 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 | ||
} | ||
} | ||
}); | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Refactor complex conditional logic in performActionFromEditor. The method has complex nested conditions. Consider extracting the page list handling logic into separate methods. + private handleSinglePageMove(apiName: string, sourcePage: string) {
+ cy.get(this.pageList).should("have.text", "No pages");
+ }
+
+ private handleMultiPageMove(apiName: string, sourcePage: string, targetPage: string) {
+ cy.get(this.pageList)
+ .should("be.visible")
+ .should("not.have.text", sourcePage)
+ .contains(targetPage)
+ .should("be.visible")
+ .trigger("click", { force: true });
+ }
|
||
|
||
public deleteAPIFromEditor(apiName: string, sourcePage: string) { | ||
// Navigate to the source page and select the API item | ||
EditorNavigation.NavigateToPage(sourcePage); | ||
PageLeftPane.selectItem(apiName); | ||
FileTabs.assertActiveTab(apiName); | ||
|
||
// Open the 'More Actions' menu and select the action | ||
cy.get(this.moreActionsTrigger).should("be.visible").click(); | ||
cy.contains("Delete") | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can we please use aghelper functions here? Please apply same for all the cy commands. |
||
.should("be.visible") | ||
.trigger("click", { force: true }); | ||
cy.contains("Are you sure?") | ||
.should("be.visible") | ||
.trigger("click", { force: true }); | ||
|
||
// Validate the absence of the deleted API | ||
PageLeftPane.assertAbsence(apiName); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -36,6 +36,12 @@ class FileTabs { | |
}); | ||
} | ||
|
||
assertActiveTab(expectedTabName: string) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please use aghelper function. |
||
cy.get(this.locators.tabName(expectedTabName)) | ||
.should("exist") | ||
.and("have.class", "active"); | ||
} | ||
|
||
closeTab(name: string) { | ||
const tab = this.locators.tabName(name); | ||
ObjectsRegistry.AggregateHelper.HoverElement(tab); | ||
|
There was a problem hiding this comment.
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:
🔗 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:
Length of output: 114
Script:
Length of output: 2086
Script:
Length of output: 230
Script:
Length of output: 13943