Skip to content
34 changes: 28 additions & 6 deletions src/org/labkey/test/WebDriverWrapper.java
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@
import org.openqa.selenium.Keys;
import org.openqa.selenium.NoAlertPresentException;
import org.openqa.selenium.NoSuchElementException;
import org.openqa.selenium.NoSuchWindowException;
import org.openqa.selenium.ScriptTimeoutException;
import org.openqa.selenium.SearchContext;
import org.openqa.selenium.StaleElementReferenceException;
Expand Down Expand Up @@ -1637,14 +1638,12 @@ public boolean isTextPresent(String... texts)
if (htmlSource == null || !htmlSource.contains(text))
present.setFalse();

return present.getValue();
return present.get();
};
TextSearcher searcher = new TextSearcher(this);
searcher.setSearchTransformer(TextSearcher.TextTransformers.IDENTITY);
searcher.setSourceTransformer(TextSearcher.TextTransformers.IDENTITY);
searcher.searchForTexts(handler, Arrays.asList(texts));

return present.getValue();
return present.get();
}

public List<String> getTextOrder(TextSearcher searcher, String... texts)
Expand Down Expand Up @@ -1735,12 +1734,12 @@ public boolean isAnyTextPresent(String... texts)
if (htmlSource.contains(text))
found.setTrue();

return !found.getValue(); // stop searching if any value is found
return !found.get(); // stop searching if any value is found
};
TextSearcher searcher = new TextSearcher(this);
searcher.searchForTexts(handler, Arrays.asList(texts));

return found.getValue();
return found.get();
}

/**
Expand Down Expand Up @@ -2140,6 +2139,29 @@ public long doAndMaybeWaitForPageToLoad(int msWait, Supplier<Boolean> action)
return loadTimer.elapsed().toMillis();
}

public long doAndWaitForWindow(Runnable action, String windowName)
{
return doAndMaybeWaitForPageToLoad(10_000, () -> {
String initialWindow = getDriver().getWindowHandle();
boolean targetWindowExists;
try
{
getDriver().switchTo().window(windowName);
getDriver().switchTo().window(initialWindow);
targetWindowExists = true;
}
catch (NoSuchWindowException e)
{
targetWindowExists = false;
}

action.run();

getDriver().switchTo().window(windowName);
return targetWindowExists;
});
}

public long doAndAcceptUnloadAlert(Runnable func, String partialAlertText)
{
return doAndWaitForPageToLoad(() ->
Expand Down
33 changes: 23 additions & 10 deletions src/org/labkey/test/components/ui/Pager.java
Original file line number Diff line number Diff line change
Expand Up @@ -63,28 +63,41 @@ public int getCurrentPage() // only works on GridPanel

public Pager selectPageSize(String pageSize) // only works on GridPanel
{
int currentPageSize = getPageSize();
if(currentPageSize != Integer.parseInt(pageSize))
{
_pagedComponent.doAndWaitForUpdate(() -> elementCache().jumpToDropdown.clickSubMenu(false, pageSize));
}
pageSize(pageSize);
return this;
}

public int getPageSize() // only works on GridPanel
{
// Changing the jumpToDropdown button from the deprecated DropdownButtonGroup class to a MultiMenu type has changed
// the way that various text from the control is gathered. Getting the current page size now requires that the dropdown
return pageSize(null);
}

/**
* Sets the page size if required (pageSize is specified and doesn't match the current page size)
* @return returns the initial page size
*/
private int pageSize(String pageSize) // only works on GridPanel
{
// Getting the current page size requires that the dropdown
// be expanded and the selected page size found in the list.
elementCache().jumpToDropdown.expand();

// Find the selected li element in the page size list
WebElement activeLi = Locator.byClass("active").findElement(elementCache().jumpToDropdown);

int size = Integer.parseInt(activeLi.getText());
elementCache().jumpToDropdown.collapse();
int initialSize = Integer.parseInt(activeLi.getText());

if (pageSize != null && initialSize != Integer.parseInt(pageSize))
{
_pagedComponent.doAndWaitForUpdate(() -> elementCache().jumpToDropdown.clickSubMenu(false, pageSize));
}
else
{
// Tooltip sometimes blocks button. Click active option to dismiss menu.
activeLi.click();
}

return size;
return initialSize;
}

/**
Expand Down
71 changes: 27 additions & 44 deletions src/org/labkey/test/components/ui/grids/EditableGrid.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import org.labkey.test.components.ui.grids.FieldReferenceManager.FieldReference;
import org.labkey.test.params.FieldDefinition;
import org.labkey.test.params.FieldKey;
import org.labkey.test.util.CachingSupplier;
import org.labkey.test.util.selenium.ScrollUtils;
import org.labkey.test.util.selenium.WebElementUtils;
import org.openqa.selenium.By;
Expand Down Expand Up @@ -176,55 +177,29 @@ public boolean canRemoveColumn(CharSequence columnIdentifier)

private boolean hasSelectColumn()
{
return elementCache().selectColumn.isDisplayed();
return elementCache().hasSelectColumn.get();
}

public EditableGrid selectRow(int index, boolean checked)
{
if (hasSelectColumn())
{
WebElement checkBox = Locator.css("td > input[type=checkbox]").findElement(getRow(index));
getWrapper().setCheckbox(checkBox, checked);
}
else
{
throw new NoSuchElementException("There is no select checkbox for row " + index);
}
elementCache().getCheckbox(index).set(checked);
return this;
}

public boolean isRowSelected(int index)
{
if (hasSelectColumn())
{
WebElement checkBox = Locator.css("td > input[type=checkbox]").findElement(getRow(index));
return checkBox.isSelected();
}
else
{
throw new NoSuchElementException("There is no select checkbox for row " + index);
}
return elementCache().getCheckbox(index).isSelected();
}

public EditableGrid selectAll(boolean checked)
{
if (hasSelectColumn())
{
getWrapper().setCheckbox(elementCache().selectColumn, checked);
}
else
{
throw new NoSuchElementException("There is no select checkbox for all rows.");
}
elementCache().selectAllCheckbox.set(checked);
return this;
}

public boolean areAllRowsSelected()
{
if (hasSelectColumn())
return new Checkbox(elementCache().selectColumn).isSelected();
else
throw new NoSuchElementException("There is no select checkbox for all rows.");
return elementCache().selectAllCheckbox.isSelected();
}

/**
Expand All @@ -237,26 +212,22 @@ public boolean areAllRowsSelected()
public EditableGrid shiftSelectRange(int start, int end)
{
if (!hasSelectColumn())
throw new NoSuchElementException("there is no select checkbox for all rows");
throw new NoSuchElementException("there is no selection column for grid");

var checkBoxes = Locator.tag("tr").child("td")
.child(Locator.tagWithAttribute("input", "type", "checkbox"))
.findElements(elementCache().table);
getWrapper().scrollIntoView(checkBoxes.get(0), true); // bring as much of the grid into view as possible
getWrapper().scrollIntoView(checkBoxes.get(start)); // Make sure the header isn't in the way
checkBoxes.get(start).click();
getWrapper().scrollIntoView(checkBoxes.get(end)); // Actions.click() doesn't scroll
new Actions(getDriver())
.click(checkBoxes.get(start))
.keyDown(Keys.SHIFT)
.click(checkBoxes.get(end))
.keyUp(Keys.SHIFT)
.perform();
return this;
}

private List<WebElement> getRows()
{
return Locators.rows.findElements(elementCache().table);
}

/**
* @param columnIdentifiers fieldKeys, names, or labels of columns
* @return grid data for the specified columns, keyed by column label
Expand Down Expand Up @@ -316,7 +287,7 @@ private <T> List<Map<T, String>> getGridData(Function<FieldReferenceManager.Fiel
}
}

for (WebElement row : getRows())
for (WebElement row : elementCache().getRows())
{
List<WebElement> cells = row.findElements(By.tagName("td"));
Map<T, String> rowMap = new LinkedHashMap<>(includedColHeaders.size());
Expand Down Expand Up @@ -362,7 +333,7 @@ public List<String> getColumnData(CharSequence columnIdentifier)

private WebElement getRow(int index)
{
return getRows().get(index);
return elementCache().getRows().get(index);
}

/**
Expand Down Expand Up @@ -412,7 +383,7 @@ public boolean isCellReadOnly(int row, CharSequence columnIdentifier)

public int getRowCount()
{
return getRows().size();
return elementCache().getRows().size();
}

/**
Expand Down Expand Up @@ -682,6 +653,7 @@ public WebElement activateCellUsingDoubleClick(int row, CharSequence columnIdent
// Account for the cell already being active.
if(!textArea.isDisplayed())
{
getWrapper().scrollIntoView(gridCell);
getWrapper().doubleClick(gridCell);
waitFor(textArea::isDisplayed,
String.format("Table cell for row %d and column '%s' was not activated.", row, columnIdentifier), 1_000);
Expand Down Expand Up @@ -1111,7 +1083,7 @@ private boolean areAllInSelection()
List<String> columns = getColumnLabels();
int selectIndexOffset = hasSelectColumn() ? 1 : 0;
WebElement indexCell = getCell(0, columns.get(1 + selectIndexOffset));
WebElement endCell = getCell(getRows().size()-1, columns.get(columns.size()-1));
WebElement endCell = getCell(elementCache().getRows().size()-1, columns.get(columns.size()-1));
return (isInSelection(indexCell) && isInSelection(endCell));
}

Expand Down Expand Up @@ -1244,7 +1216,13 @@ protected class ElementCache extends Component<?>.ElementCache
final WebElement deleteRowsBtn = Locator.byClass("bulk-remove-button").findWhenNeeded(topControls);
final ExportMenu exportMenu = ExportMenu.finder(getDriver()).findWhenNeeded(topControls);
final WebElement table = Locator.byClass("table-cellular").findWhenNeeded(this);
private final WebElement selectColumn = Locator.xpath("//th/input[@type='checkbox']").findWhenNeeded(table);
private final Checkbox selectAllCheckbox = new Checkbox(Locator.xpath("//th/input[@type='checkbox']").findWhenNeeded(table));
private final CachingSupplier<Boolean> hasSelectColumn = new CachingSupplier<>(selectAllCheckbox::isDisplayed);

Checkbox getCheckbox(int rowIndex)
{
return new Checkbox(Locator.css("td > input[type=checkbox]").findElement(getRow(rowIndex)));
}

protected WebElement getColumnHeaderCell(CharSequence columnIdentifier)
{
Expand Down Expand Up @@ -1317,6 +1295,11 @@ public ReactDateTimePicker datePicker()
final WebElement addRowsPanel = Locator.byClass("editable-grid__controls").findWhenNeeded(this);
final Input addCountInput = Input.Input(Locator.name("addCount"), getDriver()).findWhenNeeded(addRowsPanel);
final WebElement addRowsButton = Locator.byClass("btn-primary").findWhenNeeded(addRowsPanel);

List<WebElement> getRows()
{
return Locators.rows.findElements(table);
}
}

protected abstract static class Locators
Expand Down
5 changes: 3 additions & 2 deletions src/org/labkey/test/pages/ConfigureReportsAndScriptsPage.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
import org.labkey.test.util.LogMethod;
import org.labkey.test.util.LoggedParam;
import org.labkey.test.util.TestLogger;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;

import java.io.File;
Expand All @@ -45,7 +46,7 @@ public class ConfigureReportsAndScriptsPage extends LabKeyPage
private static final String DEFAULT_ENGINE = "Mozilla Rhino";
private static final String EDIT_WINDOW_TITLE = "Edit Engine Configuration";

public ConfigureReportsAndScriptsPage(WebDriverWrapper test)
public ConfigureReportsAndScriptsPage(WebDriver test)
{
super(test);
waitForEnginesGrid();
Expand All @@ -54,7 +55,7 @@ public ConfigureReportsAndScriptsPage(WebDriverWrapper test)
public static ConfigureReportsAndScriptsPage beginAt(WebDriverWrapper driver)
{
driver.beginAt(WebTestHelper.buildURL("core", "configureReportsAndScripts"));
return new ConfigureReportsAndScriptsPage(driver);
return new ConfigureReportsAndScriptsPage(driver.getDriver());
}

public void waitForEnginesGrid()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,8 @@ public static ConfigureSystemMaintenancePage beginAt(WebDriverWrapper webDriverW
*/
public PipelineStatusDetailsPage runMaintenanceTask(String description)
{
click(Locator.tagWithAttribute("input", "type", "checkbox")
.followingSibling("a").withText(description));
getDriver().switchTo().window("systemMaintenance");
doAndWaitForWindow(() -> click(Locator.tagWithAttribute("input", "type", "checkbox")
.followingSibling("a").withText(description)), "systemMaintenance");

PipelineStatusDetailsPage pipelineStatusDetailsPage = new PipelineStatusDetailsPage(getDriver());
pipelineStatusDetailsPage.waitForComplete();
Expand Down
Loading