PromucFlow_constructor/app/client/cypress/support/Pages/HomePage.ts
Aman Agarwal a40e16adb3
fix: asserting getApplicationsOfWorkspace call before clicking skip (#32311)
## Description
Asserting getApplicationsOfWorkspace call before clicking `Skip this
step, I`ll do it later` button to move to the application screen.

Tldr:
Earlier was failing because the applications in the workspace were not
available (or the network call was already in progress) and when the
button was clicked because of the application condition, it was not
redirecting to the application screen. Now we wait for the applications
network call to finish before clicking on the Skip button.

Fixes #32310
_or_  
Fixes `Issue URL`
> [!WARNING]  
> _If no issue exists, please create an issue first, and check with the
maintainers if the issue is valid._

## Automation

/ok-to-test tags="@tag.IDE"

### 🔍 Cypress test results
<!-- This is an auto-generated comment: Cypress test results  -->
> [!CAUTION]  
> Workflow run:
<https://github.com/appsmithorg/appsmith/actions/runs/8522236782>
> Commit: `e94458e2051502af269082e46c5811717877b32b`
> Cypress dashboard: <a
href="https://internal.appsmith.com/app/cypress-dashboard/rundetails-65890b3c81d7400d08fa9ee5?branch=master&workflowId=8522236782&attempt=1&selectiontype=test&testsstatus=failed&specsstatus=fail"
target="_blank"> Click here!</a>
> The following are new failures, please fix them before merging the PR:
<ol>
>
<li>cypress/e2e/Regression/ClientSide/IDE/IDE_Add_Pane_Interactions_spec.ts
</ol>
> To know the list of identified flaky tests - <a
href="https://internal.appsmith.com/app/cypress-dashboard/identified-flaky-tests-65890b3c81d7400d08fa9ee3?branch=master"
target="_blank">Refer here</a>

<!-- end of auto-generated comment: Cypress test results  -->












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



- **Refactor**
	- Enhanced user interaction on the homepage for improved usability.
	- Streamlined the process for creating superuser accounts.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2024-04-03 11:01:05 +05:30

802 lines
30 KiB
TypeScript

import { CURRENT_REPO, REPO } from "../../fixtures/REPO";
import HomePageLocators from "../../locators/HomePage";
import SignupPageLocators from "../../locators/SignupPage.json";
import { ObjectsRegistry } from "../Objects/Registry";
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 _renameWorkspaceParent = ".t--workspace-rename-input";
private _renameWorkspaceInput = this._renameWorkspaceParent + " 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]";
_newButtonCreateApplicationFromTemplates =
"[data-testid=t--workspace-action-create-app-from-template]";
_createAppFromTemplatesDialog =
"[data-testid=t--create-app-from-templates-dialog-component]";
_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')]";
public _homePageContainer =
"div.t--applications-container div.t--workspace-section:not(:empty)";
private _backToEditor = ".t--back-to-editor";
private _editorSidebar = ".t--sidebar-Editor";
private _membersTab = "[data-testid=t--tab-members]";
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();
this.RenameWorkspace(oldName, workspaceNewName, false);
});
}
public OpenWorkspaceOptions(workspaceName: string, networkCallAlias = true) {
this.SelectWorkspace(workspaceName, networkCallAlias);
this.agHelper.GetNClick(this._optionsIcon, 0, 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.AssertElementVisibility(this._renameWorkspaceContainer);
Cypress._.times(2, () => {
this.agHelper.GetNClick(this._renameWorkspaceParent, 0, true);
});
this.agHelper.WaitUntilEleAppear(this._renameWorkspaceInput);
this.agHelper
.ClearNType(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);
}
public OpenTemplatesDialogInStartFromTemplates() {
this.agHelper.GetNClick(this._homePageAppCreateBtn, 0, true);
this.agHelper.GetNClick(this._newButtonCreateApplicationFromTemplates);
this.agHelper.AssertElementVisibility(this._createAppFromTemplatesDialog);
}
//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.AssertElementVisibility(this._appMenu);
this.agHelper.GetNClickByContains(this._appMenu, "Rename");
}
});
cy.get(this._applicationName).type(appName);
this.agHelper.PressEnter();
this.assertHelper.AssertNetworkStatus("updateApplication");
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
});
}
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");
this.agHelper.AssertElementVisibility(this._username);
this.agHelper.AssertElementVisibility(this._submitBtn);
}
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();
this.assertHelper.WaitForNetworkCall("@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,
skipToApplication: boolean = true,
) {
this.agHelper.VisitNAssert("/user/signup");
this.agHelper.AssertElementVisibility(this.signupUsername);
this.agHelper.AssertAttribute(this._submitBtn, "data-disabled", "true");
this.agHelper.TypeText(this.signupUsername, uname);
this.agHelper.TypeText(this._password, pswd);
this.agHelper.AssertAttribute(this._submitBtn, "data-disabled", "false");
this.agHelper.ClickButton("Sign up");
this.agHelper.WaitForCondition(() =>
cy.url().should("include", "signup-success"),
);
this.agHelper.WaitUntilEleAppear(SignupPageLocators.proficiencyGroupButton);
this.agHelper
.GetElementLength(SignupPageLocators.proficiencyGroupButton)
.then(($len) => {
if ($len > 0) {
this.agHelper.GetNClick(SignupPageLocators.proficiencyGroupButton);
this.agHelper.GetNClick(SignupPageLocators.useCaseGroupButton);
this.agHelper.ClickButton("Get started");
}
});
this.assertHelper.AssertNetworkStatus("@getApplicationsOfWorkspace");
if (skipToApplication) {
this.agHelper.WaitUntilEleAppear(
this.onboarding.locators.skipStartFromData,
);
this.agHelper.GetNClick(this.onboarding.locators.skipStartFromData);
}
this.assertHelper.AssertNetworkStatus("@getConsolidatedData");
}
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(element?: string) {
cy.get(this._appHoverIcon("view")).should("be.visible").first().click();
this.agHelper.AssertElementAbsence(this.locator._loading);
this.assertHelper.AssertNetworkStatus("getConsolidatedData");
this.AssertViewPageLoad(element);
}
public EditAppFromSearch(appName: string, element?: string) {
this.agHelper.WaitUntilEleAppear(`[data-testid="${appName}"]`);
this.agHelper.GetNClick(`[data-testid="${appName}"]`);
this.assertHelper.AssertNetworkStatus("viewPage");
this.AssertViewPageLoad(element);
this.deployHelper.NavigateBacktoEditor();
}
public AssertViewPageLoad(element?: string) {
cy.url({ timeout: Cypress.config().pageLoadTimeout }).should(
"not.include",
"edit",
);
this.agHelper.WaitUntilEleAppear(element ?? this.locator._backToEditor);
this.agHelper.AssertElementExist(this.deployHelper._deployPageWidgets);
this.agHelper.AssertElementVisibility(this.deployHelper._deployPageWidgets);
this.agHelper.AssertElementVisibility(this.deployHelper._appViewPageName);
this.assertHelper.AssertDocumentReady();
}
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 });
this.assertHelper.AssertNetworkStatus("getMembers");
this.agHelper.AssertElementVisibility(this._membersTab);
}
public UpdateUserRoleInWorkspace(
workspaceName: string,
email: string,
currentRole: string,
newRole: string,
) {
this.OpenMembersPageForWorkspace(workspaceName);
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);
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.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");
}
}