diff --git a/app/client/cypress/fixtures/snippingTableDsl.json b/app/client/cypress/fixtures/snippingTableDsl.json new file mode 100644 index 0000000000..68a9bd5283 --- /dev/null +++ b/app/client/cypress/fixtures/snippingTableDsl.json @@ -0,0 +1,175 @@ +{ + "dsl": { + "widgetName": "MainContainer", + "backgroundColor": "none", + "rightColumn": 1095, + "snapColumns": 64, + "detachFromLayout": true, + "widgetId": "0", + "topRow": 0, + "bottomRow": 5016, + "containerStyle": "none", + "snapRows": 125, + "parentRowSpace": 1, + "type": "CANVAS_WIDGET", + "canExtend": true, + "version": 46, + "minHeight": 930, + "parentColumnSpace": 1, + "dynamicBindingPathList": [ + + ], + "leftColumn": 0, + "children": [ + { + "isVisible": true, + "defaultSelectedRow": "0", + "label": "Data", + "widgetName": "Table1", + "searchKey": "", + "textSize": "PARAGRAPH", + "horizontalAlignment": "LEFT", + "verticalAlignment": "CENTER", + "totalRecordsCount": 0, + "defaultPageSize": 0, + "dynamicBindingPathList": [ + { + "key": "primaryColumns.step.computedValue" + }, + { + "key": "primaryColumns.task.computedValue" + }, + { + "key": "primaryColumns.status.computedValue" + }, + { + "key": "primaryColumns.action.computedValue" + } + ], + "primaryColumns": { + "step": { + "index": 0, + "width": 150, + "id": "step", + "horizontalAlignment": "LEFT", + "verticalAlignment": "CENTER", + "columnType": "text", + "textSize": "PARAGRAPH", + "enableFilter": true, + "enableSort": true, + "isVisible": true, + "isCellVisible": true, + "isDerived": false, + "label": "step", + "computedValue": "{{Table1.sanitizedTableData.map((currentRow) => ( currentRow.step))}}" + }, + "task": { + "index": 1, + "width": 150, + "id": "task", + "horizontalAlignment": "LEFT", + "verticalAlignment": "CENTER", + "columnType": "text", + "textSize": "PARAGRAPH", + "enableFilter": true, + "enableSort": true, + "isVisible": true, + "isCellVisible": true, + "isDerived": false, + "label": "task", + "computedValue": "{{Table1.sanitizedTableData.map((currentRow) => ( currentRow.task))}}" + }, + "status": { + "index": 2, + "width": 150, + "id": "status", + "horizontalAlignment": "LEFT", + "verticalAlignment": "CENTER", + "columnType": "text", + "textSize": "PARAGRAPH", + "enableFilter": true, + "enableSort": true, + "isVisible": true, + "isCellVisible": true, + "isDerived": false, + "label": "status", + "computedValue": "{{Table1.sanitizedTableData.map((currentRow) => ( currentRow.status))}}" + }, + "action": { + "index": 3, + "width": 150, + "id": "action", + "horizontalAlignment": "LEFT", + "verticalAlignment": "CENTER", + "columnType": "button", + "textSize": "PARAGRAPH", + "enableFilter": true, + "enableSort": true, + "isVisible": true, + "isCellVisible": true, + "isDisabled": false, + "isDerived": false, + "label": "action", + "onClick": "{{currentRow.step === '#1' ? showAlert('Done', 'success') : currentRow.step === '#2' ? navigateTo('https://docs.appsmith.com/core-concepts/connecting-to-data-sources/querying-a-database',undefined,'NEW_WINDOW') : navigateTo('https://docs.appsmith.com/core-concepts/displaying-data-read/display-data-tables',undefined,'NEW_WINDOW')}}", + "computedValue": "{{Table1.sanitizedTableData.map((currentRow) => ( currentRow.action))}}" + } + }, + "derivedColumns": { + }, + "tableData": [ + { + "step": "#1", + "task": "Drop a table", + "status": "✅", + "action": "" + }, + { + "step": "#2", + "task": "Create a query fetch_users with the Mock DB", + "status": "--", + "action": "" + }, + { + "step": "#3", + "task": "Bind the query using => fetch_users.data", + "status": "--", + "action": "" + } + ], + "columnSizeMap": { + "task": 245, + "step": 62, + "status": 75 + }, + "columnOrder": [ + "step", + "task", + "status", + "action" + ], + "isVisibleSearch": true, + "isVisibleFilters": true, + "isVisibleDownload": true, + "isVisiblePagination": true, + "isSortable": true, + "delimiter": ",", + "version": 3, + "type": "TABLE_WIDGET", + "hideCard": false, + "displayName": "Table", + "key": "y3v2mu6lds", + "iconSVG": "/static/media/icon.db8a9cbd.svg", + "widgetId": "tulofhk1fb", + "renderMode": "CANVAS", + "isLoading": false, + "parentColumnSpace": 16.921875, + "parentRowSpace": 10, + "leftColumn": 15, + "rightColumn": 49, + "topRow": 22, + "bottomRow": 50, + "parentId": "0" + } + ] + } +} \ No newline at end of file diff --git a/app/client/cypress/integration/Smoke_TestSuite/Application/PgAdmin_spec.js b/app/client/cypress/integration/Smoke_TestSuite/Application/PgAdmin_spec.js index b6a8b053a1..4bfd9f9b7c 100644 --- a/app/client/cypress/integration/Smoke_TestSuite/Application/PgAdmin_spec.js +++ b/app/client/cypress/integration/Smoke_TestSuite/Application/PgAdmin_spec.js @@ -165,53 +165,53 @@ describe("PgAdmin Clone App", function() { cy.get(appPage.dropdownChevronLeft).click(); }); - it("Add new table", function() { - const uuid = () => Cypress._.random(0, 1e6); - const id = uuid(); - const Table = `table${id}`; - // clicking on chevron to go back to the application page - cy.get(appPage.dropdownChevronLeft).click(); - // adding new table - cy.xpath(appPage.addNewtable).click(); - cy.xpath(appPage.addTablename) - .clear() - .type(Table); - cy.wait(2000); - // adding column to the table - cy.xpath(appPage.addColumn).click(); - cy.wait(2000); - cy.xpath(appPage.columnNamefield).should("be.visible"); - cy.xpath(appPage.datatypefield).should("be.visible"); - cy.xpath(appPage.addTablename).type("id"); - cy.xpath(appPage.textField).click(); - cy.xpath(appPage.selectDatatype).click(); - // switching on the Primary Key toggle - cy.get(widgetsPage.switchWidgetInactive) - .first() - .click(); - // switching on the Not Null toggle - cy.get(widgetsPage.switchWidgetInactive) - .last() - .click(); - cy.xpath(appPage.submitButton).click(); - cy.wait(2000); - cy.xpath(appPage.addColumn).should("be.visible"); - cy.xpath(appPage.submitButton).click({ force: true }); - cy.xpath(appPage.closeButton).click(); - }); + // it("Add new table", function() { + // const uuid = () => Cypress._.random(0, 1e6); + // const id = uuid(); + // const Table = `table${id}`; + // // clicking on chevron to go back to the application page + // cy.get(appPage.dropdownChevronLeft).click(); + // // adding new table + // cy.xpath(appPage.addNewtable).click(); + // cy.xpath(appPage.addTablename) + // .clear() + // .type(Table); + // cy.wait(2000); + // // adding column to the table + // cy.xpath(appPage.addColumn).click(); + // cy.wait(2000); + // cy.xpath(appPage.columnNamefield).should("be.visible"); + // cy.xpath(appPage.datatypefield).should("be.visible"); + // cy.xpath(appPage.addTablename).type("id"); + // cy.xpath(appPage.textField).click(); + // cy.xpath(appPage.selectDatatype).click(); + // // switching on the Primary Key toggle + // cy.get(widgetsPage.switchWidgetInactive) + // .first() + // .click(); + // // switching on the Not Null toggle + // cy.get(widgetsPage.switchWidgetInactive) + // .last() + // .click(); + // cy.xpath(appPage.submitButton).click(); + // cy.wait(2000); + // cy.xpath(appPage.addColumn).should("be.visible"); + // cy.xpath(appPage.submitButton).click({ force: true }); + // cy.xpath(appPage.closeButton).click(); + // }); - it("View and Delete table", function() { - cy.xpath(appPage.addNewtable).should("be.visible"); - // viewing the table's columns by clicking on view button - cy.xpath(appPage.viewButton) - .first() - .click({ force: true }); - cy.wait(2000); - // deleting the table through modal - cy.xpath(appPage.deleteButton) - .last() - .click({ force: true }); - cy.xpath(appPage.confirmButton).click(); - cy.xpath(appPage.closeButton).click(); - }); + // it("View and Delete table", function() { + // cy.xpath(appPage.addNewtable).should("be.visible"); + // // viewing the table's columns by clicking on view button + // cy.xpath(appPage.viewButton) + // .first() + // .click({ force: true }); + // cy.wait(2000); + // // deleting the table through modal + // cy.xpath(appPage.deleteButton) + // .last() + // .click({ force: true }); + // cy.xpath(appPage.confirmButton).click(); + // cy.xpath(appPage.closeButton).click(); + // }); }); diff --git a/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/Onboarding/FirstTimeUserOnboarding_spec.js b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/Onboarding/FirstTimeUserOnboarding_spec.js index 99b1c1d526..df363aedfb 100644 --- a/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/Onboarding/FirstTimeUserOnboarding_spec.js +++ b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/Onboarding/FirstTimeUserOnboarding_spec.js @@ -161,13 +161,14 @@ describe("FirstTimeUserOnboarding", function() { it("onboarding flow - should check directly opening widget pane", function() { cy.get(OnboardingLocator.introModalBuild).click(); - cy.get(OnboardingLocator.taskDatasourceBtn).should("be.visible"); cy.get(OnboardingLocator.widgetPaneTrigger).click(); cy.get(OnboardingLocator.widgetSidebar).should("be.visible"); cy.get(OnboardingLocator.dropTarget).should("be.visible"); cy.dragAndDropToCanvas("textwidget", { x: 400, y: 400 }); - cy.get(OnboardingLocator.textWidgetName).should("be.visible"); + cy.get(OnboardingLocator.textWidgetName) + .should("be.visible") + .wait(800); cy.reload(); cy.wait("@getUser"); cy.get(OnboardingLocator.statusbar).should("be.visible"); diff --git a/app/client/cypress/integration/Smoke_TestSuite/ServerSideTests/QueryPane/AddWidget_spec.js b/app/client/cypress/integration/Smoke_TestSuite/ServerSideTests/QueryPane/AddWidget_spec.js index 2a554c96b0..286088a1ad 100644 --- a/app/client/cypress/integration/Smoke_TestSuite/ServerSideTests/QueryPane/AddWidget_spec.js +++ b/app/client/cypress/integration/Smoke_TestSuite/ServerSideTests/QueryPane/AddWidget_spec.js @@ -3,7 +3,7 @@ const queryEditor = require("../../../../locators/QueryEditor.json"); let datasourceName; -describe("Add widget", function() { +describe("Add widget - Postgress DataSource", function() { beforeEach(() => { cy.startRoutesForDatasource(); cy.createPostgresDatasource(); @@ -12,7 +12,7 @@ describe("Add widget", function() { }); }); - it("Add widget", () => { + it("1. Verify 'Add to widget [Widget Suggestion]' functionality - Postgress", () => { cy.NavigateToQueryEditor(); cy.contains(".t--datasource-name", datasourceName) .find(queryLocators.createQuery) diff --git a/app/client/cypress/integration/Smoke_TestSuite/ServerSideTests/QueryPane/MongoDatasource_spec.js b/app/client/cypress/integration/Smoke_TestSuite/ServerSideTests/QueryPane/Mongo_Spec.js similarity index 55% rename from app/client/cypress/integration/Smoke_TestSuite/ServerSideTests/QueryPane/MongoDatasource_spec.js rename to app/client/cypress/integration/Smoke_TestSuite/ServerSideTests/QueryPane/Mongo_Spec.js index 6a22acc142..e813f868f5 100644 --- a/app/client/cypress/integration/Smoke_TestSuite/ServerSideTests/QueryPane/MongoDatasource_spec.js +++ b/app/client/cypress/integration/Smoke_TestSuite/ServerSideTests/QueryPane/Mongo_Spec.js @@ -1,7 +1,6 @@ const queryLocators = require("../../../../locators/QueryEditor.json"); const generatePage = require("../../../../locators/GeneratePage.json"); const datasource = require("../../../../locators/DatasourcesEditor.json"); -const queryEditor = require("../../../../locators/QueryEditor.json"); let datasourceName; @@ -22,7 +21,7 @@ describe("Create a query with a mongo datasource, run, save and then delete the }); }); - it("2. Validate Raw query command, run, save and then delete the query", function() { + it("2. Validate Raw query command, run and then delete the query", function() { cy.NavigateToActiveDSQueryPane(datasourceName); // cy.get("@getPluginForm").should( @@ -31,52 +30,46 @@ describe("Create a query with a mongo datasource, run, save and then delete the // 200, // ); - cy.xpath('//div[contains(text(),"Find Document(s)")]').click({ - force: true, - }); - cy.xpath('//div[contains(text(),"Raw")]').click({ force: true }); - cy.get(queryLocators.templateMenu).click(); - cy.get(".CodeMirror textarea") - .first() - .focus() - .type(`{"find": "listingsAndReviews","limit": 10}`, { - parseSpecialCharSequences: false, - }); + cy.validateNSelectDropdown("Commands", "Find Document(s)", "Raw"); + + cy.get(queryLocators.templateMenu).click(); + cy.typeValueNValidate('{"find": "listingsAndReviews","limit": 10}'); + + // cy.get(".CodeMirror textarea") + // .first() + // .focus() + // .type(`{"find": "listingsAndReviews","limit": 10}`, { + // parseSpecialCharSequences: false, + // }); + // cy.EvaluateCurrentValue(`{"find": "listingsAndReviews","limit": 10}`); - cy.EvaluateCurrentValue(`{"find": "listingsAndReviews","limit": 10}`); cy.runAndDeleteQuery(); }); it("3. Validate Find documents command & Run and then delete the query", function() { - //datasourceName = 'Mongo CRUD ds 09e54713' cy.NavigateToActiveDSQueryPane(datasourceName); //cy.xpath(queryLocators.findDocs).should("exist"); //Verifying update is success or below line - cy.expect(queryLocators.findDocs).to.exist; + //cy.expect(queryLocators.findDocs).to.exist; - cy.xpath(queryLocators.collectionField).type("listingsAndReviews"); - cy.EvaluateCurrentValue("listingsAndReviews"); + cy.validateNSelectDropdown("Commands", "Find Document(s)"); + + cy.typeValueNValidate("listingsAndReviews", "Collection"); cy.runQuery(); //exeute actions - 200 response is verified in this method cy.xpath(queryLocators.countText).should("have.text", "10 Records"); - cy.xpath(queryLocators.queryField).type(`{{}beds : {{}$lte: 2}}`); - cy.EvaluateCurrentValue("{beds : {$lte: 2}}"); + cy.typeValueNValidate("{beds : {$lte: 2}}", "Query"); cy.runQuery(); //exeute actions - 200 response is verified in this method cy.xpath(queryLocators.countText).should("have.text", "10 Records"); - cy.xpath(queryLocators.sortField).type("{{}number_of_reviews: -1}"); //sort descending - cy.EvaluateCurrentValue("{number_of_reviews: -1}"); + cy.typeValueNValidate("{number_of_reviews: -1}", "Sort"); //sort descending cy.runQuery(); //exeute actions - 200 response is verified in this method cy.xpath(queryLocators.countText).should("have.text", "10 Records"); - cy.xpath(queryLocators.projectionField).type( - "{{}house_rules: 1, description:1}", - ); //Projection field - cy.EvaluateCurrentValue("{house_rules: 1, description:1}"); + cy.typeValueNValidate("{house_rules: 1, description:1}", "Projection"); //Projection field cy.runQuery(); //exeute actions - 200 response is verified in this method - cy.xpath(queryLocators.limitField).type("5"); //Projection field - cy.EvaluateCurrentValue("5"); + cy.typeValueNValidate("5", "Limit"); //Limit field cy.onlyQueryRun(); cy.wait("@postExecute").then(({ response }) => { expect(response.body.data.body[0].house_rules).to.contains( @@ -84,10 +77,9 @@ describe("Create a query with a mongo datasource, run, save and then delete the "Response is not as expected for Aggregate commmand", ); }); - cy.xpath(queryLocators.countText).should("have.text", "5 Records"); - cy.xpath(queryLocators.skipField).type("2"); //Skip field - cy.EvaluateCurrentValue("2"); + + cy.typeValueNValidate("2", "Skip"); //Skip field cy.onlyQueryRun(); cy.wait("@postExecute").then(({ response }) => { @@ -103,18 +95,10 @@ describe("Create a query with a mongo datasource, run, save and then delete the it("4. Validate Count command & Run and then delete the query", function() { cy.NavigateToActiveDSQueryPane(datasourceName); - - cy.xpath('//div[contains(text(),"Find Document(s)")]').click({ - force: true, - }); - cy.xpath('//div[contains(text(),"Count")]').click({ force: true }); - - cy.xpath(queryLocators.collectionField).type("listingsAndReviews"); - cy.EvaluateCurrentValue("listingsAndReviews"); + cy.validateNSelectDropdown("Commands", "Find Document(s)", "Count"); + cy.typeValueNValidate("listingsAndReviews", "Collection"); cy.runQuery(); - - cy.xpath(queryLocators.queryField).type(`{{}beds : {{}$lte: 2}}`); - cy.EvaluateCurrentValue("{beds : {$lte: 2}}"); + cy.typeValueNValidate("{beds : {$lte: 2}}", "Query"); cy.runQuery(); //exeute actions - 200 response is verified in this method cy.deleteQueryUsingContext(); @@ -123,21 +107,10 @@ describe("Create a query with a mongo datasource, run, save and then delete the it("5. Validate Distinct command & Run and then delete the query", function() { cy.NavigateToActiveDSQueryPane(datasourceName); - cy.xpath('//div[contains(text(),"Find Document(s)")]').click({ - force: true, - }); - cy.xpath('//div[contains(text(),"Distinct")]').click({ force: true }); - - cy.xpath(queryLocators.collectionField).type("listingsAndReviews"); - cy.EvaluateCurrentValue("listingsAndReviews"); - - cy.xpath(queryLocators.queryField).type(`{{}beds : {{}$lte: 2}}`); - cy.EvaluateCurrentValue("{beds : {$lte: 2}}"); - - cy.xpath(queryLocators.keyField).type(`property_type`); - cy.EvaluateCurrentValue("property_type"); - //cy.runQuery(); //exeute actions - 200 response is verified in this method - + cy.validateNSelectDropdown("Commands", "Find Document(s)", "Distinct"); + cy.typeValueNValidate("listingsAndReviews", "Collection"); + cy.typeValueNValidate("{beds : {$lte: 2}}", "Query"); + cy.typeValueNValidate("property_type", "Key"); cy.onlyQueryRun(); cy.wait("@postExecute").then(({ request, response }) => { expect(response.body.data.body.values[0]).to.eq( @@ -151,22 +124,12 @@ describe("Create a query with a mongo datasource, run, save and then delete the it("6. Validate Aggregate command & Run and then delete the query", function() { cy.NavigateToActiveDSQueryPane(datasourceName); - - cy.xpath('//div[contains(text(),"Find Document(s)")]').click({ - force: true, - }); - cy.xpath('//div[contains(text(),"Aggregate")]').click({ force: true }); - - cy.xpath(queryLocators.collectionField).type("listingsAndReviews"); - cy.EvaluateCurrentValue("listingsAndReviews"); - - cy.xpath(queryLocators.arrayOfPipelinesField).type( - `[{{} $project: {{} count: {{} $size:"$amenities" }}}]`, + cy.validateNSelectDropdown("Commands", "Find Document(s)", "Aggregate"); + cy.typeValueNValidate("listingsAndReviews", "Collection"); + cy.typeValueNValidate( + '[{ $project: { count: { $size:"$amenities" }}}]', + "Array of Pipelines", ); - cy.EvaluateCurrentValue('[{ $project: { count: { $size:"$amenities" }}}]'); - - //cy.runQuery(); //exeute actions - 200 response is verified in this method - cy.onlyQueryRun(); cy.wait("@postExecute").then(({ request, response }) => { // cy.log(request.method + ": is req.method") @@ -224,13 +187,86 @@ describe("Create a query with a mongo datasource, run, save and then delete the 409, ); - cy.xpath(generatePage.mongonewPageEntityMenu) - .first() - .click({ force: true }); - cy.xpath(generatePage.deleteMenuItem).click(); + cy.deleteEntitybyName("ListingsAndReviews"); }); - it("9. Delete the datasource after NewPage deletion is success", () => { + it("9. Bug 7399: Validate Form based & Raw command based templates", function() { + let id; + cy.NavigateToActiveDSQueryPane(datasourceName); + cy.validateNSelectDropdown("Commands", "Find Document(s)"); + cy.xpath(queryLocators.mongoFormFind).click({ force: true }); + cy.xpath("//div[text()='Find']") + .click() + .wait(100); //wait for Find form to open + cy.EvaluatFieldValue("Collection").then((colData) => { + colData = colData.replace("{", "").replace("}", ""); + cy.log("Collection value is fieldData: " + colData); + cy.wrap(colData).as("colData"); + }); + cy.EvaluatFieldValue("Query").then((queryData) => { + queryData = queryData.replace("{", "").replace("}", ""); + id = queryData; + cy.log("Query value is : " + queryData); + cy.wrap(queryData).as("queryData"); + }); + cy.EvaluatFieldValue("Sort").then((sortData) => { + sortData = sortData.replace("{", "").replace("}", ""); + cy.log("Sort value is : " + sortData); + cy.wrap(sortData).as("sortData"); + }); + cy.EvaluatFieldValue("Limit").then((limitData) => { + limitData = limitData.replace("{", "").replace("}", ""); + cy.log("Limit value is : " + limitData); + cy.wrap(limitData).as("limitData"); + }); + + cy.onlyQueryRun(); + cy.wait("@postExecute").then(({ response }) => { + expect(response.body.data.isExecutionSuccess).to.eq(true); + expect(response.body.data.body[0]._id).to.eq( + id + .split(":")[1] + .trim() + .replace(/['"]+/g, ""), + ); + }); + + cy.validateNSelectDropdown("Commands", "Find Document(s)", "Raw"); + cy.EvaluatFieldValue().then((rawData) => { + rawData = rawData.replace("{", "").replace("}", ""); + cy.log("rawData value is : " + rawData); + cy.wrap(rawData).as("rawData"); + }); + + cy.all( + cy.get("@colData"), + cy.get("@queryData"), + cy.get("@sortData"), + cy.get("@limitData"), + cy.get("@rawData"), + ).then((values) => { + expect(values[4].trim()).to.contain(values[0].trim()); + expect(values[4].trim()).to.contain(values[1].trim()); + expect(values[4].trim()).to.contain(values[2].trim()); + expect(values[4].trim()).to.contain(values[3].trim()); + }); + + cy.onlyQueryRun(); + cy.wait("@postExecute").then(({ response }) => { + expect(response.body.data.isExecutionSuccess).to.eq(true); + expect(response.body.data.body[0]._id).to.eq( + id + .split(":")[1] + .trim() + .replace(/['"]+/g, ""), + ); + }); + + cy.deleteQueryUsingContext(); + cy.deleteEntitybyName("Query1"); + }); + + it("10. Delete the datasource after NewPage deletion is success", () => { cy.NavigateToQueryEditor(); cy.NavigateToActiveTab(); cy.contains(".t--datasource-name", datasourceName).click(); diff --git a/app/client/cypress/integration/Smoke_TestSuite/ServerSideTests/QueryPane/PostgresCRUDOps_spec.js b/app/client/cypress/integration/Smoke_TestSuite/ServerSideTests/QueryPane/Postgres_Spec.js similarity index 82% rename from app/client/cypress/integration/Smoke_TestSuite/ServerSideTests/QueryPane/PostgresCRUDOps_spec.js rename to app/client/cypress/integration/Smoke_TestSuite/ServerSideTests/QueryPane/Postgres_Spec.js index b212b7b42a..c51aa941f6 100644 --- a/app/client/cypress/integration/Smoke_TestSuite/ServerSideTests/QueryPane/PostgresCRUDOps_spec.js +++ b/app/client/cypress/integration/Smoke_TestSuite/ServerSideTests/QueryPane/Postgres_Spec.js @@ -30,19 +30,13 @@ describe("Validate CRUD queries for Postgres along with UI flow verifications", it("2. Create & runs existing table data and deletes the query", () => { cy.NavigateToActiveDSQueryPane(datasourceName); - cy.get(queryLocators.templateMenu).click(); - cy.get(".CodeMirror textarea") - .first() - .focus() - .type("select * from users limit 10"); - - cy.EvaluateCurrentValue("select * from users limit 10"); + cy.get(queryLocators.templateMenu).click({ force: true }); + cy.typeValueNValidate("select * from users limit 10"); cy.runAndDeleteQuery(); }); it("3. Create new CRUD Table and populate", () => { cy.NavigateToActiveDSQueryPane(datasourceName); - cy.get(queryLocators.templateMenu).click(); let tableCreateQuery = `CREATE TABLE public.users_crud ( id integer NOT NULL, @@ -53,7 +47,7 @@ describe("Validate CRUD queries for Postgres along with UI flow verifications", address text, role text); - insert into public.users_crud (id, name, status, gender, email, address, role) values + insert into public.users_crud (id, name, status, gender, email, address, role) values (1, 'CRUD User1', 'PENDING', 'Male', 'cruduser1@ihg.com', '19624 Scofield Way', 'User'), (2, 'CRUD User2', 'IN PROGRESS', 'Male','cruduser2@ihg.com', '19624 Scofield Way', 'Editor'), (3, 'CRUD User3', 'APPROVED', 'Female','cruduser3@ihg.com', '19624 Scofield Way', 'Admin'), @@ -85,20 +79,25 @@ describe("Validate CRUD queries for Postgres along with UI flow verifications", (29, 'CRUD User29', 'IN PROGRESS', 'Male','cruduser29@ihg.com', '19624 Scofield Way', 'Editor'), (30, 'CRUD User30', 'APPROVED', 'Female','cruduser30@ihg.com', '19624 Scofield Way', 'Admin');`; + cy.get(queryLocators.templateMenu).click({ force: true }); + //cy.typeValueNValidate(tableCreateQuery);//Since type method is slow for such big text - using paste! + cy.get(".CodeMirror textarea").paste(tableCreateQuery); cy.get(".CodeMirror textarea").focus(); cy.EvaluateCurrentValue(tableCreateQuery); + cy.runAndDeleteQuery(); //exeute actions - 200 response is verified in this method }); it("4. Validate Select record from Postgress datasource", () => { let selectQuery = "select * from public.users_crud"; cy.NavigateToActiveDSQueryPane(datasourceName); - cy.xpath(queryLocators.querySelect).click(); - cy.get(queryLocators.codeTextArea).type("{cmd+a}{del}"); - cy.get(queryLocators.codeTextArea).paste(selectQuery); + cy.get(queryLocators.templateMenu).click({ force: true }); + cy.typeValueNValidate(selectQuery); + + // cy.xpath(queryLocators.codeTextArea).paste(selectQuery); + //cy.EvaluateCurrentValue(selectQuery); - cy.EvaluateCurrentValue(selectQuery); cy.runAndDeleteQuery(); //exeute actions - 200 response is verified in this method }); @@ -106,12 +105,8 @@ describe("Validate CRUD queries for Postgres along with UI flow verifications", let insertQuery = "INSERT INTO public.users_crud (id, name, gender, email) VALUES (31, 'CRUD User11','Male','cruduser31@ihg.com');"; cy.NavigateToActiveDSQueryPane(datasourceName); - cy.xpath(queryLocators.queryCreate).click(); - cy.get(queryLocators.codeTextArea).type("{cmd+a}{del}"); - //.type("{selectall}{del}"); - - cy.get(queryLocators.codeTextArea).paste(insertQuery); - cy.EvaluateCurrentValue(insertQuery); + cy.get(queryLocators.templateMenu).click({ force: true }); + cy.typeValueNValidate(insertQuery); cy.runAndDeleteQuery(); }); @@ -119,22 +114,16 @@ describe("Validate CRUD queries for Postgres along with UI flow verifications", let updateQuery = "UPDATE public.users_crud SET status = 'PENDING', role = 'Viewer' WHERE id = 31;"; cy.NavigateToActiveDSQueryPane(datasourceName); - cy.xpath(queryLocators.queryUpdate).click(); - cy.get(queryLocators.codeTextArea).type("{cmd+a}{del}"); - cy.get(queryLocators.codeTextArea).paste(updateQuery); - - cy.EvaluateCurrentValue(updateQuery); + cy.get(queryLocators.templateMenu).click({ force: true }); + cy.typeValueNValidate(updateQuery); cy.runAndDeleteQuery(); }); it("7. Validate Delete record from Postgress datasource", () => { let deleteQuery = "DELETE FROM public.users_crud WHERE id = 31;"; cy.NavigateToActiveDSQueryPane(datasourceName); - cy.xpath(queryLocators.queryDelete).click(); - cy.get(queryLocators.codeTextArea).type("{cmd+a}{del}"); - cy.get(queryLocators.codeTextArea).paste(deleteQuery); - - cy.EvaluateCurrentValue(deleteQuery); + cy.get(queryLocators.templateMenu).click({ force: true }); + cy.typeValueNValidate(deleteQuery); cy.runAndDeleteQuery(); }); @@ -167,8 +156,12 @@ describe("Validate CRUD queries for Postgres along with UI flow verifications", cy.ClickGotIt(); //Verifying Update from UI - cy.xpath(generatePage.selectRowinTable).click(); + cy.xpath(generatePage.selectRowinTable) + .scrollIntoView() + .should("be.visible") + .click({ force: true }); cy.xpath(generatePage.currentStatusField) + .scrollIntoView() .clear() .click() .type("APPROVED"); @@ -185,7 +178,10 @@ describe("Validate CRUD queries for Postgres along with UI flow verifications", //.should("have.nested.property", "response.body.data.request.requestParams.Query.value",); - cy.xpath(generatePage.selectRowinTable).click(); + cy.xpath(generatePage.selectRowinTable) + .scrollIntoView() + .should("be.visible") + .click({ force: true }); cy.xpath(generatePage.currentStatusField).should("have.value", "APPROVED"); //Verifying update is success //verifying Insert from UI @@ -197,14 +193,19 @@ describe("Validate CRUD queries for Postgres along with UI flow verifications", cy.xpath(generatePage.emailField) .type("curduser31@ihg.com") .wait(1000); //Waiting for Submit button to get enabled - cy.get(generatePage.submitBtn).click(); + cy.get(generatePage.submitBtn) + .first() + .click(); cy.xpath(generatePage.sortByDropdown).click(); //Sorting by descending to verify newly added record - also sorting is verified cy.xpath(generatePage.descending).click(); cy.xpath(generatePage.currentNameField).should("have.value", "CRUD User31"); //Verifying Addition is success //Verifying Delete from UI - cy.xpath(generatePage.deleteofSelectedRow).click(); + cy.xpath(generatePage.deleteofSelectedRow) + .scrollIntoView() + .should("be.visible") + .click({ force: true }); cy.get(generatePage.confirmBtn) .click() .wait(2000); //Wait for update call to be success @@ -215,7 +216,9 @@ describe("Validate CRUD queries for Postgres along with UI flow verifications", 200, ); - cy.xpath(generatePage.currentNameField).should("have.value", "CRUD User30"); //Verifying Deletion of id # 31 is success + cy.xpath(generatePage.currentNameField) + .scrollIntoView() + .should("have.value", "CRUD User30"); //Verifying Deletion of id # 31 is success }); it("9. Validate Deletion of the Newly Created Page", () => { @@ -229,30 +232,22 @@ describe("Validate CRUD queries for Postgres along with UI flow verifications", "response.body.responseMeta.status", 409, ); - - cy.xpath(generatePage.postgressnewPageEntityMenu) - .first() - .click({ force: true }); - cy.xpath(generatePage.deleteMenuItem).click(); + cy.deleteEntitybyName("Public.users_crud"); }); it("10. Validate Drop of the Newly Created Table from Postgress datasource", () => { let deleteTblQuery = "DROP TABLE public.users_crud;"; cy.NavigateToActiveDSQueryPane(datasourceName); - cy.xpath(queryLocators.queryDelete).click(); - cy.get(queryLocators.codeTextArea).type("{cmd+a}{del}"); - - cy.get(queryLocators.codeTextArea).paste(deleteTblQuery); - - cy.EvaluateCurrentValue(deleteTblQuery); + cy.get(queryLocators.templateMenu).click({ force: true }); + cy.typeValueNValidate(deleteTblQuery); cy.runAndDeleteQuery(); }); it("11. Deletes the datasource", () => { cy.NavigateToQueryEditor(); cy.NavigateToActiveTab(); - cy.contains(".t--datasource-name", datasourceName).click(); - cy.get(".t--delete-datasource").click(); + cy.contains(".t--datasource-name", datasourceName).click({ force: true }); + cy.get(".t--delete-datasource").click({ force: true }); cy.wait("@deleteDatasource").should( "have.nested.property", "response.body.responseMeta.status", diff --git a/app/client/cypress/integration/Smoke_TestSuite/ServerSideTests/QueryPane/S3_spec.js b/app/client/cypress/integration/Smoke_TestSuite/ServerSideTests/QueryPane/S3_spec.js new file mode 100644 index 0000000000..f7b54887b0 --- /dev/null +++ b/app/client/cypress/integration/Smoke_TestSuite/ServerSideTests/QueryPane/S3_spec.js @@ -0,0 +1,505 @@ +const queryLocators = require("../../../../locators/QueryEditor.json"); +const datasource = require("../../../../locators/DatasourcesEditor.json"); +const generatePage = require("../../../../locators/GeneratePage.json"); +const dsl = require("../../../../fixtures/snippingTableDsl.json"); + +let datasourceName; + +describe("Validate CRUD queries for Amazon S3 along with UI flow verifications", function() { + beforeEach(() => { + cy.startRoutesForDatasource(); + }); + + it("1. Creates a new Amazon S3 datasource", function() { + cy.NavigateToDatasourceEditor(); + cy.get(datasource.AmazonS3) + .click({ force: true }) + .wait(1000); + + cy.generateUUID().then((uid) => { + datasourceName = `Amazon S3 CRUD ds ${uid}`; + cy.renameDatasource(datasourceName); + cy.wrap(datasourceName).as("dSName"); + }); + + cy.fillAmazonS3DatasourceForm(); + cy.testSaveDatasource(); + }); + + it("2. Validate List Files in bucket (all existing files) command, run and then delete the query", () => { + cy.NavigateToActiveDSQueryPane(datasourceName); + cy.validateNSelectDropdown("Commands", "List files in bucket"); + + cy.onlyQueryRun(); + cy.wait("@postExecute").should(({ response }) => { + expect(response.body.data.isExecutionSuccess).to.eq(false); + expect(response.body.data.body).to.contains( + "Mandatory parameter 'Bucket Name' is missing.", + ); + }); + cy.typeValueNValidate("AutoTest", "Bucket Name"); + + cy.onlyQueryRun(); + cy.wait("@postExecute").then(({ response }) => { + expect(response.body.data.isExecutionSuccess).to.eq(false); + expect(response.body.data.body.split("(")[0].trim()).to.be.oneOf([ + "The specified bucket does not exist", + "The specified bucket is not valid.", + ]); + }); + + cy.typeValueNValidate("assets-test.appsmith.com", "Bucket Name"); + cy.runAndDeleteQuery(); //exeute actions - 200 response is verified in this method + }); + + it("3. Validate Create a new file in bucket command, Verify possible error msgs, run & delete the query", () => { + cy.NavigateToActiveDSQueryPane(datasourceName); + cy.validateNSelectDropdown( + "Commands", + "List files in bucket", + "Create a new file", + ); + + cy.onlyQueryRun(); + cy.wait("@postExecute").should(({ response }) => { + expect(response.body.data.isExecutionSuccess).to.eq(false); + expect(response.body.data.body).to.contains( + "Mandatory parameter 'Bucket Name' is missing.", + ); + }); + cy.typeValueNValidate("AutoTest", "Bucket Name"); + + cy.onlyQueryRun(); + cy.wait("@postExecute").then(({ response }) => { + expect(response.body.data.isExecutionSuccess).to.eq(false); + expect(response.body.data.body).to.contains( + "Required parameter 'File Path' is missing.", + ); + }); + cy.typeValueNValidate("AutoFile", "File Path"); + + cy.onlyQueryRun(); + cy.wait("@postExecute").then(({ response }) => { + expect(response.body.data.isExecutionSuccess).to.eq(false); + expect(response.body.data.body).to.eq( + "Unable to parse content. Expected to receive an object with `data` and `type`", + ); + }); + + cy.typeValueNValidate("Hi", "Content"); + cy.onlyQueryRun(); + cy.wait("@postExecute").then(({ response }) => { + expect(response.body.data.isExecutionSuccess).to.eq(false); + expect(response.body.data.body).to.eq( + "Unable to parse content. Expected to receive an object with `data` and `type`", + ); + }); + + cy.typeValueNValidate( + '{"data": "Hi, this is Automation script adding File!"}', + "Content", + ); + + cy.onlyQueryRun(); + cy.wait("@postExecute").then(({ response }) => { + expect(response.body.data.isExecutionSuccess).to.eq(false); + expect(response.body.data.body).to.contains( + "File content is not base64 encoded.", + ); + }); + cy.validateNSelectDropdown("File Data Type", "Base64", "Text / Binary"); + + cy.onlyQueryRun(); + cy.wait("@postExecute").then(({ response }) => { + expect(response.body.data.isExecutionSuccess).to.eq(false); + //expect(['The specified bucket does not exist', 'The specified bucket is not valid.']).to.include(response.body.data.body) + expect(response.body.data.body.split("(")[0].trim()).to.be.oneOf([ + "The specified bucket does not exist", + "The specified bucket is not valid.", + ]); + }); + + cy.typeValueNValidate("assets-test.appsmith.com", "Bucket Name"); + + cy.onlyQueryRun(); + cy.wait("@postExecute").then(({ response }) => { + expect(response.body.data.isExecutionSuccess).to.eq(true); + }); + + cy.deleteQueryUsingContext(); + }); + + it("4. Validate Read file command, Verify possible error msgs, run & delete the query", () => { + cy.NavigateToActiveDSQueryPane(datasourceName); + cy.validateNSelectDropdown("Commands", "List files in bucket", "Read file"); + + cy.onlyQueryRun(); + cy.wait("@postExecute").should(({ response }) => { + expect(response.body.data.isExecutionSuccess).to.eq(false); + expect(response.body.data.body).to.contains( + "Mandatory parameter 'Bucket Name' is missing.", + ); + }); + cy.typeValueNValidate("AutoTest", "Bucket Name"); + + cy.onlyQueryRun(); + cy.wait("@postExecute").then(({ response }) => { + expect(response.body.data.isExecutionSuccess).to.eq(false); + expect(response.body.data.body).to.contains( + "Required parameter 'File Path' is missing.", + ); + }); + cy.typeValueNValidate("Auto", "File Path"); + + cy.onlyQueryRun(); + cy.wait("@postExecute").then(({ response }) => { + expect(response.body.data.isExecutionSuccess).to.eq(false); + expect(response.body.data.body.split("(")[0].trim()).to.be.oneOf([ + "The specified bucket does not exist", + "The specified bucket is not valid.", + ]); + }); + + cy.typeValueNValidate("assets-test.appsmith.com", "Bucket Name"); + + cy.onlyQueryRun(); + cy.wait("@postExecute").then(({ response }) => { + expect(response.body.data.isExecutionSuccess).to.eq(false); + expect(response.body.data.body).to.contain( + "The specified key does not exist.", + ); + }); + + cy.typeValueNValidate("Autofile", "File Path"); + + cy.onlyQueryRun(); + cy.wait("@postExecute").then(({ response }) => { + expect(response.body.data.isExecutionSuccess).to.eq(false); + expect(response.body.data.body).to.contain( + "The specified key does not exist.", + ); + }); + + cy.typeValueNValidate("AutoFile", "File Path"); + cy.validateNSelectDropdown("File Data Type", "Base64", "Text / Binary"); + + cy.onlyQueryRun(); + cy.wait("@postExecute").then(({ response }) => { + expect(response.body.data.isExecutionSuccess).to.eq(true); + expect(response.body.data.body.fileData).to.not.eq( + "Hi, this is Automation script adding File!", + ); + }); + + cy.validateNSelectDropdown("Base64 Encode File - Yes/No", "Yes", "No"); + cy.onlyQueryRun(); + cy.wait("@postExecute").then(({ response }) => { + expect(response.body.data.isExecutionSuccess).to.eq(true); + expect(response.body.data.body.fileData).to.eq( + "Hi, this is Automation script adding File!", + ); + }); + + cy.deleteQueryUsingContext(); + }); + + it("5. Validate List Files in bucket command for new file, Verify possible error msgs, run & delete the query", () => { + cy.NavigateToActiveDSQueryPane(datasourceName); + cy.validateNSelectDropdown("Commands", "List files in bucket"); + + cy.onlyQueryRun(); + cy.wait("@postExecute").should(({ response }) => { + expect(response.body.data.isExecutionSuccess).to.eq(false); + expect(response.body.data.body).to.contains( + "Mandatory parameter 'Bucket Name' is missing.", + ); + }); + cy.typeValueNValidate("assets-test.appsmith.com", "Bucket Name"); + + cy.typeValueNValidate("Auto", "Prefix"); + cy.onlyQueryRun(); + cy.wait("@postExecute").then(({ response }) => { + expect(response.body.data.isExecutionSuccess).to.eq(true); + expect(response.body.data.body[0].fileName).to.contains("Auto"); + expect(response.body.data.body[0].url).to.exist; + }); + + cy.typeValueNValidate("AutoFile", "Prefix"); + cy.onlyQueryRun(); + cy.wait("@postExecute").then(({ response }) => { + expect(response.body.data.isExecutionSuccess).to.eq(true); + expect(response.body.data.body[0].fileName).to.contains("Auto"); + expect(response.body.data.body[0].url).to.exist; + expect(response.body.data.body[0].signedUrl).not.to.exist; + }); + + cy.validateNSelectDropdown("Generate Signed URL", "No", "Yes"); + cy.onlyQueryRun(); + cy.wait("@postExecute").then(({ response }) => { + expect(response.body.data.isExecutionSuccess).to.eq(true); + expect(response.body.data.body[0].fileName).to.contains("Auto"); + expect(response.body.data.body[0].signedUrl).to.exist; + expect(response.body.data.body[0].url).to.exist; + }); + + cy.validateNSelectDropdown("Generate Un-signed URL", "Yes", "No"); + cy.onlyQueryRun(); + cy.wait("@postExecute").then(({ response }) => { + expect(response.body.data.isExecutionSuccess).to.eq(true); + expect(response.body.data.body[0].fileName).to.contains("Auto"); + expect(response.body.data.body[0].signedUrl).to.exist; + expect(response.body.data.body[0].url).to.not.exist; + }); + + cy.deleteQueryUsingContext(); + }); + + it("6. Validate Delete file command for new file, Verify possible error msgs, run & delete the query", () => { + cy.NavigateToActiveDSQueryPane(datasourceName); + cy.validateNSelectDropdown( + "Commands", + "List files in bucket", + "Delete file", + ); + + cy.onlyQueryRun(); + cy.wait("@postExecute").should(({ response }) => { + expect(response.body.data.isExecutionSuccess).to.eq(false); + expect(response.body.data.body).to.contains( + "Mandatory parameter 'Bucket Name' is missing.", + ); + }); + cy.typeValueNValidate("AutoTest", "Bucket Name"); + + cy.onlyQueryRun(); + cy.wait("@postExecute").then(({ response }) => { + expect(response.body.data.isExecutionSuccess).to.eq(false); + expect(response.body.data.body).to.contains( + "Required parameter 'File Path' is missing.", + ); + }); + cy.typeValueNValidate("Auto", "File Path"); + + cy.onlyQueryRun(); + cy.wait("@postExecute").then(({ response }) => { + expect(response.body.data.isExecutionSuccess).to.eq(false); + expect(response.body.data.body.split("(")[0].trim()).to.be.oneOf([ + "The specified bucket does not exist", + "The specified bucket is not valid.", + ]); + }); + + cy.typeValueNValidate("assets-test.appsmith.com", "Bucket Name"); + cy.typeValueNValidate("AutoFile", "File Path"); + + cy.onlyQueryRun(); + cy.wait("@postExecute").then(({ response }) => { + expect(response.body.data.isExecutionSuccess).to.eq(true); + expect(response.body.data.body.status).to.eq("File deleted successfully"); + }); + + cy.deleteQueryUsingContext(); + }); + + it("7. Validate List Files in bucket command after new file is deleted, Verify possible error msgs, run & delete the query", () => { + cy.NavigateToActiveDSQueryPane(datasourceName); + cy.validateNSelectDropdown("Commands", "List files in bucket"); + cy.typeValueNValidate("assets-test.appsmith.com", "Bucket Name"); + cy.typeValueNValidate("Auto", "Prefix"); + cy.onlyQueryRun(); + cy.wait("@postExecute").then(({ response }) => { + expect(response.body.data.isExecutionSuccess).to.eq(true); + expect(response.body.data.body.length).to.eq(0); //checking that body is empty array + }); + + cy.deleteQueryUsingContext(); + }); + + it("8. Validate Create a new file in bucket for UI Operations, run & delete the query", () => { + cy.NavigateToActiveDSQueryPane(datasourceName); + cy.validateNSelectDropdown( + "Commands", + "List files in bucket", + "Create a new file", + ); + cy.typeValueNValidate("assets-test.appsmith.com", "Bucket Name"); + cy.typeValueNValidate("CRUDNewPageFile", "File Path"); + cy.validateNSelectDropdown("File Data Type", "Base64", "Text / Binary"); + cy.typeValueNValidate( + '{"data": "Hi, this is Automation script adding file for S3 CRUD New Page validation!"}', + "Content", + ); + + cy.get(queryLocators.settings).click(); + cy.xpath(queryLocators.queryTimeout) + .clear() + .type(30000); + cy.get(queryLocators.query).click(); + + cy.onlyQueryRun(); + cy.wait("@postExecute").then(({ response }) => { + expect(response.body.data.isExecutionSuccess).to.eq(true); + }); + cy.deleteQueryUsingContext(); + }); + + it("9. Verify Search, Delete operations from NewPage UI created in S3 ds", function() { + // cy.wrap(Cypress.automation('remote:debugger:protocol', { + // command: 'Browser.grantPermissions', + // params: { + // permissions: ['clipboardReadWrite', 'clipboardSanitizedWrite'], + // // make the permission tighter by allowing the current origin only + // // like "http://localhost:56978" + // origin: window.location.origin, + // }, + // })) + + cy.NavigateToDSGeneratePage(datasourceName); + + //Verifying List of Files from UI + cy.get(generatePage.selectTableDropdown).click(); + cy.get(generatePage.dropdownOption) + .contains("assets-test.appsmith.com") + .scrollIntoView() + .should("be.visible") + .click(); + cy.get(generatePage.generatePageFormSubmitBtn).click(); + + cy.wait("@replaceLayoutWithCRUDPage").should( + "have.nested.property", + "response.body.responseMeta.status", + 201, + ); + + cy.wait("@getActions"); + + cy.wait("@postExecute").should( + "have.nested.property", + "response.body.responseMeta.status", + 200, + ); //This verifies the Select on the table, ie page is created fine + + cy.ClickGotIt(); + + //Verifying Searching File from UI + cy.xpath(queryLocators.searchFilefield) + .type("CRUD") + .wait(500); //for search to finish + expect( + cy.xpath( + "//div[@data-cy='overlay-comments-wrapper']//span[text()='CRUDNewPageFile']", + ), + ).to.exist; + + cy.xpath( + "//div[@data-cy='overlay-comments-wrapper']//span[text()='CRUDNewPageFile']", + ).scrollIntoView(); + + //Verifying CopyFile URL icon from UI - Browser pop up appearing + // cy.xpath(queryLocators.copyURLicon).click() + // cy.window().its('navigator.clipboard').invoke('readText').should('contain', 'CRUDNewPageFile') + + //Verifying DeleteFile icon from UI + cy.xpath(queryLocators.deleteFileicon).click(); + expect( + cy.xpath("//span[text()='Are you sure you want to delete the file?']"), + ).to.exist; //verify Delete File dialog appears + cy.clickButton("Confirm").wait(1000); //wait for Dlete operation to be successfull + + cy.wait("@postExecute").then(({ response }) => { + expect(response.body.data.isExecutionSuccess).to.eq(true); + }); + + cy.get("span:contains('CRUDNewPageFile')").should("not.exist"); //verify Deletion of file is success from UI also + }); + + it("10. Validate Deletion of the Newly Created Page", () => { + cy.NavigateToQueryEditor(); + cy.NavigateToActiveTab(); + cy.contains(".t--datasource-name", datasourceName).click(); + cy.get(".t--delete-datasource").click(); + + cy.wait("@deleteDatasource").should( + "have.nested.property", + "response.body.responseMeta.status", + 409, + ); + + cy.deleteEntitybyName("Assets-test.appsmith.com"); + }); + + it("11. Verify 'Add to widget [Widget Suggestion]' functionality - S3", () => { + cy.NavigateToActiveDSQueryPane(datasourceName); + cy.validateNSelectDropdown("Commands", "List files in bucket"); + cy.typeValueNValidate("assets-test.appsmith.com", "Bucket Name"); + cy.runQuery(); + + cy.xpath(queryLocators.suggestedWidgetDropdown) + .click() + .wait(1000); + cy.wait("@updateLayout").then(({ response }) => { + expect(response.body.data.dsl.children[0].type).to.eq("DROP_DOWN_WIDGET"); + }); + cy.xpath(queryLocators.Query1) + .click() + .wait(2000); + + cy.get(queryLocators.suggestedTableWidget) + .click() + .wait(1000); + cy.wait("@updateLayout").then(({ response }) => { + expect(response.body.data.dsl.children[1].type).to.eq("TABLE_WIDGET"); + }); + cy.xpath(queryLocators.Query1) + .click() + .wait(2000); + + cy.xpath(queryLocators.suggestedWidgetText) + .click() + .wait(1000); + cy.wait("@updateLayout").then(({ response }) => { + expect(response.body.data.dsl.children[2].type).to.eq("TEXT_WIDGET"); + }); + cy.xpath(queryLocators.Query1) + .click() + .wait(2000); + + cy.deleteQueryUsingContext(); + }); + + it("12. Verify 'Connect Widget [snipping]' functionality - S3 ", () => { + cy.addDsl(dsl); + cy.NavigateToActiveDSQueryPane(datasourceName); + cy.validateNSelectDropdown("Commands", "List files in bucket"); + cy.typeValueNValidate("assets-test.appsmith.com", "Bucket Name"); + cy.runQuery(); + cy.clickButton("Select Widget"); + cy.xpath(queryLocators.snipeableTable).click(); + + cy.wait("@updateLayout").then(({ response }) => { + expect(response.body.data.dsl.children[0].widgetName).to.eq("Table1"); + expect(response.body.data.messages[0]).to.contain( + "will be executed automatically on page load", + ); + }); + + cy.xpath(queryLocators.Query1) + .click() + .wait(2000); + cy.deleteQueryUsingContext(); + + cy.deleteEntitybyName("Table1"); + }); + + it("11. Deletes the datasource", () => { + cy.NavigateToQueryEditor(); + cy.NavigateToActiveTab(); + cy.contains(".t--datasource-name", datasourceName).click(); + cy.get(".t--delete-datasource").click(); + cy.wait("@deleteDatasource").should( + "have.nested.property", + "response.body.responseMeta.status", + 200, + ); + }); +}); diff --git a/app/client/cypress/locators/GeneratePage.json b/app/client/cypress/locators/GeneratePage.json index 5e56c9221a..02e3effc12 100644 --- a/app/client/cypress/locators/GeneratePage.json +++ b/app/client/cypress/locators/GeneratePage.json @@ -23,8 +23,5 @@ "currentNameField": "//div[@type='FORM_WIDGET']//span[text()='name:']//ancestor::div[contains(@class,'t--widget-textwidget')]/preceding-sibling::div[contains(@class, 't--widget-inputwidget')][1]//input", "deleteofSelectedRow": "//div[@class='tr selected-row']//span[text()='Delete']", "confirmBtn": "span:contains('Confirm')", - "postgressnewPageEntityMenu": "//div[text()='Public.users_crud']/ancestor::div[contains(@class, 't--entity page')]//span[contains(@class, 'entity-context-menu')]//div", - "deleteMenuItem": "//div[text()='Delete']/parent::a[contains(@class, 'single-select')]", - "mongonewPageEntityMenu": "//div[text()='ListingsAndReviews']/ancestor::div[contains(@class, 't--entity page')]//span[contains(@class, 'entity-context-menu')]//div" - + "deleteMenuItem": "//div[text()='Delete']/parent::a[contains(@class, 'single-select')]" } \ No newline at end of file diff --git a/app/client/cypress/locators/QueryEditor.json b/app/client/cypress/locators/QueryEditor.json index c22d6f99e6..a029ed2c41 100644 --- a/app/client/cypress/locators/QueryEditor.json +++ b/app/client/cypress/locators/QueryEditor.json @@ -21,19 +21,15 @@ "queryCreate": "//div[contains(@class, 't--template-menu')]//div[text()='Create']", "queryUpdate": "//div[contains(@class, 't--template-menu')]//div[text()='Update']", "queryDelete": "//div[contains(@class, 't--template-menu')]//div[text()='Delete']", - "codeTextArea": "div.CodeMirror-code", - "findDocs" : "//div[text()='Find Document(s)']", - "collectionField": "//p[text()='Collection']/following-sibling::div//div[@class='CodeMirror-code']", - "queryField": "//p[text()='Query']/following-sibling::div//div[@class='CodeMirror-code']", - "sortField": "//p[text()='Sort']/following-sibling::div//div[@class='CodeMirror-code']", - "projectionField": "//p[text()='Projection']/following-sibling::div//div[@class='CodeMirror-code']", - "limitField": "//p[text()='Limit']/following-sibling::div//div[@class='CodeMirror-code']", - "skipField": "//p[text()='Skip']/following-sibling::div//div[@class='CodeMirror-code']", - "keyField": "//p[text()='Key']/following-sibling::div//div[@class='CodeMirror-code']", - "arrayOfPipelinesField": "//p[text()='Array of Pipelines']/following-sibling::div//div[@class='CodeMirror-code']", - "countText": "//span[contains(@class, 'cs-text')][text()='Result:']/span" - - - - + "codeTextArea": "//div[@class='CodeMirror-code']//span/span", + "countText": "//span[contains(@class, 'cs-text')][text()='Result:']/span", + "searchFilefield": "//input[@placeholder='Search File Prefix']", + "copyURLicon": "//button/span[@icon='link']", + "deleteFileicon": "//button/span[@icon='trash']", + "snipeableTable":"//input[@type='search']", + "Query1": "//div[contains(@class, 't--entity-name')][text()='Query1']", + "suggestedWidgetDropdown": "//div[contains(@class, 't--suggested-widget-DROP_DOWN_WIDGET')]", + "suggestedWidgetText": "//div[contains(@class, 't--suggested-widget-TEXT_WIDGET')]", + "queryTimeout": "//input[@name='actionConfiguration.timeoutInMillisecond']", + "mongoFormFind": "//div[text()='listingsAndReviews']/ancestor::div/following-sibling::div[contains(@class, 'entity-context-menu')]" } diff --git a/app/client/cypress/locators/commonlocators.json b/app/client/cypress/locators/commonlocators.json index 3557413649..1071d26b69 100644 --- a/app/client/cypress/locators/commonlocators.json +++ b/app/client/cypress/locators/commonlocators.json @@ -66,7 +66,7 @@ "selectMenuItem": ".bp3-menu li>a>div", "evaluatedTypeTitle": ".t--CodeEditor-evaluatedValue > p:first-of-type", "evaluatedType": ".t--CodeEditor-evaluatedValue > div:first-of-type pre", - "evaluatedCurrentValue": ".t--CodeEditor-evaluatedValue > div:last-of-type pre", + "evaluatedCurrentValue": "div:last-of-type .t--CodeEditor-evaluatedValue > div:last-of-type pre", "entityExplorersearch": "#entity-explorer-search", "entitySearchResult": ".t--entity-name:contains('", "saveStatusContainer": ".t--save-status-container", diff --git a/app/client/cypress/support/commands.js b/app/client/cypress/support/commands.js index e160552055..2d81afd2d8 100644 --- a/app/client/cypress/support/commands.js +++ b/app/client/cypress/support/commands.js @@ -29,6 +29,7 @@ const queryLocators = require("../locators/QueryEditor.json"); const welcomePage = require("../locators/welcomePage.json"); let pageidcopy = " "; +const chainStart = Symbol(); export const initLocalstorage = () => { cy.window().then((window) => { @@ -1281,7 +1282,9 @@ Cypress.Commands.add("EvaluateCurrentValue", (currentValue) => { cy.get(commonlocators.evaluatedCurrentValue) .first() .should("be.visible") - .contains(currentValue); + .then(($text) => { + expect($text.text()).to.eq(currentValue); + }); }); Cypress.Commands.add("PublishtheApp", () => { @@ -2089,9 +2092,16 @@ Cypress.Commands.add("NavigateToActiveTab", () => { Cypress.Commands.add("NavigateToActiveDSQueryPane", (datasourceName) => { cy.NavigateToQueryEditor(); cy.NavigateToActiveTab(); - cy.contains(".t--datasource-name", datasourceName) - .find(queryLocators.createQuery) - .click(); + + cy.get(datasource.datasourceCard) + .contains(datasourceName) + .scrollIntoView() + .should("be.visible") + .closest(datasource.datasourceCard) + .within(() => { + cy.get(queryLocators.createQuery).click({ force: true }); + }) + .wait(2000); //for the specified page to load }); Cypress.Commands.add("NavigateToDSGeneratePage", (datasourceName) => { @@ -2105,7 +2115,8 @@ Cypress.Commands.add("NavigateToDSGeneratePage", (datasourceName) => { .closest(datasource.datasourceCard) .within(() => { cy.get(datasource.datasourceCardGeneratePageBtn).click(); - }); + }) + .wait(2000); //for the specified page to load }); Cypress.Commands.add("ClickGotIt", () => { @@ -2363,9 +2374,7 @@ Cypress.Commands.add("deleteDatasource", (datasourceName) => { }); Cypress.Commands.add("runQuery", () => { - cy.xpath(queryEditor.runQuery) - .last() - .click(); + cy.onlyQueryRun(); cy.wait("@postExecute").should( "have.nested.property", "response.body.responseMeta.status", @@ -2376,7 +2385,7 @@ Cypress.Commands.add("runQuery", () => { Cypress.Commands.add("onlyQueryRun", () => { cy.xpath(queryEditor.runQuery) .last() - .click(); + .click({ force: true }); }); Cypress.Commands.add("hoverAndClick", () => { @@ -2670,9 +2679,9 @@ Cypress.Commands.add("createAndFillApi", (url, parameters) => { }); Cypress.Commands.add("isSelectRow", (index) => { - cy.get( - '.tbody .td[data-rowindex="' + index + '"][data-colindex="' + 0 + '"]', - ).click({ force: true }); + cy.get('.tbody .td[data-rowindex="' + index + '"][data-colindex="' + 0 + '"]') + .first() + .click({ force: true }); }); Cypress.Commands.add("readTabledata", (rowNum, colNum) => { @@ -3038,6 +3047,7 @@ Cypress.Commands.add("createJSObject", (JSCode) => { }); Cypress.Commands.add("createSuperUser", () => { + cy.wait(1000); cy.get(welcomePage.getStarted).should("be.visible"); cy.get(welcomePage.getStarted).should("not.be.disabled"); cy.get(welcomePage.getStarted).click(); @@ -3211,3 +3221,128 @@ Cypress.Commands.add( }); }, ); + +Cypress.Commands.add( + "validateNSelectDropdown", + (ddTitle, currentValue, newValue) => { + let toChange = false; + cy.xpath('//div[contains(text(),"' + currentValue + '")]').should( + "exist", + currentValue + " dropdown value not present", + ); + if (newValue) toChange = true; + if (toChange) { + cy.xpath( + "//p[text()='" + ddTitle + "']/following-sibling::div/div", + ).click(); //to expand the dropdown + cy.xpath('//div[contains(text(),"' + newValue + '")]') + .last() + .click({ force: true }); //to select the new value + } + }, +); + +Cypress.Commands.add("typeValueNValidate", (valueToType, fieldName = "") => { + if (fieldName) { + cy.xpath("//p[text()='" + fieldName + "']/following-sibling::div").then( + ($field) => { + cy.updateCodeInput($field, valueToType); + }, + ); + } else { + cy.xpath("//div[@class='CodeEditorTarget']").then(($field) => { + cy.updateCodeInput($field, valueToType); + }); + } + + cy.EvaluateCurrentValue(valueToType); + + // cy.xpath("//p[text()='" + fieldName + "']/following-sibling::div//div[@class='CodeMirror-code']//span/span").should((fieldValue) => { + // textF = fieldValue.innerText + // fieldValue.innerText = "" + // }).then(() => { + // cy.log("current field value is : '" + textF + "'") + // }) +}); + +Cypress.Commands.add("clickButton", (btnVisibleText) => { + cy.xpath("//span[text()='" + btnVisibleText + "']/parent::button").click({ + force: true, + }); +}); + +Cypress.Commands.add("deleteEntitybyName", (entityNameinLeftSidebar) => { + cy.xpath( + "//div[text()='" + + entityNameinLeftSidebar + + "']/ancestor::div[contains(@class, 't--entity')]//span[contains(@class, 'entity-context-menu')]//div", + ) + .first() + .click({ force: true }); + + cy.xpath(generatePage.deleteMenuItem).click(); +}); + +Cypress.Commands.add( + "EvaluatFieldValue", + (fieldName = "", currentValue = "") => { + let toValidate = false; + if (currentValue) toValidate = true; + + if (fieldName) { + cy.xpath( + "//p[text()='" + + fieldName + + "']/following-sibling::div//div[@class='CodeMirror-code']", + ).click(); + } else { + cy.xpath("//div[@class='CodeMirror-code']").click(); + } + + cy.wait(2000); + const val = cy + .get(commonlocators.evaluatedCurrentValue) + .first() + .should("be.visible") + .invoke("text"); + + if (toValidate) expect(val).to.eq(currentValue); + + return val; + }, +); + +cy.all = function(...commands) { + const _ = Cypress._; + const chain = cy.wrap(null, { log: false }); + const stopCommand = _.find(cy.queue.commands, { + attributes: { chainerId: chain.chainerId }, + }); + const startCommand = _.find(cy.queue.commands, { + attributes: { chainerId: commands[0].chainerId }, + }); + const p = chain.then(() => { + return _(commands) + .map((cmd) => { + return cmd[chainStart] + ? cmd[chainStart].attributes + : _.find(cy.queue.commands, { + attributes: { chainerId: cmd.chainerId }, + }).attributes; + }) + .concat(stopCommand.attributes) + .slice(1) + .flatMap((cmd) => { + return cmd.prev.get("subject"); + }) + .value(); + }); + p[chainStart] = startCommand; + return p; +}; + +// Cypress.Commands.overwrite("type", (originalFn, element, text, options) => { +// const clearedText = '{selectall}{backspace}'+`${text}`; + +// return originalFn(element, clearedText, options); +// });