test: Cypress | Text_With_Different_Size_spec.ts re-write + Flaky fixes (#30445)

## Description
- This PR re-writes the entire Text_With_Different_Size_spec.ts spec to
fix the master run flakyness and and improves the overall complexity of
the test case format
- cypress/e2e/Regression/ClientSide/Onboarding/StartFromScratch_spec.ts
(agHelper.VisitNAssert improved)
- Master runs pass at
[Run1](https://github.com/appsmithorg/appsmith-ee/pull/3337#issuecomment-1899183181),
[Run2](https://github.com/appsmithorg/appsmith-ee/pull/3337#issuecomment-1899197871)
- cypress/e2e/Regression/ClientSide/BugTests/AbortAction_Spec.ts (1st
test - replace with TED url)
- getConsolidatedDataApi() separated, created new
agHelper.CypressReload()
- Removed cy.log statements from few places
- homePage.LogOutviaAPI() removed static wait
- Replaced homePage.LogOutviaAPI(); with homePage.Signout(); in places
where its flaky
- Split /Onboarding/StartFromScratch_spec.ts to 3 specs to reduce
flakyness
- Split /ClientSide/PartialImportExport/PartialExport_Widgets_spec.ts
with failing test to run the other tests in CI
- /Templates/Fork_Template_To_App_spec.ts - Added dynamic check to fix
CI flakiness
- agHelper.AssertURL(), assertHelper.AssertDocumentReady() improved
- jsEditor.NavigateToNewJSEditor() improved
-
cypress/e2e/Regression/ClientSide/ExplorerTests/JSEditorContextMenu_Spec.ts
- jsEditor.ValidateDefaultJSObjProperties improved
- cypress/e2e/Regression/ServerSide/OnLoadTests/OnLoadActions_Spec.ts -
(3rd case - flaky fix)

#### 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 changes were reviewed

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


## Summary by CodeRabbit

- **Tests**
	- Enhanced test flexibility by dynamically constructing API URLs.
	- Improved test setup and flow in onboarding and regression suites.
- Added new test spec files for dynamic height, onboarding, bug tests,
login failure, and starting from scratch scenarios.
- **Refactor**
- Updated function calls and parameters across various test files for
consistency and efficiency.
	- Removed redundant code and streamlined test actions.
- **Chores**
- Updated intercepted HTTP methods and added new utility functions to
support test operations.
- **Bug Fixes**
- Fixed issues related to element visibility assertions in test scripts.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
Aishwarya-U-R 2024-02-08 16:55:58 +05:30 committed by GitHub
parent b7be2e3b6e
commit a6b8a3440e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
19 changed files with 243 additions and 375 deletions

View File

@ -2,6 +2,7 @@ import {
agHelper,
locators,
apiPage,
dataManager,
dataSources,
entityItems,
} from "../../../../support/Objects/ObjectsCore";
@ -10,13 +11,13 @@ import {
createMessage,
} from "../../../../support/Objects/CommonErrorMessages";
const largeResponseApiUrl = "https://api.github.com/emojis";
//"https://api.publicapis.org/entries";
//"https://jsonplaceholder.typicode.com/photos";//Commenting since this is faster sometimes & case is failing
describe("Abort Action Execution", { tags: ["@tag.Datasource"] }, function () {
it("1. Bug #14006, #16093 - Cancel request button should abort API action execution", function () {
apiPage.CreateAndFillApi(largeResponseApiUrl, "AbortApi", 0);
apiPage.CreateAndFillApi(
dataManager.dsValues[dataManager.defaultEnviorment].mockApiUrl + "00",
"AbortApi",
0,
);
apiPage.RunAPI(false, 0);
agHelper.GetNClick(locators._cancelActionExecution, 0, true);
agHelper.AssertContains(

View File

@ -10,254 +10,78 @@ import EditorNavigation, {
describe(
"Dynamic Height Width validation",
{ tags: ["@tag.AutoHeight"] },
function () {
function validateCssProperties(property) {
agHelper.GetNClickByContains("button", "Small", 0, true);
agHelper.Sleep(2000);
EditorNavigation.SelectEntityByName("Text1", EntityType.Widget);
agHelper.Sleep(2000);
agHelper
.GetWidgetCSSFrAttribute(
locators._widgetInDeployed(draggableWidgets.TEXT),
property,
0,
)
.then((CurrentValueOfFirstText) => {
EditorNavigation.SelectEntityByName("Text2", EntityType.Widget);
agHelper
.GetWidgetCSSFrAttribute(
locators._widgetInDeployed(draggableWidgets.TEXT),
property,
1,
)
.then((CurrentValueOfSecondText) => {
EditorNavigation.SelectEntityByName("Text3", EntityType.Widget);
agHelper.Sleep(2000);
agHelper
.GetWidgetCSSFrAttribute(
locators._widgetInDeployed(draggableWidgets.TEXT),
property,
2,
)
.then((CurrentValueOfThirdText) => {
EditorNavigation.SelectEntityByName(
"Text4",
EntityType.Widget,
);
agHelper.Sleep(2000);
agHelper
.GetWidgetCSSFrAttribute(
locators._widgetInDeployed(draggableWidgets.TEXT),
property,
3,
)
.then((CurrentValueOfFourthText) => {
agHelper.GetNClickByContains("button", "Large", 0, true);
agHelper.Sleep(3000);
EditorNavigation.SelectEntityByName(
"Text1",
EntityType.Widget,
);
agHelper
.GetWidgetCSSFrAttribute(
locators._widgetInDeployed(draggableWidgets.TEXT),
property,
0,
)
.then((UpdatedLargeValueOfFirstText) => {
EditorNavigation.SelectEntityByName(
"Text2",
EntityType.Widget,
);
agHelper
.GetWidgetCSSFrAttribute(
locators._widgetInDeployed(draggableWidgets.TEXT),
property,
1,
)
.then((UpdatedLargeValueOfSecondText) => {
EditorNavigation.SelectEntityByName(
"Text3",
EntityType.Widget,
);
agHelper
.GetWidgetCSSFrAttribute(
locators._widgetInDeployed(
draggableWidgets.TEXT,
),
property,
2,
)
.then((UpdatedLargeValueOfThirdText) => {
EditorNavigation.SelectEntityByName(
"Text4",
EntityType.Widget,
);
agHelper
.GetWidgetCSSFrAttribute(
locators._widgetInDeployed(
draggableWidgets.TEXT,
),
property,
3,
)
.then((UpdatedLargeValueOfFourthText) => {
if (property == "left") {
expect(
CurrentValueOfFirstText,
).to.equal(
UpdatedLargeValueOfFirstText,
);
expect(
CurrentValueOfSecondText,
).to.equal(
UpdatedLargeValueOfSecondText,
);
expect(
CurrentValueOfThirdText,
).to.equal(
UpdatedLargeValueOfThirdText,
);
expect(
CurrentValueOfFourthText,
).to.equal(
UpdatedLargeValueOfFourthText,
);
} else {
expect(
CurrentValueOfFirstText,
).to.not.equal(
UpdatedLargeValueOfFirstText,
);
expect(
CurrentValueOfSecondText,
).to.not.equal(
UpdatedLargeValueOfSecondText,
);
expect(
CurrentValueOfThirdText,
).to.not.equal(
UpdatedLargeValueOfThirdText,
);
expect(
CurrentValueOfFourthText,
).to.not.equal(
UpdatedLargeValueOfFourthText,
);
}
agHelper.GetNClickByContains(
"button",
"Small",
0,
true,
);
agHelper.Sleep(2000);
EditorNavigation.SelectEntityByName(
"Text1",
EntityType.Widget,
);
agHelper.Sleep(2000);
agHelper
.GetWidgetCSSFrAttribute(
locators._widgetInDeployed(
draggableWidgets.TEXT,
),
property,
0,
)
.then(
(UpdatedSmallValueOfFirstText) => {
EditorNavigation.SelectEntityByName(
"Text2",
EntityType.Widget,
);
agHelper
.GetWidgetCSSFrAttribute(
locators._widgetInDeployed(
draggableWidgets.TEXT,
),
property,
1,
)
.then(
(
UpdatedSmallValueOfSecondText,
) => {
EditorNavigation.SelectEntityByName(
"Text3",
EntityType.Widget,
);
agHelper.Sleep(2000);
agHelper
.GetWidgetCSSFrAttribute(
locators._widgetInDeployed(
draggableWidgets.TEXT,
),
property,
2,
)
.then(
(
UpdatedSmallValueOfThirdText,
) => {
EditorNavigation.SelectEntityByName(
"Text4",
EntityType.Widget,
);
agHelper.Sleep(2000);
agHelper
.GetWidgetCSSFrAttribute(
locators._widgetInDeployed(
draggableWidgets.TEXT,
),
property,
3,
)
.then(
(
UpdatedSmallValueOfFourthText,
) => {
expect(
CurrentValueOfFirstText,
).to.equal(
UpdatedSmallValueOfFirstText,
);
expect(
CurrentValueOfSecondText,
).to.equal(
UpdatedSmallValueOfSecondText,
);
expect(
CurrentValueOfThirdText,
).to.equal(
UpdatedSmallValueOfThirdText,
);
expect(
CurrentValueOfFourthText,
).to.equal(
UpdatedSmallValueOfFourthText,
);
},
);
},
);
},
);
},
);
});
});
});
});
});
});
});
});
}
() => {
it("1. Validate change with auto height width for text widgets", function () {
agHelper.AddDsl("alignmentWithDynamicHeightDsl");
validateCssProperties("height");
validateCssProperties("left");
VerifyAttributeValues("height");
VerifyAttributeValues("left");
});
function VerifyAttributeValues(attribName: string) {
const widgetNames = ["Text1", "Text2", "Text3", "Text4"];
let smallValues: any[] = [];
let largeValues: any[] = [];
let smallAfterLargeValues: any[] = [];
agHelper.ClickButton("Small");
for (let i = 0; i < widgetNames.length; i++) {
GetWidgetCSSAttribute(widgetNames[i], i, attribName);
AssignPropertyValues((value) => {
smallValues[i] = value;
});
}
agHelper.ClickButton("Large");
for (let i = 0; i < widgetNames.length; i++) {
GetWidgetCSSAttribute(widgetNames[i], i, attribName);
AssignPropertyValues((value) => {
largeValues[i] = value;
});
}
cy.then(() => {
if (attribName == "left") {
for (let i = 0; i < widgetNames.length; i++) {
expect(smallValues[i]).to.equal(largeValues[i]);
}
} else if (attribName == "height") {
for (let i = 0; i < widgetNames.length; i++) {
expect(smallValues[i]).to.not.equal(largeValues[i]);
}
}
});
agHelper.ClickButton("Small");
for (let i = 0; i < widgetNames.length; i++) {
GetWidgetCSSAttribute(widgetNames[i], i, attribName);
AssignPropertyValues((value) => {
smallAfterLargeValues[i] = value;
});
}
cy.then(() => {
for (let i = 0; i < widgetNames.length; i++) {
expect(smallValues[i]).to.equal(smallAfterLargeValues[i]);
}
});
}
function GetWidgetCSSAttribute(
widgetName: string,
index: any,
attribName: string,
) {
EditorNavigation.SelectEntityByName(widgetName, EntityType.Widget);
agHelper.GetWidgetCSSValue(
locators._widgetInDeployed(draggableWidgets.TEXT),
attribName,
index,
);
}
function AssignPropertyValues(callback: (value: any) => void) {
cy.get("@cssAttributeValue").then(($currentValue: any) => {
callback($currentValue);
});
}
},
);

View File

@ -24,8 +24,7 @@ describe(
});
it("1. Verify Repo limit flow for CE/EE instances", function () {
agHelper.Sleep(2000); // adding wait for app to load
homePage.LogOutviaAPI();
homePage.Signout();
cy.generateUUID().then((uid) => {
homePage.SignUp(`${uid}@appsmithtest.com`, uid);
onboarding.closeIntroModal();

View File

@ -12,11 +12,14 @@ describe(
{ tags: ["@tag.excludeForAirgap", "@tag.Datasource"] },
function () {
beforeEach(() => {
homePage.LogOutviaAPI();
featureFlagIntercept({
ab_show_templates_instead_of_blank_canvas_enabled: true,
ab_create_new_apps_enabled: true,
});
homePage.Signout();
featureFlagIntercept(
{
ab_show_templates_instead_of_blank_canvas_enabled: true,
ab_create_new_apps_enabled: true,
},
false,
);
agHelper.GenerateUUID();
cy.get("@guid").then((uid) => {
homePage.SignUp(`${uid}@appsmithtest.com`, uid as unknown as string);

View File

@ -3,11 +3,10 @@ import { featureFlagIntercept } from "../../../../support/Objects/FeatureFlags";
import {
agHelper,
onboarding,
templates,
dataSources,
templates,
homePage,
} from "../../../../support/Objects/ObjectsCore";
import FirstTimeUserOnboardingLocators from "../../../../locators/FirstTimeUserOnboarding.json";
import {
AppSidebar,
AppSidebarButton,
@ -18,20 +17,20 @@ describe(
{ tags: ["@tag.excludeForAirgap", "@tag.Templates"] },
function () {
beforeEach(() => {
homePage.LogOutviaAPI();
featureFlagIntercept({
ab_show_templates_instead_of_blank_canvas_enabled: true,
ab_create_new_apps_enabled: true,
});
homePage.Signout(true);
featureFlagIntercept(
{
ab_show_templates_instead_of_blank_canvas_enabled: true,
ab_create_new_apps_enabled: true,
},
false,
);
agHelper.GenerateUUID();
cy.get("@guid").then((uid) => {
homePage.SignUp(`${uid}@appsmithtest.com`, uid as unknown as string);
onboarding.closeIntroModal();
});
agHelper.GetNClick(onboarding.locators.startFromScratchCard);
agHelper.GetNClick(FirstTimeUserOnboardingLocators.introModalCloseBtn);
onboarding.closeIntroModal();
featureFlagIntercept({
ab_show_templates_instead_of_blank_canvas_enabled: true,
});
@ -56,6 +55,7 @@ describe(
.first()
.prev()
.should("have.text", "Building Blocks");
agHelper.GetNClick(template.closeButton);
});
it("2. `Connect your data` pop up should come up when we fork a building block from canvas.", function () {

View File

@ -0,0 +1,31 @@
import { featureFlagIntercept } from "../../../../support/Objects/FeatureFlags";
import {
homePage,
partialImportExport,
} from "../../../../support/Objects/ObjectsCore";
const fixtureName = "PartialImportExportSampleApp.json";
describe(
"Partial export functionality",
{ tags: ["@tag.ImportExport"] },
() => {
before(() => {
homePage.ImportApp(`PartialImportExport/${fixtureName}`);
featureFlagIntercept({
release_show_partial_import_export_enabled: true,
});
partialImportExport.OpenExportModal();
});
it("1. Should export all the widgets", () => {
partialImportExport.ExportAndCompareDownloadedFile(
"widgets",
4,
partialImportExport.locators.export.modelContents.widgetsSection,
"WidgetsExportedOnly.json",
fixtureName,
);
});
},
);

View File

@ -63,15 +63,5 @@ describe(
fixtureName,
);
});
it("5. Should export all the widgets", () => {
partialImportExport.ExportAndCompareDownloadedFile(
"widgets",
4,
partialImportExport.locators.export.modelContents.widgetsSection,
"WidgetsExportedOnly.json",
fixtureName,
);
});
},
);

View File

@ -4,6 +4,7 @@ import {
assertHelper,
deployMode,
homePage,
locators,
} from "../../../../support/Objects/ObjectsCore";
import PageList from "../../../../support/Pages/PageList";
@ -43,6 +44,10 @@ describe(
agHelper.GetNClick(template.selectCheckbox, 1);
// [Bug]: On forking selected pages from a template, resource not found error is shown #17270
agHelper.GetNClick(template.templateViewForkButton);
agHelper.AssertElementAbsence(
locators._visibleTextSpan("Setting up the template"),
Cypress.config().pageLoadTimeout,
);
assertHelper.AssertNetworkStatus("fetchTemplate");
agHelper.ValidateToastMessage("template added successfully");
assertHelper.AssertNetworkStatus("updateLayout");

View File

@ -8,8 +8,8 @@ describe(
{ tags: ["@tag.excludeForAirgap", "@tag.Templates"] },
() => {
beforeEach(() => {
_.homePage.LogOutviaAPI();
featureFlagIntercept({ ab_create_new_apps_enabled: true });
_.homePage.Signout();
featureFlagIntercept({ ab_create_new_apps_enabled: true }, false);
cy.generateUUID().then((uid) => {
_.homePage.SignUp(`${uid}@appsmithtest.com`, uid);
_.onboarding.closeIntroModal();

View File

@ -3,7 +3,6 @@ import {
deployMode,
homePage,
locators,
assertHelper,
} from "../../../../support/Objects/ObjectsCore";
describe("Login failure", function () {

View File

@ -192,13 +192,20 @@ describe(
"https://api.genderize.io?name={{RandomUser.data.results[0].name.first}}",
"Genderize",
30000,
"GET",
false,
false,
);
apiPage.ValidateQueryParams({
key: "name",
value: "{{RandomUser.data.results[0].name.first}}",
}); // verifies Bug 10055
deployMode.DeployApp(locators._widgetInDeployed("textwidget"), false);
deployMode.DeployApp(
locators._widgetInDeployed("textwidget"),
false,
false,
);
assertHelper.AssertNetworkStatus("@getConsolidatedData");
cy.get("@getConsolidatedData").then(($response: any) => {

View File

@ -1,9 +1,12 @@
import { LICENSE_FEATURE_FLAGS } from "../Constants";
import { ObjectsRegistry } from "./Registry";
import produce from "immer";
export const featureFlagIntercept = (
flags: Record<string, boolean> = {},
reload = true,
) => {
getConsolidatedDataApi(flags, false);
const response = {
responseMeta: {
status: 200,
@ -19,9 +22,20 @@ export const featureFlagIntercept = (
};
cy.intercept("GET", "/api/v1/users/features", response);
if (reload) ObjectsRegistry.AggregateHelper.CypressReload();
};
export const getConsolidatedDataApi = (
flags: Record<string, boolean> = {},
reload = true,
) => {
cy.intercept("GET", "/api/v1/consolidated-api/*?*", (req) => {
req.reply((res: any) => {
if (res.statusCode === 200) {
if (
res.statusCode === 200 ||
res.statusCode === 401 ||
res.statusCode === 500
) {
const originalResponse = res?.body;
const updatedResponse = produce(originalResponse, (draft: any) => {
draft.data.featureFlags.data = { ...flags };
@ -37,20 +51,7 @@ export const featureFlagIntercept = (
}
});
}).as("getConsolidatedData");
if (reload) {
cy.reload();
cy.waitUntil(() =>
cy.document().should((doc) => {
expect(doc.readyState).to.equal("complete");
}),
);
cy.waitUntil(() =>
cy
.window({ timeout: Cypress.config().pageLoadTimeout })
.then((win) => expect(win).haveOwnProperty("onload")),
);
}
if (reload) ObjectsRegistry.AggregateHelper.CypressReload();
};
export const featureFlagInterceptForLicenseFlags = () => {
@ -111,6 +112,5 @@ export const featureFlagInterceptForLicenseFlags = () => {
});
}).as("getConsolidatedData");
cy.reload();
cy.wait(2000); //for the page to re-load finish for CI runs
ObjectsRegistry.AggregateHelper.CypressReload();
};

View File

@ -130,7 +130,6 @@ export class AggregateHelper {
cy.fixture(dslFile).then((val) => {
cy.url().then((url) => {
pageid = url.split("/")[5]?.split("-").pop() as string;
cy.log(pageid + "page id");
//Fetch the layout id
cy.request("GET", "api/v1/pages/" + pageid).then((response: any) => {
const respBody = JSON.stringify(response.body);
@ -152,7 +151,6 @@ export class AggregateHelper {
"X-Requested-By": "Appsmith",
},
}).then((dslDumpResp) => {
//cy.log("Pages resposne is : " + dslDumpResp.body);
expect(dslDumpResp.status).equal(200);
//this.Sleep(3000); //for dsl to settle in layouts api & then refresh
this.RefreshPage();
@ -279,7 +277,6 @@ export class AggregateHelper {
) {
let locator;
if (typeof selector == "string") {
//cy.log(selector, "selector");
locator =
selector.startsWith("//") || selector.startsWith("(//")
? cy.xpath(selector, {
@ -314,7 +311,6 @@ export class AggregateHelper {
public GetElementsNAssertTextPresence(selector: string, text: string) {
this.GetElement(selector).then(($elements: any) => {
let found = false;
cy.log("elements length is" + $elements.length);
$elements.each((index: any, element: any) => {
const eleText = Cypress.$(element).text().trim();
if (eleText === text) {
@ -349,7 +345,6 @@ export class AggregateHelper {
if ($body.find(this.locator._evalPopup).length > 0) {
this.GetElement(this.locator._evalPopup).then(($evalPopUp) => {
$evalPopUp.remove();
cy.log("Eval pop up removed");
});
}
break;
@ -362,7 +357,6 @@ export class AggregateHelper {
.parents("div.rc-tooltip")
.then(($tooltipElement) => {
$tooltipElement.remove();
cy.log(toolTipOrToasttext + " tooltip removed");
});
}
break;
@ -382,7 +376,6 @@ export class AggregateHelper {
"'))",
).then(($toastContainer) => {
$toastContainer.remove();
cy.log(toolTipOrToasttext + " toast removed");
});
}
break;
@ -590,7 +583,6 @@ export class AggregateHelper {
endpoint = "dropdownwidget",
) {
const mode = window.localStorage.getItem("inDeployedMode");
//cy.log("mode frm deployed is:" + mode)
const modeSelector =
mode == "true"
? this.locator._selectWidgetDropdownInDeployed(endpoint)
@ -598,7 +590,6 @@ export class AggregateHelper {
const finalSelector = insideParent
? this.locator._divWithClass(insideParent) + modeSelector
: modeSelector;
cy.log(finalSelector);
this.GetNClick(finalSelector, index);
cy.get(this.locator._dropDownValue(dropdownOption)).click({ force: true });
@ -724,7 +715,6 @@ export class AggregateHelper {
// .type("{ctrl}{shift}{downarrow}{del}", { force: true });
cy.focused().then(($cm: any) => {
if ($cm.contents != "") {
cy.log("The field is not empty");
this.ScrollIntoView(this.locator._actionTextArea(actionName), index)
.click({ force: true })
.focused()
@ -778,7 +768,9 @@ export class AggregateHelper {
ctrlKey: ctrlKey,
metaKey,
})
.wait(waitTimeInterval);
.then(($element) => {
return cy.wrap($element).wait(waitTimeInterval);
});
}
public GetClosestNClick(
@ -1003,7 +995,6 @@ export class AggregateHelper {
this.GetElement(selector)
.invoke("attr", "data-selected-value")
.then((dataSelectedValue) => {
cy.log("dataSelectedValue:" + dataSelectedValue);
if (dataSelectedValue !== undefined) {
this.GetElement(selector).should(
"have.attr",
@ -1130,6 +1121,11 @@ export class AggregateHelper {
this.assertHelper.AssertNetworkStatus("@" + networkCallAlias); //getWorkspace for Edit page!
}
public CypressReload() {
cy.reload();
this.assertHelper.AssertDocumentReady();
}
public ActionContextMenuWithInPane({
action = "Delete",
entityType = EntityItems.JSObject,
@ -1201,6 +1197,7 @@ export class AggregateHelper {
public EnterValue(
valueToEnter: string,
options: IEnterValue = DEFAULT_ENTERVALUE_OPTIONS,
toVerifySave = true,
) {
const { apiOrQuery, directInput, inputFieldName, propFieldName } = options;
if (propFieldName && directInput && !inputFieldName) {
@ -1211,7 +1208,7 @@ export class AggregateHelper {
valueToEnter,
);
}
this.AssertAutoSave();
toVerifySave && this.AssertAutoSave();
}
public VerifyCodeInputValue(propFieldName: string, value: string) {
@ -1615,9 +1612,10 @@ export class AggregateHelper {
}
public AssertURL(url: string) {
cy.url({ timeout: Cypress.config().pageLoadTimeout }).should(
"include",
url,
this.WaitForCondition(() =>
cy.url().then((currentUrl) => {
return currentUrl.includes(url);
}),
);
this.assertHelper.AssertDocumentReady();
}
@ -1670,6 +1668,18 @@ export class AggregateHelper {
return this.GetElement(widgetSelector).eq(index).invoke("css", attribute);
}
public GetWidgetCSSValue(
widgetSelector: string,
attribute: string,
index = 0,
) {
return this.GetElement(widgetSelector)
.eq(index)
.then(($element) => {
cy.wrap($element.css(attribute)).as("cssAttributeValue");
});
}
GetWidgetByName(widgetName: string) {
return this.GetElement(this.locator._widgetByName(widgetName));
}
@ -1726,10 +1736,8 @@ export class AggregateHelper {
}
public VisitNAssert(url: string, apiToValidate = "") {
cy.visit(url, { timeout: 60000 });
// cy.window({ timeout: 60000 }).then((win) => {
// win.location.href = url;
// });
cy.visit(url);
this.AssertURL(url);
if (
apiToValidate.includes("getAllWorkspaces") &&
Cypress.env("AIRGAPPED")

View File

@ -129,29 +129,32 @@ export class ApiPage {
queryTimeout = 10000,
apiVerb: "GET" | "POST" | "PUT" | "DELETE" | "PATCH" = "GET",
aftDSSaved = false,
toVerifySave = true,
) {
this.CreateApi(apiName, apiVerb, aftDSSaved);
this.EnterURL(url);
this.EnterURL(url, "", toVerifySave);
this.agHelper.Sleep(); //Is needed for the entered url value to be registered, else failing locally & CI
this.AssertRunButtonDisability();
if (queryTimeout != 10000) this.SetAPITimeout(queryTimeout);
if (queryTimeout != 10000) this.SetAPITimeout(queryTimeout, toVerifySave);
}
AssertRunButtonDisability(disabled = false) {
this.agHelper.AssertElementEnabledDisabled(this._apiRunBtn, 0, disabled);
}
EnterURL(url: string, evaluatedValue = "") {
this.agHelper.EnterValue(url, {
propFieldName: this._resourceUrl,
directInput: true,
inputFieldName: "",
apiOrQuery: "api",
});
EnterURL(url: string, evaluatedValue = "", toVerifySave = true) {
this.agHelper.EnterValue(
url,
{
propFieldName: this._resourceUrl,
directInput: true,
inputFieldName: "",
apiOrQuery: "api",
},
toVerifySave,
);
this.agHelper.Sleep(); //Is needed for the entered url value to be registered, else failing locally & CI
if (evaluatedValue) {
this.agHelper.VerifyEvaluatedValue(evaluatedValue);
}
evaluatedValue && this.agHelper.VerifyEvaluatedValue(evaluatedValue);
}
EnterHeader(hKey: string, hValue: string, index = 0) {
@ -242,10 +245,10 @@ export class ApiPage {
);
}
SetAPITimeout(timeout: number) {
SetAPITimeout(timeout: number, toVerifySave = true) {
this.SelectPaneTab("Settings");
cy.xpath(this._queryTimeout).clear().type(timeout.toString(), { delay: 0 }); //Delay 0 to work like paste!
this.agHelper.AssertAutoSave();
toVerifySave && this.agHelper.AssertAutoSave();
this.SelectPaneTab("Headers");
}

View File

@ -21,18 +21,26 @@ export class AssertHelper {
}
public AssertDocumentReady() {
cy.waitUntil(() =>
cy.document().should((doc) => {
expect(doc.readyState).to.equal("complete");
this.waitForCondition(() =>
cy.document().then((doc) => {
return doc.readyState === "complete";
}),
);
cy.waitUntil(() =>
cy
.window({ timeout: Cypress.config().pageLoadTimeout })
.then((win) => expect(win).haveOwnProperty("onload")),
this.waitForCondition(() =>
cy.window().then((win) => {
return win.hasOwnProperty("onload");
}),
);
}
private waitForCondition(conditionFn: any) {
cy.waitUntil(() => conditionFn, {
timeout: Cypress.config("pageLoadTimeout"),
interval: 1000,
});
}
public AssertDelete(entityType: EntityItemsType) {
let networkCall = "";
switch (entityType) {
@ -64,7 +72,7 @@ export class AssertHelper {
return aliasName;
}
public WaitForNetworkCall(aliasName: string, responseTimeout = 100000) {
public WaitForNetworkCall(aliasName: string, responseTimeout = 150000) {
// cy.wait(aliasName).then(($apiCall: any) => {
// expect($apiCall.response.body.responseMeta.status).to.eq(expectedStatus);
// });

View File

@ -367,7 +367,6 @@ export class DataSources {
currentURL = url;
const myRegexp = /applications(.*)/;
const match = myRegexp.exec(currentURL);
cy.log(currentURL + "currentURL from intercept is");
currentAppId = match ? match[1].split("/")[1] : null;
data.data.page.applicationId = currentAppId;
cy.writeFile(fixtureFile, JSON.stringify(data));
@ -700,23 +699,12 @@ export class DataSources {
this.locator._inputField,
this.dataManager.dsValues[environment].firestore_projectID,
);
// cy.fixture("firestore-ServiceAccCreds").then((json: any) => {
// let ServiceAccCreds = JSON.parse(
// JSON.stringify(json.serviceAccCredentials),
// );
// ServiceAccCreds.private_key = Cypress.env("FIRESTORE_PRIVATE_KEY");
// //cy.log("ServiceAccCreds is " + JSON.stringify(ServiceAccCreds));
// cy.log(
// "ServiceAccCreds.private_key is " +
// JSON.stringify(ServiceAccCreds.private_key),
// );
this.agHelper.UpdateFieldInput(
this.locator._inputFieldByName("Service account credentials"),
JSON.stringify(
this.dataManager.dsValues[environment].firestore_serviceaccountkey,
),
);
//});
}
public FillElasticSearchDSForm(
@ -1898,7 +1886,6 @@ export class DataSources {
);
// Total height of the parent container holding the tables in the dom normally without virtualization rendering
const totalScroll = tables.length * elementHeight;
cy.log(JSON.stringify({ heightOfParentElement, totalScroll }));
if (heightOfParentElement < totalScroll) {
// Index of the table present in the array of tables which will determine the presence of element inside the parent container
let offset = indexOfTable * elementHeight;

View File

@ -3,6 +3,7 @@ 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;
@ -169,7 +170,6 @@ export class HomePage {
.find(this.adsV2Text)
.then(($ele) => {
oldName = $ele.text();
cy.log("oldName is : " + oldName);
this.RenameWorkspace(oldName, workspaceNewName, false);
});
}
@ -354,7 +354,7 @@ export class HomePage {
}).then((response) => {
expect(response.status).equal(200); //Verifying logout is success
});
this.agHelper.Sleep(2000); //for logout to complete - CI!
this.agHelper.CypressReload();
}
public Signout(toNavigateToHome = true) {
@ -424,7 +424,7 @@ export class HomePage {
}
public SignUp(uname: string, pswd: string) {
this.agHelper.VisitNAssert("/user/signup", "@getConsolidatedData");
this.agHelper.VisitNAssert("/user/signup");
this.agHelper.AssertElementVisibility(this.signupUsername);
this.agHelper.AssertAttribute(this._submitBtn, "data-disabled", "true");
this.agHelper.TypeText(this.signupUsername, uname);
@ -567,7 +567,6 @@ export class HomePage {
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);

View File

@ -43,7 +43,7 @@ export class JSEditor {
onLoad ? "Yes" : "No"
}) input`;
private _onPageLoadSwitch = (functionName: string) =>
`.${functionName}-on-page-load-setting
`.${functionName}-on-page-load-setting
input[role="switch"]`;
private _onPageLoadRadioButtonStatus = (
functionName: string,
@ -62,7 +62,7 @@ export class JSEditor {
shouldConfirm ? "Yes" : "No"
}) input`;
private _confirmBeforeExecuteSwitch = (functionName: string) =>
`.${functionName}-confirm-before-execute
`.${functionName}-confirm-before-execute
input[role="switch"]`;
private _confirmBeforeExecuteRadioButtonStatus = (
functionName: string,
@ -151,13 +151,13 @@ export class JSEditor {
this.agHelper.RemoveUIElement("Tooltip", "Add a new query/JS Object");
//Checking JS object was created successfully
this.assertHelper.AssertNetworkStatus("@jsCollections", 200);
this.agHelper.AssertElementVisibility(this._jsObjTxt);
// Assert that the name of the JS Object is focused when newly created
//cy.get(this._jsObjTxt).should("be.focused").type("{enter}");
this.agHelper.PressEnter();
this.agHelper.PressEnter();
// Assert that the name of the JS Object is no longer in the editable form after pressing "enter"
cy.get(this._jsObjTxt).should("not.exist");
this.agHelper.AssertElementAbsence(this._jsObjTxt);
//cy.waitUntil(() => cy.get(this.locator._toastMsg).should('not.be.visible')) // fails sometimes
this.agHelper.Sleep();
@ -286,22 +286,24 @@ export class JSEditor {
cy.get(this._propertyList).then(function ($lis) {
const bindingsLength = $lis.length;
expect(bindingsLength).to.be.at.least(4);
expect($lis.eq(0).text()).to.be.oneOf([
"{{" + jsObjName + ".myFun2()}}",
"{{" + jsObjName + ".myFun1()}}",
]);
expect($lis.eq(1).text()).to.be.oneOf([
const expectedTexts = [
"{{" + jsObjName + ".myFun2()}}",
"{{" + jsObjName + ".myFun1()}}",
"{{" + jsObjName + ".myVar1}}",
"{{" + jsObjName + ".myVar2}}",
"{{" + jsObjName + ".myFun2.data}}",
"{{" + jsObjName + ".myFun1.data}}",
]);
expect($lis.eq(bindingsLength - 2).text()).to.contain(
"{{" + jsObjName + ".myVar1}}",
);
expect($lis.eq(bindingsLength - 1).text()).to.contain(
"{{" + jsObjName + ".myVar2}}",
);
];
let foundMatch = false;
for (let i = 0; i < bindingsLength; i++) {
const text = $lis.eq(i).text();
if (expectedTexts.includes(text)) {
foundMatch = true;
break;
}
}
expect(foundMatch).to.be.true;
});
cy.get(this._bindingsClose).click({ force: true });
}

View File

@ -1073,6 +1073,7 @@ Cypress.Commands.add("startServerAndRoutes", () => {
}).as("postTenant");
cy.intercept("PUT", "/api/v1/git/discard/app/*").as("discardChanges");
cy.intercept("GET", "/api/v1/libraries/*").as("getLibraries");
if (Cypress.currentTest.titlePath[0].includes(ANVIL_EDITOR_TEST)) {
// intercept features call for creating pages that support Anvil + WDS tests
featureFlagIntercept(
@ -1082,6 +1083,7 @@ Cypress.Commands.add("startServerAndRoutes", () => {
} else {
featureFlagIntercept({}, false);
}
cy.intercept(
{
method: "GET",