From a3a02a2c94656cc352d3e616e7aa142d21f5a29a Mon Sep 17 00:00:00 2001 From: labkey-tchad Date: Tue, 28 Oct 2025 14:16:55 -0700 Subject: [PATCH 1/2] Fix synchronization of ResponsiveGrid.editColumnLabel --- .../components/ui/grids/ResponsiveGrid.java | 25 ++++++------- .../test/util/LabKeyExpectedConditions.java | 37 +++++++++++++++++++ 2 files changed, 49 insertions(+), 13 deletions(-) diff --git a/src/org/labkey/test/components/ui/grids/ResponsiveGrid.java b/src/org/labkey/test/components/ui/grids/ResponsiveGrid.java index cf643d2d19..089b02a687 100644 --- a/src/org/labkey/test/components/ui/grids/ResponsiveGrid.java +++ b/src/org/labkey/test/components/ui/grids/ResponsiveGrid.java @@ -4,6 +4,7 @@ */ package org.labkey.test.components.ui.grids; +import org.awaitility.Awaitility; import org.jetbrains.annotations.Nullable; import org.labkey.remoteapi.query.Filter; import org.labkey.test.Locator; @@ -17,6 +18,7 @@ import org.labkey.test.components.ui.grids.FieldReferenceManager.FieldReference; import org.labkey.test.components.ui.search.FilterExpressionPanel; import org.labkey.test.params.FieldKey; +import org.labkey.test.util.LabKeyExpectedConditions; import org.labkey.test.util.selenium.WebElementUtils; import org.openqa.selenium.Keys; import org.openqa.selenium.NotFoundException; @@ -26,6 +28,7 @@ import org.openqa.selenium.interactions.Actions; import org.openqa.selenium.support.ui.ExpectedConditions; +import java.time.Duration; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; @@ -325,13 +328,13 @@ public void clickColumnMenuItem(CharSequence columnIdentifier, String menuText, // Use getDriver() because the grid menus are rendered in a "react portal" at the end of the HTML body, so they // are totally detached from the rest of the grid. WebElement menu = Locator.css("ul.grid-header-cell__dropdown-menu.open").findWhenNeeded(getDriver()); - WebElement menuItem = Locator.css("li > a").containing(menuText).findWhenNeeded(menu); - waitFor(menuItem::isDisplayed, 1000); + WebElement menuItem = getWrapper().quickWait().until(LabKeyExpectedConditions + .visibilityOf(Locator.css("li > a").containing(menuText), menu)); if (waitForUpdate) doAndWaitForUpdate(menuItem::click); else menuItem.click(); - waitFor(()-> !menuItem.isDisplayed(), 1000); + getWrapper().quickWait().until(ExpectedConditions.invisibilityOf(menuItem)); } /** @@ -357,20 +360,16 @@ public void editColumnLabel(CharSequence columnIdentifier, String newColumnLabel .keyUp(Keys.SHIFT) .perform(); - // Enter the new text. - textEdit.sendKeys(newColumnLabel, Keys.RETURN); + doAndWaitForUpdate(()-> { + textEdit.sendKeys(newColumnLabel, Keys.RETURN); - getWrapper().shortWait() + getWrapper().shortWait() .withMessage("Column label edit text box did not go away.") .until(ExpectedConditions.stalenessOf(textEdit)); - doAndWaitForUpdate(()-> - WebDriverWrapper.waitFor(()-> WebElementUtils.getTextContent(headerCell).equals(newColumnLabel), - "Column header not updated.", 1_000) - ); - waitForLoaded(); - clearElementCache(); - + Awaitility.await().atMost(Duration.ofSeconds(1)).untilAsserted(() -> assertEquals("Column label", + newColumnLabel, WebElementUtils.getTextContent(headerCell))); + }); } /** diff --git a/src/org/labkey/test/util/LabKeyExpectedConditions.java b/src/org/labkey/test/util/LabKeyExpectedConditions.java index 89a0960d32..d4d55f8d66 100644 --- a/src/org/labkey/test/util/LabKeyExpectedConditions.java +++ b/src/org/labkey/test/util/LabKeyExpectedConditions.java @@ -23,6 +23,7 @@ import org.openqa.selenium.NoSuchElementException; import org.openqa.selenium.NoSuchWindowException; import org.openqa.selenium.Point; +import org.openqa.selenium.SearchContext; import org.openqa.selenium.StaleElementReferenceException; import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebElement; @@ -182,6 +183,42 @@ public String toString() }; } + /** + * An expectation for checking child WebElement as a part of parent element to be visible + * + * @param childLocator used to find the child element. For example, {@code Locator.css("tr > td")} + * @param context used as the search context. For example, table with {@code Locator.tag("table")} + * @return visible sub-element + */ + public static ExpectedCondition visibilityOf(By childLocator, SearchContext context) + { + return new ExpectedCondition<>() + { + @Override + public WebElement apply(WebDriver webDriver) + { + try + { + WebElement element = context.findElement(childLocator); + if (element.isDisplayed()) + return element; + else + return null; + } + catch (NoSuchElementException | StaleElementReferenceException ex) + { + return null; + } + } + + @Override + public String toString() + { + return "visibility of element located by %s -> %s".formatted(context, childLocator); + } + }; + } + /** * Wraps {@link ExpectedConditions#stalenessOf(WebElement)} * Firefox occasionally throws "NoSuchElementException: Web element reference not seen before" From 9f8cee710de9651f350a59efc92d775aa00b2d9a Mon Sep 17 00:00:00 2001 From: labkey-tchad Date: Tue, 28 Oct 2025 14:59:42 -0700 Subject: [PATCH 2/2] Revert unrelated changes --- .../components/ui/grids/ResponsiveGrid.java | 7 ++-- .../test/util/LabKeyExpectedConditions.java | 37 ------------------- 2 files changed, 3 insertions(+), 41 deletions(-) diff --git a/src/org/labkey/test/components/ui/grids/ResponsiveGrid.java b/src/org/labkey/test/components/ui/grids/ResponsiveGrid.java index 089b02a687..e8bfad7634 100644 --- a/src/org/labkey/test/components/ui/grids/ResponsiveGrid.java +++ b/src/org/labkey/test/components/ui/grids/ResponsiveGrid.java @@ -18,7 +18,6 @@ import org.labkey.test.components.ui.grids.FieldReferenceManager.FieldReference; import org.labkey.test.components.ui.search.FilterExpressionPanel; import org.labkey.test.params.FieldKey; -import org.labkey.test.util.LabKeyExpectedConditions; import org.labkey.test.util.selenium.WebElementUtils; import org.openqa.selenium.Keys; import org.openqa.selenium.NotFoundException; @@ -328,13 +327,13 @@ public void clickColumnMenuItem(CharSequence columnIdentifier, String menuText, // Use getDriver() because the grid menus are rendered in a "react portal" at the end of the HTML body, so they // are totally detached from the rest of the grid. WebElement menu = Locator.css("ul.grid-header-cell__dropdown-menu.open").findWhenNeeded(getDriver()); - WebElement menuItem = getWrapper().quickWait().until(LabKeyExpectedConditions - .visibilityOf(Locator.css("li > a").containing(menuText), menu)); + WebElement menuItem = Locator.css("li > a").containing(menuText).findWhenNeeded(menu); + waitFor(menuItem::isDisplayed, 1000); if (waitForUpdate) doAndWaitForUpdate(menuItem::click); else menuItem.click(); - getWrapper().quickWait().until(ExpectedConditions.invisibilityOf(menuItem)); + waitFor(()-> !menuItem.isDisplayed(), 1000); } /** diff --git a/src/org/labkey/test/util/LabKeyExpectedConditions.java b/src/org/labkey/test/util/LabKeyExpectedConditions.java index d4d55f8d66..89a0960d32 100644 --- a/src/org/labkey/test/util/LabKeyExpectedConditions.java +++ b/src/org/labkey/test/util/LabKeyExpectedConditions.java @@ -23,7 +23,6 @@ import org.openqa.selenium.NoSuchElementException; import org.openqa.selenium.NoSuchWindowException; import org.openqa.selenium.Point; -import org.openqa.selenium.SearchContext; import org.openqa.selenium.StaleElementReferenceException; import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebElement; @@ -183,42 +182,6 @@ public String toString() }; } - /** - * An expectation for checking child WebElement as a part of parent element to be visible - * - * @param childLocator used to find the child element. For example, {@code Locator.css("tr > td")} - * @param context used as the search context. For example, table with {@code Locator.tag("table")} - * @return visible sub-element - */ - public static ExpectedCondition visibilityOf(By childLocator, SearchContext context) - { - return new ExpectedCondition<>() - { - @Override - public WebElement apply(WebDriver webDriver) - { - try - { - WebElement element = context.findElement(childLocator); - if (element.isDisplayed()) - return element; - else - return null; - } - catch (NoSuchElementException | StaleElementReferenceException ex) - { - return null; - } - } - - @Override - public String toString() - { - return "visibility of element located by %s -> %s".formatted(context, childLocator); - } - }; - } - /** * Wraps {@link ExpectedConditions#stalenessOf(WebElement)} * Firefox occasionally throws "NoSuchElementException: Web element reference not seen before"