Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
e4f1c05
Modernize EditableGridTest
labkey-tchad Jun 13, 2025
f842781
Merge remote-tracking branch 'origin/develop' into fb_editableGridNee…
labkey-tchad Jun 13, 2025
aa229a8
Merge remote-tracking branch 'origin/develop' into fb_editableGridNee…
labkey-tchad Jun 16, 2025
e1b2bff
Merge remote-tracking branch 'origin/develop' into fb_editableGridNee…
labkey-tchad Jun 16, 2025
e3faea4
FieldInfo and FieldKey updates and more random field names
labkey-tchad Jun 17, 2025
5b8c11c
Merge remote-tracking branch 'origin/develop' into fb_editableGridNee…
labkey-tchad Jun 18, 2025
28dbcd0
Merge remote-tracking branch 'origin/develop' into fb_editableGridNee…
labkey-tchad Jun 18, 2025
ea50db2
Merge remote-tracking branch 'origin/develop' into fb_editableGridNee…
labkey-tchad Jun 19, 2025
1c74fd9
Merge remote-tracking branch 'origin/develop' into fb_editableGridNee…
labkey-tchad Jun 20, 2025
e2c6dc7
Merge remote-tracking branch 'origin/develop' into fb_editableGridNee…
labkey-tchad Jun 24, 2025
ee0a4c4
Check for blank fieldkey parts
labkey-tchad Jun 25, 2025
36310b1
Improve FieldInfo and use random names for nameexpressiontest
labkey-tchad Jun 25, 2025
52ccae8
Update EditableGridTest with FieldInfo.random
labkey-tchad Jun 25, 2025
95d3f0b
Merge remote-tracking branch 'origin/develop' into fb_editableGridNee…
labkey-tchad Jul 3, 2025
145d0b7
Merge remote-tracking branch 'origin/develop' into fb_editableGridNee…
labkey-tchad Jul 7, 2025
df80ff2
Tidy up grid selection test
labkey-tchad Jul 7, 2025
c3a646d
Clean up some warnings
labkey-tchad Jul 8, 2025
a93aa78
Merge remote-tracking branch 'origin/develop' into fb_editableGridNee…
labkey-tchad Jul 9, 2025
3e9cf46
Merge remote-tracking branch 'origin/develop' into fb_editableGridNee…
labkey-tchad Jul 9, 2025
244498e
Remove bad merge bit and fix bad string format
labkey-tchad Jul 9, 2025
be96efe
Don't introduce '\' to random strings (yet)
labkey-tchad Jul 9, 2025
c33e754
Merge remote-tracking branch 'origin/develop' into fb_editableGridNee…
labkey-tchad Jul 10, 2025
a53cd24
Merge remote-tracking branch 'origin/develop' into fb_editableGridNee…
labkey-tchad Jul 10, 2025
5cd1893
code review feedback
labkey-tchad Jul 11, 2025
fd0b562
Fix AdminConsoleNavigationTest
labkey-tchad Jul 11, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 1 addition & 3 deletions src/org/labkey/test/BaseWebDriverTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -216,8 +216,6 @@ public abstract class BaseWebDriverTest extends LabKeySiteWrapper implements Cle

public static final double DELTA = 10E-10;

@Deprecated // Going away soon
public static final String[] ILLEGAL_QUERY_KEY_CHARACTERS = FieldKey.getIllegalChars().toArray(new String[0]);
public static final String ALL_ILLEGAL_QUERY_KEY_CHARACTERS = StringUtils.join(FieldKey.getIllegalChars(), "");
// See TSVWriter.shouldQuote. Generally we are not able to use the tab and new line characters when creating field names in the UI, but including here for completeness
public static final String[] TRICKY_IMPORT_FIELD_CHARACTERS = {"\\", "\"", "\\t", ",", "\\n", "\\r"};
Expand Down Expand Up @@ -300,7 +298,7 @@ public WebDriver getWrappedDriver()
return SingletonWebDriver.getInstance().getWebDriver();
}

protected abstract @Nullable String getProjectName();
protected abstract String getProjectName();

public final @Nullable String getPrimaryTestProject()
{
Expand Down
32 changes: 27 additions & 5 deletions src/org/labkey/test/components/ui/grids/EditableGrid.java
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.TimeZone;
import java.util.function.Function;
Expand Down Expand Up @@ -1114,6 +1115,20 @@ public String getCellError(int row, CharSequence columnIdentifier)
return null;
}

/**
* @param row row index
* @param columnIdentifier fieldKey, name, or label of column
* @return error popover text in the specified cell or 'null' if there is no error
*/
public String getErrorPopoverText(int row, CharSequence columnIdentifier)
{
WebElement gridCell = getCell(row, columnIdentifier);

if (cellHasError(gridCell))
return getCellPopoverText(row, columnIdentifier);
return null;
}

/**
* @param row row index
* @param columnIdentifier fieldKey, name, or label of column
Expand All @@ -1123,11 +1138,17 @@ public String getCellPopoverText(int row, CharSequence columnIdentifier)
{
WebElement cellDiv = Locator.tagWithClass("div", "cellular-display").findElement(getCell(row, columnIdentifier));
getWrapper().mouseOver(cellDiv); // cause the tooltip to be present
if (WebDriverWrapper.waitFor(()-> null != Locator.byClass("popover").findElementOrNull(getDriver()), 1000))
{
return Locator.byClass("popover").findElement(getDriver()).getText();
}
return null;
return Optional.ofNullable(WebDriverWrapper.waitFor(()-> Locators.popover.findElementOrNull(getDriver()), 1000))
.map(WebElement::getText)
.orElse(null);
}

public void dismissPopover()
{
Locators.popover.findOptionalElement(getDriver()).ifPresent(popover -> {
getWrapper().mouseOut();
getWrapper().shortWait().until(ExpectedConditions.invisibilityOf(popover));
});
}

public List<WebElement> getCellErrors()
Expand Down Expand Up @@ -1286,6 +1307,7 @@ private Locators()
static final Locator.XPathLocator rows = Locator.tag("tbody").childTag("tr").withoutClass("grid-empty").withoutClass("grid-loading");
static final Locator headerCells = Locator.css("thead tr th");
static final Locator inputCell = Locator.css(".eg-input-cell");
static final Locator popover = Locator.byClass("popover");
}

public static class EditableGridFinder extends WebDriverComponent.WebDriverComponentFinder<EditableGrid, EditableGridFinder>
Expand Down
25 changes: 19 additions & 6 deletions src/org/labkey/test/components/ui/grids/GridFilterModal.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@
import org.labkey.test.components.react.Tabs;
import org.labkey.test.components.ui.search.FilterExpressionPanel;
import org.labkey.test.components.ui.search.FilterFacetedPanel;
import org.labkey.test.params.WrapsFieldKey;
import org.labkey.test.util.selenium.WebElementUtils;
import org.openqa.selenium.NoSuchElementException;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.ui.ExpectedConditions;
Expand Down Expand Up @@ -36,12 +38,13 @@ protected void waitForReady()

/**
* Select field to configure filters for
* @param fieldLabel Field's label
* @param fieldIdentifier fieldKey or field label
* @return this component
*/
public GridFilterModal selectField(String fieldLabel)
public GridFilterModal selectField(CharSequence fieldIdentifier)
{
WebElement fieldItem = elementCache().findFieldOption(fieldLabel);
WebElement fieldItem = elementCache().findFieldOption(fieldIdentifier);
String fieldLabel = WebElementUtils.getTextContent(fieldItem);
fieldItem.click();
Locator.byClass("field-modal__col-sub-title").withText("Find values for " + fieldLabel)
.waitForElement(elementCache().filterPanel, 10_000);
Expand Down Expand Up @@ -182,15 +185,25 @@ protected ElementCache newElementCache()

protected class ElementCache extends ModalDialog.ElementCache
{
public final Locator listItemLoc = Locator.byClass("list-group-item");
public final Locator.XPathLocator listItemLoc = Locator.byClass("list-group-item");

// Fields column
public final WebElement fieldsSelectionPanel = Locator.byClass("filter-modal__col_fields")
.findWhenNeeded(this);

protected WebElement findFieldOption(String queryName)
protected WebElement findFieldOption(CharSequence queryName)
{
return listItemLoc.withText(queryName).findElement(elementCache().fieldsSelectionPanel);
try
{
return listItemLoc.withChild(Locator.tagWithAttribute("span", "data-fieldkey", queryName.toString())).findElement(fieldsSelectionPanel);
}
catch (NoSuchElementException nse)
{
if (!(queryName instanceof WrapsFieldKey))
return listItemLoc.withText(queryName.toString()).findElement(elementCache().fieldsSelectionPanel);
else
throw nse;
}
}
protected List<WebElement> findFieldOptions()
{
Expand Down
12 changes: 12 additions & 0 deletions src/org/labkey/test/components/ui/grids/ResponsiveGrid.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
import org.openqa.selenium.support.ui.ExpectedConditions;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
Expand Down Expand Up @@ -449,6 +450,17 @@ public T selectRows(CharSequence columnIdentifier, Collection<String> texts, boo
return getThis();
}

/**
* Checks the specified rows' selector checkboxes
* @param columnIdentifier fieldKey, name, or label of column
* @param texts Text to search for in the specified column
* @return this grid
*/
public T selectRows(CharSequence columnIdentifier, String... texts)
{
return selectRows(columnIdentifier, Arrays.asList(texts), true);
}

/**
* Is the row at the selected index selected
* @param index Row index (zero-based)
Expand Down
2 changes: 1 addition & 1 deletion src/org/labkey/test/tests/AdminConsoleNavigationTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ public void testAdminNavTrails()
{
linkHrefs.put(link.getText(), link.getAttribute("href"));
}
Assertions.assertThat(linkHrefs.keySet()).as("Expected links").containsAll(ignoredLinks);
Assertions.assertThat(linkHrefs.keySet()).as("Expected links").containsAll(ignoredLinks.stream().map(String::toUpperCase).toList());

List<String> pagesMissingNavTrail = new ArrayList<>();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -896,7 +896,7 @@ public void testNameExpressionPreview() throws IOException, CommandException
mouseOver(createPage.getComponentElement());

log("Use a name expression using a field from the named parent, with parent type not encoded.");
nameExpressionBad = String.format("SNP_${genId}_${%s/$s}_${materialInputs/%s/%s}", parentAlias, PARENT_FIELD_CURLY_RIGHT_INT.getExpName(), PARENT_SAMPLE_TYPE, PARENT_FIELD_CURLY_LEFT.getName());
nameExpressionBad = String.format("SNP_${genId}_${%s/%s}_${materialInputs/%s/%s}", parentAlias, PARENT_FIELD_CURLY_RIGHT_INT.getExpName(), PARENT_SAMPLE_TYPE, PARENT_FIELD_CURLY_LEFT.getName());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This bugs me, I should have caught this when I was in this code last week. The linter was clearly calling this out but I overlooked it.

createPage.setNameExpression(nameExpressionBad);
actualMsg = createPage.getNameExpressionPreview();
checker().withScreenshot("Parent_Fields_Preview_Error")
Expand Down
6 changes: 6 additions & 0 deletions src/org/labkey/test/util/DeferredErrorCollector.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import org.awaitility.core.ConditionTimeoutException;
import org.hamcrest.Matcher;
import org.hamcrest.MatcherAssert;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull;
import org.junit.Assert;
import org.labkey.junit.LabKeyAssert;
Expand Down Expand Up @@ -283,6 +284,7 @@ public final <T> boolean verifyEqualsSorted(String message, Collection<T> expect
* @see Assert#assertTrue(String, boolean)
* @return <code>true</code> if condition is true
*/
@Contract("_, true -> true; _, false -> false")
public final boolean verifyTrue(String message, boolean condition)
{
return wrapAssertion(() -> Assert.assertTrue(message, condition));
Expand All @@ -296,6 +298,7 @@ public final boolean verifyTrue(String message, boolean condition)
* @see Assert#assertFalse(String, boolean)
* @return <code>true</code> if condition is false
*/
@Contract("_, false -> true; _, true -> false")
public final boolean verifyFalse(String message, boolean condition)
{
return wrapAssertion(() -> Assert.assertFalse(message, condition));
Expand All @@ -309,6 +312,7 @@ public final boolean verifyFalse(String message, boolean condition)
* @see Assert#assertNull(String, Object)
* @return <code>true</code> if object is null
*/
@Contract("_, null -> true; _, !null -> false")
public final boolean verifyNull(String message, Object object)
{
return wrapAssertion(() -> Assert.assertNull(message, object));
Expand All @@ -322,6 +326,7 @@ public final boolean verifyNull(String message, Object object)
* @see Assert#assertNotNull(String, Object)
* @return <code>true</code> if object is not null
*/
@Contract("_, !null -> true; _, null -> false")
public final boolean verifyNotNull(String message, Object object)
{
return wrapAssertion(() -> Assert.assertNotNull(message, object));
Expand Down Expand Up @@ -349,6 +354,7 @@ public final <T> boolean verifyThat(String reason, T actual, Matcher<? super T>
* @see Assert#fail()
* @return Always returns <code>false</code>
*/
@Contract("_ -> false")
public final boolean error(String message)
{
return wrapAssertion(() -> Assert.fail(message));
Expand Down
6 changes: 0 additions & 6 deletions src/org/labkey/test/util/data/TestDataUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -621,10 +621,4 @@ protected boolean shouldQuote(String value)
return StringUtils.containsAny(value, _escapedChars);
}
}

@Deprecated // Going away soon
public static String getEscapedNameExpression(String name)
{
return EscapeUtil.escapeForNameExpression(name);
}
}