Skip to content
46 changes: 43 additions & 3 deletions src/org/labkey/test/Locator.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@
import org.apache.commons.lang3.mutable.MutableObject;
import org.intellij.lang.annotations.Language;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.labkey.test.selenium.LazyWebElement;
import org.labkey.test.selenium.ReclickingWebElement;
import org.labkey.test.selenium.RefindingWebElement;
Expand Down Expand Up @@ -1019,6 +1019,41 @@ public static String cq(String value)
return "\"" + value.replace("\\", "\\\\").replace("\"", "\\\"") + "\"";
}

public static Locator union(Locator... locators)
{
if (locators.length < 1)
throw new IllegalArgumentException("Specify at least one locator");
if (locators.length == 1)
return locators[0];

List<CssLocator> cssLocators = Arrays.stream(locators).map(Locator::asRawCssLocator)
.filter(Objects::nonNull).toList();
if (cssLocators.size() == locators.length)
return CssLocator.union(cssLocators.toArray(new CssLocator[0]));

List<XPathLocator> xPathLocators = Arrays.stream(locators).map(locator -> {
if (locator instanceof XPathLocator)
return (XPathLocator) locator;
else
return null;
}).filter(Objects::nonNull).toList();
if (xPathLocators.size() == locators.length)
return XPathLocator.union(xPathLocators.toArray(new XPathLocator[0]));

throw new IllegalArgumentException("Locators should be all CSS or all XPath");
}

private static CssLocator asRawCssLocator(Locator locator)
{
CssLocator cssLocator = null;
if (locator instanceof CssLocator cssLoc)
cssLocator = cssLoc;
else if (locator instanceof XPathCSSLocator xcLoc)
cssLocator = xcLoc.getCssLoc();

return cssLocator != null && cssLocator.isRawCssLocator() ? cssLocator : null;
}

private static class XPathCSSLocator extends XPathLocator
{
private final XPathLocator _xLoc;
Expand Down Expand Up @@ -1670,9 +1705,9 @@ public static Locator union(CssLocator... locators)
if (locators.length == 0)
throw new IllegalArgumentException("Specify one or more locators to union");

for (Locator loc : locators)
for (CssLocator loc : locators)
{
if (loc._contains != null || loc._text != null || loc._index != null)
if (!loc.isRawCssLocator())
throw new IllegalArgumentException("Only able to union raw CSS selectors");
}

Expand All @@ -1687,6 +1722,11 @@ public static Locator union(CssLocator... locators)
return new WrappedLocator(new CssLocator(unionedLocators.toString()));
}

private boolean isRawCssLocator()
{
return _contains == null && _text == null && _index == null;
}

@Override
public Locator containing(String contains)
{
Expand Down
32 changes: 31 additions & 1 deletion src/org/labkey/test/WebTestHelper.java
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.net.URLDecoder;
import java.net.UnknownHostException;
import java.nio.charset.StandardCharsets;
import java.security.KeyManagementException;
Expand Down Expand Up @@ -544,6 +545,11 @@ public static Map<String, String> parseUrlQuery(URL url)
}

public static Map<String, String> parseUrlQueryString(String query)
{
return parseUrlQueryString(query, true);
}

public static Map<String, String> parseUrlQueryString(String query, boolean decode)
{
if (query != null)
{
Expand All @@ -556,7 +562,7 @@ public static Map<String, String> parseUrlQueryString(String query)
for (String arg : queryArgs)
{
String[] split = arg.split("=", 2);
parsedQuery.put(split[0], split.length > 1 ? split[1] : null);
parsedQuery.put(maybeDecode(split[0], decode), split.length > 1 ? maybeDecode(split[1], decode) : null);
}

return parsedQuery;
Expand All @@ -565,6 +571,30 @@ public static Map<String, String> parseUrlQueryString(String query)
return Collections.emptyMap();
}

private static String maybeDecode(String value, boolean decode)
{
return decode
? URLDecoder.decode(value, StandardCharsets.UTF_8)
: value;
}

public static Map<String, String> parseAppQuery(URL url)
{
String ref = url.getRef();

if (ref != null)
{
int queryIndex = ref.indexOf("?");

if (queryIndex > -1)
{
return parseUrlQueryString(ref.substring(queryIndex), true);
}
}

return Collections.emptyMap();
}

public static Connection getRemoteApiConnection()
{
return getRemoteApiConnection(true);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.support.ui.ExpectedConditions;

import java.util.List;
import java.util.stream.Collectors;
Expand Down Expand Up @@ -158,7 +159,9 @@ public String getDeleteConfirmationText()
*/
public ManageViewsDialog confirmDelete()
{
elementCache().deleteYesButton.click();
WebElement deleteYesButton = elementCache().deleteYesButton;
deleteYesButton.click();
getWrapper().quickWait().until(ExpectedConditions.stalenessOf(deleteYesButton));
return this;
}

Expand All @@ -169,7 +172,9 @@ public ManageViewsDialog confirmDelete()
*/
public ManageViewsDialog cancelDelete()
{
elementCache().deleteNoButton.click();
WebElement deleteNoButton = elementCache().deleteNoButton;
deleteNoButton.click();
getWrapper().quickWait().until(ExpectedConditions.stalenessOf(deleteNoButton));
return this;
}

Expand Down
8 changes: 8 additions & 0 deletions src/org/labkey/test/tests/BaseAppTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package org.labkey.test.tests;

import org.labkey.test.BaseWebDriverTest;

public abstract class BaseAppTest extends BaseWebDriverTest
{
public abstract String getAppControllerName();
}