test: Cypress | Replace static with Dynamic waits - Part 1 (#29405)

## Description
- Removed hard waits from below specs:
    - Apps/CurrencyInputIssue_Spec.js
    - ClientSide/Widgets/Modal/Modal_spec.ts (Fix & unskip)
    - /Binding/TableV2_Widget_API_Pagination_spec.js
- Unskip - ApiTests/API_Unique_name_spec.js
- Flaky fix - TableV2_Widget_API_Pagination_spec.js
- Flaky fix - /ServerSide/QueryPane/S3_1_spec.js
- Removed empty ReusableHelper.ts
- Improved agHelper.GetElement() to include the assertion for element
presence/absence
- Modified helpers/function calls to fit the above syntax of
GetElement()
- Improved WaitUntilEleAppear(), WaitUntilEleDisappear() to use timeout
from cypress config

#### Type of change
- Script fix (non-breaking change which fixes an issue)

## Testing
#### How Has This Been Tested?
- [X] Cypress CI runs

## Checklist:
#### QA activity:
- [X] Added `Test Plan Approved` label after Cypress tests were reviewed

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

## Summary by CodeRabbit

- **Tests**
- Enhanced end-to-end test stability by replacing static waits with
dynamic element-based synchronization.
  - Skipped certain test suites to streamline the testing process.
- Improved test assertions and control flow for more reliable
verification of UI components.

- **Chores**
  - Updated test helper methods to support new verification strategies.
- Cleaned up unnecessary imports and inheritance in test support
classes.

- **Documentation**
- Adjusted test case descriptions to reflect the new synchronization
methods used.

- **Bug Fixes**
- Fixed issues with test synchronization that could lead to flaky test
results.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
Aishwarya-U-R 2023-12-11 14:39:36 +05:30 committed by GitHub
parent c29a7e1712
commit fe3863eb65
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
16 changed files with 129 additions and 119 deletions

View File

@ -1,4 +1,3 @@
/// <reference types="Cypress" />
import { homePage, agHelper } from "../../../support/Objects/ObjectsCore"; import { homePage, agHelper } from "../../../support/Objects/ObjectsCore";
import reconnectDatasourceModal from "../../../locators/ReconnectLocators"; import reconnectDatasourceModal from "../../../locators/ReconnectLocators";
const themelocators = require("../../../locators/ThemeLocators.json"); const themelocators = require("../../../locators/ThemeLocators.json");
@ -12,13 +11,11 @@ describe("Currency Input Issue", function () {
agHelper.VisitNAssert("/applications", "getReleaseItems"); agHelper.VisitNAssert("/applications", "getReleaseItems");
homePage.ImportApp("CurrencyInputIssueExport.json"); homePage.ImportApp("CurrencyInputIssueExport.json");
cy.wait("@importNewApplication").then((interception) => { cy.wait("@importNewApplication").then((interception) => {
agHelper.Sleep();
const { isPartialImport } = interception.response.body.data; const { isPartialImport } = interception.response.body.data;
if (isPartialImport) { if (isPartialImport) {
cy.get(reconnectDatasourceModal.SkipToAppBtn).click({ cy.get(reconnectDatasourceModal.SkipToAppBtn).click({
force: true, force: true,
}); });
cy.wait(2000);
} else { } else {
homePage.AssertImportToast(); homePage.AssertImportToast();
} }

View File

@ -5,7 +5,7 @@ import EditorNavigation, {
const commonlocators = require("../../../../locators/commonlocators.json"); const commonlocators = require("../../../../locators/commonlocators.json");
import { import {
agHelper, agHelper,
entityExplorer, locators,
propPane, propPane,
apiPage, apiPage,
table, table,
@ -34,10 +34,10 @@ describe("Test Create Api and Bind to Table widget V2", function () {
cy.get(`.t--widget-tablewidgetv2 .t--table-widget-next-page`) cy.get(`.t--widget-tablewidgetv2 .t--table-widget-next-page`)
.first() .first()
.click(); .click();
cy.wait(2000);
cy.get(`.t--widget-tablewidgetv2 .page-item`) cy.get(`.t--widget-tablewidgetv2 .page-item`)
.first() .first()
.should("contain", "2"); .should("contain", "2");
agHelper.WaitUntilToastDisappear("done");
}); });
it("2. Bug #22477: should check whether the next page button is disabled and not clickable when last page is reached", () => { it("2. Bug #22477: should check whether the next page button is disabled and not clickable when last page is reached", () => {
@ -51,6 +51,6 @@ describe("Test Create Api and Bind to Table widget V2", function () {
agHelper.GetNClick(table._nextPage("v2")); agHelper.GetNClick(table._nextPage("v2"));
agHelper.AssertAttribute(table._nextPage("v2"), "disabled", "disabled"); agHelper.AssertAttribute(table._nextPage("v2"), "disabled", "disabled");
agHelper.AssertElementAbsence(commonlocators._toastMsg); agHelper.AssertElementAbsence(locators._toastMsg);
}); });
}); });

View File

@ -27,9 +27,8 @@ describe("excludeForAirgap", "Widget property navigation", () => {
_.propPane.NavigateBackToPropertyPane(); _.propPane.NavigateBackToPropertyPane();
_.debuggerHelper.ClickDebuggerIcon(); _.debuggerHelper.ClickDebuggerIcon();
_.debuggerHelper.ClicklogEntityLink(); _.debuggerHelper.ClicklogEntityLink();
_.agHelper.GetElement(_.propPane._paneTitle).contains("Tab 2"); _.agHelper.GetNAssertContains(_.propPane._paneTitle, "Tab 2");
_.propPane.AssertIfPropertyIsVisible("visible"); _.propPane.AssertIfPropertyIsVisible("visible");
_.debuggerHelper.CloseBottomBar(); _.debuggerHelper.CloseBottomBar();
EditorNavigation.SelectEntityByName("Tabs1", EntityType.Widget); EditorNavigation.SelectEntityByName("Tabs1", EntityType.Widget);
_.entityExplorer.DeleteWidgetFromEntityExplorer("Tabs1"); _.entityExplorer.DeleteWidgetFromEntityExplorer("Tabs1");
@ -48,9 +47,8 @@ describe("excludeForAirgap", "Widget property navigation", () => {
_.propPane.NavigateBackToPropertyPane(); _.propPane.NavigateBackToPropertyPane();
_.debuggerHelper.ClickDebuggerIcon(); _.debuggerHelper.ClickDebuggerIcon();
_.debuggerHelper.ClicklogEntityLink(); _.debuggerHelper.ClicklogEntityLink();
_.agHelper.GetElement(_.propPane._paneTitle).contains("Menu Item 1"); _.agHelper.GetNAssertContains(_.propPane._paneTitle, "Menu Item 1");
_.propPane.AssertIfPropertyIsVisible("icon"); _.propPane.AssertIfPropertyIsVisible("icon");
_.debuggerHelper.CloseBottomBar(); _.debuggerHelper.CloseBottomBar();
EditorNavigation.SelectEntityByName("ButtonGroup1", EntityType.Widget); EditorNavigation.SelectEntityByName("ButtonGroup1", EntityType.Widget);
_.entityExplorer.DeleteWidgetFromEntityExplorer("ButtonGroup1"); _.entityExplorer.DeleteWidgetFromEntityExplorer("ButtonGroup1");
@ -66,10 +64,9 @@ describe("excludeForAirgap", "Widget property navigation", () => {
_.propPane.NavigateBackToPropertyPane(); _.propPane.NavigateBackToPropertyPane();
_.debuggerHelper.ClickDebuggerIcon(); _.debuggerHelper.ClickDebuggerIcon();
_.debuggerHelper.ClicklogEntityLink(); _.debuggerHelper.ClicklogEntityLink();
_.agHelper.GetElement(_.propPane._paneTitle).contains("Second Menu Item"); _.agHelper.GetNAssertContains(_.propPane._paneTitle, "Second Menu Item");
_.agHelper.Sleep(); _.agHelper.Sleep();
_.propPane.AssertIfPropertyIsVisible("disabled"); _.propPane.AssertIfPropertyIsVisible("disabled");
_.debuggerHelper.CloseBottomBar(); _.debuggerHelper.CloseBottomBar();
EditorNavigation.SelectEntityByName("MenuButton1", EntityType.Widget); EditorNavigation.SelectEntityByName("MenuButton1", EntityType.Widget);
_.entityExplorer.DeleteWidgetFromEntityExplorer("MenuButton1"); _.entityExplorer.DeleteWidgetFromEntityExplorer("MenuButton1");
@ -113,7 +110,7 @@ describe("excludeForAirgap", "Widget property navigation", () => {
_.debuggerHelper.ClickDebuggerIcon(); _.debuggerHelper.ClickDebuggerIcon();
_.debuggerHelper.ClicklogEntityLink(); _.debuggerHelper.ClicklogEntityLink();
_.agHelper.GetElement(_.propPane._paneTitle).contains("Custom Field 2"); _.agHelper.GetNAssertContains(_.propPane._paneTitle, "Custom Field 2");
_.propPane.AssertIfPropertyIsVisible("borderradius"); _.propPane.AssertIfPropertyIsVisible("borderradius");
_.debuggerHelper.CloseBottomBar(); _.debuggerHelper.CloseBottomBar();
@ -136,8 +133,7 @@ describe("excludeForAirgap", "Widget property navigation", () => {
_.debuggerHelper.ClickDebuggerIcon(); _.debuggerHelper.ClickDebuggerIcon();
_.debuggerHelper.ClicklogEntityLink(true); _.debuggerHelper.ClicklogEntityLink(true);
_.agHelper.GetElement(_.propPane._paneTitle).contains("First Menu Item"); _.agHelper.GetNAssertContains(_.propPane._paneTitle, "First Menu Item");
_.debuggerHelper.CloseBottomBar(); _.debuggerHelper.CloseBottomBar();
EditorNavigation.SelectEntityByName("MenuButton1", EntityType.Widget); EditorNavigation.SelectEntityByName("MenuButton1", EntityType.Widget);
_.entityExplorer.DeleteWidgetFromEntityExplorer("MenuButton1"); _.entityExplorer.DeleteWidgetFromEntityExplorer("MenuButton1");
@ -176,8 +172,7 @@ describe("excludeForAirgap", "Widget property navigation", () => {
_.debuggerHelper.ClickDebuggerIcon(); _.debuggerHelper.ClickDebuggerIcon();
_.debuggerHelper.ClicklogEntityLink(); _.debuggerHelper.ClicklogEntityLink();
_.agHelper.GetElement(_.propPane._paneTitle).contains("imdb_id"); _.agHelper.GetNAssertContains(_.propPane._paneTitle, "imdb_id");
_.debuggerHelper.CloseBottomBar(); _.debuggerHelper.CloseBottomBar();
EditorNavigation.SelectEntityByName("Table1", EntityType.Widget); EditorNavigation.SelectEntityByName("Table1", EntityType.Widget);
_.entityExplorer.DeleteWidgetFromEntityExplorer("Table1"); _.entityExplorer.DeleteWidgetFromEntityExplorer("Table1");

View File

@ -1,5 +1,14 @@
import HomePage from "../../../../locators/HomePage"; import HomePage from "../../../../locators/HomePage";
import * as _ from "../../../../support/Objects/ObjectsCore"; import {
agHelper,
entityExplorer,
jsEditor,
deployMode,
homePage,
debuggerHelper,
installer,
draggableWidgets,
} from "../../../../support/Objects/ObjectsCore";
import { import {
AppSidebar, AppSidebar,
AppSidebarButton, AppSidebarButton,
@ -10,27 +19,27 @@ import {
describe("excludeForAirgap", "Tests JS Libraries", () => { describe("excludeForAirgap", "Tests JS Libraries", () => {
it("1. Validates Library install/uninstall", () => { it("1. Validates Library install/uninstall", () => {
AppSidebar.navigate(AppSidebarButton.Libraries); AppSidebar.navigate(AppSidebarButton.Libraries);
_.installer.OpenInstaller(); installer.OpenInstaller();
_.installer.InstallLibrary("uuidjs", "UUID"); installer.InstallLibrary("uuidjs", "UUID");
_.installer.uninstallLibrary("uuidjs"); installer.uninstallLibrary("uuidjs");
_.installer.assertUnInstall("uuidjs"); installer.assertUnInstall("uuidjs");
}); });
it("2. Installs the library against a unique namespace when there is a collision with the existing entity", () => { it("2. Installs the library against a unique namespace when there is a collision with the existing entity", () => {
AppSidebar.navigate(AppSidebarButton.Editor); AppSidebar.navigate(AppSidebarButton.Editor);
_.entityExplorer.DragDropWidgetNVerify(_.draggableWidgets.TABLE, 200, 200); entityExplorer.DragDropWidgetNVerify(draggableWidgets.TABLE, 200, 200);
PageLeftPane.switchSegment(PagePaneSegment.Explorer); PageLeftPane.switchSegment(PagePaneSegment.Explorer);
_.entityExplorer.RenameEntityFromExplorer("Table1", "jsonwebtoken"); entityExplorer.RenameEntityFromExplorer("Table1", "jsonwebtoken");
AppSidebar.navigate(AppSidebarButton.Libraries); AppSidebar.navigate(AppSidebarButton.Libraries);
_.installer.OpenInstaller(); installer.OpenInstaller();
_.installer.InstallLibrary("jsonwebtoken", "jsonwebtoken_1", true); installer.InstallLibrary("jsonwebtoken", "jsonwebtoken_1", true);
}); });
it("3. Checks jspdf library", () => { it("3. Checks jspdf library", () => {
AppSidebar.navigate(AppSidebarButton.Libraries); AppSidebar.navigate(AppSidebarButton.Libraries);
_.installer.OpenInstaller(); installer.OpenInstaller();
_.installer.InstallLibrary("jspdf", "jspdf"); installer.InstallLibrary("jspdf", "jspdf");
_.jsEditor.CreateJSObject( jsEditor.CreateJSObject(
`export default { `export default {
myFun1: () => { myFun1: () => {
const doc = new jspdf.jsPDF(); const doc = new jspdf.jsPDF();
@ -47,26 +56,26 @@ describe("excludeForAirgap", "Tests JS Libraries", () => {
prettify: true, prettify: true,
}, },
); );
_.jsEditor.RunJSObj(); jsEditor.RunJSObj();
_.debuggerHelper.ClickResponseTab(); debuggerHelper.ClickResponseTab();
_.agHelper.AssertContains("data:application/pdf;filename=generated.pdf"); agHelper.AssertContains("data:application/pdf;filename=generated.pdf");
}); });
it("4. ESM build should pass installation, uninstallation and reinstallation", () => { it("4. ESM build should pass installation, uninstallation and reinstallation", () => {
AppSidebar.navigate(AppSidebarButton.Libraries); AppSidebar.navigate(AppSidebarButton.Libraries);
_.installer.OpenInstaller(); installer.OpenInstaller();
_.installer.InstallLibraryViaURL( installer.InstallLibraryViaURL(
"https://cdn.jsdelivr.net/npm/fast-xml-parser@4.2.7/+esm", "https://cdn.jsdelivr.net/npm/fast-xml-parser@4.2.7/+esm",
"fast_xml_parser", "fast_xml_parser",
); );
_.agHelper.Sleep(2000); agHelper.Sleep(2000);
// Uninstallation should succeed // Uninstallation should succeed
_.installer.uninstallLibrary("fast_xml_parser"); installer.uninstallLibrary("fast_xml_parser");
_.installer.assertUnInstall("fast_xml_parser"); installer.assertUnInstall("fast_xml_parser");
// Reinstallation should succeed with the same accessor // Reinstallation should succeed with the same accessor
_.installer.OpenInstaller(); installer.OpenInstaller();
_.installer.InstallLibraryViaURL( installer.InstallLibraryViaURL(
"https://cdn.jsdelivr.net/npm/fast-xml-parser@4.2.7/+esm", "https://cdn.jsdelivr.net/npm/fast-xml-parser@4.2.7/+esm",
"fast_xml_parser", "fast_xml_parser",
); );
@ -75,30 +84,30 @@ describe("excludeForAirgap", "Tests JS Libraries", () => {
it("5. Shows list of recommended libraries", () => { it("5. Shows list of recommended libraries", () => {
const recommendedLibraryNames = ["jsonwebtoken", "jspdf", "bcryptjs"]; const recommendedLibraryNames = ["jsonwebtoken", "jspdf", "bcryptjs"];
AppSidebar.navigate(AppSidebarButton.Libraries); AppSidebar.navigate(AppSidebarButton.Libraries);
_.installer.OpenInstaller(); installer.OpenInstaller();
for (const recommendedLib of recommendedLibraryNames) { for (const [index, recommendedLib] of recommendedLibraryNames.entries()) {
cy.contains(recommendedLib); cy.contains(recommendedLib);
} }
}); });
it("6. Checks installation in exported/forked app", () => { it("6. Checks installation in exported/forked app", () => {
_.homePage.NavigateToHome(); homePage.NavigateToHome();
_.homePage.ImportApp("library_export.json"); homePage.ImportApp("library_export.json");
_.homePage.AssertImportToast(); homePage.AssertImportToast();
_.agHelper.ValidateToastMessage("true"); agHelper.ValidateToastMessage("true");
_.agHelper.WaitUntilAllToastsDisappear(); agHelper.WaitUntilAllToastsDisappear();
//Checks installation in forked app //Checks installation in forked app
_.homePage.NavigateToHome(); homePage.NavigateToHome();
_.homePage.ForkApplication("Library_export"); homePage.ForkApplication("Library_export");
_.agHelper.ValidateToastMessage("true"); agHelper.ValidateToastMessage("true");
_.agHelper.WaitUntilAllToastsDisappear(); agHelper.WaitUntilAllToastsDisappear();
//Deploy app and check installation //Deploy app and check installation
_.deployMode.DeployApp(); deployMode.DeployApp();
_.agHelper.WaitUntilToastDisappear("true"); agHelper.WaitUntilToastDisappear("true");
_.deployMode.NavigateBacktoEditor(); deployMode.NavigateBacktoEditor();
_.agHelper.ValidateToastMessage("true"); agHelper.ValidateToastMessage("true");
}); });
it("7. Tests library access and installation in public apps", () => { it("7. Tests library access and installation in public apps", () => {
@ -106,12 +115,12 @@ describe("excludeForAirgap", "Tests JS Libraries", () => {
cy.get(HomePage.shareApp).click(); cy.get(HomePage.shareApp).click();
//@ts-expect-error no type access //@ts-expect-error no type access
cy.enablePublicAccess(true); cy.enablePublicAccess(true);
_.deployMode.DeployApp(); deployMode.DeployApp();
cy.url().then((url) => { cy.url().then((url) => {
appURL = url; appURL = url;
_.homePage.LogOutviaAPI(); homePage.LogOutviaAPI();
cy.visit(appURL); cy.visit(appURL);
_.agHelper.AssertContains("true"); agHelper.AssertContains("true");
}); });
}); });
}); });

View File

@ -9,7 +9,7 @@ describe("List Widget parse error test", () => {
// no toast message should be visible // no toast message should be visible
agHelper agHelper
.GetElement(CommonLocators._toastMsg) .GetElement(CommonLocators._toastMsg, "noVerify")
.should("not.have.length.above", 0); .should("not.have.length.above", 0);
}); });
}); });

View File

@ -13,7 +13,7 @@ import EditorNavigation, {
EntityType, EntityType,
} from "../../../../../support/Pages/EditorNavigation"; } from "../../../../../support/Pages/EditorNavigation";
describe.skip("Modal Widget test cases", function () { describe("Modal Widget test cases", function () {
const image = (src: string) => 'img[src="' + src + '"]'; const image = (src: string) => 'img[src="' + src + '"]';
const jpgImg = "https://jpeg.org/images/jpegsystems-home.jpg"; const jpgImg = "https://jpeg.org/images/jpegsystems-home.jpg";
const gifImg = const gifImg =
@ -24,9 +24,10 @@ describe.skip("Modal Widget test cases", function () {
entityExplorer.DragDropWidgetNVerify(draggableWidgets.MODAL, 300, 300); entityExplorer.DragDropWidgetNVerify(draggableWidgets.MODAL, 300, 300);
EditorNavigation.SelectEntityByName("Button1", EntityType.Widget); EditorNavigation.SelectEntityByName("Button1", EntityType.Widget);
propPane.EnterJSContext("onClick", "{{showModal('Modal1');}}"); propPane.EnterJSContext("onClick", "{{showModal('Modal1');}}");
agHelper.Sleep();
deployMode.DeployApp(locators._widgetInDeployed(draggableWidgets.BUTTON)); deployMode.DeployApp(locators._widgetInDeployed(draggableWidgets.BUTTON));
agHelper.Sleep(2000); //Wait for widgets to settle agHelper.WaitUntilEleAppear(
locators._widgetInDeployed(draggableWidgets.BUTTON),
); //Wait for widgets to settle
//Verify that the Modal widget opens correctly when configured on a button click. //Verify that the Modal widget opens correctly when configured on a button click.
agHelper.ClickButton("Submit"); agHelper.ClickButton("Submit");
@ -38,6 +39,7 @@ describe.skip("Modal Widget test cases", function () {
locators._widgetInDeployed(draggableWidgets.ICONBUTTON), locators._widgetInDeployed(draggableWidgets.ICONBUTTON),
); );
agHelper.GetNClick(locators._widgetInDeployed(draggableWidgets.ICONBUTTON)); agHelper.GetNClick(locators._widgetInDeployed(draggableWidgets.ICONBUTTON));
agHelper.WaitUntilEleDisappear(locators._modal);
agHelper.AssertElementAbsence(locators._modal); agHelper.AssertElementAbsence(locators._modal);
//Verify that clicking outside the Modal widget closes it as expected when Quick dismiss is enabled //Verify that clicking outside the Modal widget closes it as expected when Quick dismiss is enabled
@ -45,7 +47,7 @@ describe.skip("Modal Widget test cases", function () {
agHelper.WaitUntilEleAppear(locators._modal); agHelper.WaitUntilEleAppear(locators._modal);
agHelper.AssertElementExist(locators._modal); agHelper.AssertElementExist(locators._modal);
agHelper.ClickOutside(350, 150, false); agHelper.ClickOutside(350, 150, false);
agHelper.Sleep(); agHelper.WaitUntilEleDisappear(locators._modal);
agHelper.AssertElementAbsence(locators._modal); agHelper.AssertElementAbsence(locators._modal);
}); });
@ -54,11 +56,11 @@ describe.skip("Modal Widget test cases", function () {
EditorNavigation.SelectEntityByName("Button1", EntityType.Widget); EditorNavigation.SelectEntityByName("Button1", EntityType.Widget);
propPane.ToggleJSMode("onClick", false); propPane.ToggleJSMode("onClick", false);
propPane.CreateModal("onClick"); propPane.CreateModal("onClick");
agHelper.Sleep(500);
propPane.CreateModal("onClick"); propPane.CreateModal("onClick");
agHelper.Sleep(500);
deployMode.DeployApp(locators._widgetInDeployed(draggableWidgets.BUTTON)); deployMode.DeployApp(locators._widgetInDeployed(draggableWidgets.BUTTON));
agHelper.Sleep(2000); //Wait for widgets to settle & be visible agHelper.WaitUntilEleAppear(
locators._widgetInDeployed(draggableWidgets.BUTTON),
); //Wait for widgets to settle
agHelper.ClickButton("Submit"); agHelper.ClickButton("Submit");
agHelper.AssertElementLength(locators._modal, 3); agHelper.AssertElementLength(locators._modal, 3);
agHelper.AssertElementVisibility(locators._modal, true, 2); agHelper.AssertElementVisibility(locators._modal, true, 2);
@ -264,7 +266,6 @@ describe.skip("Modal Widget test cases", function () {
1, 1,
); );
assertHelper.WaitForNetworkCall("@postExecute").then((response: any) => { assertHelper.WaitForNetworkCall("@postExecute").then((response: any) => {
agHelper.Sleep();
const name = response.body.data.body[0].name; const name = response.body.data.body[0].name;
agHelper.ValidateToastMessage("Executed api!"); agHelper.ValidateToastMessage("Executed api!");

View File

@ -48,7 +48,9 @@ describe("Select Widget", () => {
.GetElement(".multi-select-dropdown input.bp3-input") .GetElement(".multi-select-dropdown input.bp3-input")
.should("have.css", "direction", "rtl"); .should("have.css", "direction", "rtl");
agHelper.GetElement(".rc-select-dropdown [dir='rtl']").should("exist"); agHelper
.GetElement(".rc-select-dropdown [dir='rtl']", "exist")
.should("exist");
propPane.TogglePropertyState("Enable RTL", "Off"); propPane.TogglePropertyState("Enable RTL", "Off");
@ -66,6 +68,8 @@ describe("Select Widget", () => {
.GetElement(".multi-select-dropdown input.bp3-input") .GetElement(".multi-select-dropdown input.bp3-input")
.should("have.css", "direction", "ltr"); .should("have.css", "direction", "ltr");
agHelper.GetElement(".rc-select-dropdown [dir='rtl']").should("not.exist"); agHelper
.GetElement(".rc-select-dropdown [dir='rtl']", "not.exist")
.should("not.exist");
}); });
}); });

View File

@ -61,7 +61,7 @@ describe("Radio Widget test cases", function () {
deployMode.DeployApp( deployMode.DeployApp(
locators._widgetInDeployed(draggableWidgets.RADIO_GROUP), locators._widgetInDeployed(draggableWidgets.RADIO_GROUP),
); );
agHelper.GetElement("@postExecute").then((interception: any) => { cy.get("@postExecute").then((interception: any) => {
agHelper.Sleep(); agHelper.Sleep();
const name = interception.response.body.data.body[0].name; const name = interception.response.body.data.body[0].name;
agHelper.AssertExistingCheckedState( agHelper.AssertExistingCheckedState(
@ -319,7 +319,7 @@ describe("Radio Widget test cases", function () {
}); });
agHelper.GetWidth(locators._widgetInDeployed(draggableWidgets.RADIO_GROUP)); agHelper.GetWidth(locators._widgetInDeployed(draggableWidgets.RADIO_GROUP));
agHelper.GetElement("@eleWidth").then(($currentWidth) => { cy.get("@eleWidth").then(($currentWidth) => {
expect($currentWidth).to.be.greaterThan(420); expect($currentWidth).to.be.greaterThan(420);
}); });
}); });
@ -368,7 +368,7 @@ describe("Radio Widget test cases", function () {
}); });
agHelper.GetWidth(locators._widgetInDeployed(draggableWidgets.RADIO_GROUP)); agHelper.GetWidth(locators._widgetInDeployed(draggableWidgets.RADIO_GROUP));
agHelper.GetElement("@eleWidth").then(($currentWidth) => { cy.get("@eleWidth").then(($currentWidth) => {
expect($currentWidth).to.be.greaterThan(420); expect($currentWidth).to.be.greaterThan(420);
}); });
}); });
@ -401,7 +401,7 @@ describe("Radio Widget test cases", function () {
locators._widgetInDeployed(draggableWidgets.RADIO_GROUP), locators._widgetInDeployed(draggableWidgets.RADIO_GROUP),
); );
agHelper.GetElement("@postExecute").then((interception: any) => { cy.get("@postExecute").then((interception: any) => {
agHelper.Sleep(); agHelper.Sleep();
const name = interception.response.body.data.body[0].name; const name = interception.response.body.data.body[0].name;
agHelper.AssertExistingCheckedState( agHelper.AssertExistingCheckedState(

View File

@ -394,7 +394,7 @@ describe("Validate CRUD queries for Amazon S3 along with UI flow verifications",
it("6. Create new 'text' file in bucket for UI Operations & Verify Search, Delete operations from NewPage CRUD UI created in S3 ds & Bug 8686, 8684", function () { it("6. Create new 'text' file in bucket for UI Operations & Verify Search, Delete operations from NewPage CRUD UI created in S3 ds & Bug 8686, 8684", function () {
//Creating new file in bucket //Creating new file in bucket
dataSources.CreateQueryAfterDSSaved(datasourceName); dataSources.CreateQueryForDS(datasourceName);
dataSources.ValidateNSelectDropdown( dataSources.ValidateNSelectDropdown(
"Commands", "Commands",
"List files in bucket", "List files in bucket",

View File

@ -25,7 +25,6 @@ import { Onboarding } from "../Pages/Onboarding";
import { AutoLayout } from "../Pages/AutoLayout"; import { AutoLayout } from "../Pages/AutoLayout";
import { DataManager } from "./DataManager"; import { DataManager } from "./DataManager";
import { AssertHelper } from "../Pages/AssertHelper"; import { AssertHelper } from "../Pages/AssertHelper";
import { ReusableHelper } from "./ReusableHelper";
import { Tabs } from "../Pages/Tabs"; import { Tabs } from "../Pages/Tabs";
import { GsheetHelper } from "../Pages/GSheetHelper"; import { GsheetHelper } from "../Pages/GSheetHelper";
import { CommunityTemplates } from "../Pages/CommunityTemplates"; import { CommunityTemplates } from "../Pages/CommunityTemplates";
@ -47,14 +46,6 @@ export class ObjectsRegistry {
return ObjectsRegistry.assertHelper__; return ObjectsRegistry.assertHelper__;
} }
private static reusableHelper__: ReusableHelper;
static get ReusableHelper(): ReusableHelper {
if (ObjectsRegistry.reusableHelper__ === undefined) {
ObjectsRegistry.reusableHelper__ = new ReusableHelper();
}
return ObjectsRegistry.reusableHelper__;
}
private static jsEditor__: JSEditor; private static jsEditor__: JSEditor;
static get JSEditor(): JSEditor { static get JSEditor(): JSEditor {
if (ObjectsRegistry.jsEditor__ === undefined) { if (ObjectsRegistry.jsEditor__ === undefined) {

View File

@ -1 +0,0 @@
export class ReusableHelper {}

View File

@ -2,7 +2,6 @@ import "cypress-wait-until";
import { v4 as uuidv4 } from "uuid"; import { v4 as uuidv4 } from "uuid";
import { ObjectsRegistry } from "../Objects/Registry"; import { ObjectsRegistry } from "../Objects/Registry";
import type CodeMirror from "codemirror"; import type CodeMirror from "codemirror";
import { ReusableHelper } from "../Objects/ReusableHelper";
import type { EntityItemsType } from "./AssertHelper"; import type { EntityItemsType } from "./AssertHelper";
import { EntityItems } from "./AssertHelper"; import { EntityItems } from "./AssertHelper";
@ -35,7 +34,7 @@ const DEFAULT_ENTERVALUE_OPTIONS = {
inputFieldName: "", inputFieldName: "",
}; };
export class AggregateHelper extends ReusableHelper { export class AggregateHelper {
private locator = ObjectsRegistry.CommonLocators; private locator = ObjectsRegistry.CommonLocators;
private assertHelper = ObjectsRegistry.AssertHelper; private assertHelper = ObjectsRegistry.AssertHelper;
@ -214,7 +213,10 @@ export class AggregateHelper extends ReusableHelper {
public CheckForPageSaveError() { public CheckForPageSaveError() {
// Wait for "saving" status to disappear // Wait for "saving" status to disappear
this.GetElement(this.locator._statusSaving, 30000).should("not.exist"); this.AssertElementAbsence(
this.locator._statusSaving,
Cypress.config("defaultCommandTimeout"),
);
// Check for page save error // Check for page save error
cy.get("body").then(($ele) => { cy.get("body").then(($ele) => {
if ($ele.find(this.locator._saveStatusError).length) { if ($ele.find(this.locator._saveStatusError).length) {
@ -271,7 +273,8 @@ export class AggregateHelper extends ReusableHelper {
public GetElement( public GetElement(
selector: ElementType, selector: ElementType,
timeout = Cypress.config().defaultCommandTimeout, exists: "exist" | "not.exist" | "noVerify" = "exist",
timeout = Cypress.config("defaultCommandTimeout"),
) { ) {
let locator; let locator;
if (typeof selector == "string") { if (typeof selector == "string") {
@ -285,7 +288,11 @@ export class AggregateHelper extends ReusableHelper {
timeout, timeout,
}); });
} else locator = cy.wrap(selector); } else locator = cy.wrap(selector);
return locator; return exists === "noVerify"
? locator // Return the locator without verification if exists is "noVerify"
: exists === "exist"
? locator.should("have.length.at.least", 1)
: locator.should("have.length", 0);
} }
public GetNAssertElementText( public GetNAssertElementText(
@ -320,7 +327,7 @@ export class AggregateHelper extends ReusableHelper {
public ValidateToastMessage(text: string, index = 0, length = 1) { public ValidateToastMessage(text: string, index = 0, length = 1) {
if (index != 0) { if (index != 0) {
this.GetElement(this.locator._toastMsg) this.GetElement(this.locator._toastMsg, "noVerify")
.should("have.length.at.least", length) .should("have.length.at.least", length)
.eq(index) .eq(index)
.should("contain.text", text); .should("contain.text", text);
@ -466,12 +473,9 @@ export class AggregateHelper extends ReusableHelper {
} }
public WaitUntilEleDisappear(selector: string) { public WaitUntilEleDisappear(selector: string) {
const locator = selector.includes("//") cy.waitUntil(() => this.GetElement(selector, "not.exist"), {
? cy.xpath(selector)
: cy.get(selector);
locator.waitUntil(($ele) => cy.wrap($ele).should("have.length", 0), {
errorMsg: "Element did not disappear even after 10 seconds", errorMsg: "Element did not disappear even after 10 seconds",
timeout: 20000, timeout: Cypress.config().pageLoadTimeout,
interval: 1000, interval: 1000,
}); });
} }
@ -492,10 +496,7 @@ export class AggregateHelper extends ReusableHelper {
} }
public WaitUntilEleAppear(selector: string) { public WaitUntilEleAppear(selector: string) {
const locator = selector.includes("//") this.GetElement(selector).waitUntil(
? cy.xpath(selector)
: cy.get(selector);
locator.waitUntil(
($ele) => ($ele) =>
cy cy
.wrap($ele) .wrap($ele)
@ -505,8 +506,8 @@ export class AggregateHelper extends ReusableHelper {
.should("be.gte", 1), .should("be.gte", 1),
{ {
errorMsg: "Element did not appear even after 10 seconds", errorMsg: "Element did not appear even after 10 seconds",
timeout: 10000, timeout: Cypress.config().pageLoadTimeout,
interval: 1000, interval: 2000,
}, },
); );
@ -1249,6 +1250,7 @@ export class AggregateHelper extends ReusableHelper {
setTimeout(() => { setTimeout(() => {
input.setValue(value); input.setValue(value);
setTimeout(() => { setTimeout(() => {
input.execCommand("goLineStart");
// Move cursor to the end of the line // Move cursor to the end of the line
input.execCommand("goLineEnd"); input.execCommand("goLineEnd");
}, 1000); }, 1000);
@ -1455,7 +1457,7 @@ export class AggregateHelper extends ReusableHelper {
public AssertElementAbsence(selector: ElementType, timeout = 0) { public AssertElementAbsence(selector: ElementType, timeout = 0) {
//Should not exists - cannot take indexes //Should not exists - cannot take indexes
return this.GetElement(selector, timeout).should("not.exist"); return this.GetElement(selector, "not.exist", timeout).should("not.exist");
} }
public GetText( public GetText(
@ -1495,7 +1497,7 @@ export class AggregateHelper extends ReusableHelper {
index = 0, index = 0,
timeout = Cypress.config("defaultCommandTimeout"), timeout = Cypress.config("defaultCommandTimeout"),
) { ) {
return this.GetElement(selector, timeout) return this.GetElement(selector, "exist", timeout)
.eq(index) .eq(index)
.scrollIntoView() .scrollIntoView()
.should(visibility == true ? "be.visible" : "not.be.visible"); .should(visibility == true ? "be.visible" : "not.be.visible");
@ -1512,12 +1514,23 @@ export class AggregateHelper extends ReusableHelper {
}); });
} }
public AssertElementExist(selector: ElementType, index = 0, timeout = 20000) { public AssertElementExist(
return this.GetElement(selector, timeout).eq(index).should("exist"); selector: ElementType,
index = 0,
timeout = Cypress.config("defaultCommandTimeout"),
) {
return this.GetElement(selector, "exist", timeout)
.eq(index)
.should("exist");
} }
public ScrollIntoView(selector: ElementType, index = 0, timeout = 20000) { public ScrollIntoView(
return this.GetElement(selector, timeout) selector: ElementType,
index = 0,
timeout = Cypress.config("defaultCommandTimeout"),
) {
return this.GetElement(selector, "exist", timeout)
.should("have.length.at.least", 1)
.eq(index) .eq(index)
.then(($element) => { .then(($element) => {
if ( if (
@ -1538,8 +1551,14 @@ export class AggregateHelper extends ReusableHelper {
index: number | null = null, index: number | null = null,
) { ) {
if (index) if (index)
return this.GetElement(selector).eq(index).should("have.length", length); return this.GetElement(selector, "noVerify")
else return this.GetElement(selector).should("have.length", length); .eq(index)
.should("have.length", length);
else
return this.GetElement(selector, "noVerify").should(
"have.length",
length,
);
} }
public FocusElement(selector: ElementType) { public FocusElement(selector: ElementType) {
@ -1562,7 +1581,7 @@ export class AggregateHelper extends ReusableHelper {
text: string | number | RegExp, text: string | number | RegExp,
exists: "exist" | "not.exist" = "exist", exists: "exist" | "not.exist" = "exist",
) { ) {
return this.GetElement(selector).contains(text).should(exists); return this.GetElement(selector, "noVerify").contains(text).should(exists);
} }
public AssertURL(url: string) { public AssertURL(url: string) {

View File

@ -1,6 +1,4 @@
import "cypress-wait-until"; import "cypress-wait-until";
import { ObjectsRegistry } from "../Objects/Registry";
import { ReusableHelper } from "../Objects/ReusableHelper";
export const EntityItems = { export const EntityItems = {
Page: 0, Page: 0,
@ -13,7 +11,7 @@ export const EntityItems = {
export type EntityItemsType = (typeof EntityItems)[keyof typeof EntityItems]; export type EntityItemsType = (typeof EntityItems)[keyof typeof EntityItems];
export class AssertHelper extends ReusableHelper { export class AssertHelper {
public _modifierKey = Cypress.platform === "darwin" ? "meta" : "ctrl"; public _modifierKey = Cypress.platform === "darwin" ? "meta" : "ctrl";
public isMac = Cypress.platform === "darwin"; public isMac = Cypress.platform === "darwin";

View File

@ -141,7 +141,6 @@ export class HomePage {
let oldName = ""; let oldName = "";
this.agHelper.GetNClick(this._newWorkSpaceLink); this.agHelper.GetNClick(this._newWorkSpaceLink);
this.assertHelper.AssertNetworkStatus("createWorkspace", 201); this.assertHelper.AssertNetworkStatus("createWorkspace", 201);
this.agHelper.Sleep(2000);
cy.get("@createWorkspace").then((interception: any) => { cy.get("@createWorkspace").then((interception: any) => {
localStorage.setItem("workspaceId", interception.response.body.data.id); localStorage.setItem("workspaceId", interception.response.body.data.id);
localStorage.setItem( localStorage.setItem(

View File

@ -618,6 +618,7 @@ export class PropertyPane {
this.SelectPlatformFunction(property, "Show modal"); this.SelectPlatformFunction(property, "Show modal");
this.agHelper.GetNClick(this._actionOpenDropdownSelectModal); this.agHelper.GetNClick(this._actionOpenDropdownSelectModal);
this.agHelper.GetNClick(this._createModalButton); this.agHelper.GetNClick(this._createModalButton);
this.agHelper.WaitUntilEleAppear(this.locator._modal);
this.agHelper.AssertAutoSave(); this.agHelper.AssertAutoSave();
} }

View File

@ -242,10 +242,7 @@ export class Table {
tableVersion: "v1" | "v2" = "v1", tableVersion: "v1" | "v2" = "v1",
) { ) {
this.agHelper this.agHelper
.GetElement( .GetElement(this._tableRowColumnData(rowIndex, colIndex, tableVersion))
this._tableRowColumnData(rowIndex, colIndex, tableVersion),
30000,
)
.waitUntil(($ele) => .waitUntil(($ele) =>
cy.wrap($ele).children("span").should("not.be.empty"), cy.wrap($ele).children("span").should("not.be.empty"),
); );
@ -253,7 +250,7 @@ export class Table {
public WaitForTableEmpty(tableVersion: "v1" | "v2" = "v1") { public WaitForTableEmpty(tableVersion: "v1" | "v2" = "v1") {
this.agHelper this.agHelper
.GetElement(this._tableEmptyColumnData(tableVersion)) .GetElement(this._tableEmptyColumnData(tableVersion), "noVerify")
.children() .children()
.should("have.length", 0); //or below .should("have.length", 0); //or below
//expect($children).to.have.lengthOf(0) //expect($children).to.have.lengthOf(0)
@ -291,7 +288,7 @@ export class Table {
//timeout can be sent higher values incase of larger tables //timeout can be sent higher values incase of larger tables
this.agHelper.Sleep(timeout); //Settling time for table! this.agHelper.Sleep(timeout); //Settling time for table!
return this.agHelper return this.agHelper
.GetElement(this._tableRowColumnData(rowNum, colNum, tableVersion), 30000) .GetElement(this._tableRowColumnData(rowNum, colNum, tableVersion))
.invoke("text"); .invoke("text");
} }