From f417add70cb8f6f628a6c2c2aafe5879f2080023 Mon Sep 17 00:00:00 2001 From: Daria Bodiakova <70635654+DariaBod@users.noreply.github.com> Date: Thu, 16 Jul 2026 12:35:25 -0700 Subject: [PATCH] test fixes --- .../ui/grids/FieldSelectionDialog.java | 95 ++++++++++++------- .../components/ui/navigation/ProductMenu.java | 2 +- 2 files changed, 60 insertions(+), 37 deletions(-) diff --git a/src/org/labkey/test/components/ui/grids/FieldSelectionDialog.java b/src/org/labkey/test/components/ui/grids/FieldSelectionDialog.java index 73b5c143e6..3e57a7b333 100644 --- a/src/org/labkey/test/components/ui/grids/FieldSelectionDialog.java +++ b/src/org/labkey/test/components/ui/grids/FieldSelectionDialog.java @@ -522,49 +522,67 @@ private List getSelectedListItems(String fieldLabel) */ public FieldSelectionDialog repositionField(FieldKey fieldToMove, FieldKey targetField, boolean beforeTarget) { - WebElement elementToMove = elementCache().findSelectedField(fieldToMove); - WebElement elementTarget = elementCache().findSelectedField(targetField); + List order = selectedFieldKeys(); + int from = indexOfFieldKey(order, fieldToMove); + int target = indexOfFieldKey(order, targetField); + int to = beforeTarget ? (from < target ? target - 1 : target) : (from < target ? target : target + 1); - int yBefore = elementToMove.getRect().getY(); + keyboardReorder(elementCache().findDragHandle(fieldToMove), to - from); - int offset; + WebDriverWrapper.waitFor(() -> { + List now = selectedFieldKeys(); + return indexOfFieldKey(now, fieldToMove) - indexOfFieldKey(now, targetField) == (beforeTarget ? -1 : 1); + }, "Field '" + fieldToMove + "' was not repositioned as expected", 5_000); - if(beforeTarget) - { - if(elementTarget.getRect().getY() < elementToMove.getRect().getY()) - { - // If the target is above the field being moved. - offset = -1 * elementTarget.getSize().getHeight(); - } - else - { - // If the target is below the field being moved. - offset = -1 * elementTarget.getSize().getHeight() / 2; - } - } - else - { - offset = elementTarget.getSize().getHeight() / 2 + 10; - } - - WebElement dragHandle = Locator.tagWithAttribute("div", "role", "button").findWhenNeeded(elementToMove); - getWrapper().mouseOver(dragHandle); - new Actions(getDriver()) - .clickAndHold(dragHandle) - .moveToElement(elementTarget) - .moveByOffset(2, offset) - .release() - .perform(); + return this; + } - // Maybe I don't need to wait? - WebDriverWrapper.sleep(1_000); + /** + * Reorder a row via the keyboard controls: focus the handle, Space to lift, one Arrow per + * step, Space to drop. (Mouse drag is unreliable with the library's sensor.) + * + * @param dragHandle The row's drag handle. + * @param steps Positions to move; negative moves up, positive moves down. + */ + private void keyboardReorder(WebElement dragHandle, int steps) + { + getWrapper().scrollIntoView(dragHandle); + getWrapper().executeScript("arguments[0].focus();", dragHandle); - int yAfter = elementToMove.getRect().getY(); + Actions drag = new Actions(getDriver()).sendKeys(Keys.SPACE).pause(Duration.ofMillis(400)); // lift + Keys arrow = steps < 0 ? Keys.ARROW_UP : Keys.ARROW_DOWN; + for (int i = 0; i < Math.abs(steps); i++) + drag.sendKeys(arrow).pause(Duration.ofMillis(300)); + drag.sendKeys(Keys.SPACE).perform(); // drop + } - WebDriverWrapper.waitFor(()-> yAfter != yBefore, "I don't think I repositioned the field in the list.", - 1_000); + /** + * Get the 'data-fieldkey' values of the selected fields, in display order. + * + * @return The encoded field keys. + */ + private List selectedFieldKeys() + { + return elementCache().getListItemElements(elementCache().selectedFieldsPanel).stream() + .map(el -> el.getDomAttribute("data-fieldkey")) + .collect(Collectors.toList()); + } - return this; + /** + * Get the index of a field in the given list, matched case-insensitively (as findFieldRow locates rows). + * + * @param fieldKeys Encoded field keys, in display order. + * @param fieldKey Field to locate. + * @return The index, or -1 if not present. + */ + private static int indexOfFieldKey(List fieldKeys, FieldKey fieldKey) + { + for (int i = 0; i < fieldKeys.size(); i++) + { + if (fieldKey.toString().equalsIgnoreCase(fieldKeys.get(i))) + return i; + } + return -1; } /** @@ -662,6 +680,11 @@ protected WebElement findSelectedField(FieldKey fieldKey) return findFieldRow(fieldKey, selectedFieldsPanel); } + protected WebElement findDragHandle(FieldKey fieldKey) + { + return Locator.tagWithAttribute("div", "role", "button").findElement(findSelectedField(fieldKey)); + } + protected WebElement findAvailableField(FieldKey fieldKey) { return findFieldRow(fieldKey, availableFieldsPanel); diff --git a/src/org/labkey/test/components/ui/navigation/ProductMenu.java b/src/org/labkey/test/components/ui/navigation/ProductMenu.java index 6889af2730..2858f65ff3 100644 --- a/src/org/labkey/test/components/ui/navigation/ProductMenu.java +++ b/src/org/labkey/test/components/ui/navigation/ProductMenu.java @@ -267,7 +267,7 @@ protected ElementCache newElementCache() protected class ElementCache extends Component.ElementCache { private final WebElement toggle = Locator.byClass("product-menu-button").findWhenNeeded(this); - private final WebElement menuContent = Locator.tagWithClass("div", "product-menu-content").findWhenNeeded(this); + private final WebElement menuContent = Locator.tagWithClass("div", "product-menu-content").refindWhenNeeded(this); private final WebElement folderColumn = Locator.tagWithClass("div", "col-folders").findWhenNeeded(menuContent); private final WebElement sectionContent = Locator.tagWithClass("div", "sections-content").findWhenNeeded(menuContent);