From 7d0f40bb4a278835838915700a7126d30ba1804d Mon Sep 17 00:00:00 2001 From: labkey-danield Date: Fri, 7 Feb 2025 01:09:46 -0800 Subject: [PATCH 1/5] Add TRICKY_DOMAIN_NAME_CHARACTERS to BaseWebDriverTest. Change pasteSamplesInput in BulkAddReferenceModalDialog from a method to use refind. Update ContainerList to account for archived containers (folders). Change ContainerList.getContainers to getAllContainers. Update usages. Add DeleteConfirmationDialog.clickConfirmButton so class can be used by FolderArchiveDialog. Add FolderArchiveDialog. Change finders in FolderManagementPage to refind. Add archive functionality to FolderSettingsPanel. Change locator in NavBar. Now it can be used with Admin pages. Add simple archive test. --- src/org/labkey/test/BaseWebDriverTest.java | 2 + .../ui/DeleteConfirmationDialog.java | 9 ++++- .../components/ui/FolderArchiveDialog.java | 39 +++++++++++++++++++ .../test/components/ui/navigation/NavBar.java | 2 +- 4 files changed, 49 insertions(+), 3 deletions(-) create mode 100644 src/org/labkey/test/components/ui/FolderArchiveDialog.java diff --git a/src/org/labkey/test/BaseWebDriverTest.java b/src/org/labkey/test/BaseWebDriverTest.java index b5b2158e10..47688d974d 100644 --- a/src/org/labkey/test/BaseWebDriverTest.java +++ b/src/org/labkey/test/BaseWebDriverTest.java @@ -221,6 +221,8 @@ public abstract class BaseWebDriverTest extends LabKeySiteWrapper implements Cle public static final String[] ILLEGAL_QUERY_KEY_CHARACTERS = {"$", "/", "&", "}", "~", ",", "."}; // 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"}; + // Sample type names cannot contain: <>[]{};,`"~!@#$%^*=|?\ + public static final String[] TRICKY_DOMAIN_NAME_CHARACTERS = {"&", "()", "-", "_", ":", "'", ".", "/"}; public static final String TRICKY_CHARACTERS = "><&/%\\' \"1\u00E4\u00F6\u00FC\u00C5"; public static final String TRICKY_CHARACTERS_NO_QUOTES = "> elementCache().body.isDisplayed() && !elementCache().title.getText().isEmpty() && !BootstrapLocators.loadingSpinner.existsIn(this), - "The delete confirmation dialog did not become ready.", 1_000); + "The delete / archive confirmation dialog did not become ready.", 1_000); } public void cancelDelete() @@ -80,7 +80,12 @@ public ConfirmPage confirmDelete() public ConfirmPage confirmDelete(Integer waitSeconds) { - return _confirmationSynchronizationFunction.apply(() -> this.dismiss("Yes, Delete", waitSeconds)); + return clickConfirmButton(waitSeconds, "Yes, Delete"); + } + + protected ConfirmPage clickConfirmButton(Integer waitSeconds, String buttonText) + { + return _confirmationSynchronizationFunction.apply(() -> this.dismiss(buttonText, waitSeconds)); } public Boolean isDeleteEnabled() diff --git a/src/org/labkey/test/components/ui/FolderArchiveDialog.java b/src/org/labkey/test/components/ui/FolderArchiveDialog.java new file mode 100644 index 0000000000..2b7e1803e0 --- /dev/null +++ b/src/org/labkey/test/components/ui/FolderArchiveDialog.java @@ -0,0 +1,39 @@ +package org.labkey.test.components.ui; + +import org.jetbrains.annotations.NotNull; +import org.labkey.test.WebDriverWrapper; +import org.openqa.selenium.WebElement; +import org.openqa.selenium.support.ui.ExpectedConditions; + +import java.util.function.Supplier; + +public class FolderArchiveDialog extends DeleteConfirmationDialog +{ + + public FolderArchiveDialog(String dialogTitle, @NotNull WebDriverWrapper sourcePage, WebElement staleOnConfirmElement, Supplier confirmPageSupplier) + { + super(dialogTitle, sourcePage, runnable -> { + runnable.run(); + sourcePage.longWait().until(ExpectedConditions.stalenessOf(staleOnConfirmElement)); + return confirmPageSupplier.get(); + } + ); + + } + + public ConfirmPage clickYesArchive() + { + return clickYesArchive(10); + } + + public ConfirmPage clickYesArchive(Integer waitSeconds) + { + return super.clickConfirmButton(waitSeconds, "Yes, Archive Folder"); + } + + public void clickCancel() + { + this.dismiss("Cancel"); + } + +} diff --git a/src/org/labkey/test/components/ui/navigation/NavBar.java b/src/org/labkey/test/components/ui/navigation/NavBar.java index fae4ffed11..8295e331f0 100644 --- a/src/org/labkey/test/components/ui/navigation/NavBar.java +++ b/src/org/labkey/test/components/ui/navigation/NavBar.java @@ -23,7 +23,7 @@ public abstract class NavBar extends WebDriverComponent protected NavBar(WebDriver driver) { - this(Locator.tagWithClass("nav", "navbar-container").findElement(driver), driver); + this(Locator.tagWithClass("nav", "navbar").findElement(driver), driver); } protected NavBar(WebElement element, WebDriver driver) From fdf8cd6a2f970d6b2faa5fc5bb1a23fcdd48212d Mon Sep 17 00:00:00 2001 From: labkey-danield Date: Tue, 24 Jun 2025 18:06:27 -0700 Subject: [PATCH 2/5] Fix some bad merge resolutions. --- .../test/components/ui/DeleteConfirmationDialog.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/org/labkey/test/components/ui/DeleteConfirmationDialog.java b/src/org/labkey/test/components/ui/DeleteConfirmationDialog.java index 8817a51e04..dafdc582a7 100644 --- a/src/org/labkey/test/components/ui/DeleteConfirmationDialog.java +++ b/src/org/labkey/test/components/ui/DeleteConfirmationDialog.java @@ -91,11 +91,16 @@ public ConfirmPage confirmDelete() } public ConfirmPage confirmDelete(Integer waitSeconds) + { + return clickConfirmButton(waitSeconds, "Yes, Delete"); + } + + protected ConfirmPage clickConfirmButton(Integer waitSeconds, String buttonText) { Integer count = getCountFromTitle(); AuditLogHelper.AuditEvent auditEventName = getAuditEvent(); - var confirmPage = _confirmationSynchronizationFunction.apply(() -> this.dismiss("Yes, Delete", waitSeconds)); + var confirmPage = _confirmationSynchronizationFunction.apply(() -> this.dismiss(buttonText, waitSeconds)); if (!skipAuditEventCheck && count != null && auditEventName != null && !TestProperties.isTrialServer()) verifyAuditEvents(getWrapper(), getWrapper().getCurrentProject(), auditEventName, count); From e28826a3d611bf2116f8291e0650f9b891b60450 Mon Sep 17 00:00:00 2001 From: labkey-danield Date: Wed, 13 Aug 2025 19:05:50 -0700 Subject: [PATCH 3/5] Added tests for searching, filter and file import. Made public the ResponsiveGrid.clickColumnMenuItem --- src/org/labkey/test/components/ui/grids/ResponsiveGrid.java | 2 +- src/org/labkey/test/components/ui/search/SampleFinder.java | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/org/labkey/test/components/ui/grids/ResponsiveGrid.java b/src/org/labkey/test/components/ui/grids/ResponsiveGrid.java index 4ffc4d2151..f0f9055b95 100644 --- a/src/org/labkey/test/components/ui/grids/ResponsiveGrid.java +++ b/src/org/labkey/test/components/ui/grids/ResponsiveGrid.java @@ -305,7 +305,7 @@ public FieldSelectionDialog insertColumn(CharSequence columnIdentifier) return new FieldSelectionDialog(getDriver(), this); } - protected void clickColumnMenuItem(CharSequence columnIdentifier, String menuText, boolean waitForUpdate) + public void clickColumnMenuItem(CharSequence columnIdentifier, String menuText, boolean waitForUpdate) { if(hasLockedColumn()) diff --git a/src/org/labkey/test/components/ui/search/SampleFinder.java b/src/org/labkey/test/components/ui/search/SampleFinder.java index 3e7dd53e88..d235f02911 100644 --- a/src/org/labkey/test/components/ui/search/SampleFinder.java +++ b/src/org/labkey/test/components/ui/search/SampleFinder.java @@ -70,11 +70,13 @@ public void waitForReady() /** * Open the entity filter dialog for the specified filter type. * - * @param filterKind "Source" or "Parent" or "Assay" in SM. "Registry Parent" or "Sample Parent" or "Assay" in Biologics + * @param filterKind "Sample", "Source" or "Parent" or "Assay" in SM. "Registry Parent" or "Sample Parent" or "Assay" in Biologics * @return component wrapper for the EntityFieldFilterModal */ public EntityFieldFilterModal clickAddParent(String filterKind) { + // Why is this method called clickAddParent? + elementCache().findFilterKindButton(filterKind).click(); return new EntityFieldFilterModal(getDriver(), this::doAndWaitForUpdate); } From 9a15007f25981e12b29a662e55c274aa61a170ac Mon Sep 17 00:00:00 2001 From: labkey-danield Date: Fri, 15 Aug 2025 15:48:59 -0700 Subject: [PATCH 4/5] Remove unneeded constant. Reverting changes from container to folder. --- src/org/labkey/test/BaseWebDriverTest.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/org/labkey/test/BaseWebDriverTest.java b/src/org/labkey/test/BaseWebDriverTest.java index b5561e4379..c7527b0b4b 100644 --- a/src/org/labkey/test/BaseWebDriverTest.java +++ b/src/org/labkey/test/BaseWebDriverTest.java @@ -218,10 +218,8 @@ public abstract class BaseWebDriverTest extends LabKeySiteWrapper implements Cle public static final double DELTA = 10E-10; 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 + // 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"}; - // Sample type names cannot contain: <>[]{};,`"~!@#$%^*=|?\ - public static final String[] TRICKY_DOMAIN_NAME_CHARACTERS = {"&", "()", "-", "_", ":", "'", ".", "/"}; public static final String TRICKY_CHARACTERS = "><&/%\\' \"1\u00E4\u00F6\u00FC\u00C5"; public static final String TRICKY_CHARACTERS_NO_QUOTES = "> Date: Mon, 18 Aug 2025 19:17:26 -0700 Subject: [PATCH 5/5] Change FolderArchiveDialog to extend ModalDialog and not DeleteConfirmationDialog. Revert changes to DeleteConfirmationDialog. In SampleFinder, change clickAddParent to clickAddSearchCard In FolderManagementPage moved the finders out of the elementCache and into the appropriate methods. Updated constructor of FolderSettingsPanel to take a FolderManagementPage and not a WebDriver Consolidated some test code and added screenshots on failures. --- .../ui/DeleteConfirmationDialog.java | 9 ++---- .../components/ui/FolderArchiveDialog.java | 30 +++++++++++++------ .../components/ui/search/SampleFinder.java | 8 ++--- 3 files changed, 26 insertions(+), 21 deletions(-) diff --git a/src/org/labkey/test/components/ui/DeleteConfirmationDialog.java b/src/org/labkey/test/components/ui/DeleteConfirmationDialog.java index dafdc582a7..b2e62029bc 100644 --- a/src/org/labkey/test/components/ui/DeleteConfirmationDialog.java +++ b/src/org/labkey/test/components/ui/DeleteConfirmationDialog.java @@ -71,7 +71,7 @@ protected void waitForReady() WebDriverWrapper.waitFor(()-> elementCache().body.isDisplayed() && !elementCache().title.getText().isEmpty() && !BootstrapLocators.loadingSpinner.existsIn(this), - "The delete / archive confirmation dialog did not become ready.", 1_000); + "The delete confirmation dialog did not become ready.", 1_000); } public DeleteConfirmationDialog setSkipAuditEventCheck(boolean skipAuditEventCheck) @@ -91,16 +91,11 @@ public ConfirmPage confirmDelete() } public ConfirmPage confirmDelete(Integer waitSeconds) - { - return clickConfirmButton(waitSeconds, "Yes, Delete"); - } - - protected ConfirmPage clickConfirmButton(Integer waitSeconds, String buttonText) { Integer count = getCountFromTitle(); AuditLogHelper.AuditEvent auditEventName = getAuditEvent(); - var confirmPage = _confirmationSynchronizationFunction.apply(() -> this.dismiss(buttonText, waitSeconds)); + var confirmPage = _confirmationSynchronizationFunction.apply(() -> this.dismiss("Yes, Delete", waitSeconds)); if (!skipAuditEventCheck && count != null && auditEventName != null && !TestProperties.isTrialServer()) verifyAuditEvents(getWrapper(), getWrapper().getCurrentProject(), auditEventName, count); diff --git a/src/org/labkey/test/components/ui/FolderArchiveDialog.java b/src/org/labkey/test/components/ui/FolderArchiveDialog.java index 2b7e1803e0..f65b6d3a92 100644 --- a/src/org/labkey/test/components/ui/FolderArchiveDialog.java +++ b/src/org/labkey/test/components/ui/FolderArchiveDialog.java @@ -2,22 +2,34 @@ import org.jetbrains.annotations.NotNull; import org.labkey.test.WebDriverWrapper; +import org.labkey.test.components.UpdatingComponent; +import org.labkey.test.components.bootstrap.ModalDialog; import org.openqa.selenium.WebElement; import org.openqa.selenium.support.ui.ExpectedConditions; +import java.util.function.Function; import java.util.function.Supplier; -public class FolderArchiveDialog extends DeleteConfirmationDialog +public class FolderArchiveDialog extends ModalDialog { - public FolderArchiveDialog(String dialogTitle, @NotNull WebDriverWrapper sourcePage, WebElement staleOnConfirmElement, Supplier confirmPageSupplier) + private final Function _confirmationSynchronizationFunction; + + public FolderArchiveDialog(@NotNull WebDriverWrapper sourcePage, WebElement staleOnConfirmElement, Supplier confirmPageSupplier) { - super(dialogTitle, sourcePage, runnable -> { - runnable.run(); - sourcePage.longWait().until(ExpectedConditions.stalenessOf(staleOnConfirmElement)); - return confirmPageSupplier.get(); - } - ); + + // Dialog finder stumbles with 'tricky characters' so limiting the search to just the word 'Archive'. + super(new ModalDialog.ModalDialogFinder(sourcePage.getDriver()).withTitleIgnoreCase("Archive")); + + UpdatingComponent updatingComponent = runnable -> { + runnable.run(); + sourcePage.longWait().until(ExpectedConditions.stalenessOf(staleOnConfirmElement)); + }; + + _confirmationSynchronizationFunction = runnable -> { + updatingComponent.doAndWaitForUpdate(runnable); + return confirmPageSupplier.get(); + }; } @@ -28,7 +40,7 @@ public ConfirmPage clickYesArchive() public ConfirmPage clickYesArchive(Integer waitSeconds) { - return super.clickConfirmButton(waitSeconds, "Yes, Archive Folder"); + return _confirmationSynchronizationFunction.apply(() -> this.dismiss( "Yes, Archive Folder", waitSeconds)); } public void clickCancel() diff --git a/src/org/labkey/test/components/ui/search/SampleFinder.java b/src/org/labkey/test/components/ui/search/SampleFinder.java index d235f02911..905777a5b0 100644 --- a/src/org/labkey/test/components/ui/search/SampleFinder.java +++ b/src/org/labkey/test/components/ui/search/SampleFinder.java @@ -58,7 +58,7 @@ public WebDriver getDriver() } /** - * Waits for initial state (empty filter card panel) or for search results grid to appear + * Waits for the initial state (empty filter card panel) or for the search results grid to appear */ @Override public void waitForReady() @@ -73,10 +73,8 @@ public void waitForReady() * @param filterKind "Sample", "Source" or "Parent" or "Assay" in SM. "Registry Parent" or "Sample Parent" or "Assay" in Biologics * @return component wrapper for the EntityFieldFilterModal */ - public EntityFieldFilterModal clickAddParent(String filterKind) + public EntityFieldFilterModal clickAddSearchCard(String filterKind) { - // Why is this method called clickAddParent? - elementCache().findFilterKindButton(filterKind).click(); return new EntityFieldFilterModal(getDriver(), this::doAndWaitForUpdate); } @@ -112,7 +110,7 @@ public void removeSearchCard(String queryName) } /** - * Reset sample finder to its initial state, with no search criteria + * Reset the sample finder to its initial state, with no search criteria */ public void removeAllSearchCards() {