From 0f60cb84573e82c26e66cb9b1837759ce4599689 Mon Sep 17 00:00:00 2001 From: labkey-danield Date: Mon, 8 Sep 2025 10:11:07 -0700 Subject: [PATCH 1/6] Cherry-pick fix for FieldSelectionDialog from develop (and associated test changes). Don't need to click on the chevron icon. --- .../ui/grids/FieldSelectionDialog.java | 38 +++++++++---------- .../components/ui/grids/ResponsiveGrid.java | 5 +-- 2 files changed, 20 insertions(+), 23 deletions(-) diff --git a/src/org/labkey/test/components/ui/grids/FieldSelectionDialog.java b/src/org/labkey/test/components/ui/grids/FieldSelectionDialog.java index c7c01bbcae..994ee13f92 100644 --- a/src/org/labkey/test/components/ui/grids/FieldSelectionDialog.java +++ b/src/org/labkey/test/components/ui/grids/FieldSelectionDialog.java @@ -22,6 +22,7 @@ import java.util.List; import java.util.stream.Collectors; +import static org.labkey.test.util.TextUtils.normalizeSpace; import static org.labkey.test.util.selenium.WebElementUtils.getTextContent; /** @@ -180,13 +181,13 @@ public WebElement getAvailableFieldElement(FieldKey fieldKey) if(iterator.hasNext()) { // If the field is already expanded don't try to expand it. - if(!isFieldKeyExpanded(elementCache().findAvailableField(fieldKey.toString()))) - expandOrCollapseByFieldKey(fieldKey.toString(), true); + if(!isFieldKeyExpanded(elementCache().findAvailableField(fieldKey))) + expandOrCollapseByFieldKey(fieldKey, true); } } - return elementCache().findAvailableField(fieldKey.toString()); + return elementCache().findAvailableField(fieldKey); } /** @@ -195,7 +196,7 @@ public WebElement getAvailableFieldElement(FieldKey fieldKey) * @param fieldKey The data-fieldkey value of the field to expand. * @param expand True to expand false to collapse. */ - private void expandOrCollapseByFieldKey(String fieldKey, boolean expand) + private void expandOrCollapseByFieldKey(FieldKey fieldKey, boolean expand) { WebElement listItem = elementCache().findAvailableField(fieldKey); @@ -433,7 +434,7 @@ public FieldSelectionDialog setFieldLabel(String fieldName, String newFieldLabel */ public FieldSelectionDialog setFieldLabel(FieldKey fieldKey, String newFieldLabel) { - WebElement listItem = elementCache().findSelectedField(fieldKey.toString()); + WebElement listItem = elementCache().findSelectedField(fieldKey); WebElement updateIcon = Locator.tagWithClass("span", "edit-inline-field__toggle").findWhenNeeded(listItem); updateIcon.click(); @@ -453,9 +454,9 @@ public FieldSelectionDialog setFieldLabel(FieldKey fieldKey, String newFieldLabe getWrapper().mouseOver(elementCache().title); // Dismiss tooltip - WebDriverWrapper.waitFor(()->!elementCache().fieldLabelEdit.isDisplayed() && - elementCache().getListItemElement(elementCache().selectedFieldsPanel, newFieldLabel).isDisplayed(), + WebDriverWrapper.waitFor(()->!elementCache().fieldLabelEdit.isDisplayed(), String.format("New field label '%s' is not in the list.", newFieldLabel), 500); + Assert.assertEquals("Label after update", normalizeSpace(newFieldLabel), elementCache().getFieldLabel(fieldKey)); return this; } @@ -503,10 +504,10 @@ private List getSelectedListItems(String fieldLabel) * @param beforeTarget Will the field being moved go before (above) or after (below) the target field. * @return This dialog. */ - public FieldSelectionDialog repositionField(String fieldToMove, String targetField, boolean beforeTarget) + public FieldSelectionDialog repositionField(FieldKey fieldToMove, FieldKey targetField, boolean beforeTarget) { - WebElement elementToMove = elementCache().getListItemElement(elementCache().selectedFieldsPanel, fieldToMove); - WebElement elementTarget = elementCache().getListItemElement(elementCache().selectedFieldsPanel, targetField); + WebElement elementToMove = elementCache().findSelectedField(fieldToMove); + WebElement elementTarget = elementCache().findSelectedField(targetField); int yBefore = elementToMove.getRect().getY(); @@ -633,28 +634,27 @@ protected List getListItemElements(WebElement panel, String fieldLab .findElements(panel); } - // Will get the first list item that matches the fieldLabel. - protected WebElement getListItemElement(WebElement panel, String fieldLabel) + protected String getFieldLabel(FieldKey fieldKey) { - return Locator.tagWithClass("div", "list-group-item") - .withDescendant(Locator.tagWithClass("div", "field-caption").withText(fieldLabel)) - .findElement(panel); + return Locator.tagWithClass("div", "field-caption") + .findElement(findFieldRow(fieldKey, selectedFieldsPanel)) + .getText(); } - protected WebElement findSelectedField(String fieldKey) + protected WebElement findSelectedField(FieldKey fieldKey) { return findFieldRow(fieldKey, selectedFieldsPanel); } - protected WebElement findAvailableField(String fieldKey) + protected WebElement findAvailableField(FieldKey fieldKey) { return findFieldRow(fieldKey, availableFieldsPanel); } - protected WebElement findFieldRow(String fieldKey, WebElement panel) + protected WebElement findFieldRow(FieldKey fieldKey, WebElement panel) { return Locator.tagWithClass("div", "list-group-item") - .withAttributeIgnoreCase("data-fieldkey", fieldKey) + .withAttributeIgnoreCase("data-fieldkey", fieldKey.toString()) .findElement(panel); } diff --git a/src/org/labkey/test/components/ui/grids/ResponsiveGrid.java b/src/org/labkey/test/components/ui/grids/ResponsiveGrid.java index f0f9055b95..1f89296013 100644 --- a/src/org/labkey/test/components/ui/grids/ResponsiveGrid.java +++ b/src/org/labkey/test/components/ui/grids/ResponsiveGrid.java @@ -317,10 +317,7 @@ public void clickColumnMenuItem(CharSequence columnIdentifier, String menuText, // Scroll to middle in order to make room for the dropdown menu getWrapper().scrollToMiddle(headerCell); - WebElement toggle = Locator.tagWithClass("span", "fa-chevron-circle-down") - .findElement(headerCell); - getWrapper().shortWait().until(ExpectedConditions.elementToBeClickable(toggle)); - toggle.click(); + headerCell.click(); // 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. From 3e6929c53feb0cb9c23751809386bf70cac29ab1 Mon Sep 17 00:00:00 2001 From: labkey-danield Date: Mon, 8 Sep 2025 14:33:01 -0700 Subject: [PATCH 2/6] Exclude {} and () from field nmaes used in name expresion test. Cherry-picked fix to avoid popups in the query grid header. Don't use the url to validate navigation. --- src/org/labkey/test/selenium/ReclickingWebElement.java | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/src/org/labkey/test/selenium/ReclickingWebElement.java b/src/org/labkey/test/selenium/ReclickingWebElement.java index cf0e34f256..0417cf1c19 100644 --- a/src/org/labkey/test/selenium/ReclickingWebElement.java +++ b/src/org/labkey/test/selenium/ReclickingWebElement.java @@ -15,7 +15,6 @@ */ package org.labkey.test.selenium; -import org.apache.commons.lang3.Strings; import org.apache.commons.lang3.mutable.Mutable; import org.apache.commons.lang3.mutable.MutableObject; import org.jetbrains.annotations.NotNull; @@ -212,18 +211,15 @@ private void revealElement(WebElement el, String shortMessage) if (!blockResolved) { + // Move mouse to corner to dismiss tooltips + new Actions(getDriver()).moveToLocation(0,0).perform(); + Locator.XPathLocator interceptingElLoc = parseInterceptingElementLoc(shortMessage); if (interceptingElLoc != null) { List interceptingElements = interceptingElLoc.findElements(getDriver()); TestLogger.debug("Found %s element(s) matching extracted locator: %s".formatted(interceptingElements.size(), shortMessage)); - if (Strings.CI.containsAny(interceptingElLoc.toString(), "popover", "ws-pre-wrap", "tip")) - { - // Move mouse to corner to dismiss tooltips - new Actions(getDriver()).moveToLocation(0,0).perform(); - } - if (interceptingElements.size() == 1) { //noinspection ResultOfMethodCallIgnored From 7b234db3e88d06df609521fd39f39b5996a7d4b4 Mon Sep 17 00:00:00 2001 From: labkey-danield Date: Mon, 8 Sep 2025 15:42:46 -0700 Subject: [PATCH 3/6] Try to get thread dump if there is a serverside socket timeout exception. --- src/org/labkey/test/BaseWebDriverTest.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/org/labkey/test/BaseWebDriverTest.java b/src/org/labkey/test/BaseWebDriverTest.java index ca319c26c4..bf3ee85a87 100644 --- a/src/org/labkey/test/BaseWebDriverTest.java +++ b/src/org/labkey/test/BaseWebDriverTest.java @@ -984,7 +984,8 @@ private void handleFailure(Throwable error, @LoggedParam String testName) } try { - if (wasCausedBy(error, Arrays.asList(TestTimeoutException.class, SocketTimeoutException.class))) + if (wasCausedBy(error, Arrays.asList(TestTimeoutException.class, SocketTimeoutException.class)) || + wasCausedBy(error, Arrays.asList(RuntimeException.class, SocketTimeoutException.class))) ArtifactCollector.dumpThreads(); } catch (RuntimeException | Error e) From dc887f45b1a3a434d99ece8b37ea9369bce9668d Mon Sep 17 00:00:00 2001 From: labkey-danield Date: Mon, 8 Sep 2025 15:58:37 -0700 Subject: [PATCH 4/6] Revert GridColumnMenu change. --- src/org/labkey/test/components/ui/grids/ResponsiveGrid.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/org/labkey/test/components/ui/grids/ResponsiveGrid.java b/src/org/labkey/test/components/ui/grids/ResponsiveGrid.java index 1f89296013..f0f9055b95 100644 --- a/src/org/labkey/test/components/ui/grids/ResponsiveGrid.java +++ b/src/org/labkey/test/components/ui/grids/ResponsiveGrid.java @@ -317,7 +317,10 @@ public void clickColumnMenuItem(CharSequence columnIdentifier, String menuText, // Scroll to middle in order to make room for the dropdown menu getWrapper().scrollToMiddle(headerCell); - headerCell.click(); + WebElement toggle = Locator.tagWithClass("span", "fa-chevron-circle-down") + .findElement(headerCell); + getWrapper().shortWait().until(ExpectedConditions.elementToBeClickable(toggle)); + toggle.click(); // 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. From 5b7260c160ae4a9437c27a46fc35916100b73c61 Mon Sep 17 00:00:00 2001 From: labkey-danield Date: Tue, 9 Sep 2025 07:56:14 -0700 Subject: [PATCH 5/6] Revert BaseWebDriverTest --- src/org/labkey/test/BaseWebDriverTest.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/org/labkey/test/BaseWebDriverTest.java b/src/org/labkey/test/BaseWebDriverTest.java index bf3ee85a87..ca319c26c4 100644 --- a/src/org/labkey/test/BaseWebDriverTest.java +++ b/src/org/labkey/test/BaseWebDriverTest.java @@ -984,8 +984,7 @@ private void handleFailure(Throwable error, @LoggedParam String testName) } try { - if (wasCausedBy(error, Arrays.asList(TestTimeoutException.class, SocketTimeoutException.class)) || - wasCausedBy(error, Arrays.asList(RuntimeException.class, SocketTimeoutException.class))) + if (wasCausedBy(error, Arrays.asList(TestTimeoutException.class, SocketTimeoutException.class))) ArtifactCollector.dumpThreads(); } catch (RuntimeException | Error e) From c96c2c29d49023cc95b6f083da750e4f024928b7 Mon Sep 17 00:00:00 2001 From: labkey-danield Date: Fri, 12 Sep 2025 13:14:59 -0700 Subject: [PATCH 6/6] Fix LinkedSchemaTest --- src/org/labkey/test/tests/LinkedSchemaTest.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/org/labkey/test/tests/LinkedSchemaTest.java b/src/org/labkey/test/tests/LinkedSchemaTest.java index fa7ccf7ca3..dbac31103c 100644 --- a/src/org/labkey/test/tests/LinkedSchemaTest.java +++ b/src/org/labkey/test/tests/LinkedSchemaTest.java @@ -44,7 +44,6 @@ import org.labkey.test.util.AuditLogHelper; import org.labkey.test.util.DataRegionTable; import org.labkey.test.util.LogMethod; -import org.labkey.test.util.PortalHelper; import org.labkey.test.util.SchemaHelper; import org.labkey.test.util.TestDataGenerator; import org.labkey.test.util.exp.DataClassAPIHelper; @@ -1057,7 +1056,7 @@ private void createExperiment(String externalProject, String subFolder, String s goToProjectHome(externalProject); clickTab("Experiment"); waitAndClickAndWait(Locator.linkContainingText("Create Run Group")); - setFormElement(Locator.name("name"), "Parent Run Group"); + setFormElement(Locator.name("Name"), "Parent Run Group"); clickButton("Submit"); _containerHelper.createSubfolder(externalProject, subFolder); @@ -1065,7 +1064,7 @@ private void createExperiment(String externalProject, String subFolder, String s // Create a RunGroup in the subfolder. clickTab("Experiment"); waitAndClickAndWait(Locator.linkContainingText("Create Run Group")); - setFormElement(Locator.name("name"), subFolderRunGroup); + setFormElement(Locator.name("Name"), subFolderRunGroup); clickButton("Submit"); }