From 84489c5414901086ce1b63b48cd6485cb2ebd309 Mon Sep 17 00:00:00 2001 From: subrata71 Date: Mon, 6 Apr 2026 01:51:04 +0600 Subject: [PATCH 1/2] fix(test): stabilize flaky Tree_Select_2_spec test #6 with two-phase dropdown synchronization The test was failing intermittently because the click on .rc-tree-select-selector after deploy did not always open the dropdown. The root cause is a React hydration timing gap: the element is visible in the DOM before React attaches its event handlers, so the click fires but is swallowed silently, leaving the dropdown in its hidden state (rc-tree-select-dropdown-hidden with display: none). Prior fixes (409e03d4, 2a262ac8, d31ea856) all addressed DOM presence but not React readiness, so the flakiness persisted. This fix uses a two-phase approach: - Phase 1: A cy.waitUntil loop that clicks the selector and checks the library's own rc-tree-select-open class on the widget root. Only re-clicks when the dropdown is actually closed, preventing toggle oscillation. - Phase 2: Once open, waits for the specific "Green" option to be visible via cy.xpath().should("be.visible") before clicking it. Also closes the dropdown at the end of test #5 to prevent state leakage into test #6. --- .../Widgets/TreeSelect/Tree_Select_2_spec.ts | 45 ++++++++++++++++--- 1 file changed, 38 insertions(+), 7 deletions(-) diff --git a/app/client/cypress/e2e/Regression/ClientSide/Widgets/TreeSelect/Tree_Select_2_spec.ts b/app/client/cypress/e2e/Regression/ClientSide/Widgets/TreeSelect/Tree_Select_2_spec.ts index 72526c8327fb..2b0334703884 100644 --- a/app/client/cypress/e2e/Regression/ClientSide/Widgets/TreeSelect/Tree_Select_2_spec.ts +++ b/app/client/cypress/e2e/Regression/ClientSide/Widgets/TreeSelect/Tree_Select_2_spec.ts @@ -186,9 +186,12 @@ describe( `{{JSON.parse(Api1.data).map((item) => {return {"label":item.value, "value":item.abbr};})}}`, ); agHelper.GetNClick( - `${locators._widgetInDeployed("singleselecttreewidget")}`, + `${locators._widgetInDeployed("singleselecttreewidget")} ${locators._treeSelectSelector}`, ); agHelper.AssertElementExist(locators._treeSelectTitle); + agHelper.GetNClick( + `${locators._widgetInDeployed("singleselecttreewidget")} ${locators._treeSelectSelector}`, + ); }); it("6. Verify onOptionChange with query", () => { @@ -228,13 +231,41 @@ describe( ); agHelper.GetNClick(propPane._actionSelectorPopupClose); deployMode.DeployApp(); - agHelper.WaitUntilEleAppear( - `${locators._widgetInDeployed("singleselecttreewidget")} ${locators._treeSelectSelector}`, - ); - agHelper.GetNClick( - `${locators._widgetInDeployed("singleselecttreewidget")} ${locators._treeSelectSelector}`, + const treeSelectWidget = `${locators._widgetInDeployed("singleselecttreewidget")}`; + const treeSelectClickTarget = `${treeSelectWidget} ${locators._treeSelectSelector}`; + const dropdownOpenClass = "rc-tree-select-open"; + agHelper.WaitUntilEleAppear(treeSelectClickTarget); + // Phase 1: Click selector until the dropdown is confirmed open. + // Uses the library's own open-state class on the widget root, not + // the dropdown content, so a slow option render cannot cause a + // toggle-close retry. + cy.waitUntil( + () => { + const isOpen = + Cypress.$(`${treeSelectWidget} .rc-tree-select`).hasClass( + dropdownOpenClass, + ); + if (!isOpen) { + cy.get(treeSelectClickTarget).first().click(); + } + return cy.then(() => + Cypress.$(`${treeSelectWidget} .rc-tree-select`).hasClass( + dropdownOpenClass, + ), + ); + }, + { + errorMsg: + "TreeSelect dropdown did not open after clicking the selector", + timeout: Cypress.config().pageLoadTimeout, + interval: 1000, + }, ); - agHelper.AssertElementVisibility(locators._treeSelectTitle); + // Phase 2: Dropdown is open — wait for the specific option to be + // visible before clicking it. + cy.xpath(locators._dropDownMultiTreeValue("Green"), { + timeout: 10000, + }).should("be.visible"); agHelper.GetNClick(locators._dropDownMultiTreeValue("Green")); agHelper.ValidateToastMessage("Success"); }); From 9d2a3d943115a178472497b007cdfa7f61ac51bc Mon Sep 17 00:00:00 2001 From: subrata71 Date: Wed, 8 Apr 2026 12:59:25 +0600 Subject: [PATCH 2/2] fix(test): use agHelper.GetElement instead of cy.xpath and apply prettier Replace direct cy.xpath call with agHelper.GetElement which auto-routes XPath selectors internally, consistent with how every other usage of _dropDownMultiTreeValue works in the codebase. Apply prettier formatting. --- .../Widgets/TreeSelect/Tree_Select_2_spec.ts | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/app/client/cypress/e2e/Regression/ClientSide/Widgets/TreeSelect/Tree_Select_2_spec.ts b/app/client/cypress/e2e/Regression/ClientSide/Widgets/TreeSelect/Tree_Select_2_spec.ts index 2b0334703884..cf3d4d76724c 100644 --- a/app/client/cypress/e2e/Regression/ClientSide/Widgets/TreeSelect/Tree_Select_2_spec.ts +++ b/app/client/cypress/e2e/Regression/ClientSide/Widgets/TreeSelect/Tree_Select_2_spec.ts @@ -241,10 +241,9 @@ describe( // toggle-close retry. cy.waitUntil( () => { - const isOpen = - Cypress.$(`${treeSelectWidget} .rc-tree-select`).hasClass( - dropdownOpenClass, - ); + const isOpen = Cypress.$( + `${treeSelectWidget} .rc-tree-select`, + ).hasClass(dropdownOpenClass); if (!isOpen) { cy.get(treeSelectClickTarget).first().click(); } @@ -263,9 +262,9 @@ describe( ); // Phase 2: Dropdown is open — wait for the specific option to be // visible before clicking it. - cy.xpath(locators._dropDownMultiTreeValue("Green"), { - timeout: 10000, - }).should("be.visible"); + agHelper + .GetElement(locators._dropDownMultiTreeValue("Green"), "exist", 10000) + .should("be.visible"); agHelper.GetNClick(locators._dropDownMultiTreeValue("Green")); agHelper.ValidateToastMessage("Success"); });