## Description Removing the bulk delete applications feature as it not generally used by many users and this was creating some UI conflicts rather than giving us some valuable output. Please follow this thread for more context : https://theappsmith.slack.com/archives/C02Q4B2AGM8/p1706249168968689 #### PR fixes following issue(s) Fixes #30660 > if no issue exists, please create an issue and ask the maintainers about this first > > #### Media > A video or a GIF is preferred. when using Loom, don’t embed because it looks like it’s a GIF. instead, just link to the video > > #### Type of change > Please delete options that are not relevant. - Bug fix (non-breaking change which fixes an issue) - New feature (non-breaking change which adds functionality) - Breaking change (fix or feature that would cause existing functionality to not work as expected) - Chore (housekeeping or task changes that don't impact user perception) - This change requires a documentation update > > > ## Testing > #### How Has This Been Tested? > Please describe the tests that you ran to verify your changes. Also list any relevant details for your test configuration. > Delete anything that is not relevant - [ ] Manual - [ ] JUnit - [ ] Jest - [ ] Cypress > > #### Test Plan > Add Testsmith test cases links that relate to this PR > > #### Issues raised during DP testing > Link issues raised during DP testing for better visiblity and tracking (copy link from comments dropped on this PR) > > > ## Checklist: #### Dev activity - [ ] My code follows the style guidelines of this project - [ ] I have performed a self-review of my own code - [ ] I have commented my code, particularly in hard-to-understand areas - [ ] I have made corresponding changes to the documentation - [ ] My changes generate no new warnings - [ ] I have added tests that prove my fix is effective or that my feature works - [ ] New and existing unit tests pass locally with my changes - [ ] PR is being merged under a feature flag #### QA activity: - [ ] [Speedbreak features](https://github.com/appsmithorg/TestSmith/wiki/Guidelines-for-test-plans#speedbreakers-) have been covered - [ ] Test plan covers all impacted features and [areas of interest](https://github.com/appsmithorg/TestSmith/wiki/Guidelines-for-test-plans#areas-of-interest-) - [ ] Test plan has been peer reviewed by project stakeholders and other QA members - [ ] Manually tested functionality on DP - [ ] We had an implementation alignment call with stakeholders post QA Round 2 - [ ] Cypress test cases have been added and approved by SDET/manual QA - [ ] Added `Test Plan Approved` label after Cypress tests were reviewed - [ ] Added `Test Plan Approved` label after JUnit tests were reviewed <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **Refactor** - Streamlined the application deletion process to handle multiple deletions more efficiently. - **Bug Fixes** - Removed redundant code and unused features related to the multiple selection and deletion of applications. - **Chores** - Cleaned up various files by removing unused imports, constants, and state variables. - **Documentation** - Adjusted code comments and documentation to reflect removal of multiple application deletion features and related UI elements. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
777 lines
29 KiB
TypeScript
777 lines
29 KiB
TypeScript
import { ObjectsRegistry } from "../Objects/Registry";
|
|
import { REPO, CURRENT_REPO } from "../../fixtures/REPO";
|
|
import HomePageLocators from "../../locators/HomePage";
|
|
import SignupPageLocators from "../../locators/SignupPage.json";
|
|
import { AppSidebar, PageLeftPane } from "./EditorNavigation";
|
|
export class HomePage {
|
|
private agHelper = ObjectsRegistry.AggregateHelper;
|
|
private locator = ObjectsRegistry.CommonLocators;
|
|
private onboarding = ObjectsRegistry.Onboarding;
|
|
private assertHelper = ObjectsRegistry.AssertHelper;
|
|
private deployHelper = ObjectsRegistry.DeployMode;
|
|
|
|
private _inviteButton = ".t--invite-user-btn";
|
|
private _username = "input[name='username']";
|
|
private _password = "input[name='password']";
|
|
private _submitBtn = "button[type='submit']";
|
|
private _workspaceCompleteSection = ".t--workspace-section";
|
|
private _workspaceName = ".t--workspace-name";
|
|
private _workspaceNameText = ".t--workspace-name-text";
|
|
private _optionsIcon = ".t--options-icon";
|
|
public _newIcon = ".createnew";
|
|
private _renameWorkspaceContainer = ".editable-text-container";
|
|
private _renameWorkspaceInput = ".t--workspace-rename-input input";
|
|
private _workspaceList = (workspaceName: string) =>
|
|
".t--workspace-section:contains(" + workspaceName + ")";
|
|
private _workspaceNoApps = (workspaceName: string) =>
|
|
this._workspaceList(workspaceName) +
|
|
":contains('There are no applications in this workspace')";
|
|
private _workspaceShareUsersIcon = (workspaceName: string) =>
|
|
".t--workspace-section:contains(" + workspaceName + ") .ads-v2-avatar";
|
|
_shareWorkspace = (workspaceName: string) =>
|
|
".t--workspace-section:contains(" +
|
|
workspaceName +
|
|
") button:contains('Share')";
|
|
private _email =
|
|
CURRENT_REPO === REPO.CE
|
|
? "//input[@type='email' and contains(@class,'bp3-input-ghost')]"
|
|
: "//input[@type='text' and contains(@class,'bp3-input-ghost')]";
|
|
_visibleTextSpan = (spanText: string) => "//span[text()='" + spanText + "']";
|
|
_newWorkSpaceLink = "[data-testid=t--workspace-new-workspace-auto-create]";
|
|
private _userRole = (role: string) =>
|
|
"//div[contains(@class, 'rc-select-item-option-content')]//span[1][text()='" +
|
|
role +
|
|
"']";
|
|
_profileMenu = ".t--profile-menu-icon";
|
|
private _editProfileMenu = ".t--edit-profile";
|
|
private _signout = ".t--sign-out";
|
|
_searchUsersInput = ".search-input input";
|
|
private _leftPanel = "[data-testid=t--left-panel]";
|
|
|
|
private _manageUsers = ".manageUsers";
|
|
public _closeBtn = ".ads-v2-modal__content-header-close-button";
|
|
private _appHome = "//a[@href='/applications']";
|
|
_applicationCard = ".t--application-card";
|
|
_appEditIcon = ".t--application-edit-link";
|
|
_homeIcon = ".t--appsmith-logo";
|
|
private _homeAppsmithImage = "a.t--appsmith-logo";
|
|
_appContainer = ".t--applications-container";
|
|
_homePageAppCreateBtn = " .createnew";
|
|
_newButtonCreateApplication = "[data-testid=t--workspace-action-create-app]";
|
|
_existingWorkspaceCreateNewApp = (existingWorkspaceName: string) =>
|
|
`//span[text()='${existingWorkspaceName}']/ancestor::div[contains(@class, 't--workspace-section')]//button[contains(@class, 't--new-button')]`;
|
|
_applicationName = ".t--application-name";
|
|
private _editAppName = "bp3-editable-text-editing";
|
|
private _appMenu = ".ads-v2-menu__menu-item-children";
|
|
_buildFromDataTableActionCard = "[data-testid='generate-app']";
|
|
private _selectRole = "//span[text()='Select a role']/ancestor::div";
|
|
private _searchInput = "input[type='text']";
|
|
_appHoverIcon = (action: string) => ".t--application-" + action + "-link";
|
|
private _deleteUser = (email: string) =>
|
|
"//td[text()='" +
|
|
email +
|
|
"']/following-sibling::td//span[contains(@class, 't--deleteUser')]";
|
|
private _userRoleDropDown = (role: string) => "//span[text()='" + role + "']";
|
|
//private _userRoleDropDown = (email: string) => "//td[text()='" + email + "']/following-sibling::td"
|
|
private _leaveWorkspaceConfirmModal = ".t--member-delete-confirmation-modal";
|
|
private _workspaceImportAppModal = ".t--import-application-modal";
|
|
private _leaveWorkspaceConfirmButton =
|
|
"[data-testid=t--workspace-leave-button]";
|
|
private _leaveWorkspace = "//span[text()='Leave workspace']";
|
|
private _leaveWorkspaceConfirm = "//span[text()='Are you sure?']";
|
|
_editPageLanding = "//h2[text()='Drag and drop a widget here']";
|
|
_usersEmailList = "[data-colindex='0']";
|
|
private _workspaceImport = "[data-testid=t--workspace-import-app]";
|
|
public _uploadFile = "//div/form/input";
|
|
private _importSuccessModal = ".t--import-app-success-modal";
|
|
private _forkModal = ".fork-modal";
|
|
public _appCard = (applicationName: string) =>
|
|
"//span[text()='" +
|
|
applicationName +
|
|
"']/ancestor::div[contains(@class, 't--application-card')]";
|
|
private _applicationContextMenu = (applicationName: string) =>
|
|
this._appCard(applicationName) + "//button[@aria-haspopup='menu']";
|
|
private _forkApp = '[data-testid="t--fork-app"]';
|
|
private _deleteApp = '[data-testid="t--delete-confirm"]';
|
|
private _deleteAppConfirm = '[data-testid="t--delete"]';
|
|
private _wsAction = (action: string) =>
|
|
".ads-v2-menu__menu-item-children:contains('" + action + "')";
|
|
private _homeTab = ".t--apps-tab";
|
|
private adsV2Text = ".ads-v2-text";
|
|
private _forkWorkspaceDropdownOption = "div.rc-select-selector";
|
|
private _forkWorkspaceSelectOptions = (option: string) =>
|
|
"div[title='" + option + "']";
|
|
_welcomeTour = ".t--welcome-tour";
|
|
_welcomeTourBuildingButton = ".t--start-building";
|
|
_reconnectDataSourceModal = "[data-testid='reconnect-datasource-modal']";
|
|
_skiptoApplicationBtn = "//span[text()='Skip to Application']/parent::a";
|
|
_workspaceSettingOption = "[data-testid=t--workspace-setting]";
|
|
_inviteUserMembersPage = "[data-testid=t--page-header-input]";
|
|
// _appRenameTooltip =
|
|
// '//span[text()="Rename application"]/ancestor::div[contains(@class,"rc-tooltip")]';
|
|
_appRenameTooltip = "span:contains('Rename application')";
|
|
_sharePublicToggle =
|
|
"//div[contains(@class, 't--share-public-toggle')]//input[@role='switch']";
|
|
_modeSwitchToggle = ".t--comment-mode-switch-toggle";
|
|
_importFromGitBtn = "div.t--import-json-card + div";
|
|
_helpButton = ".t--help-menu-option";
|
|
private signupUsername = "input[name='email']";
|
|
private _applicationEditedText = (applicationName: string) =>
|
|
this._appCard(applicationName) +
|
|
"//div[contains(@class, 't--application-edited-text')]";
|
|
private _deployPageWidgets =
|
|
".bp3-heading, section.canvas div.canvas:not(:empty)";
|
|
public _homePageContainer =
|
|
"div.t--applications-container div.t--workspace-section:not(:empty)";
|
|
private _backToEditor = ".t--back-to-editor";
|
|
private _editorSidebar = ".t--sidebar-Editor";
|
|
|
|
public _searchWorkspaceLocator = (workspaceName: string) =>
|
|
`[data-testid="${workspaceName}"]`;
|
|
public SwitchToAppsTab() {
|
|
this.agHelper.GetNClick(this._homeTab);
|
|
}
|
|
|
|
//trying to wrap multiple values, not used
|
|
public WrapAndAliasMultipleValues(
|
|
values: Record<string, string>,
|
|
): Record<string, string> {
|
|
const aliases: Record<string, string> = {};
|
|
Object.keys(values).forEach((key) => {
|
|
aliases[key] = values[key];
|
|
cy.wrap(values[key]).as(key);
|
|
});
|
|
return aliases;
|
|
}
|
|
|
|
public CreateNewWorkspace(workspaceNewName = "", toNavigateToHome = false) {
|
|
if (toNavigateToHome) this.NavigateToHome();
|
|
let oldName = "";
|
|
this.agHelper.GetNClick(this._newWorkSpaceLink);
|
|
this.assertHelper.AssertNetworkStatus("createWorkspace", 201);
|
|
this.agHelper.RemoveUIElement("Tooltip", "Create a new workspace");
|
|
cy.get("@createWorkspace").then((interception: any) => {
|
|
localStorage.setItem("workspaceId", interception.response.body.data.id);
|
|
localStorage.setItem(
|
|
"workspaceName",
|
|
interception.response.body.data.name,
|
|
);
|
|
cy.wrap(interception.response.body.data.name).as("workspaceName");
|
|
});
|
|
cy.get("@workspaceName").then((workspaceName: any) => {
|
|
this.agHelper.AssertElementVisibility(
|
|
this._workspaceNoApps(workspaceName),
|
|
);
|
|
});
|
|
|
|
workspaceNewName &&
|
|
cy
|
|
.get(this._workspaceNameText)
|
|
.find(this.adsV2Text)
|
|
.then(($ele) => {
|
|
oldName = $ele.text();
|
|
cy.log("oldName is : " + oldName);
|
|
this.RenameWorkspace(oldName, workspaceNewName, false);
|
|
});
|
|
}
|
|
|
|
public OpenWorkspaceOptions(workspaceName: string, networkCallAlias = true) {
|
|
this.SelectWorkspace(workspaceName, networkCallAlias);
|
|
this.agHelper.GetElement(this._optionsIcon).click({ force: true });
|
|
}
|
|
|
|
public OpenWorkspaceSettings(workspaceName: string) {
|
|
this.OpenWorkspaceOptions(workspaceName);
|
|
this.agHelper.GetNClick(this._workspaceSettingOption);
|
|
}
|
|
|
|
public RenameWorkspace(
|
|
oldName: string,
|
|
newWorkspaceName: string,
|
|
networkCallAlias = true,
|
|
) {
|
|
this.OpenWorkspaceOptions(oldName, networkCallAlias);
|
|
this.agHelper.GetNClick(this._renameWorkspaceContainer, 0, true);
|
|
this.agHelper.WaitUntilEleAppear(this._renameWorkspaceInput);
|
|
this.agHelper.TypeText(this._renameWorkspaceInput, newWorkspaceName).blur();
|
|
this.assertHelper.AssertNetworkStatus("@updateWorkspace");
|
|
this.agHelper.AssertContains(newWorkspaceName);
|
|
this.agHelper.AssertElementVisibility(
|
|
this._workspaceList(newWorkspaceName),
|
|
);
|
|
}
|
|
|
|
//Maps to CheckShareIcon in command.js
|
|
public CheckWorkspaceShareUsersCount(workspaceName: string, count: number) {
|
|
this.SelectWorkspace(workspaceName);
|
|
cy.get(this._workspaceShareUsersIcon(workspaceName)).should(
|
|
"have.length",
|
|
count,
|
|
);
|
|
}
|
|
|
|
//Maps to inviteUserForWorkspace in command.js
|
|
public InviteUserToWorkspace(
|
|
workspaceName: string,
|
|
email: string,
|
|
role: string,
|
|
networkCallAlias = true,
|
|
) {
|
|
this.SelectWorkspace(workspaceName, networkCallAlias);
|
|
const successMessage =
|
|
CURRENT_REPO === REPO.CE
|
|
? "The user has been invited successfully"
|
|
: "The user/group have been invited successfully";
|
|
this.StubPostHeaderReq();
|
|
this.agHelper.AssertElementVisibility(this._workspaceList(workspaceName));
|
|
this.agHelper.GetNClick(this._shareWorkspace(workspaceName), 0, true);
|
|
this.agHelper.AssertElementExist(
|
|
"//span[text()='Users will have access to all applications in this workspace']",
|
|
);
|
|
cy.xpath(this._email).click({ force: true }).type(email);
|
|
cy.xpath(this._selectRole).first().click({ force: true });
|
|
this.agHelper.Sleep(500);
|
|
cy.xpath(this._userRole(role)).click({ force: true });
|
|
this.agHelper.GetNClick(this._inviteButton, 0, true);
|
|
cy.wait("@mockPostInvite")
|
|
.its("request.headers")
|
|
.should("have.property", "origin", "Cypress");
|
|
this.agHelper.ValidateToastMessage(successMessage);
|
|
}
|
|
|
|
public InviteUserToWorkspaceErrorMessage(
|
|
workspaceName: string,
|
|
text: string,
|
|
) {
|
|
const errorMessage =
|
|
CURRENT_REPO === REPO.CE
|
|
? "Invalid email address(es) found"
|
|
: "Invalid email address(es) or group(s) found";
|
|
this.StubPostHeaderReq();
|
|
this.agHelper.AssertElementVisibility(this._workspaceList(workspaceName));
|
|
this.agHelper.GetNClick(this._shareWorkspace(workspaceName), 0, true);
|
|
cy.xpath(this._email).click({ force: true }).type(text);
|
|
this.agHelper.GetNClick(this._inviteButton, 0, true);
|
|
cy.contains(text, { matchCase: false });
|
|
cy.contains(errorMessage, { matchCase: false });
|
|
cy.get(".ads-v2-modal__content-header-close-button").click({ force: true });
|
|
}
|
|
|
|
public StubPostHeaderReq() {
|
|
cy.intercept("POST", "/api/v1/users/invite", (req) => {
|
|
req.headers["origin"] = "Cypress";
|
|
}).as("mockPostInvite");
|
|
cy.intercept("POST", "/api/v1/applications/invite", (req) => {
|
|
req.headers["origin"] = "Cypress";
|
|
}).as("mockPostAppInvite");
|
|
}
|
|
|
|
public NavigateToHome() {
|
|
this.agHelper.AssertElementVisibility(this._homeIcon);
|
|
this.agHelper.GetNClick(this._homeIcon, 0, true, 2500);
|
|
if (!Cypress.env("AIRGAPPED")) {
|
|
this.assertHelper.AssertNetworkStatus("@getAllWorkspaces");
|
|
} else {
|
|
this.agHelper.Sleep(2000);
|
|
}
|
|
this.agHelper.WaitUntilEleAppear(this._homeAppsmithImage);
|
|
this.agHelper.AssertElementVisibility(this._newWorkSpaceLink);
|
|
this.agHelper.AssertElementExist(this._homePageContainer);
|
|
this.agHelper.AssertElementVisibility(this._homePageContainer);
|
|
}
|
|
|
|
public AssertApplicationCreated() {
|
|
this.assertHelper.AssertNetworkStatus("@createNewApplication", 201);
|
|
cy.get("@createNewApplication").then((interception: any) => {
|
|
localStorage.setItem("applicationId", interception.response.body.data.id);
|
|
localStorage.setItem("appName", interception.response.body.data.name);
|
|
cy.wrap(interception.response.body.data.name).as("appName");
|
|
cy.wrap(interception.response.body.data.id).as("applicationId");
|
|
});
|
|
// should resolve auditlog test case
|
|
cy.wait("@getConsolidatedData");
|
|
this.agHelper.AssertElementAbsence(this.locator._loading);
|
|
}
|
|
|
|
public CreateNewApplication(skipSignposting = true) {
|
|
this.agHelper.GetNClick(this._homePageAppCreateBtn, 0, true);
|
|
this.agHelper.GetNClick(this._newButtonCreateApplication, 0, true);
|
|
this.AssertApplicationCreated();
|
|
if (skipSignposting) {
|
|
AppSidebar.assertVisible();
|
|
this.agHelper.AssertElementVisibility(PageLeftPane.locators.selector);
|
|
this.onboarding.skipSignposting();
|
|
}
|
|
this.assertHelper.AssertNetworkStatus("getWorkspace");
|
|
}
|
|
|
|
//Maps to CreateAppForWorkspace in command.js
|
|
public CreateAppInWorkspace(workspaceName: string, appname = "") {
|
|
this.agHelper
|
|
.GetElement(this._existingWorkspaceCreateNewApp(workspaceName))
|
|
.last()
|
|
.scrollIntoView()
|
|
.should("be.visible")
|
|
.click({ force: true });
|
|
this.agHelper.GetNClick(this._newButtonCreateApplication);
|
|
this.AssertApplicationCreated();
|
|
this.agHelper.AssertElementVisibility(this.locator._sidebar);
|
|
this.agHelper.AssertElementAbsence(this.locator._loading);
|
|
if (appname) this.RenameApplication(appname);
|
|
}
|
|
|
|
//Maps to AppSetupForRename in command.js
|
|
public RenameApplication(appName: string) {
|
|
this.onboarding.closeIntroModal();
|
|
cy.get(this._applicationName).then(($appName) => {
|
|
if (!$appName.hasClass(this._editAppName)) {
|
|
this.agHelper.GetNClick(this._applicationName);
|
|
this.agHelper.GetNClickByContains(this._appMenu, "Rename");
|
|
}
|
|
});
|
|
cy.get(this._applicationName).type(appName);
|
|
this.agHelper.PressEnter();
|
|
this.agHelper.RemoveUIElement("Tooltip", "Rename application");
|
|
}
|
|
|
|
public GetAppName() {
|
|
return this.agHelper.GetText(this._applicationName, "text");
|
|
}
|
|
|
|
//Maps to LogOut in command.js
|
|
public LogOutviaAPI() {
|
|
let httpMethod = "POST";
|
|
if (CURRENT_REPO === REPO.EE) {
|
|
httpMethod = "GET";
|
|
}
|
|
cy.request({
|
|
method: httpMethod,
|
|
url: "/api/v1/logout",
|
|
headers: {
|
|
"X-Requested-By": "Appsmith",
|
|
},
|
|
}).then((response) => {
|
|
expect(response.status).equal(200); //Verifying logout is success
|
|
});
|
|
this.agHelper.Sleep(2000); //for logout to complete - CI!
|
|
}
|
|
|
|
public Signout(toNavigateToHome = true) {
|
|
if (toNavigateToHome) this.NavigateToHome();
|
|
this.agHelper.GetNClick(this._profileMenu);
|
|
this.agHelper.GetNClick(this._signout);
|
|
//Logout is still a POST request in CE
|
|
if (CURRENT_REPO === REPO.CE) {
|
|
this.assertHelper.AssertNetworkStatus("@postLogout");
|
|
}
|
|
this.agHelper.AssertURL("/login");
|
|
}
|
|
|
|
public GotoProfileMenu() {
|
|
this.agHelper.GetNClick(this._profileMenu);
|
|
}
|
|
|
|
public GotoEditProfile() {
|
|
cy.location().then((loc) => {
|
|
if (loc.pathname !== "/profile") {
|
|
this.NavigateToHome();
|
|
this.GotoProfileMenu();
|
|
this.agHelper.GetNClick(this._editProfileMenu);
|
|
}
|
|
});
|
|
}
|
|
|
|
public InvokeDispatchOnStore() {
|
|
cy.window().then((win: any) => {
|
|
if (win && win.store) {
|
|
cy.window()
|
|
.its("store")
|
|
.invoke("dispatch", { type: "LOGOUT_USER_INIT" });
|
|
} else {
|
|
// Handle the case where "store" is not present, or simply ignore and continue.
|
|
}
|
|
});
|
|
}
|
|
|
|
public LogintoApp(
|
|
uname: string,
|
|
pswd: string,
|
|
role: "App Viewer" | "Developer" | "Administrator" = "Administrator",
|
|
) {
|
|
this.agHelper.Sleep(); //waiting for window to load
|
|
this.InvokeDispatchOnStore();
|
|
cy.wait("@postLogout");
|
|
this.agHelper.VisitNAssert("/user/login", "getConsolidatedData");
|
|
this.agHelper.AssertElementVisibility(this._username);
|
|
this.agHelper.TypeText(this._username, uname);
|
|
this.agHelper.TypeText(this._password, pswd);
|
|
this.agHelper.GetNClick(this._submitBtn);
|
|
this.assertHelper.AssertNetworkStatus("@getConsolidatedData");
|
|
this.agHelper.Sleep(3000);
|
|
this.agHelper.AssertElementExist(this._homePageContainer);
|
|
this.agHelper.AssertElementVisibility(this._homePageContainer);
|
|
if (role != "App Viewer") {
|
|
this.agHelper.AssertElementVisibility(this._homePageAppCreateBtn);
|
|
this.agHelper.AssertElementEnabledDisabled(
|
|
this._homePageAppCreateBtn,
|
|
undefined,
|
|
false,
|
|
);
|
|
}
|
|
}
|
|
|
|
public SignUp(uname: string, pswd: string) {
|
|
this.agHelper.VisitNAssert("/user/signup", "@getConsolidatedData");
|
|
this.agHelper.AssertElementVisibility(this.signupUsername);
|
|
this.agHelper.TypeText(this.signupUsername, uname);
|
|
this.agHelper.TypeText(this._password, pswd);
|
|
this.agHelper.GetNClick(this._submitBtn);
|
|
this.agHelper.Sleep(1000);
|
|
cy.url().then((url) => {
|
|
if (url.indexOf("/signup-success") > -1) {
|
|
cy.get("body").then(($body) => {
|
|
if (
|
|
$body.find(SignupPageLocators.proficiencyGroupButton).length > 0
|
|
) {
|
|
this.agHelper.GetNClick(SignupPageLocators.proficiencyGroupButton);
|
|
this.agHelper.GetNClick(SignupPageLocators.useCaseGroupButton);
|
|
this.agHelper.GetNClick(
|
|
SignupPageLocators.getStartedSubmit,
|
|
undefined,
|
|
true,
|
|
);
|
|
}
|
|
});
|
|
}
|
|
});
|
|
this.assertHelper.AssertNetworkStatus("@getConsolidatedData");
|
|
this.agHelper.Sleep(3000);
|
|
}
|
|
|
|
public FilterApplication(
|
|
appName: string,
|
|
workspaceId?: string,
|
|
checkForShareButton = true,
|
|
) {
|
|
cy.get(this._searchInput).type(appName, { force: true });
|
|
this.agHelper.Sleep(2000);
|
|
if (workspaceId) {
|
|
this.SelectWorkspace(workspaceId);
|
|
cy.get(this._appContainer).contains(workspaceId);
|
|
}
|
|
if (checkForShareButton) {
|
|
cy.xpath(this.locator._buttonByText("Share"))
|
|
.first()
|
|
.should("be.visible");
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Searches for given app name and clicks edit icon
|
|
* @param appName
|
|
*/
|
|
public SearchAndOpenApp(appName: string, ele?: string) {
|
|
this.agHelper.WaitUntilEleAppear(this._searchInput);
|
|
this.agHelper.TypeText(this._searchInput, appName);
|
|
this.EditAppFromSearch(appName, ele);
|
|
}
|
|
|
|
//Maps to launchApp in command.js
|
|
public LaunchAppFromAppHover() {
|
|
cy.get(this._appHoverIcon("view")).should("be.visible").first().click();
|
|
this.agHelper.AssertElementAbsence(this.locator._loading);
|
|
this.assertHelper.AssertNetworkStatus("getConsolidatedData");
|
|
}
|
|
|
|
public EditAppFromSearch(appName: string, element?: string) {
|
|
this.agHelper.WaitUntilEleAppear(`[data-testid="${appName}"]`);
|
|
this.agHelper.GetNClick(`[data-testid="${appName}"]`);
|
|
this.assertHelper.AssertNetworkStatus("viewPage");
|
|
cy.url({ timeout: Cypress.config().pageLoadTimeout }).should(
|
|
"not.include",
|
|
"edit",
|
|
);
|
|
this.agHelper.WaitUntilEleAppear(element ?? this.locator._backToEditor);
|
|
this.agHelper.AssertElementExist(this._deployPageWidgets);
|
|
this.agHelper.AssertElementVisibility(this._deployPageWidgets);
|
|
this.assertHelper.AssertDocumentReady();
|
|
this.deployHelper.NavigateBacktoEditor();
|
|
}
|
|
|
|
public EditAppFromAppHover(appName = "") {
|
|
if (appName)
|
|
this.agHelper
|
|
.GetElement(this._appCard(appName))
|
|
.first()
|
|
.trigger("mouseover");
|
|
else
|
|
this.agHelper
|
|
.GetElement(this._applicationCard)
|
|
.first()
|
|
.trigger("mouseover");
|
|
this.agHelper.GetNClick(this._appHoverIcon("edit"));
|
|
this.agHelper.AssertElementAbsence(this.locator._loading);
|
|
this.assertHelper.AssertNetworkStatus("getWorkspace");
|
|
}
|
|
|
|
//Maps to deleteUserFromWorkspace in command.js
|
|
public DeleteUserFromWorkspace(
|
|
appName: string,
|
|
workspaceName: string,
|
|
email: string,
|
|
) {
|
|
cy.get(this._workspaceList(workspaceName))
|
|
.scrollIntoView()
|
|
.should("be.visible");
|
|
this.FilterApplication(appName, workspaceName);
|
|
this.agHelper.GetNClick(this._optionsIcon).click({ force: true });
|
|
cy.xpath(this._visibleTextSpan("Members")).click({ force: true });
|
|
cy.wait("@getMembers").should(
|
|
"have.nested.property",
|
|
"response.body.responseMeta.status",
|
|
200,
|
|
);
|
|
this.agHelper.TypeText(this._searchUsersInput, email);
|
|
cy.wait(2000);
|
|
cy.get(HomePageLocators.DeleteBtn).first().click({ force: true });
|
|
cy.get(this._leaveWorkspaceConfirmModal).should("be.visible");
|
|
cy.get(this._leaveWorkspaceConfirmButton).click({ force: true });
|
|
cy.wait(4000);
|
|
}
|
|
|
|
public OpenMembersPageForWorkspace(workspaceName: string) {
|
|
cy.get(this._appContainer)
|
|
.contains(workspaceName)
|
|
.scrollIntoView()
|
|
.should("be.visible");
|
|
cy.get(this._appContainer)
|
|
.contains(workspaceName)
|
|
.closest(this._workspaceCompleteSection)
|
|
.find(this._optionsIcon)
|
|
.click({ force: true });
|
|
|
|
cy.xpath(this._visibleTextSpan("Members")).last().click({ force: true });
|
|
cy.wait("@getMembers").should(
|
|
"have.nested.property",
|
|
"response.body.responseMeta.status",
|
|
200,
|
|
);
|
|
this.agHelper.Sleep(2500);
|
|
//wait for members page to load!
|
|
}
|
|
|
|
public UpdateUserRoleInWorkspace(
|
|
workspaceName: string,
|
|
email: string,
|
|
currentRole: string,
|
|
newRole: string,
|
|
) {
|
|
this.OpenMembersPageForWorkspace(workspaceName);
|
|
cy.log(workspaceName, email, currentRole);
|
|
this.agHelper.TypeText(this._searchUsersInput, email);
|
|
cy.get(".search-highlight").should("exist").contains(email);
|
|
this.agHelper.Sleep(2000);
|
|
cy.xpath(this._userRoleDropDown(currentRole))
|
|
.first()
|
|
.click({ force: true });
|
|
this.agHelper.Sleep();
|
|
//cy.xpath(this._userRoleDropDown(email)).first().click({force: true});
|
|
if (CURRENT_REPO === REPO.EE) {
|
|
this.agHelper.AssertElementExist(
|
|
this._visibleTextSpan("Assign Custom Role"),
|
|
);
|
|
}
|
|
cy.xpath(this._visibleTextSpan(`${newRole}`))
|
|
.last()
|
|
.parent("div")
|
|
.click();
|
|
this.agHelper.Sleep();
|
|
this.agHelper.AssertElementVisibility(this._userRoleDropDown(newRole));
|
|
this.NavigateToHome();
|
|
}
|
|
|
|
public ImportApp(
|
|
fixtureJson: string,
|
|
intoWorkspaceName = "",
|
|
onlyImport = false,
|
|
) {
|
|
this.agHelper.Sleep(3000); //for new workspace to settle for CI
|
|
if (onlyImport === false) {
|
|
cy.get(this._homeIcon).click({ force: true });
|
|
if (intoWorkspaceName) {
|
|
this.agHelper
|
|
.GetElement(this._leftPanel)
|
|
.contains("span", intoWorkspaceName)
|
|
.click();
|
|
this.agHelper.GetNClick(this._newIcon);
|
|
} else this.agHelper.GetNClick(this._newIcon);
|
|
this.agHelper.GetNClick(this._workspaceImport, 0, true);
|
|
this.agHelper.AssertElementVisibility(this._workspaceImportAppModal);
|
|
}
|
|
cy.xpath(this._uploadFile).selectFile("cypress/fixtures/" + fixtureJson, {
|
|
force: true,
|
|
});
|
|
this.agHelper.Sleep(3500);
|
|
this.agHelper.AssertElementAbsence(
|
|
this.locator._specificToast("Unable to import application in workspace"),
|
|
);
|
|
}
|
|
|
|
public ImportGitApp(intoWorkspaceName = "") {
|
|
this.NavigateToHome();
|
|
if (intoWorkspaceName) {
|
|
this.agHelper
|
|
.GetElement(this._leftPanel)
|
|
.contains("span", intoWorkspaceName)
|
|
.click();
|
|
this.agHelper.GetNClick(this._newIcon);
|
|
} else this.agHelper.GetNClick(this._optionsIcon);
|
|
this.agHelper.GetNClick(this._workspaceImport, 0, true);
|
|
this.agHelper.AssertElementVisibility(this._workspaceImportAppModal);
|
|
this.agHelper.GetNClick(this._importFromGitBtn);
|
|
this.agHelper.Sleep(1000);
|
|
}
|
|
|
|
// Do not use this directly, it will fail on EE. Use `InviteUserToApplication` instead
|
|
private InviteUserToWorkspaceFromApp(
|
|
email: string,
|
|
role: string,
|
|
validate = true,
|
|
) {
|
|
const successMessage =
|
|
CURRENT_REPO === REPO.CE
|
|
? "The user has been invited successfully"
|
|
: "The user/group have been invited successfully";
|
|
this.StubPostHeaderReq();
|
|
this.agHelper.AssertElementExist(
|
|
"//span[text()='Users will have access to all applications in the workspace. For application-level access, try out our ']",
|
|
);
|
|
this.agHelper.AssertElementExist("//span[text()='business edition']");
|
|
cy.xpath(this._email).click({ force: true }).type(email);
|
|
cy.xpath(this._selectRole).first().click({ force: true });
|
|
this.agHelper.Sleep(500);
|
|
cy.xpath(this._userRole(role)).click({ force: true });
|
|
this.agHelper.GetNClick(this._inviteButton, 0, true);
|
|
cy.wait("@mockPostInvite")
|
|
.its("request.headers")
|
|
.should("have.property", "origin", "Cypress");
|
|
// cy.contains(email, { matchCase: false });
|
|
if (validate) {
|
|
cy.contains(successMessage);
|
|
}
|
|
}
|
|
|
|
public InviteUserToApplicationFromApp(email: string, role: string) {
|
|
const successMessage = "The user/group have been invited successfully";
|
|
this.StubPostHeaderReq();
|
|
this.agHelper.AssertElementExist(
|
|
"//span[text()='Users will only have access to this application']",
|
|
);
|
|
cy.xpath(this._email).click({ force: true }).type(email);
|
|
cy.xpath(this._selectRole).first().click({ force: true });
|
|
this.agHelper.Sleep(500);
|
|
cy.xpath(this._userRole(role)).click({ force: true });
|
|
this.agHelper.GetNClick(this._inviteButton, 0, true);
|
|
cy.wait("@mockPostAppInvite")
|
|
.its("request.headers")
|
|
.should("have.property", "origin", "Cypress");
|
|
// cy.contains(email, { matchCase: false });
|
|
cy.contains(successMessage);
|
|
}
|
|
|
|
public InviteUserToApplication(email: string, role: string) {
|
|
if (CURRENT_REPO === REPO.CE) {
|
|
this.InviteUserToWorkspaceFromApp(email, role);
|
|
} else {
|
|
this.InviteUserToApplicationFromApp(email, role);
|
|
}
|
|
}
|
|
|
|
public DeleteWorkspace(workspaceNameToDelete: string) {
|
|
cy.get(this._homeIcon).click({ force: true });
|
|
this.SelectWorkspace(workspaceNameToDelete);
|
|
this.agHelper.GetNClick(this._optionsIcon);
|
|
this.agHelper.GetNClick(this._wsAction("Delete workspace"));
|
|
this.agHelper.GetNClick(this._wsAction("Are you sure?"));
|
|
this.assertHelper.AssertNetworkStatus("deleteWorkspaceApiCall");
|
|
}
|
|
|
|
public AssertNCloseImport() {
|
|
this.agHelper.AssertElementVisibility(this._importSuccessModal);
|
|
this.agHelper.AssertElementVisibility(
|
|
this.locator._visibleTextSpan("Your application is ready to use."),
|
|
);
|
|
this.agHelper.ClickButton("Got it");
|
|
}
|
|
|
|
public AssertImportToast(timeout = 5000) {
|
|
this.agHelper.AssertContains("Application imported successfully");
|
|
this.agHelper.Sleep(timeout); //for imported app to settle!
|
|
cy.get(this.locator._loading).should("not.exist");
|
|
}
|
|
|
|
public ForkApplication(appliName: string, forkWorkspaceName = "") {
|
|
this.agHelper.GetNClick(this._applicationContextMenu(appliName));
|
|
this.agHelper.GetNClick(this._forkApp);
|
|
this.agHelper.AssertElementVisibility(this._forkModal);
|
|
if (forkWorkspaceName) {
|
|
this.agHelper.GetNClick(this._forkWorkspaceDropdownOption);
|
|
this.agHelper.GetNClick(
|
|
this._forkWorkspaceSelectOptions(forkWorkspaceName),
|
|
);
|
|
}
|
|
this.agHelper.ClickButton("Fork");
|
|
this.assertHelper.AssertNetworkStatus("getWorkspace");
|
|
}
|
|
|
|
public DeleteApplication(appliName: string) {
|
|
this.agHelper.GetNClick(this._applicationContextMenu(appliName));
|
|
this.agHelper.GetNClick(this._deleteApp);
|
|
this.agHelper.GetNClick(this._deleteAppConfirm);
|
|
// Toast has been removed
|
|
// this.agHelper.WaitUntilToastDisappear("Deleting application...");
|
|
this.assertHelper.AssertNetworkStatus("@deleteApp", 200);
|
|
}
|
|
|
|
public DeleteAppviaAPI(appId: any) {
|
|
cy.request({
|
|
method: "DELETE",
|
|
url: "api/v1/applications/" + appId,
|
|
failOnStatusCode: false,
|
|
headers: {
|
|
"X-Requested-By": "Appsmith",
|
|
},
|
|
});
|
|
}
|
|
|
|
//Maps to leaveworkspace in command.js
|
|
public LeaveWorkspace(workspaceName: string) {
|
|
this.SelectWorkspace(workspaceName);
|
|
this.OpenWorkspaceOptions(workspaceName);
|
|
this.agHelper.GetNClick(this._leaveWorkspace, 0, true);
|
|
this.agHelper.GetNClick(this._leaveWorkspaceConfirm, 0, true);
|
|
this.assertHelper.AssertNetworkStatus("@leaveWorkspaceApiCall");
|
|
|
|
this.agHelper.ValidateToastMessage(
|
|
"You have successfully left the workspace",
|
|
);
|
|
}
|
|
|
|
public CloseReconnectDataSourceModal() {
|
|
cy.get("body").then(($ele) => {
|
|
if ($ele.find(this._reconnectDataSourceModal).length) {
|
|
this.agHelper.GetNClick(this._skiptoApplicationBtn);
|
|
this.NavigateToHome();
|
|
}
|
|
});
|
|
}
|
|
public SelectWorkspace(workspaceName: string, networkCallAlias = true) {
|
|
this.agHelper
|
|
.GetElement(this._leftPanel)
|
|
.contains("span", workspaceName)
|
|
.click({ force: true });
|
|
networkCallAlias &&
|
|
this.assertHelper.AssertNetworkStatus("@getApplicationsOfWorkspace");
|
|
}
|
|
}
|