Skip to content

Commit

Permalink
test: Cypress | Replace static waits from Helpers + Flaky fixes (#29856)
Browse files Browse the repository at this point in the history
## Description
- This PR removes static waits from below helpers & added dynamic checks
as needed:
         - apiPage.CreateApi(), apiPage.CreateAndFillGraphqlApi()
         - app/client/cypress/support/Pages/AppSettings/ThemeSettings.ts
- cy.CreateNewAppInNewWorkspace() - replaced static wait with dynamic
check
- dataSources.NavigateToDSCreateNew() - removed wait, updated logic
         - agHelper.VerifyEvaluatedValue()
- Flaky fix below specs:
- /Git/GitSync/GitSyncedApps_spec.js (fixed testcase # 2 - 4th onwards
is failing due to childbranch/master change - to be checked further)
- /Git/GitDiscardChange/DiscardChanges_spec.js
(EditorNavigation.NavigateToDatasource(), Sidebar.navigate())
         - /BugTests/ApiBugs_Spec.ts (3rd case)
         - /Dropdown/Dropdown_onOptionChange_spec.js (3rd case)
         - /ServerSide/ApiTests/API_Search_spec.js (3rd case)
- Removed extra Refresh call from before hook in
/BugTests/ApiBugs_Spec.ts
         

#### Type of change
- Script update (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

- **Bug Fixes**
	- Improved the reliability of API creation processes.
- Enhanced the user experience in theme settings by removing unnecessary
delays.
	- Streamlined navigation in the data source creation workflow.

- **Refactor**
- Optimized test automation scripts for better performance and
maintainability.
	- Updated element interaction methods to increase test robustness.
- Refined logic for selecting and asserting UI components within test
cases.

- **Chores**
- Adjusted test suite configurations to include new test cases and
exclude a specific test file.
	- Removed redundant page refresh steps to improve test execution speed.

- **Tests**
- Added new assertions to validate the evaluated values in test
scenarios.
- Simplified data source and query creation in widget test cases for
clarity.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
  • Loading branch information
Aishwarya-U-R authored Jan 5, 2024
1 parent 7f3929e commit 01b31b3
Show file tree
Hide file tree
Showing 11 changed files with 50 additions and 94 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,6 @@ import {
} from "../../../../support/Pages/EditorNavigation";

describe("API Bugs", { tags: ["@tag.Datasource"] }, function () {
before(() => {
agHelper.RefreshPage();
});

it("1. Bug 14037, 25432: User gets an error even when table widget is added from the API page successfully", function () {
// Case where api returns array response
apiPage.CreateAndFillApi(
Expand All @@ -53,6 +49,9 @@ describe("API Bugs", { tags: ["@tag.Datasource"] }, function () {
const apiUrl = `http://host.docker.internal:5001/v1/{{true ? 'mock-api' : 'mock-apis'}}?records=10`;

apiPage.CreateAndFillApi(apiUrl, "BindingExpressions");
agHelper.VerifyEvaluatedValue(
dataManager.dsValues[dataManager.defaultEnviorment].mockApiUrl,
);
apiPage.RunAPI();
agHelper.AssertElementAbsence(
locators._specificToast(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ const explorer = require("../../../../../locators/explorerlocators.json");
const apiwidget = require("../../../../../locators/apiWidgetslocator.json");
const dynamicInputLocators = require("../../../../../locators/DynamicInput.json");
import gitSyncLocators from "../../../../../locators/gitSyncLocators";
import ApiEditor from "../../../../../locators/ApiEditor";
import homePageLocators from "../../../../../locators/HomePage";
import datasource from "../../../../../locators/DatasourcesEditor.json";

Expand Down Expand Up @@ -135,17 +134,10 @@ describe("Git sync apps", { tags: ["@tag.Git"] }, function () {
apiPage.RunAPI();
apiPage.ResponseStatusCheck("200 OK");
// curl import
dataSources.NavigateToDSCreateNew();
cy.get(ApiEditor.curlImage).click({ force: true });
cy.get("textarea").type(
'curl -d \'{"name":"morpheus","job":"leader"}\' -H Content-Type:application/json -X POST ' +
dataSources.FillCurlNImport(
`curl -d \'{"name":"morpheus","job":"leader"}\' -H Content-Type:application/json -X POST '` +
datasourceFormData["echoApiUrl"],
{
force: true,
parseSpecialCharSequences: false,
},
);
cy.importCurl();
cy.RunAPI();
apiPage.ResponseStatusCheck("200 OK");
cy.get("@curlImport").then((response) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import EditorNavigation, {
const commonlocators = require("../../../../../locators/commonlocators.json");
const formWidgetsPage = require("../../../../../locators/FormWidgets.json");
const widgetLocators = require("../../../../../locators/Widgets.json");
const datasource = require("../../../../../locators/DatasourcesEditor.json");
import {
agHelper,
locators,
Expand Down Expand Up @@ -91,34 +90,11 @@ describe(

it("3. Dropdown-Call-Query Validation", function () {
//creating a query and calling it from the onOptionChangeAction of the Dropdown widget.
// Creating a mock query
// cy.CreateMockQuery("Query1");
let postgresDatasourceName;

cy.startRoutesForDatasource();
cy.NavigateToDatasourceEditor();
cy.get(datasource.PostgreSQL).click();
cy.generateUUID().then((uid) => {
postgresDatasourceName = uid;

cy.get(".t--edit-datasource-name").click();
cy.get(".t--edit-datasource-name input")
.clear()
.type(postgresDatasourceName, { force: true })
.should("have.value", postgresDatasourceName)
.blur();

// cy.wait("@saveDatasource").should(
// "have.nested.property",
// "response.body.responseMeta.status",
// 201,
// );
cy.fillPostgresDatasourceForm();
cy.saveDatasource();
dataSources.CreateQueryForDS(postgresDatasourceName);
});

cy.CreateMockQuery("Query1");
// Creating a query
dataSources.CreateDataSource("Postgres");
dataSources.CreateQueryAfterDSSaved(
'SELECT * FROM public."country" LIMIT 10;',
);
// Going to HomePage where the button widget is located and opeing it's property pane.
cy.get("[data-guided-tour-id='explorer-entity-Page1']").click({
force: true,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,14 +60,11 @@ describe(
cy.get(ApiEditor.tableResponseTab).click();
cy.checkIfApiPaneIsVisible();
});

it("3. Bug 14242: Appsmith crash when create an API pointing to Github hosted json", function () {
cy.generateUUID().then((uid) => {
APIName = uid;
cy.CreateAPI(APIName);
});
cy.enterDatasource(testUrl3);
cy.SaveAndRunAPI();
cy.ResponseStatusCheck("200");
apiPage.CreateAndFillApi(testUrl3);
apiPage.RunAPI();
apiPage.ResponseStatusCheck("200 OK");
});
},
);
20 changes: 8 additions & 12 deletions app/client/cypress/support/Pages/AggregateHelper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1283,15 +1283,15 @@ export class AggregateHelper {
this.Sleep(200);
}
});
this.Sleep(); //for value set to settle
this.Sleep(); //for value set to register
}

public UpdateFieldInput(selector: string, value: string) {
this.GetElement(selector)
.find("input")
.invoke("attr", "value", value)
.trigger("input");
this.Sleep(); //for value set to settle
this.Sleep(); //for value set to register
}

public ValidateFieldInputValue(selector: string, value: string) {
Expand All @@ -1302,7 +1302,7 @@ export class AggregateHelper {
.then((inputValue) => {
expect(inputValue).to.equal(value);
});
this.Sleep(); //for value set to settle
this.Sleep(); //for value set to register
}

public UpdateTextArea(selector: string, value: string) {
Expand All @@ -1311,15 +1311,15 @@ export class AggregateHelper {
.first()
.invoke("val", value)
.trigger("input");
this.Sleep(500); //for value set to settle
this.Sleep(500); //for value set to register
}

public TypeIntoTextArea(selector: string, value: string) {
this.GetElement(selector)
.find("textarea")
.first()
.type(value, { delay: 0, force: true, parseSpecialCharSequences: false });
this.Sleep(500); //for value set to settle
this.Sleep(500); //for value set to register
}

public UpdateInputValue(selector: string, value: string, force = false) {
Expand Down Expand Up @@ -1447,21 +1447,17 @@ export class AggregateHelper {
// this should only be used when we want to verify the evaluated value of dynamic bindings for example {{Api1.data}} or {{"asa"}}
// and should not be called for plain strings
public VerifyEvaluatedValue(currentValue: string) {
this.Sleep(3000);
cy.get(this.locator._evaluatedCurrentValue)
this.GetElement(this.locator._evaluatedCurrentValue)
.first()
.should("be.visible")
.should("not.have.text", "undefined");
cy.get(this.locator._evaluatedCurrentValue)
this.GetElement(this.locator._evaluatedCurrentValue)
.first()
.click({ force: true })
.then(($text) => {
if ($text.text()) expect($text.text()).to.eq(currentValue);
})
.trigger("mouseout")
.then(() => {
cy.wait(2000);
});
.trigger("mouseout");
}

public UploadFile(fixtureName: string, toClickUpload = true, index = 0) {
Expand Down
15 changes: 8 additions & 7 deletions app/client/cypress/support/Pages/ApiPage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,6 @@ export class ApiPage {
private _paginationTypeLabels = ".t--apiFormPaginationType label";
_saveAsDS = ".t--store-as-datasource";
_responseStatus = ".t--response-status-code";
private _importedDataButton = ".t--show-imported-datas";
public _responseTabHeader = "[data-testid=t--tab-headers]";
public _autoGeneratedHeaderInfoIcon = (key: string) =>
`.t--auto-generated-${key}-info`;
Expand All @@ -87,6 +86,7 @@ export class ApiPage {
public _editorDS = ".t--datasource-editor";
public _addMoreHeaderFieldButton = ".t--addApiHeader";
public jsonBody = `.t--apiFormPostBody`;
private _entityName = ".t--entity-name";

CreateApi(
apiName = "",
Expand Down Expand Up @@ -115,8 +115,11 @@ export class ApiPage {
// });
// }); // to check if Api1 = Api1 when Create Api invoked

if (apiName) this.agHelper.RenameWithInPane(apiName);
cy.get(this._resourceUrl).should("be.visible");
if (apiName) {
this.agHelper.RenameWithInPane(apiName);
this.agHelper.GetNAssertContains(this._entityName, apiName);
}
this.agHelper.AssertElementVisibility(this._resourceUrl);
if (apiVerb != "GET") this.SelectAPIVerb(apiVerb);
}

Expand All @@ -129,7 +132,7 @@ export class ApiPage {
) {
this.CreateApi(apiName, apiVerb, aftDSSaved);
this.EnterURL(url);
this.agHelper.Sleep(2000); // Added because api name edit takes some time to reflect in api sidebar after the call passes.
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);
}
Expand All @@ -145,8 +148,7 @@ export class ApiPage {
inputFieldName: "",
apiOrQuery: "api",
});
//this.agHelper.GetNClick(this._resourceUrl);
this.agHelper.Sleep();
this.agHelper.Sleep(); //Is needed for the entered url value to be registered, else failing locally & CI
if (evaluatedValue) {
this.agHelper.VerifyEvaluatedValue(evaluatedValue);
}
Expand Down Expand Up @@ -429,7 +431,6 @@ export class ApiPage {
this.CreateGraphqlApi(apiName);
this.EnterURL(url);
this.agHelper.AssertAutoSave();
//this.agHelper.Sleep(2000);// Added because api name edit takes some time to reflect in api sidebar after the call passes.
this.AssertRunButtonDisability();
if (queryTimeout != 10000) this.SetAPITimeout(queryTimeout);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ export class ThemeSettings {
type == "Primary"
? this.locators._colorRingPrimary
: this.locators._colorRingBackground;
this.agHelper.Sleep(200); //for themes to complete opening
this.agHelper.AssertContains("Theme settings");
this.agHelper.GetNClick(colorType);
if (typeof colorIndex == "number") {
this.agHelper.GetNClick(this.locators._colorPickerV2Popover);
Expand Down
23 changes: 8 additions & 15 deletions app/client/cypress/support/Pages/DataSources.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ export class DataSources {
}; //Container KeyValuePair
private _dsReviewSection = "[data-testid='t--ds-review-section']";
public _addNewDataSource = ".t--add-datasource-button";
public _addNewDatasourceFromBlankScreen =
private _addNewDatasourceFromBlankScreen =
".t--add-datasource-button-blank-screen";
private _createNewPlgin = (pluginName: string) =>
".t--plugin-name:contains('" + pluginName + "')";
Expand Down Expand Up @@ -447,21 +447,14 @@ export class DataSources {

public NavigateToDSCreateNew() {
AppSidebar.navigate(AppSidebarButton.Data);
Cypress._.times(2, () => {
cy.get("body").then(($body) => {
if ($body.find(this._addNewDataSource).length) {
this.agHelper.GetNClick(this._addNewDataSource, 0, true);
} else {
this.agHelper.GetNClick(
this._addNewDatasourceFromBlankScreen,
0,
true,
);
}
});
this.agHelper.Sleep();
cy.get("body").then(($body) => {
if ($body.find(this._addNewDataSource).length > 0) {
this.agHelper.GetNClick(this._addNewDataSource, 0, true);
} else {
this.agHelper.GetNClick(this._addNewDatasourceFromBlankScreen, 0, true);
}
});
cy.get(this._newDatabases).should("be.visible");
this.agHelper.AssertElementVisibility(this._newDatabases);
}

CreateMockDB(dbName: "Users" | "Movies"): Cypress.Chainable<string> {
Expand Down
3 changes: 2 additions & 1 deletion app/client/cypress/support/Pages/EditorNavigation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,8 @@ class EditorNavigation {
.should("be.visible")
.click()
.parents(datasource.datasourceCard)
.should("have.attr", "data-selected", "true");
.as("dsCard");
cy.get("@dsCard").should("have.attr", "data-selected", "true");
}

NavigateToWidget(
Expand Down
9 changes: 7 additions & 2 deletions app/client/cypress/support/Pages/IDE/Sidebar.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,13 @@ export class Sidebar {
this.assertVisible();
cy.get(this.locators.sidebar)
.find(this.locators.sidebarButton(button))
.click({ force: true })
.should("have.attr", "data-selected", willFail ? "false" : "true");
.as("navigateBtn")
.click({ force: true });
cy.get("@navigateBtn").should(
"have.attr",
"data-selected",
willFail ? "false" : "true",
);
}

assertVisible() {
Expand Down
8 changes: 2 additions & 6 deletions app/client/cypress/support/WorkspaceCommands.js
Original file line number Diff line number Diff line change
Expand Up @@ -268,7 +268,6 @@ Cypress.Commands.add("CreateNewAppInNewWorkspace", () => {
}
});
homePageTS.CreateNewWorkspace("", toNavigateToHome); //Creating a new workspace for every test, since we are deleting the workspace in the end of the test
//agHelper.Sleep(2000); //for workspace to open
cy.get("@workspaceName").then((workspaceName) => {
localStorage.setItem("workspaceName", workspaceName);
homePageTS.CreateAppInWorkspace(localStorage.getItem("workspaceName"));
Expand All @@ -285,18 +284,15 @@ Cypress.Commands.add("CreateNewAppInNewWorkspace", () => {
localStorage.setItem("applicationId", applicationId);
localStorage.setItem("appName", appName);

// eslint-disable-next-line cypress/no-unnecessary-waiting
cy.wait(4000);
cy.get("#loading").should("not.exist");
agHelper.AssertElementAbsence("#loading", Cypress.config().pageLoadTimeout);

cy.url().then((url) => {
if (url.indexOf("/applications") > -1) {
homePageTS.EditAppFromAppHover(appName);
agHelper.Sleep(2000); //for app to open
}
});
});
cy.get("#sidebar").should("be.visible");
agHelper.AssertElementVisibility("#sidebar");
assertHelper.AssertNetworkResponseData("@getPluginForm"); //for auth rest api
assertHelper.AssertNetworkResponseData("@getPluginForm"); //for graphql

Expand Down

0 comments on commit 01b31b3

Please sign in to comment.