diff --git a/src/org/labkey/test/WebDriverWrapper.java b/src/org/labkey/test/WebDriverWrapper.java index 27e2aaafc9..1effae6b41 100644 --- a/src/org/labkey/test/WebDriverWrapper.java +++ b/src/org/labkey/test/WebDriverWrapper.java @@ -3088,6 +3088,35 @@ public void dragAndDrop(WebElement fromEl, int xOffset, int yOffset) builder.clickAndHold(fromEl).moveByOffset(xOffset + 1, yOffset + 1).release().build().perform(); } + /** + * Reorder a drag-and-drop list with the keyboard instead of the mouse: focus the drag handle, Space to lift, + * one Arrow per step, Space to drop. Required for lists built on '@hello-pangea/dnd' (auth configurations, + * domain designer, field selection). + * + * @param dragHandle Element carrying the library's drag handle props; must be focusable. + * @param steps Positions to move; negative moves up, positive moves down. + */ + public void keyboardDragAndDrop(WebElement dragHandle, int steps) + { + dragHandle.sendKeys(Keys.SPACE); + + Actions drag = new Actions(getDriver()).pause(Duration.ofMillis(400)); + 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(); + } + + /** + * @see #keyboardDragAndDrop(WebElement, int) + * @param dragHandle Drag handle of the element to move. + * @param target Drag handle of a sibling element to move it to. + */ + public void keyboardDragAndDrop(WebElement dragHandle, WebElement target) + { + keyboardDragAndDrop(dragHandle, getElementIndex(target) - getElementIndex(dragHandle)); + } + // This is useful when making a draggin selection in a plot, and there may be many elements ontop of the one you want. public void dragAndDrop(int xOffset, int yOffset) { diff --git a/src/org/labkey/test/components/ui/grids/FieldSelectionDialog.java b/src/org/labkey/test/components/ui/grids/FieldSelectionDialog.java index 583bb3098d..f8f0dda716 100644 --- a/src/org/labkey/test/components/ui/grids/FieldSelectionDialog.java +++ b/src/org/labkey/test/components/ui/grids/FieldSelectionDialog.java @@ -530,7 +530,7 @@ public FieldSelectionDialog repositionField(FieldKey fieldToMove, FieldKey targe int target = indexOfFieldKey(order, targetField); int to = beforeTarget ? (from < target ? target - 1 : target) : (from < target ? target : target + 1); - keyboardReorder(elementCache().findDragHandle(fieldToMove), to - from); + getWrapper().keyboardDragAndDrop(elementCache().findDragHandle(fieldToMove), to - from); WebDriverWrapper.waitFor(() -> { List now = selectedFieldKeys(); @@ -540,25 +540,6 @@ public FieldSelectionDialog repositionField(FieldKey fieldToMove, FieldKey targe return this; } - /** - * 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); - - 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 - } - /** * Get the 'data-fieldkey' values of the selected fields, in display order. * diff --git a/src/org/labkey/test/pages/core/login/LoginConfigRow.java b/src/org/labkey/test/pages/core/login/LoginConfigRow.java index 2f840381e8..42059113e0 100644 --- a/src/org/labkey/test/pages/core/login/LoginConfigRow.java +++ b/src/org/labkey/test/pages/core/login/LoginConfigRow.java @@ -72,6 +72,11 @@ public boolean canEdit() return elementCache().editButtonLoc.existsIn(this); } + public WebElement getDragHandle() + { + return elementCache().dragHandle; + } + @Override public WebElement getComponentElement() { @@ -93,6 +98,9 @@ protected ElementCache newElementCache() protected class ElementCache extends Component.ElementCache { + final WebElement dragHandle = Locator.xpath("ancestor::div") + .withAttribute("data-rfd-drag-handle-draggable-id").findWhenNeeded(this); + final WebElement baseFieldsElement = Locator.tagWithClass("div", "domain-row-base-fields").findWhenNeeded(this); final WebElement description = Locator.tagWithClass("div", "description").findWhenNeeded(baseFieldsElement); final WebElement details = Locator.tagWithClass("div", "details").findWhenNeeded(baseFieldsElement);