Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

test: adding tests for jsobject regression tests #38214

Open
wants to merge 5 commits into
base: release
Choose a base branch
from
Open
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
@@ -0,0 +1,58 @@
import {
agHelper,
assertHelper,
entityExplorer,
homePage,
jsEditor,
locators,
} from "../../../../support/Objects/ObjectsCore";
import HomePage from "../../../../locators/HomePage";
import {
PageLeftPane,
PagePaneSegment,
} from "../../../../support/Pages/EditorNavigation";

describe("Fork application", {}, function () {
it("1. Fork app and verify", () => {
homePage.ImportApp("jsObjectTesting.json");
agHelper.GetNClick(homePage._applicationName);
agHelper.GetNClickByContains;
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 incomplete statement

This line appears to be an incomplete function call and serves no purpose.

-    agHelper.GetNClickByContains;

agHelper.GetNClickByContains(
HomePage.applicationEditMenu,
"Fork application",
);
agHelper.GetNClick(locators._forkAppToWorkspaceBtn);
agHelper.FailIfErrorToast("");
assertHelper.AssertNetworkStatus("@postForkAppWorkspace", 200);
agHelper.WaitUntilEleDisappear(homePage._forkModal);
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 wait with better assertion

According to the guidelines, we should avoid using wait functions. Instead, use Cypress's built-in retry-ability with assertions.

-    agHelper.WaitUntilEleDisappear(homePage._forkModal);
+    cy.get(homePage._forkModal).should('not.exist');
📝 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
agHelper.WaitUntilEleDisappear(homePage._forkModal);
cy.get(homePage._forkModal).should('not.exist');

homePage.NavigateToHome();
agHelper.AssertElementExist(
`${homePage._applicationCard}:contains('JS object testing upto 1.5 MB (1)')`,
);
Comment on lines +29 to +31
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 selectors*

Avoid using string selectors in assertions. Instead, use data-* attributes for more reliable element selection.

-    agHelper.AssertElementExist(
-      `${homePage._applicationCard}:contains('JS object testing upto 1.5 MB (1)')`,
-    );
+    cy.get('[data-testid="t--application-card"]')
+      .should('exist')
+      .and('contain', 'JS object testing upto 1.5 MB (1)');
📝 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
agHelper.AssertElementExist(
`${homePage._applicationCard}:contains('JS object testing upto 1.5 MB (1)')`,
);
cy.get('[data-testid="t--application-card"]')
.should('exist')
.and('contain', 'JS object testing upto 1.5 MB (1)');

homePage.EditAppFromAppHover("JS object testing upto 1.5 MB (1)");
PageLeftPane.switchSegment(PagePaneSegment.JS);
for (let i = 1; i <= 11; i++) {
agHelper.GetNClick(locators._entityTestId(`JS${i}`));
agHelper.FailIfErrorToast("");
agHelper.AssertClassExists(locators._entityTestId(`JS${i}`), "active");
}
for (let i = 12; i <= 17; i++) {
agHelper.GetNClick(locators._entityTestId(`J${i}`));
agHelper.FailIfErrorToast("");
agHelper.AssertClassExists(locators._entityTestId(`J${i}`), "active");
}
Comment on lines +34 to +43
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

Refactor duplicate loops

The two loops have similar logic and can be combined to reduce code duplication.

-    for (let i = 1; i <= 11; i++) {
-      agHelper.GetNClick(locators._entityTestId(`JS${i}`));
-      agHelper.FailIfErrorToast("");
-      agHelper.AssertClassExists(locators._entityTestId(`JS${i}`), "active");
-    }
-    for (let i = 12; i <= 17; i++) {
-      agHelper.GetNClick(locators._entityTestId(`J${i}`));
-      agHelper.FailIfErrorToast("");
-      agHelper.AssertClassExists(locators._entityTestId(`J${i}`), "active");
-    }
+    const entityIds = [
+      ...Array.from({ length: 11 }, (_, i) => `JS${i + 1}`),
+      ...Array.from({ length: 6 }, (_, i) => `J${i + 12}`)
+    ];
+    entityIds.forEach(id => {
+      cy.get(locators._entityTestId(id))
+        .click()
+        .should('have.class', 'active');
+      agHelper.FailIfErrorToast("");
+    });
📝 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
for (let i = 1; i <= 11; i++) {
agHelper.GetNClick(locators._entityTestId(`JS${i}`));
agHelper.FailIfErrorToast("");
agHelper.AssertClassExists(locators._entityTestId(`JS${i}`), "active");
}
for (let i = 12; i <= 17; i++) {
agHelper.GetNClick(locators._entityTestId(`J${i}`));
agHelper.FailIfErrorToast("");
agHelper.AssertClassExists(locators._entityTestId(`J${i}`), "active");
}
const entityIds = [
...Array.from({ length: 11 }, (_, i) => `JS${i + 1}`),
...Array.from({ length: 6 }, (_, i) => `J${i + 12}`)
];
entityIds.forEach(id => {
cy.get(locators._entityTestId(id))
.click()
.should('have.class', 'active');
agHelper.FailIfErrorToast("");
});


jsEditor.CreateJSObject('"MiddleName": "Test",\n', {
paste: false,
toRun: false,
completeReplace: false,
shouldCreateNewJSObj: false,
lineNumber: 5,
});
agHelper.GetNClick(locators._entityTestId("J16"));
agHelper.AssertClassExists(locators._entityTestId("J16"), "active");
agHelper.GetNClick(locators._entityTestId("J17"));
agHelper.AssertClassExists(locators._entityTestId("J17"), "active");
agHelper.GetNAssertContains(".CodeMirror-line ", '"MiddleName": "Test"');
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-testid for CodeMirror assertions

Avoid using class selectors for assertions. Instead, use data-testid attributes.

-    agHelper.GetNAssertContains(".CodeMirror-line ", '"MiddleName": "Test"');
+    cy.get('[data-testid="code-editor-line"]').should('contain', '"MiddleName": "Test"');

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

});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,310 @@
import HomePage from "../../../../locators/HomePage";
import {
agHelper,
entityExplorer,
jsEditor,
propPane,
draggableWidgets,
locators,
debuggerHelper,
dataSources,
assertHelper,
table,
} from "../../../../support/ee/ObjectsCore_EE";
import EditorNavigation, {
EntityType,
PageLeftPane,
PagePaneSegment,
} from "../../../../support/Pages/EditorNavigation";
import PageList from "../../../../support/Pages/PageList";

describe("Validate JSObj", {}, () => {
before(() => {});

it("1. Verify adding/deleting JSObject and more actions options", () => {
jsEditor.CreateJSObject(
`setInterval(() => {
showAlert("Hi", "success")
}, 2500, "Int")`,
{
paste: true,
completeReplace: false,
toRun: true,
shouldCreateNewJSObj: true,
},
);
jsEditor.EnableDisableAsyncFuncSettings("myFun1");

// Add new JSObject
PageList.AddNewPage("New blank page");
PageLeftPane.switchSegment(PagePaneSegment.JS);
agHelper.GetNClick(locators._createNew);
agHelper.GetNClick(jsEditor._addJSObj);
agHelper.AssertContains("JSObject2", "exist", entityExplorer._entityName);
agHelper.GetNClick(EditorNavigation.locators.MinimizeBtn);
EditorNavigation.CloseAnnouncementModal();
// List view
agHelper.GetNClick('[data-testid="t--list-toggle"]');
agHelper.AssertContains("JSObject1", "exist", entityExplorer._entityName);
agHelper.AssertContains("JSObject2", "exist", entityExplorer._entityName);
// Verify menu item in List view
agHelper.GetNClick(jsEditor._jsPageActions, 0, true);
agHelper.AssertContains("Rename", "exist", HomePage.portalMenuItem);
agHelper.AssertContains("Show bindings", "exist", HomePage.portalMenuItem);
agHelper.AssertContains("Copy to page", "exist", HomePage.portalMenuItem);
agHelper.AssertContains("Move to page", "exist", HomePage.portalMenuItem);
agHelper.AssertContains("Delete", "exist", HomePage.portalMenuItem);

// Add JSObj in List view
agHelper.GetNClick(jsEditor._addJSObj, 0, true);
agHelper.GetNClick(EditorNavigation.locators.MaximizeBtn);
agHelper.AssertContains("JSObject2", "exist", entityExplorer._entityName);

// Delete JSObj
agHelper.GetNClick(jsEditor._addJSObj, 0, true);
agHelper.GetNClick(jsEditor._moreActions, 0, true);
agHelper.GetNClickByContains(HomePage.portalMenuItem, "Delete");
agHelper.GetNClickByContains(HomePage.portalMenuItem, "Are you sure?");
agHelper.ValidateToastMessage("JSObject4 deleted successfully");

// Verify Copy to Page
Copy link
Contributor

Choose a reason for hiding this comment

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

Please give bug link.

// agHelper.GetNClick(jsEditor._moreActions, 0, true);
// agHelper.GetNClickByContains(HomePage.portalMenuItem, "Copy to page");
// agHelper.GetNClickByContains(HomePage.portalMenuItem, "Page1");
// agHelper.ValidateToastMessage(
// "JSObject3 copied to page Page1 successfully",
// );
// agHelper.AssertContains("JSObject3", "exist", entityExplorer._entityName);

// Verify Rename
// agHelper.GetNClick(jsEditor._moreActions, 0, true);
// agHelper.AssertContains("Rename", "exist", HomePage.portalMenuItem);
// agHelper.GetNClickByContains(HomePage.portalMenuItem, 'Rename');
// agHelper.ClearNType('[value="JSObject3"]', 'JSObject3New');
// agHelper.AssertContains("JSObject3New", "exist", entityExplorer._entityName);
// agHelper.AssertContains("Copy to page", "exist", HomePage.portalMenuItem);
});

it("2. Verify alert message on page load and adding Function 2 to remove message", () => {
// Verify alert message on page load
EditorNavigation.NavigateToPage("Page1", true);
agHelper.ValidateToastMessage("Hi");
PageLeftPane.switchSegment(PagePaneSegment.JS);
jsEditor.CreateJSObject(`clearInterval("Int")`, {
paste: true,
completeReplace: false,
shouldCreateNewJSObj: false,
lineNumber: 10,
});
jsEditor.SelectFunctionDropdown("myFun2");
jsEditor.RunJSObj();
agHelper.WaitUntilAllToastsDisappear();
});

it("3. Verify moving JSObject to new page", () => {
// Verify Move to Page
agHelper.GetNClick(jsEditor._moreActions, 0, true);
agHelper.HoverElement(
`${HomePage.portalMenuItem}:contains("Move to page")`,
);
agHelper.GetNClick(`${HomePage.portalMenuItem}:contains("Page2")`);

EditorNavigation.NavigateToPage("Page1", true);
PageLeftPane.switchSegment(PagePaneSegment.JS);
agHelper.AssertElementAbsence('.t--entity-name:contains("JSObject1")');
});

it("4. Verify JSObject binding", () => {
EditorNavigation.NavigateToPage("Page2", true);
PageLeftPane.switchSegment(PagePaneSegment.UI);
entityExplorer.DragDropWidgetNVerify(draggableWidgets.BUTTON, 500, 100);
propPane.EnterJSContext("onClick", "{{JSObject11.myFun1();}}", true, false);
agHelper.GetNClick(locators._widgetInDeployed("buttonwidget"));
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 selectors.*

Replace hardcoded widget selector with a data-* attribute as per coding guidelines.

-    agHelper.GetNClick(locators._widgetInDeployed("buttonwidget"));
+    agHelper.GetNClick("[data-testid='t--widget-buttonwidget']");

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

agHelper.ValidateToastMessage("Hi");
});

it("5. Verify JSObject Coalescing Logs", () => {
PageList.AddNewPage("New blank page");
jsEditor.CreateJSObject(
`// Basic example using nullish coalescing operator
const userProvidedValue = null;
const defaultValue = "Default Value";

const finalValue = userProvidedValue ?? defaultValue;

console.log(finalValue);`,
{
paste: true,
completeReplace: false,
shouldCreateNewJSObj: true,
lineNumber: 5,
},
);
jsEditor.RenameJSObjFromExplorer("JSObject1", "Coalescing");
agHelper.GetNClick(jsEditor.runButtonLocator);
agHelper.GetNClick(debuggerHelper.locators._logsTab);
debuggerHelper.DoesConsoleLogExist("Default Value");
});

it("6. Verify JSObject Typecasting", () => {
// typecasting a string to a number
jsEditor.CreateJSObject(
`export default {
myVar1: [],
myVar2: {},
myFun1 () {
const stringNumber = "42";
const actualNumber = Number(stringNumber);

console.log(typeof stringNumber);
console.log(typeof actualNumber);
console.log(actualNumber);

const numberValue = 100;
const stringValue = String(numberValue);

console.log(typeof numberValue);
console.log(typeof stringValue);
console.log(stringValue);
}
}
`,
{
paste: true,
completeReplace: true,
shouldCreateNewJSObj: true,
},
);
jsEditor.RenameJSObjFromExplorer("JSObject1", "Typecasting");
agHelper.GetNClick(jsEditor.runButtonLocator);
agHelper.GetNClick(debuggerHelper.locators._logsTab);
debuggerHelper.DoesConsoleLogExist("string");
debuggerHelper.DoesConsoleLogExist("number");
debuggerHelper.DoesConsoleLogExist("42");

// typecasting a number to a string
jsEditor.CreateJSObject(
`export default {
myVar1: [],
myVar2: {},
myFun1 () {
const numberValue = 100;
const stringValue = String(numberValue);

console.log(typeof numberValue);
console.log(typeof stringValue);
console.log(stringValue);
}
}
`,
{
paste: true,
completeReplace: true,
shouldCreateNewJSObj: true,
lineNumber: 5,
},
);
agHelper.GetNClick(jsEditor.runButtonLocator);
agHelper.GetNClick(debuggerHelper.locators._logsTab);
debuggerHelper.DoesConsoleLogExist("number");
debuggerHelper.DoesConsoleLogExist("string");
debuggerHelper.DoesConsoleLogExist("100");
});

it("7. Verify Promise", () => {
jsEditor.CreateJSObject(
`export default {
myVar1: [],
myVar2: {},
myFun1 () {
// Create a promise that simulates an asynchronous operation
const myPromise = new Promise((resolve, reject) => {
const success = true; // You can change this to false to simulate a rejection

setTimeout(() => {
if (success) {
resolve("Operation was successful!"); // Fulfill the promise
} else {
reject("Operation failed."); // Reject the promise
}
}, 2000); // Simulate a 2-second delay
});

// Handle the promise
myPromise
.then((message) => {
console.log(message); // Output: "Operation was successful!" if fulfilled
})
.catch((error) => {
console.log(error); // Output: "Operation failed." if rejected
});
}
}
`,
{
paste: true,
completeReplace: true,
shouldCreateNewJSObj: true,
},
);
jsEditor.RenameJSObjFromExplorer("JSObject2", "Pr");
agHelper.GetNClick(jsEditor.runButtonLocator);
agHelper.GetNClick(debuggerHelper.locators._logsTab);
debuggerHelper.DoesConsoleLogExist("Operation was successful!");
});

it("8. Verify Queries", () => {
dataSources.CreateDataSource("Postgres");
dataSources.CreateQueryAfterDSSaved(" ");
agHelper.TypeIntoTextArea(locators._codeEditorTarget, "/");
agHelper.GetNAssertContains(locators._hints, "Coalescing");
agHelper.GetNAssertContains(locators._hints, "Typecasting");
agHelper.GetNAssertContains(locators._hints, "Pr");
agHelper.GetNAssertContains(locators._hints, "JSObject1");
agHelper.GetNAssertContains(locators._hints, "MainContainer");

cy.get("@guid").then((uid) => {
dataSources.GeneratePageForDS(`Postgres ${uid}`);
});
assertHelper.AssertNetworkStatus("@postExecute", 200);
agHelper.ClickButton("Got it");
assertHelper.AssertNetworkStatus("@updateLayout", 200);
agHelper.Sleep(2000);
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 explicit sleep calls.

Using agHelper.Sleep() violates the coding guidelines. Use Cypress's built-in retry-ability and assertions instead.

-    agHelper.Sleep(2000);
+    agHelper.AssertElementVisibility(table.locators._table);
📝 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
agHelper.Sleep(2000);
agHelper.AssertElementVisibility(table.locators._table);

table.WaitUntilTableLoad(0, 0, "v2");
EditorNavigation.SelectEntityByName("SelectQuery", EntityType.Query);
agHelper.GetNClick(locators._codeEditorTarget);
agHelper.AssertElementVisibility(locators._evaluatedValue);

cy.get(`${locators._codeMirrorCode} pre`).then(($elements) => {
const text = [...$elements].map((el) => el.innerText).join("");
agHelper.GetText(locators._evaluatedValue).then((evalText: any) => {
expect(evalText.replace(/\n/g, "")).to.eq(text);
});
});
});
//Bug: https://github.com/appsmithorg/appsmith/issues/35385
it.skip("9. Verify JSObject with identical name should not exist Bug: #35385", () => {
for (let i = 0; i < 10; i++) {
agHelper.GetNClick(locators._createNew, 0, true, 0);
}
agHelper.AssertElementAbsence(locators._toastMsg);
});

//Bug: https://github.com/appsmithorg/appsmith/issues/38216
it.skip("10. Verify selecting JSObject does not change the page", () => {
PageList.AddNewPage("New blank page");
PageLeftPane.switchSegment(PagePaneSegment.JS);
agHelper.GetNClick(locators._createNew);
agHelper.AssertContains("JSObject1", "exist", entityExplorer._entityName);
agHelper.GetNClick(jsEditor._addJSObj);
agHelper.AssertContains("JSObject2", "exist", entityExplorer._entityName);
EditorNavigation.NavigateToPage("Page1", true);
PageLeftPane.switchSegment(PagePaneSegment.JS);
agHelper.GetNClick(locators._editorTab);
PageList.VerifyIsCurrentPage("Page1");
EditorNavigation.NavigateToPage("Page2", true);
agHelper.AssertContains("JSObject1", "exist", entityExplorer._entityName);
agHelper.GetNClick(locators._editorTab);
PageList.VerifyIsCurrentPage("Page2");
});
});
Loading
Loading