test: Cypress | Firestore validations added + CI Stabilize (#27554)

## Description
- This PR adds below validation for firestore DS
- Firestore - Added documentation verification (added Staging dummy data
for Firestore DS)
  - Firestore - Added mandatory fields validations
  - Firestore - added placeholder validation
  - Firestore - Added widget binding & deploy app validation
  - Firestore - DS logo validation
- Flaky fix - Templates/Filtering/TemplatesModal_filtering_spec.ts
- CreateAppInFirstListedWorkspace() improved to navigate to New
Application edit page after creation
- Pin_Spec.js - updated validation for airgap
- Trial fix - ServerSide/Datasources/Oracle_Spec.ts
- Removing cypress/package.json as its not used

#### 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

---------

Co-authored-by: Parthvi <80334441+Parthvi12@users.noreply.github.com>
This commit is contained in:
Aishwarya-U-R 2023-09-25 20:02:54 +05:30 committed by GitHub
parent d2cfa47443
commit 61db723d35
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
16 changed files with 136 additions and 85 deletions

View File

@ -1,4 +1,3 @@
import { featureFlagIntercept } from "../../../../support/Objects/FeatureFlags";
import {
agHelper,
entityItems,

View File

@ -114,7 +114,7 @@ describe("Entity explorer tests related to pinning and unpinning", function () {
(menu) => menu !== ExplorerMenu.ADD_LIBRARY,
);
Cypress._.times(menu.length - 1, (index) => {
Cypress._.times(menu.length, (index) => {
OpenExplorerMenu(menu[index]);
agHelper.Sleep();
cy.get("[data-testid=sidebar-active]").should("exist");

View File

@ -1,4 +1,3 @@
import { featureFlagIntercept } from "../../../../support/Objects/FeatureFlags";
import {
entityExplorer,
agHelper,

View File

@ -5,7 +5,6 @@ import {
agHelper,
} from "../../../../support/Objects/ObjectsCore";
import { Widgets } from "../../../../support/Pages/DataSources";
import { featureFlagIntercept } from "../../../../support/Objects/FeatureFlags";
describe("Check Suggested Widgets Feature in auto-layout", function () {
before(() => {

View File

@ -137,19 +137,19 @@ describe("Text widget tests", function () {
widgetLocators.textWidgetContainer + " > div > div",
"color",
)
.then((textColor) => {
.then((textColor: any) => {
agHelper
.GetWidgetCSSFrAttribute(
widgetLocators.textWidgetContainer + " > div > div",
"background",
)
.then((backgroundColor) => {
.then((backgroundColor: any) => {
agHelper
.GetWidgetCSSFrAttribute(
widgetLocators.textWidgetContainer,
"border-color",
)
.then((borderColor) => {
.then((borderColor: any) => {
deployMode.DeployApp(
locators._widgetInDeployed(draggableWidgets.TEXT),
);
@ -214,13 +214,13 @@ describe("Text widget tests", function () {
widgetLocators.textWidgetContainer + " > div > div",
"color",
)
.then((textColor) => {
.then((textColor: any) => {
agHelper
.GetWidgetCSSFrAttribute(
widgetLocators.textWidgetContainer + " > div > div",
"background",
)
.then((backgroundColor) => {
.then((backgroundColor: any) => {
deployMode.DeployApp(
locators._widgetInDeployed(draggableWidgets.TEXT),
);
@ -273,19 +273,19 @@ describe("Text widget tests", function () {
widgetLocators.textWidgetContainer + " > div > div",
"color",
)
.then((textColor) => {
.then((textColor: any) => {
agHelper
.GetWidgetCSSFrAttribute(
widgetLocators.textWidgetContainer + " > div > div",
"background",
)
.then((backgroundColor) => {
.then((backgroundColor: any) => {
agHelper
.GetWidgetCSSFrAttribute(
widgetLocators.textWidgetContainer,
"border-color",
)
.then((borderColor) => {
.then((borderColor: any) => {
deployMode.DeployApp(
locators._widgetInDeployed(draggableWidgets.TEXT),
);

View File

@ -3,22 +3,58 @@ import {
entityExplorer,
dataSources,
entityItems,
deployMode,
locators,
draggableWidgets,
table,
} from "../../../../support/Objects/ObjectsCore";
import { Widgets } from "../../../../support/Pages/DataSources";
let dsName: any,
guid: any,
cities: any,
newCityPath: any,
createCity: any,
cityName = "LA_";
describe("Validate Firestore DS", () => {
before("Create a new Firestore DS", () => {
dataSources.CreateDataSource("Firestore");
cy.get("@dsName").then(($dsName) => {
dsName = $dsName;
before("Generate GUID for new Firestore DS", () => {
agHelper.GenerateUUID();
cy.get("@guid").then((uid) => {
guid = uid;
dsName = "Firestore" + " " + uid;
});
});
it("1. Validate List/Create/Update/Get", () => {
it("1. Firestore placeholder & mandatory mark verification", () => {
dataSources.NavigateToDSCreateNew();
dataSources.CreatePlugIn("Firestore");
agHelper.AssertElementVisibility(dataSources._imgFireStoreLogo);
agHelper.GetNAssertContains(locators._dsName, "Untitled datasource");
agHelper.GetNClick(locators._dsName);
agHelper.ClearTextField(locators._dsNameTxt); //removing ds name
agHelper.AssertTooltip("Please enter a valid name");
//agHelper.ValidateToastMessage("Invalid name");
agHelper.TypeText(locators._dsNameTxt, dsName);
agHelper.PressEnter();
agHelper.AssertAttribute(
locators._inputFieldByName("Database URL") + "//" + locators._inputField,
"placeholder",
"https://your-project-id.firebaseio.com",
);
agHelper
.GetElement(
locators._inputFieldByName("Project Id") + "//" + locators._inputField,
)
.should("not.have.attr", "placeholder");
dataSources.TestDatasource(false);
agHelper.ValidateToastMessage("Missing Firestore URL.");
agHelper.ValidateToastMessage("Missing ProjectID in datasource.");
agHelper.ValidateToastMessage("Missing ClientJSON in datasource.");
dataSources.FillFirestoreDSForm();
dataSources.TestSaveDatasource();
});
it("2. Validate List/Create/Update/Get", () => {
agHelper.GenerateUUID();
cy.get("@guid").then((uid) => {
cityName += uid;
@ -187,11 +223,31 @@ describe("Validate Firestore DS", () => {
});
});
it("2. Validate Upsert [Update & Insert]/Delete documents", () => {
//Validating Upsert
it("3. Validate Widget binding & Deploy app", () => {
dataSources.ValidateNSelectDropdown(
"Commands",
"Get Document",
"List Documents",
);
agHelper.EnterValue("cities", {
propFieldName: "",
directInput: false,
inputFieldName: "Collection Name",
});
agHelper.GetNClick(dataSources._whereDelete(0)); //removign where clause, add new condition
dataSources.RunQuery();
dataSources.AddSuggestedWidget(Widgets.Table);
deployMode.DeployApp(locators._widgetInDeployed(draggableWidgets.TABLE));
table.WaitUntilTableLoad(0, 0, "v2");
deployMode.NavigateBacktoEditor();
entityExplorer.SelectEntityByName("Query1", "Queries/JS");
});
it("4. Validate Upsert [Update & Insert]/Delete documents", () => {
//Validating Upsert
dataSources.ValidateNSelectDropdown(
"Commands",
"List Documents",
"Upsert Document",
);
@ -297,11 +353,16 @@ describe("Validate Firestore DS", () => {
action: "Delete",
entityType: entityItems.Query,
});
entityExplorer.SelectEntityByName(dsName, "Datasources");
entityExplorer.ActionContextMenuByEntityName({
entityNameinLeftSidebar: dsName,
action: "Delete",
entityType: entityItems.Datasource,
});
dataSources.DeleteDatasouceFromActiveTab(dsName, 409);
//commenting below since after query delete, we run into risk of not seeing the datasource in EntityExplorer
// entityExplorer.SelectEntityByName(dsName, "Datasources");
// entityExplorer.ActionContextMenuByEntityName({
// entityNameinLeftSidebar: dsName,
// action: "Delete",
// entityType: entityItems.Datasource,
// });
deployMode.DeployApp();
deployMode.NavigateBacktoEditor();
dataSources.DeleteDatasourceFromWithinDS(dsName, 200);
});
});

View File

@ -427,6 +427,7 @@ WHERE aircraft_type = 'Passenger Plane'`;
subAction: "Page2",
toastToValidate: "moved to page",
});
agHelper.WaitUntilAllToastsDisappear();
agHelper.GetNAssertContains(locators._queryName, "Query1Copy");
dataSources.RunQueryNVerifyResponseViews(2);
agHelper.ActionContextMenuWithInPane({
@ -459,13 +460,13 @@ WHERE aircraft_type = 'Passenger Plane'`;
after(
"Verify Deletion of the Oracle datasource after all created queries are deleted",
() => {
dataSources.DeleteDatasouceFromWinthinDS(dataSourceName, 409); //Since all queries exists
dataSources.DeleteDatasourceFromWithinDS(dataSourceName, 409); //Since all queries exists
entityExplorer.ExpandCollapseEntity("Queries/JS");
entityExplorer.DeleteAllQueriesForDB(dataSourceName);
deployMode.DeployApp();
deployMode.NavigateBacktoEditor();
entityExplorer.ExpandCollapseEntity("Queries/JS");
dataSources.DeleteDatasouceFromWinthinDS(dataSourceName, 200);
dataSources.DeleteDatasourceFromWithinDS(dataSourceName, 200);
},
);
});

View File

@ -1,6 +1,5 @@
import {
agHelper,
entityExplorer,
dataSources,
entityItems,
} from "../../../../support/Objects/ObjectsCore";

View File

@ -404,7 +404,7 @@ describe("Binary Datatype tests", function () {
// entityExplorer.ExpandCollapseEntity("Datasources", false);
// //Delete all queries
// dataSources.DeleteDatasouceFromWinthinDS(dsName, 409); //Since all queries exists
// dataSources.DeleteDatasourceFromWithinDS(dsName, 409); //Since all queries exists
// entityExplorer.ExpandCollapseEntity("Queries/JS");
// entityExplorer.DeleteAllQueriesForDB(dsName);
@ -412,7 +412,7 @@ describe("Binary Datatype tests", function () {
// deployMode.DeployApp();
// deployMode.NavigateBacktoEditor();
// entityExplorer.ExpandCollapseEntity("Queries/JS");
// dataSources.DeleteDatasouceFromWinthinDS(dsName, 200);
// dataSources.DeleteDatasourceFromWithinDS(dsName, 200);
// },
// );
});

View File

@ -120,6 +120,24 @@ describe("Check datasource doc links", function () {
});
});
it("9. Verify Firestore documentation opens", function () {
dataSources.CreateDataSource(
"Firestore",
true,
false,
dataManager.environments[1],
); //using mock dataset for oracle
cy.get("@dsName").then(($dsName) => {
dsName = $dsName;
dataSources.CreateQueryAfterDSSaved();
deployMode.StubWindowNAssert(
dataSources._queryDoc,
"querying-firestore#understanding-commands",
"getWorkspace",
);
});
});
afterEach(() => {
agHelper.PressEscape();
agHelper.ActionContextMenuWithInPane({

View File

@ -1,45 +0,0 @@
{
"name": "appsmith-ci-test",
"version": "0.1.0",
"private": true,
"engines": {
"node": "^18.17.1",
"yarn": "^3.5.1"
},
"scripts": {
"install": "node apply-patches.js"
},
"browserslist": [
">0.2%",
"not dead",
"not ie <= 11",
"not op_mini all"
],
"devDependencies": {
"@blueprintjs/core": "^3.36.0",
"@blueprintjs/datetime": "^3.23.6",
"@blueprintjs/icons": "^3.10.0",
"@blueprintjs/popover2": "^0.5.0",
"@blueprintjs/select": "^3.10.0",
"@faker-js/faker": "^7.4.0",
"@typescript-eslint/eslint-plugin": "^5.25.0",
"@typescript-eslint/parser": "^5.25.0",
"chalk": "^4.1.1",
"cy-verify-downloads": "^0.0.5",
"cypress": "^12.17.4",
"cypress-file-upload": "^4.1.1",
"cypress-image-snapshot": "^4.0.1",
"cypress-log-to-output": "^1.1.2",
"cypress-multi-reporters": "^1.2.4",
"cypress-plugin-tab": "^1.0.5",
"cypress-real-events": "^1.8.1",
"cypress-tags": "^1.1.2",
"cypress-wait-until": "^1.7.2",
"cypress-xpath": "^1.4.0",
"diff": "^5.0.0",
"dotenv": "^8.1.0",
"eslint-plugin-cypress": "^2.11.2",
"tinycolor2": "^1.4.2",
"typescript": "4.9.5"
}
}

View File

@ -83,6 +83,7 @@ export class DataManager {
firestore_database_url: "https://appsmith-22e8b.firebaseio.com",
firestore_projectID: "appsmith-22e8b",
firestore_serviceaccountkey: Cypress.env("FIRESTORE_PRIVATE_KEY"),
restapi_url: "https://my-json-server.typicode.com/typicode/demo/posts",
connection_type: "Replica set",
@ -173,8 +174,9 @@ export class DataManager {
AirtableTableForME: "tblsFCQSskVFf7xNd",
ApiUrlME: "http://host.docker.internal:5001/v1/staging",
firestore_database_url: "https://appsmith-22e8b.firebaseio.com",
firestore_projectID: "appsmith-22e8b",
firestore_database_url: "https://staging-sample.firebaseio.com",
firestore_projectID: "appsmith-dummy",
firestore_serviceaccountkey: "dummy_service_creds_key",
restapi_url: "https://my-json-server.typicode.com/typicode/demo/posts",
connection_type: "Replica set",

View File

@ -283,6 +283,8 @@ export class DataSources {
_stagingTab = "[data-testid='t--ds-data-filter-Staging']";
_graphQlDsFromRightPane = (dsName: string) =>
"//div/span[text() ='" + dsName + "']";
_imgFireStoreLogo =
"img[src='https://assets.appsmith.com/logo/firestore.svg']";
public AssertDSEditViewMode(mode: "Edit" | "View") {
if (mode == "Edit") this.agHelper.AssertElementAbsence(this._editButton);
@ -680,7 +682,9 @@ export class DataSources {
// );
this.agHelper.UpdateFieldInput(
this.locator._inputFieldByName("Service account credentials"),
JSON.stringify(Cypress.env("FIRESTORE_PRIVATE_KEY")),
JSON.stringify(
this.dataManager.dsValues[environment].firestore_serviceaccountkey,
),
);
//});
}

View File

@ -183,6 +183,7 @@ export class DeployMode {
}); // //only reloading edit page to load elements
});
this.assertHelper.AssertDocumentReady();
this.agHelper.Sleep(2000); //wait for getWorkspace to go thru!
this.assertHelper.AssertNetworkStatus("@getWorkspace");
this.agHelper.AssertElementVisibility(this.locator._editPage); //Assert if canvas is visible after Navigating back!
}

View File

@ -45,6 +45,7 @@ export class GitSync {
public _gitStatusChanges = "[data-testid='t--git-change-statuses']";
private _gitSyncBranches = ".t--sync-branches";
learnMoreSshUrl = ".t--learn-more-ssh-url";
repoLimitExceededErrorModal = ".t--git-repo-limited-modal";
OpenGitSyncModal() {
this.agHelper.GetNClick(this._connectGitBottomBar);

View File

@ -10,6 +10,7 @@ import { ObjectsRegistry } from "../support/Objects/Registry";
const agHelper = ObjectsRegistry.AggregateHelper;
const assertHelper = ObjectsRegistry.AssertHelper;
const homePageTS = ObjectsRegistry.HomePage;
export const initLocalstorage = () => {
cy.window().then((window) => {
@ -214,6 +215,7 @@ Cypress.Commands.add("launchApp", () => {
});
Cypress.Commands.add("AppSetupForRename", () => {
cy.wait(2000); //wait a bit for app to load
cy.get(homePage.applicationName).then(($appName) => {
if (!$appName.hasClass(homePage.editingAppName)) {
cy.get(homePage.applicationName).click({ force: true });
@ -256,25 +258,35 @@ Cypress.Commands.add("CreateAppForWorkspace", (workspaceName, appname) => {
});
Cypress.Commands.add("CreateAppInFirstListedWorkspace", (appname) => {
let applicationId;
let applicationId, appName;
cy.get(homePage.createNew).first().click({ force: true });
cy.wait("@createNewApplication").then((xhr) => {
const response = xhr.response;
expect(response.body.responseMeta.status).to.eq(201);
applicationId = response.body.data.id;
appName = response.body.data.name;
cy.log("appName", appName);
localStorage.setItem("applicationId", applicationId);
//});
//cy.get("#loading").should("not.exist");
// eslint-disable-next-line cypress/no-unnecessary-waiting
//cy.reload();
cy.wait(4000);
cy.get("#loading").should("not.exist");
cy.url().then((url) => {
if (url.indexOf("/applications") > -1) {
homePageTS.EditAppFromAppHover(appName);
agHelper.Sleep(2000); //for app to open
}
});
});
//cy.get("#loading").should("not.exist");
// eslint-disable-next-line cypress/no-unnecessary-waiting
//cy.reload();
cy.wait(4000);
cy.get("#loading").should("not.exist");
assertHelper.AssertNetworkStatus("@getPage");
assertHelper.AssertNetworkStatus("@getLibraries");
assertHelper.AssertNetworkStatus("@getPlugins");
cy.get("#sidebar", { timeout: 60000 }).should("be.visible");
cy.get("#sidebar").should("be.visible");
cy.wait("@getPluginForm") //replacing this since flaky in CI - to monitor
.its("response.body.responseMeta.status")
.should("eq", 200);