Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ import * as _ from "../../../../support/Objects/ObjectsCore";
import EditorNavigation, {
EntityType,
} from "../../../../support/Pages/EditorNavigation";
import BottomPane from "../../../../support/Pages/IDE/BottomPane";

let valueToTest: any, jsName: any;

describe(
Expand All @@ -17,7 +19,7 @@ describe(
_.dataManager.dsValues[_.dataManager.defaultEnviorment].mockApiUrl,
);
_.apiPage.RunAPI();
_.agHelper.GetNClick(_.dataSources._queryResponse("JSON"));
BottomPane.response.switchResponseType("JSON");
_.apiPage.ReadApiResponsebyKey("name");
cy.get("@apiResp").then((value) => {
valueToTest = value;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {
import EditorNavigation, {
EntityType,
} from "../../../../support/Pages/EditorNavigation";
import BottomPane from "../../../../support/Pages/IDE/BottomPane";

let dsName: any;
let queryName: string;
Expand Down Expand Up @@ -43,7 +44,11 @@ describe(

EditorNavigation.SelectEntityByName(queryName, EntityType.Query);

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Remove agHelper.Sleep(1000)

Replace the sleep with proper Cypress wait commands or assertions to ensure the page has loaded.

Apply this change:

- agHelper.Sleep(1000);
+ cy.waitUntil(() => EditorNavigation.isEntityPresent(queryName, EntityType.Query));

Committable suggestion skipped: line range outside the PR's diff.

agHelper.AssertElementVisibility(dataSources._queryResponse("TABLE"));
BottomPane.response.switchToResponseTab();

agHelper.AssertElementVisibility(
BottomPane.response.getResponseTypeSelector("TABLE"),
);
});
});
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {
import EditorNavigation, {
EntityType,
} from "../../../../support/Pages/EditorNavigation";
import BottomPane from "../../../../support/Pages/IDE/BottomPane";

describe(
"Layout OnLoad Actions tests",
Expand Down Expand Up @@ -55,7 +56,7 @@ describe(
);

apiPage.RunAPI();
agHelper.GetNClick(dataSources._queryResponse("JSON"));
BottomPane.response.switchResponseType("JSON");

apiPage.CreateAndFillApi(
"http://host.docker.internal:5001/v1/favqs/qotd",
Expand All @@ -64,7 +65,7 @@ describe(
);
apiPage.EnterHeader("dependency", "{{RandomUser.data}}"); //via Params tab
apiPage.RunAPI();
agHelper.GetNClick(dataSources._queryResponse("JSON"));
BottomPane.response.switchResponseType("JSON");

apiPage.CreateAndFillApi(
"http://host.docker.internal:5001/v1/boredapi/activity",
Expand All @@ -73,7 +74,7 @@ describe(
);
apiPage.EnterHeader("dependency", "{{InspiringQuotes.data.data}}");
apiPage.RunAPI();
agHelper.GetNClick(dataSources._queryResponse("JSON"));
BottomPane.response.switchResponseType("JSON");

apiPage.CreateAndFillApi(
"http://host.docker.internal:5001/v1/genderize/sampledata",
Expand All @@ -82,7 +83,7 @@ describe(
);
apiPage.EnterParams("name", "{{RandomUser.data[0].name}}"); //via Params tab
apiPage.RunAPI();
agHelper.GetNClick(dataSources._queryResponse("JSON"));
BottomPane.response.switchResponseType("JSON");

//Adding dependency in right order matters!
EditorNavigation.SelectEntityByName("Image1", EntityType.Widget);
Expand Down Expand Up @@ -162,7 +163,7 @@ describe(
value: "{{RandomUser.data[0].name}}",
}); // verifies Bug 10055
apiPage.RunAPI();
agHelper.GetNClick(dataSources._queryResponse("JSON"));
BottomPane.response.switchResponseType("JSON");

deployMode.DeployApp(
locators._widgetInDeployed("textwidget"),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import EditorNavigation, {
EntityType,
} from "../../../../support/Pages/EditorNavigation";
import PageList from "../../../../support/Pages/PageList";
import BottomPane from "../../../../support/Pages/IDE/BottomPane";

let dsName: any;

Expand Down Expand Up @@ -429,8 +430,12 @@ describe(
parseInt(JSON.stringify(resObj.response.body.data.body.n)),
).to.eq(3);
});
agHelper.AssertElementVisibility(dataSources._queryResponse("JSON"));
agHelper.AssertElementVisibility(dataSources._queryResponse("RAW"));
agHelper.AssertElementVisibility(
BottomPane.response.getResponseTypeSelector("JSON"),
);
agHelper.AssertElementVisibility(
BottomPane.response.getResponseTypeSelector("RAW"),
);
Comment on lines +433 to +438
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Consider extracting repeated assertions into a helper function

The same response type selector assertions are repeated across multiple test cases. This violates the DRY principle and makes maintenance harder.

Consider creating a helper function in the test utilities:

// In support/Objects/ObjectsCore.ts
export const assertResponseTypeSelectors = () => {
  agHelper.AssertElementVisibility(
    BottomPane.response.getResponseTypeSelector("JSON")
  );
  agHelper.AssertElementVisibility(
    BottomPane.response.getResponseTypeSelector("RAW")
  );
};

// In the test file
assertResponseTypeSelectors();

Also applies to: 470-475, 517-522, 559-564, 590-595, 623-628, 660-665, 685-690, 722-727

agHelper.ActionContextMenuWithInPane({
action: "Delete",
entityType: entityItems.Query,
Expand Down Expand Up @@ -462,8 +467,12 @@ describe(
parseInt(JSON.stringify(resObj.response.body.data.body.nModified)),
).to.eq(0);
});
agHelper.AssertElementVisibility(dataSources._queryResponse("JSON"));
agHelper.AssertElementVisibility(dataSources._queryResponse("RAW"));
agHelper.AssertElementVisibility(
BottomPane.response.getResponseTypeSelector("JSON"),
);
agHelper.AssertElementVisibility(
BottomPane.response.getResponseTypeSelector("RAW"),
);
agHelper.ActionContextMenuWithInPane({
action: "Delete",
entityType: entityItems.Query,
Expand Down Expand Up @@ -505,8 +514,12 @@ describe(
parseInt(JSON.stringify(resObj.response.body.data.body.nModified)),
).to.eq(2);
});
agHelper.AssertElementVisibility(dataSources._queryResponse("JSON"));
agHelper.AssertElementVisibility(dataSources._queryResponse("RAW"));
agHelper.AssertElementVisibility(
BottomPane.response.getResponseTypeSelector("JSON"),
);
agHelper.AssertElementVisibility(
BottomPane.response.getResponseTypeSelector("RAW"),
);
agHelper.ActionContextMenuWithInPane({
action: "Delete",
entityType: entityItems.Query,
Expand Down Expand Up @@ -543,8 +556,12 @@ describe(
parseInt(JSON.stringify(resObj.response.body.data.body.nModified)),
).to.eq(1);
});
agHelper.AssertElementVisibility(dataSources._queryResponse("JSON"));
agHelper.AssertElementVisibility(dataSources._queryResponse("RAW"));
agHelper.AssertElementVisibility(
BottomPane.response.getResponseTypeSelector("JSON"),
);
agHelper.AssertElementVisibility(
BottomPane.response.getResponseTypeSelector("RAW"),
);
agHelper.ActionContextMenuWithInPane({
action: "Delete",
entityType: entityItems.Query,
Expand All @@ -570,8 +587,12 @@ describe(
parseInt(JSON.stringify(resObj.response.body.data.body.n)),
).to.eq(0);
});
agHelper.AssertElementVisibility(dataSources._queryResponse("JSON"));
agHelper.AssertElementVisibility(dataSources._queryResponse("RAW"));
agHelper.AssertElementVisibility(
BottomPane.response.getResponseTypeSelector("JSON"),
);
agHelper.AssertElementVisibility(
BottomPane.response.getResponseTypeSelector("RAW"),
);
agHelper.ActionContextMenuWithInPane({
action: "Delete",
entityType: entityItems.Query,
Expand Down Expand Up @@ -599,8 +620,12 @@ describe(
parseInt(JSON.stringify(resObj.response.body.data.body.n)),
).to.eq(1);
});
agHelper.AssertElementVisibility(dataSources._queryResponse("JSON"));
agHelper.AssertElementVisibility(dataSources._queryResponse("RAW"));
agHelper.AssertElementVisibility(
BottomPane.response.getResponseTypeSelector("JSON"),
);
agHelper.AssertElementVisibility(
BottomPane.response.getResponseTypeSelector("RAW"),
);
agHelper.ActionContextMenuWithInPane({
action: "Delete",
entityType: entityItems.Query,
Expand Down Expand Up @@ -632,8 +657,12 @@ describe(
2,
);
});
agHelper.AssertElementVisibility(dataSources._queryResponse("JSON"));
agHelper.AssertElementVisibility(dataSources._queryResponse("RAW"));
agHelper.AssertElementVisibility(
BottomPane.response.getResponseTypeSelector("JSON"),
);
agHelper.AssertElementVisibility(
BottomPane.response.getResponseTypeSelector("RAW"),
);
agHelper.ActionContextMenuWithInPane({
action: "Delete",
entityType: entityItems.Query,
Expand All @@ -653,8 +682,12 @@ describe(
7,
);
});
agHelper.AssertElementVisibility(dataSources._queryResponse("JSON"));
agHelper.AssertElementVisibility(dataSources._queryResponse("RAW"));
agHelper.AssertElementVisibility(
BottomPane.response.getResponseTypeSelector("JSON"),
);
agHelper.AssertElementVisibility(
BottomPane.response.getResponseTypeSelector("RAW"),
);
agHelper.ActionContextMenuWithInPane({
action: "Delete",
entityType: entityItems.Query,
Expand Down Expand Up @@ -686,8 +719,12 @@ describe(
JSON.parse(JSON.stringify(resObj.response.body.data.body.values[1])),
).to.eql("51e062189c6ae665454e301d");
});
agHelper.AssertElementVisibility(dataSources._queryResponse("JSON"));
agHelper.AssertElementVisibility(dataSources._queryResponse("RAW"));
agHelper.AssertElementVisibility(
BottomPane.response.getResponseTypeSelector("JSON"),
);
agHelper.AssertElementVisibility(
BottomPane.response.getResponseTypeSelector("RAW"),
);
agHelper.ActionContextMenuWithInPane({
action: "Delete",
entityType: entityItems.Query,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import {
apiPage,
} from "../../../../support/Objects/ObjectsCore";
import { Widgets } from "../../../../support/Pages/DataSources";
import BottomPane from "../../../../support/Pages/IDE/BottomPane";

let datasourceName;

Expand Down Expand Up @@ -70,7 +71,7 @@ describe(
dataSources.EnterQuery(`{"find": "listingAndReviews","limit": 10}`);
agHelper.FocusElement(locators._codeMirrorTextArea);
dataSources.RunQuery();
dataSources.CheckResponseRecordsCount(10);
BottomPane.response.validateRecordCount(10);
cy.deleteQueryUsingContext();
});

Expand All @@ -92,23 +93,23 @@ describe(
fieldValue: "listingAndReviews",
});
dataSources.RunQuery();
dataSources.CheckResponseRecordsCount(10);
BottomPane.response.validateRecordCount(10);

agHelper.EnterValue("{beds : {$lte: 2}}", {
propFieldName: "",
directInput: false,
inputFieldName: "Query",
});
dataSources.RunQuery();
dataSources.CheckResponseRecordsCount(10);
BottomPane.response.validateRecordCount(10);

agHelper.EnterValue("{number_of_reviews: -1}", {
propFieldName: "",
directInput: false,
inputFieldName: "Sort",
}); //sort descending
dataSources.RunQuery();
dataSources.CheckResponseRecordsCount(10);
BottomPane.response.validateRecordCount(10);

agHelper.EnterValue("{house_rules: 1, description:1}", {
propFieldName: "",
Expand All @@ -130,7 +131,7 @@ describe(
"Response is not as expected for Find commmand with multiple conditions",
);
});
dataSources.CheckResponseRecordsCount(5);
BottomPane.response.validateRecordCount(5);

agHelper.EnterValue("2", {
propFieldName: "",
Expand All @@ -144,7 +145,7 @@ describe(
"Response is not as expected for Find commmand with multiple conditions",
);
});
dataSources.CheckResponseRecordsCount(5);
BottomPane.response.validateRecordCount(5);
cy.deleteQueryUsingContext();
});

Expand Down Expand Up @@ -432,7 +433,7 @@ describe(
);

dataSources.RunQuery();
dataSources.CheckResponseRecordsCount(3);
BottomPane.response.validateRecordCount(3);

dataSources.AssertTableInVirtuosoList(datasourceName, "NonAsciiTest");

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
/// <reference types="Cypress" />

import BottomPane from "../../../../support/Pages/IDE/BottomPane";

const queryLocators = require("../../../../locators/QueryEditor.json");
const generatePage = require("../../../../locators/GeneratePage.json");
const formControls = require("../../../../locators/FormControl.json");
Expand Down Expand Up @@ -189,8 +191,8 @@ describe(
cy.typeValueNValidate(fileName, formControls.s3ListPrefix);
dataSources.RunQuery({ toValidateResponse: false });

agHelper.GetNClick(dataSources._queryResponse("TABLE"));
agHelper.GetNClick(dataSources._queryResponse("JSON"));
BottomPane.response.switchResponseType("TABLE");
BottomPane.response.switchResponseType("JSON");

cy.wait("@postExecute").then(({ response }) => {
expect(response.body.data.isExecutionSuccess).to.eq(true);
Expand Down
24 changes: 13 additions & 11 deletions app/client/cypress/support/Pages/DataSources.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import EditorNavigation, {
import datasource from "../../locators/DatasourcesEditor.json";
import PageList from "./PageList";
import { anvilLocators } from "./Anvil/Locators";
import BottomPane from "./IDE/BottomPane";

export const DataSourceKVP = {
Postgres: "PostgreSQL",
Expand Down Expand Up @@ -1137,17 +1138,18 @@ export class DataSources {
tableCheck = true,
) {
this.RunQuery();
tableCheck &&
this.agHelper.AssertElementVisibility(this._queryResponse("TABLE"));
this.agHelper.AssertElementVisibility(this._queryResponse("JSON"));
this.agHelper.AssertElementVisibility(this._queryResponse("RAW"));
this.CheckResponseRecordsCount(expectedRecordsCount);
}

public CheckResponseRecordsCount(expectedRecordCount: number) {
this.agHelper.AssertElementVisibility(
this._queryRecordResult(expectedRecordCount),
);
if (tableCheck) {
this.agHelper.AssertElementVisibility(
BottomPane.response.getResponseTypeSelector("TABLE"),
);
this.agHelper.AssertElementVisibility(
BottomPane.response.getResponseTypeSelector("JSON"),
);
this.agHelper.AssertElementVisibility(
BottomPane.response.getResponseTypeSelector("RAW"),
);
}
BottomPane.response.validateRecordCount(expectedRecordsCount);
}

public CreateDataSource(
Expand Down
21 changes: 21 additions & 0 deletions app/client/cypress/support/Pages/IDE/BottomPane/Response.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
class Response {
private ResponseTab = "//button[@data-testid='t--tab-RESPONSE_TAB']";
Comment on lines +1 to +2
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Replace XPath selector with data- attribute selector*

The XPath selector usage violates our coding guidelines. Use data-* attributes for more maintainable selectors.

class Response {
-  private ResponseTab = "//button[@data-testid='t--tab-RESPONSE_TAB']";
+  private ResponseTab = "[data-testid='t--tab-RESPONSE_TAB']";
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
class Response {
private ResponseTab = "//button[@data-testid='t--tab-RESPONSE_TAB']";
class Response {
private ResponseTab = "[data-testid='t--tab-RESPONSE_TAB']";


public switchToResponseTab(): void {
cy.xpath(this.ResponseTab).click({ force: true });
}
Comment on lines +4 to +6
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Avoid force clicks and XPath in Cypress commands

Force clicks can make tests brittle and mask underlying issues. Consider adding proper wait conditions or element visibility checks.

  public switchToResponseTab(): void {
-    cy.xpath(this.ResponseTab).click({ force: true });
+    cy.get(this.ResponseTab)
+      .should('be.visible')
+      .click();
  }

Committable suggestion skipped: line range outside the PR's diff.


public getResponseTypeSelector(type: string): string {
return `//div[@data-testid='t--response-tab-segmented-control']//span[text()='${type}']`;
}
Comment on lines +8 to +10
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Use data attributes for response type selection

String interpolation in selectors is fragile. Consider using data attributes with specific values for each type.

  public getResponseTypeSelector(type: string): string {
-    return `//div[@data-testid='t--response-tab-segmented-control']//span[text()='${type}']`;
+    return `[data-testid='t--response-type-${type.toLowerCase()}']`;
  }

Committable suggestion skipped: line range outside the PR's diff.


public switchResponseType(type: string): void {
this.switchToResponseTab();
cy.xpath(this.getResponseTypeSelector(type)).click({ force: true });
}
Comment on lines +12 to +15
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Improve response type switching reliability

Similar to the tab switching, avoid force clicks and use proper wait conditions.

  public switchResponseType(type: string): void {
    this.switchToResponseTab();
-    cy.xpath(this.getResponseTypeSelector(type)).click({ force: true });
+    cy.get(this.getResponseTypeSelector(type))
+      .should('be.visible')
+      .click();
  }

Committable suggestion skipped: line range outside the PR's diff.


// TODO: Implement this method when response UI is ready
public validateRecordCount(count: number): void {}
}

export { Response };
11 changes: 11 additions & 0 deletions app/client/cypress/support/Pages/IDE/BottomPane/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { Response } from "./Response";

class BottomPane {
public readonly response: Response;

constructor() {
this.response = new Response();
}
}

export default new BottomPane();