Skip to content
Merged
6 changes: 3 additions & 3 deletions src/org/labkey/test/AssayAPITest.java
Original file line number Diff line number Diff line change
Expand Up @@ -311,8 +311,8 @@ public void testImportRun_dataRows() throws Exception
assayHelper.importAssay(assayId, runName, dataRowsInvalidResultFileDirectory, getProjectName(), Collections.singletonMap("RunFileField", CREST_FILE.getName()), Collections.emptyMap(), "DataFileField: Invalid file path: ../");

// valid run file and valid result file
FileBrowserHelper.FileDetailInfo runFileInfo = _fileBrowserHelper.getFileDetailInfo(getProjectName(), CREST_FILE.getName());
FileBrowserHelper.FileDetailInfo resultFileInfo = _fileBrowserHelper.getFileDetailInfo(getProjectName(), SCREENSHOT_FILE.getName());
FileBrowserHelper.FileDetailInfo runFileInfo = FileBrowserHelper.getFileDetailInfo(getProjectName(), CREST_FILE.getName());
FileBrowserHelper.FileDetailInfo resultFileInfo = FileBrowserHelper.getFileDetailInfo(getProjectName(), SCREENSHOT_FILE.getName());
List<Pair<String, String>> scenarios = List.of(new Pair<>(CREST_FILE.getName(), SCREENSHOT_FILE.getName()),
new Pair<>(runFileInfo.absoluteFilePath(), resultFileInfo.absoluteFilePath()),
new Pair<>(runFileInfo.webDavUrl(), resultFileInfo.webDavUrl()),
Expand Down Expand Up @@ -388,7 +388,7 @@ public void testGpatSaveBatch() throws Exception
goToModule("FileContent");
_fileBrowserHelper.uploadFile(HELP_ICON_FILE);
goToManageAssays();
FileBrowserHelper.FileDetailInfo runFileInfo = _fileBrowserHelper.getFileDetailInfo(getProjectName(), "help.jpg");
FileBrowserHelper.FileDetailInfo runFileInfo = FileBrowserHelper.getFileDetailInfo(getProjectName(), "help.jpg");
((APIAssayHelper) _assayHelper).saveBatch(assayName, "Valid absolute path", Collections.singletonMap("RunFileField", runFileInfo.absoluteFilePath()), resultRows, getProjectName(), null);
((APIAssayHelper) _assayHelper).saveBatch(assayName, "Valid webdav full path", Collections.singletonMap("RunFileField", runFileInfo.webDavUrl()), resultRows, getProjectName(), null);
((APIAssayHelper) _assayHelper).saveBatch(assayName, "Valid webdav relative path", Collections.singletonMap("RunFileField", runFileInfo.webDavUrlRelative()), resultRows, getProjectName(), null);
Expand Down
9 changes: 9 additions & 0 deletions src/org/labkey/test/Locator.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.mutable.MutableObject;
import org.intellij.lang.annotations.Language;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.labkey.test.selenium.LazyWebElement;
Expand Down Expand Up @@ -373,11 +374,13 @@ protected static <T> T extractInputFromFluentWait(FluentWait<T> wait)
return wrappedContext.getValue();
}

@Contract(pure = true)
public LazyWebElement<?> findWhenNeeded(SearchContext context)
{
return new LazyWebElement<>(this, context);
}

@Contract(pure = true)
public RefindingWebElement refindWhenNeeded(SearchContext context)
{
return new RefindingWebElement(this, context);
Expand All @@ -391,11 +394,13 @@ public WebElement findElement(SearchContext context)
new NoSuchElementException("Unable to find element: " + getFindDescription(context)));
}

@Contract(pure = true)
public WebElement findElementOrNull(SearchContext context)
{
return findOptionalElement(context).orElse(null);
}

@Contract(pure = true)
public Optional<WebElement> findOptionalElement(SearchContext context)
{
List<WebElement> elements = findElements(context);
Expand All @@ -404,6 +409,7 @@ public Optional<WebElement> findOptionalElement(SearchContext context)
return Optional.of(elements.get(0));
}

@Contract(pure = true)
@Override
public List<WebElement> findElements(SearchContext context)
{
Expand Down Expand Up @@ -454,11 +460,13 @@ public List<WebElement> findElements(SearchContext context)
}
}

@Contract(pure = true)
public boolean existsIn(SearchContext context)
{
return findElementOrNull(context) != null;
}

@Contract(pure = true)
public boolean isDisplayed(SearchContext context)
{
WebElement element = findElementOrNull(context);
Expand All @@ -471,6 +479,7 @@ public boolean isDisplayed(SearchContext context)
* @param context Search context.
* @return True if there are any elements visible, false otherwise.
*/
@Contract(pure = true)
public boolean areAnyVisible(SearchContext context)
{
List<WebElement> elements = findElements(context);
Expand Down
41 changes: 10 additions & 31 deletions src/org/labkey/test/TestFileUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import org.apache.commons.compress.archivers.ArchiveStreamFactory;
import org.apache.commons.compress.archivers.tar.TarArchiveEntry;
import org.apache.commons.compress.archivers.tar.TarArchiveInputStream;
import org.apache.commons.io.FileSystem;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
Expand All @@ -27,8 +28,6 @@
import org.apache.pdfbox.Loader;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.text.PDFTextStripper;
import org.apache.poi.xssf.streaming.SXSSFRow;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.openpgp.PGPCompressedData;
import org.bouncycastle.openpgp.PGPEncryptedDataList;
Expand All @@ -41,12 +40,10 @@
import org.bouncycastle.openpgp.operator.jcajce.JcePBEDataDecryptorFactoryBuilder;
import org.bouncycastle.util.io.Streams;
import org.jetbrains.annotations.NotNull;
import org.labkey.serverapi.reader.Readers;
import org.openqa.selenium.NotFoundException;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
Expand All @@ -71,6 +68,7 @@
import java.util.List;
import java.util.Set;
import java.util.TreeSet;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import java.util.zip.GZIPInputStream;
import java.util.zip.ZipEntry;
Expand Down Expand Up @@ -707,34 +705,15 @@ public static byte[] decrypt(byte[] encrypted, char[] passPhrase) throws IOExcep
return Streams.readAll(ld.getInputStream());
}

private static final Pattern badChars = Pattern.compile("[\\\\:/\\[\\]?*|]");

public static File convertTabularToXlsx(File tabularFile, String delimiter, String sheetName, String xlsxFileName) throws IOException, PGPException
/**
* Determining expected file names for downloaded files that are named according to some
* value that might include characters that are not legal for files
* @see FileSystem#toLegalFileName(String, char)
*/
public static String makeLegalFileName(String candidate)
{
File excelFile = new File(getTestTempDir(), xlsxFileName);
FileUtils.forceMkdirParent(excelFile);

try(SXSSFWorkbook workBook = new SXSSFWorkbook(1000); // holds 1000 rows at a time
BufferedReader br = Readers.getReader(tabularFile);
FileOutputStream out = new FileOutputStream(excelFile))
{
var sheet = workBook.createSheet(sheetName);

String currentLine;
int rowNum=0;

while ((currentLine = br.readLine()) != null)
{
String str[] = currentLine.split(delimiter);
SXSSFRow currentRow = sheet.createRow(rowNum);
for (int i = 0; i < str.length; i++)
{
currentRow.createCell(i).setCellValue(str[i]);
}
rowNum++;
}
workBook.write(out); // flush remaining rows
}

return excelFile;
return badChars.matcher(candidate).replaceAll("_");
}
}
5 changes: 5 additions & 0 deletions src/org/labkey/test/TestProperties.java
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,11 @@ public static boolean isTrialServer()
return getBooleanProperty("webtest.server.trial", false);
}

public static boolean isRemoteNameValidationEnabled()
{
return getBooleanProperty("webtest.remote.domain.validation", false);
}

public static boolean isCheckerFatal()
{
return "true".equals(System.getProperty("webtest.checker.fatal"));
Expand Down
8 changes: 8 additions & 0 deletions src/org/labkey/test/WebDriverWrapper.java
Original file line number Diff line number Diff line change
Expand Up @@ -2148,6 +2148,14 @@ public long doAndMaybeWaitForPageToLoad(int msWait, Supplier<Boolean> action)
return loadTimer.elapsed().toMillis();
}

public void doAndWaitForNewWindow(Runnable action)
{
Set<String> windows = getDriver().getWindowHandles();
action.run();
switchToWindow(windows.size());
waitForDocument();
}

public long doAndWaitForWindow(Runnable action, String windowName)
{
String initialWindow = getDriver().getWindowHandle();
Expand Down
36 changes: 25 additions & 11 deletions src/org/labkey/test/components/bootstrap/Panel.java
Original file line number Diff line number Diff line change
Expand Up @@ -71,26 +71,20 @@ public class ElementCache extends Component<?>.ElementCache
protected final WebElement panelBody = Locator.byClass("panel-body").findWhenNeeded(this);
}

public static class PanelFinder extends WebDriverComponentFinder<Panel<?>, PanelFinder>
protected static abstract class AbstractPanelFinder<C extends Panel<?>, F extends AbstractPanelFinder<C, F>> extends WebDriverComponentFinder<C, F>
{
private final Locator.XPathLocator _baseLocator = Locator.tagWithClass("div", "panel-default");
private final Locator.XPathLocator _baseLocator = Locator.tagWithClass("div", "panel");
private String _title = null;

public PanelFinder(WebDriver driver)
public AbstractPanelFinder(WebDriver driver)
{
super(driver);
}

public PanelFinder withTitle(String title)
public F withTitle(String title)
{
_title = title;
return this;
}

@Override
protected Panel<?> construct(WebElement el, WebDriver driver)
{
return new PanelImpl(el, driver);
return getThis();
}

@Override
Expand All @@ -103,6 +97,26 @@ protected Locator locator()
return _baseLocator;
}
}

public static class PanelFinder extends AbstractPanelFinder<Panel<?>, PanelFinder>
{
public PanelFinder(WebDriver driver)
{
super(driver);
}

@Override
protected PanelFinder getThis()
{
return this;
}

@Override
protected Panel<?> construct(WebElement el, WebDriver driver)
{
return new PanelImpl(el, driver);
}
}
}

class PanelImpl extends Panel<ElementCache>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,20 @@
import org.labkey.test.BootstrapLocators;
import org.labkey.test.Locator;
import org.labkey.test.WebDriverWrapper;
import org.labkey.test.components.Component;
import org.labkey.test.components.WebDriverComponent;
import org.labkey.test.components.bootstrap.Panel;
import org.labkey.test.components.react.BaseReactSelect;
import org.labkey.test.components.react.FilteringReactSelect;
import org.labkey.test.components.react.ReactSelect;
import org.openqa.selenium.NoSuchElementException;
import org.openqa.selenium.StaleElementReferenceException;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.ui.ExpectedConditions;

import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
* <p>
Expand All @@ -25,11 +27,8 @@
* </p>
* @see <a href="https://github.com/LabKey/labkey-ui-components/blob/master/packages/components/src/components/entities/ParentEntityEditPanel.tsx">ParentEntityEditPanel.tsx</a>
*/
public class ParentEntityEditPanel extends WebDriverComponent<ParentEntityEditPanel.ElementCache>
public class ParentEntityEditPanel extends Panel<ParentEntityEditPanel.ElementCache>
{
private final WebDriver driver;
private final WebElement editingDiv;

/**
* Constructor for the panel.
*
Expand All @@ -38,20 +37,7 @@ public class ParentEntityEditPanel extends WebDriverComponent<ParentEntityEditPa
*/
public ParentEntityEditPanel(WebElement element, WebDriver driver)
{
this.driver = driver;
editingDiv = element;
}

@Override
public WebElement getComponentElement()
{
return editingDiv;
}

@Override
protected WebDriver getDriver()
{
return driver;
super(element, driver);
}

@Override
Expand Down Expand Up @@ -184,6 +170,10 @@ public void clickSave(int waitTime)
WebDriverWrapper.waitFor(()->elementCache().saveButton.isEnabled(),
"Save button is not enabled.", 2_500);

String parentType = getTitle().split(" ", 2)[1].trim(); // Trim "Editing" from the title
Set<String> selections = new HashSet<>();
getAllParents().stream().map(BaseReactSelect::getSelections).forEach(selections::addAll);

// The wait time is used here to validate the panel exits edit mode.
clickButtonWaitForPanel(elementCache().saveButton, waitTime);

Expand All @@ -192,6 +182,20 @@ public void clickSave(int waitTime)
WebDriverWrapper.waitFor(()->!progressbar.isDisplayed(),
"It looks like an update took too long.", waitTime);

Panel<?> detailsPanel = new Panel.PanelFinder(getDriver()).withTitle(parentType).waitFor(getDriver());
if (!selections.isEmpty())
{
for (String selection : selections)
{
getWrapper().quickWait().until(ExpectedConditions.visibilityOf(
Locator.linkWithText(selection).findWhenNeeded(detailsPanel)));
}
}
else
{
getWrapper().quickWait().until(ExpectedConditions.visibilityOf(
Locator.tag("td").containing("has been set for this").findWhenNeeded(detailsPanel))); // e.g. "No source parent type has been set for this source."
}
}

/**
Expand Down Expand Up @@ -467,28 +471,19 @@ public boolean hasParentInputError()
/**
* Simple finder for this panel.
*/
public static class ParentEntityEditPanelFinder extends WebDriverComponentFinder<ParentEntityEditPanel, ParentEntityEditPanelFinder>
public static class ParentEntityEditPanelFinder extends AbstractPanelFinder<ParentEntityEditPanel, ParentEntityEditPanelFinder>
{
public ParentEntityEditPanelFinder(WebDriver driver)
{
super(driver);
withTitle("Editing");
}

@Override
protected ParentEntityEditPanel construct(WebElement element, WebDriver driver)
{
return new ParentEntityEditPanel(element, driver);
}

@Override
protected Locator locator()
{
return Locator
.tagContainingText("div", "Editing")
.withClass("panel-heading")
.parent()
.child(Locator.tagWithClass("div", "panel-body"));
}
}

public static class DataClassAddParentEntityPanelFinder extends WebDriverComponentFinder<ParentEntityEditPanel, DataClassAddParentEntityPanelFinder>
Expand Down Expand Up @@ -517,7 +512,7 @@ protected ElementCache newElementCache()
return new ElementCache();
}

protected class ElementCache extends Component<?>.ElementCache
protected class ElementCache extends Panel<?>.ElementCache
{
final WebElement saveButton = Locator.byClass("btn-success").withText("Save").findWhenNeeded(this);
final WebElement cancelButton = Locator.byClass("btn-default").withText("Cancel").refindWhenNeeded(this);
Expand Down
Loading