test: Cypress - Fix flaky tests (#21292)

## Description

**Fixed below flaky tests**

- DeleteWorkspace_spec.js
- Listv2_BasicChildWidgetInteraction_spec.js
- JSOnLoad_cyclic_dependency_errors_spec.js

## Type of change

- Flaky test fix

## How Has This Been Tested?
- Cypress test runs

## Checklist:
### QA activity:
- [ ] Test plan has been approved by relevant developers
- [ ] Test plan has been peer reviewed by QA
- [ ] Cypress test cases have been added and approved by either SDET or
manual QA
- [ ] Organized project review call with relevant stakeholders after
Round 1/2 of QA
- [ ] Added Test Plan Approved label after reveiwing all Cypress test

---------

Co-authored-by: Aishwarya UR <aishwarya@appsmith.com>
This commit is contained in:
Vijetha-Kaja 2023-03-10 12:25:13 +05:30 committed by GitHub
parent d96f2a14d3
commit 8c6ac8afa6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 54 additions and 88 deletions

View File

@ -52,12 +52,8 @@ function checkSelectedRadioValue(selector, value) {
describe("List widget v2 - Basic Child Widget Interaction", () => { describe("List widget v2 - Basic Child Widget Interaction", () => {
before(() => { before(() => {
cy.addDsl(emptyListDSL); cy.addDsl(emptyListDSL);
agHelper.RestoreLocalStorageCache();
cy.get(publishLocators.containerWidget).should("have.length", 3); cy.get(publishLocators.containerWidget).should("have.length", 3);
}); cy.wait(3000); // for dsl to settle
after(() => {
agHelper.SaveLocalStorageCache();
}); });
it("1. Child widgets", () => { it("1. Child widgets", () => {
@ -187,6 +183,16 @@ describe("List widget v2 - Basic Child Widget Interaction", () => {
cy.get(publishLocators.switchwidget) cy.get(publishLocators.switchwidget)
.find("input") .find("input")
.should("be.checked"); .should("be.checked");
cy.wait(1000);
cy.waitUntil(() =>
cy
.get(
`${widgetSelector("List1")} ${containerWidgetSelector} ${
publishLocators.switchwidget
}`,
)
.should("have.length", 3),
);
// Uncheck // Uncheck
cy.get(publishLocators.switchwidget) cy.get(publishLocators.switchwidget)
.find("label") .find("label")
@ -225,7 +231,16 @@ describe("List widget v2 - Basic Child Widget Interaction", () => {
// Check radio with value=1 is selected // Check radio with value=1 is selected
checkSelectedRadioValue(publishLocators.radioWidget, "Y"); checkSelectedRadioValue(publishLocators.radioWidget, "Y");
cy.wait(1000);
cy.waitUntil(() =>
cy
.get(
`${widgetSelector("List1")} ${containerWidgetSelector} ${
publishLocators.radioWidget
}`,
)
.should("have.length", 3),
);
// Check option 2 and then check it's value: // Check option 2 and then check it's value:
cy.get(`${publishLocators.radioWidget} input`).check("N", { force: true }); cy.get(`${publishLocators.radioWidget} input`).check("N", { force: true });
checkSelectedRadioValue(publishLocators.radioWidget, "N"); checkSelectedRadioValue(publishLocators.radioWidget, "N");

View File

@ -7,14 +7,11 @@ describe("Delete workspace test spec", function() {
it("1. Should delete the workspace", function() { it("1. Should delete the workspace", function() {
cy.visit("/applications"); cy.visit("/applications");
cy.generateUUID().then((uid) => { _.agHelper.GenerateUUID();
newWorkspaceName = uid; cy.get("@guid").then((uid) => {
newWorkspaceName = "Deleteworkspace" + uid;
_.homePage.CreateNewWorkspace(newWorkspaceName); _.homePage.CreateNewWorkspace(newWorkspaceName);
cy.wait(500); _.homePage.DeleteWorkspace(newWorkspaceName)
cy.contains(".cs-text", "Delete Workspace")
.scrollIntoView()
.click();
cy.contains("Are you sure").click();
cy.wait("@deleteWorkspaceApiCall").then((httpResponse) => { cy.wait("@deleteWorkspaceApiCall").then((httpResponse) => {
expect(httpResponse.status).to.equal(200); expect(httpResponse.status).to.equal(200);
}); });

View File

@ -1,13 +1,9 @@
import { ObjectsRegistry } from "../../../../support/Objects/Registry";
const dsl = require("../../../../fixtures/inputdsl.json"); const dsl = require("../../../../fixtures/inputdsl.json");
const datasource = require("../../../../locators/DatasourcesEditor.json");
const widgetsPage = require("../../../../locators/Widgets.json"); const widgetsPage = require("../../../../locators/Widgets.json");
const queryLocators = require("../../../../locators/QueryEditor.json"); const queryLocators = require("../../../../locators/QueryEditor.json");
const jsEditor = ObjectsRegistry.JSEditor;
const ee = ObjectsRegistry.EntityExplorer; let queryName = "Query1";
const agHelper = ObjectsRegistry.AggregateHelper; import * as _ from "../../../../support/Objects/ObjectsCore";
let queryName;
/* /*
Cyclic Dependency Error if occurs, Message would be shown in following 6 cases: Cyclic Dependency Error if occurs, Message would be shown in following 6 cases:
@ -27,51 +23,13 @@ describe("Cyclic Dependency Informational Error Messages", function() {
cy.wait(3000); //dsl to settle! cy.wait(3000); //dsl to settle!
}); });
it("1. Create Users Sample DB & Sample DB Query", () => { it("1. Create Users Sample DB Query & Simulate cyclic depedency", () => {
//Step1 //Step1 : Create Mock Users DB
cy.wait(2000); _.dataSources.CreateMockDB("Users").then((dbName) => {
cy.NavigateToDatasourceEditor(); _.dataSources.CreateQueryFromActiveTab(dbName, false);
_.agHelper.GetNClick(_.dataSources._templateMenuOption("Select"));
//Step2 _.dataSources.ToggleUsePreparedStatement(false);
cy.get(datasource.mockUserDatabase).click();
//Step3 & 4
cy.contains(`${datasource.datasourceCard}`, "Users")
.last()
.find(`${datasource.createQuery}`)
.click({ force: true });
//Step5.1: Click the editing field
cy.get(".t--action-name-edit-field").click({ force: true });
cy.generateUUID().then((uid) => {
queryName = "query" + uid;
//Step5.2: Click the editing field
cy.get(queryLocators.queryNameField).type(queryName);
// switching off Use Prepared Statement toggle
cy.get(queryLocators.switch)
.last()
.click({ force: true });
//Step 6.1: Click on Write query area
cy.get(queryLocators.templateMenu).click();
cy.get(queryLocators.query).click({ force: true });
// Step6.2: writing query to get the schema
cy.get(".CodeMirror textarea")
.first()
.focus()
.type("SELECT gender FROM users ORDER BY id LIMIT 10;", {
force: true,
parseSpecialCharSequences: false,
});
cy.WaitAutoSave();
}); });
});
// Step 1: simulate cyclic depedency
it("2. Create Input Widget & Bind Input Widget Default text to Query Created", () => {
cy.get(widgetsPage.widgetSwitchId).click(); cy.get(widgetsPage.widgetSwitchId).click();
cy.openPropertyPane("inputwidgetv2"); cy.openPropertyPane("inputwidgetv2");
cy.get(widgetsPage.defaultInput).type("{{" + queryName + ".data[0].gender"); cy.get(widgetsPage.defaultInput).type("{{" + queryName + ".data[0].gender");
@ -84,7 +42,7 @@ describe("Cyclic Dependency Informational Error Messages", function() {
}); });
//Case 1: On page load actions //Case 1: On page load actions
it("3. Reload Page and it should not provide errors in response", () => { it("2. Reload Page and it should not provide errors in response & update input widget's placeholder property and check errors array to be empty", () => {
// cy.get(widgetsPage.NavHomePage).click({ force: true }); // cy.get(widgetsPage.NavHomePage).click({ force: true });
cy.reload(); cy.reload();
cy.openPropertyPane("inputwidgetv2"); cy.openPropertyPane("inputwidgetv2");
@ -93,9 +51,7 @@ describe("Cyclic Dependency Informational Error Messages", function() {
"response.body.data.layouts[0].layoutOnLoadActionErrors.length", "response.body.data.layouts[0].layoutOnLoadActionErrors.length",
0, 0,
); );
});
it("4. update input widget's placeholder property and check errors array to be empty", () => {
// Case 2: When updating DSL attribute // Case 2: When updating DSL attribute
cy.get(widgetsPage.placeholder).type("cyclic placeholder"); cy.get(widgetsPage.placeholder).type("cyclic placeholder");
cy.wait("@updateLayout").should( cy.wait("@updateLayout").should(
@ -105,9 +61,9 @@ describe("Cyclic Dependency Informational Error Messages", function() {
); );
}); });
it("5. Add JSObject and update its name, content and check for no errors", () => { it("3. Add JSObject and update its name, content and check for no errors", () => {
// Case 3: When updating JS Object name // Case 3: When updating JS Object name
jsEditor.CreateJSObject( _.jsEditor.CreateJSObject(
`export default { `export default {
fun: async () => { fun: async () => {
showAlert("New Js Object"); showAlert("New Js Object");
@ -120,7 +76,7 @@ describe("Cyclic Dependency Informational Error Messages", function() {
shouldCreateNewJSObj: true, shouldCreateNewJSObj: true,
}, },
); );
jsEditor.RenameJSObjFromPane("newName"); _.jsEditor.RenameJSObjFromPane("newName");
cy.wait("@renameJsAction").should( cy.wait("@renameJsAction").should(
"have.nested.property", "have.nested.property",
@ -134,7 +90,7 @@ describe("Cyclic Dependency Informational Error Messages", function() {
return "yes"; return "yes";
} }
}`; }`;
jsEditor.EditJSObj(syncJSCode, false); _.jsEditor.EditJSObj(syncJSCode, false);
cy.wait("@jsCollections").should( cy.wait("@jsCollections").should(
"have.nested.property", "have.nested.property",
@ -144,21 +100,19 @@ describe("Cyclic Dependency Informational Error Messages", function() {
}); });
// Case 5: When updating DSL name // Case 5: When updating DSL name
it("6. Update Widget Name and check for no errors", () => { it("4. Update Widget Name and check for no errors & Update Query and check for errors", () => {
let entityName = "gender"; let entityName = "gender";
let newEntityName = "newInput"; let newEntityName = "newInput";
ee.SelectEntityByName(entityName, "Widgets"); _.entityExplorer.SelectEntityByName(entityName, "Widgets");
agHelper.RenameWidget(entityName, newEntityName); _.agHelper.RenameWidget(entityName, newEntityName);
cy.wait("@updateWidgetName").should( cy.wait("@updateWidgetName").should(
"have.nested.property", "have.nested.property",
"response.body.data.layoutOnLoadActionErrors.length", "response.body.data.layoutOnLoadActionErrors.length",
0, 0,
); );
});
// Case 6: When updating Datasource query // Case 6: When updating Datasource query
it("7. Update Query and check for errors", () => { _.entityExplorer.SelectEntityByName(queryName, "Queries/JS");
ee.SelectEntityByName(queryName, "Queries/JS");
// update query and check no cyclic dependency issue should occur // update query and check no cyclic dependency issue should occur
cy.get(queryLocators.query).click({ force: true }); cy.get(queryLocators.query).click({ force: true });
cy.get(".CodeMirror textarea") cy.get(".CodeMirror textarea")

View File

@ -86,6 +86,10 @@ export class HomePage {
"//span[text()='" + action + "']/ancestor::a"; "//span[text()='" + action + "']/ancestor::a";
private _homeTab = ".t--apps-tab"; private _homeTab = ".t--apps-tab";
private _templatesTab = ".t--templates-tab"; private _templatesTab = ".t--templates-tab";
private _workSpaceByName = (wsName: string) =>
"//div[contains(@class, 't--applications-container')]//span[text()='" +
wsName +
"']";
public SwitchToAppsTab() { public SwitchToAppsTab() {
this.agHelper.GetNClick(this._homeTab); this.agHelper.GetNClick(this._homeTab);
@ -112,23 +116,19 @@ export class HomePage {
}); });
} }
public RenameWorkspace(workspaceName: string, newWorkspaceName: string) { public RenameWorkspace(oldName: string, newWorkspaceName: string) {
cy.get(this._appContainer) cy.xpath(this._workSpaceByName(oldName))
.contains(workspaceName) .last()
.closest(this._workspaceCompleteSection) .closest(this._workspaceCompleteSection)
.find(this._workspaceName) .scrollIntoView()
.find(this._optionsIcon) .find(this._optionsIcon)
.click({ force: true }); .click({ force: true });
cy.get(this._renameWorkspaceInput) cy.get(this._renameWorkspaceInput)
.should("be.visible") .should("be.visible")
.type(newWorkspaceName.concat("{enter}")); .type(newWorkspaceName.concat("{enter}"));
this.agHelper.Sleep(2000); this.agHelper.Sleep(2000);
cy.wait("@updateWorkspace").should( this, this.agHelper.ValidateNetworkStatus("@updateWorkspace");
"have.nested.property", this.agHelper.AssertContains(newWorkspaceName);
"response.body.responseMeta.status",
200,
);
cy.contains(newWorkspaceName);
} }
//Maps to CheckShareIcon in command.js //Maps to CheckShareIcon in command.js