diff --git a/src/org/labkey/test/components/ui/grids/EditableGrid.java b/src/org/labkey/test/components/ui/grids/EditableGrid.java index f4a98faf73..fb0e315767 100644 --- a/src/org/labkey/test/components/ui/grids/EditableGrid.java +++ b/src/org/labkey/test/components/ui/grids/EditableGrid.java @@ -1034,39 +1034,9 @@ public String copyCurrentSelection() throws IOException, UnsupportedFlavorExcept return getWrapper().getClipboardContent(); } - /** - * Select a cell range and drag-fill from the end of that selection to {@code dragEnd}. - * Because this overload owns the {@link #selectCellRange} step, it can fully restore state - * and retry if the first drag extended the selection without applying the fill. - * - * @param selectStart first cell of the selection (passed to {@link #selectCellRange}) - * @param selectEnd last cell of the selection; also the source of the fill value - * @param dragEnd destination cell for the fill drag - */ - public void dragFill(WebElement selectStart, WebElement selectEnd, WebElement dragEnd) - { - Locator.XPathLocator selectionHandleLoc = Locator.byClass("cell-selection-handle"); - selectCellRange(selectStart, selectEnd); - selectEnd.click(); - String fillValue = getCellValue(selectEnd); - WebElement selectionHandle = selectionHandleLoc.waitForElement(getComponentElement(), 2_000); - dragToCell(selectionHandle, dragEnd); - if (!WebDriverWrapper.waitFor(() -> fillValue.equals(getCellValue(dragEnd)), 3_000)) - { - // Fill didn't complete — the drag likely extended the selection without triggering the fill. - selectCellRange(selectStart, selectEnd); - selectEnd.click(); - selectionHandle = selectionHandleLoc.waitForElement(getComponentElement(), 2_000); - dragToCell(selectionHandle, dragEnd); - WebDriverWrapper.waitFor(() -> fillValue.equals(getCellValue(dragEnd)), - "Drag fill did not populate end cell with value: " + fillValue, 5_000); - } - } - /** * Drag-fill from {@code startCell} (which must already be selected / part of the current - * selection) to {@code endCell}. Prefer {@link #dragFill(WebElement, WebElement, WebElement)} - * when the selection range is known — that overload can retry reliably. + * selection) to {@code endCell}. */ public void dragFill(WebElement startCell, WebElement endCell) { @@ -1077,6 +1047,21 @@ public void dragFill(WebElement startCell, WebElement endCell) selectionHandleLoc.waitForElement(endCell, 5_000); } + /** + * Select {@code selectStart} through {@code dragEnd} and fill down from {@code selectEnd}'s row using Ctrl/Cmd+D. + * @param selectStart top-left cell of the range to select + * @param selectEnd cell whose value will be filled down (must be in {@code selectStart}'s row) + * @param dragEnd bottom-right cell of the range to select and fill down to + */ + public void fillDown(WebElement selectStart, WebElement selectEnd, WebElement dragEnd) + { + selectCellRange(selectStart, dragEnd); + String fillValue = getCellValue(selectEnd); + new Actions(getDriver()).keyDown(MODIFIER_KEY).sendKeys("d").keyUp(MODIFIER_KEY).build().perform(); + WebDriverWrapper.waitFor(() -> fillValue.equals(getCellValue(dragEnd)), + "Fill-down did not populate end cell with value: " + fillValue, 3_000); + } + public void selectCellRange(WebElement startCell, WebElement endCell) { dragToCell(startCell, endCell); @@ -1195,8 +1180,9 @@ private boolean isInSelection(WebElement cell) // 'in selection' shows as blue { // Should not need to add code for a reactSelect here. A selection involves clicking/dragging, which closes the reactSelect. return Locator.tagWithClass("div", "cellular-display") - .findElement(cell) - .getDomAttribute("class").contains("cell-selection"); + .findOptionalElement(cell) + .map(el -> el.getDomAttribute("class").contains("cell-selection")) + .orElse(false); } /**