From a584a02230b19b15a5d60a277d0294e4ce77f272 Mon Sep 17 00:00:00 2001 From: labkey-tchad Date: Wed, 25 Feb 2026 14:33:05 -0800 Subject: [PATCH 1/6] Skip specimen import if specimen module isn't present --- src/org/labkey/test/tests/StudyBaseTest.java | 22 +++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/src/org/labkey/test/tests/StudyBaseTest.java b/src/org/labkey/test/tests/StudyBaseTest.java index db507488351..450c731e8a2 100644 --- a/src/org/labkey/test/tests/StudyBaseTest.java +++ b/src/org/labkey/test/tests/StudyBaseTest.java @@ -58,6 +58,8 @@ public abstract class StudyBaseTest extends BaseWebDriverTest { protected static final File ARCHIVE_TEMP_DIR = StudyHelper.getStudyTempDir(); + private static Boolean _specimenModulePresent; + protected int datasetCount = getDatasetCount(); protected int visitCount = 65; @@ -74,6 +76,14 @@ protected void setupRequestStatuses() new SpecimenHelper(this).setupRequestStatuses(); } + public boolean isSpecimenModulePresent() + { + if (null == _specimenModulePresent) + _specimenModulePresent = _containerHelper.getAllModules().contains("specimen"); + + return _specimenModulePresent; + } + protected final AuditLogHelper _auditLogHelper = new AuditLogHelper(this); @Override @@ -130,13 +140,19 @@ protected void startSpecimenImport(int completeJobsExpected) protected void startSpecimenImport(int completeJobsExpected, File specimenArchive) { - _specimenImporter = new SpecimenImporter(new File(StudyHelper.getStudySubfolderPath()), specimenArchive, ARCHIVE_TEMP_DIR, getFolderName(), completeJobsExpected); - _specimenImporter.startImport(); + if (isSpecimenModulePresent()) + { + _specimenImporter = new SpecimenImporter(new File(StudyHelper.getStudySubfolderPath()), specimenArchive, ARCHIVE_TEMP_DIR, getFolderName(), completeJobsExpected); + _specimenImporter.startImport(); + } } protected void waitForSpecimenImport() { - _specimenImporter.waitForComplete(); + if (isSpecimenModulePresent()) + { + _specimenImporter.waitForComplete(); + } } protected void setExpectSpecimenImportError(boolean expected) From c796e287724c2971d7fc8c4be13bd880d9f35d14 Mon Sep 17 00:00:00 2001 From: labkey-tchad Date: Wed, 25 Feb 2026 14:34:31 -0800 Subject: [PATCH 2/6] Skip specimen import if specimen module isn't present --- src/org/labkey/test/tests/AliquotTest.java | 3 +-- src/org/labkey/test/tests/SpecimenCustomizeTest.java | 3 +-- src/org/labkey/test/tests/SpecimenExportTest.java | 3 +-- src/org/labkey/test/tests/SpecimenMultipleImportTest.java | 3 +-- src/org/labkey/test/tests/SpecimenTest.java | 3 +-- 5 files changed, 5 insertions(+), 10 deletions(-) diff --git a/src/org/labkey/test/tests/AliquotTest.java b/src/org/labkey/test/tests/AliquotTest.java index 3a95f168feb..dc37cf1367b 100644 --- a/src/org/labkey/test/tests/AliquotTest.java +++ b/src/org/labkey/test/tests/AliquotTest.java @@ -21,7 +21,6 @@ import org.labkey.test.Locator; import org.labkey.test.Locators; import org.labkey.test.TestTimeoutException; -import org.labkey.test.categories.Daily; import org.labkey.test.categories.Specimen; import org.labkey.test.components.html.BootstrapMenu; import org.labkey.test.components.html.OptionSelect; @@ -32,7 +31,7 @@ import java.io.File; -@Category({Daily.class, Specimen.class}) +@Category({Specimen.class}) @BaseWebDriverTest.ClassTimeout(minutes = 8) public class AliquotTest extends SpecimenBaseTest { diff --git a/src/org/labkey/test/tests/SpecimenCustomizeTest.java b/src/org/labkey/test/tests/SpecimenCustomizeTest.java index d01a2a2710b..7f380c65349 100644 --- a/src/org/labkey/test/tests/SpecimenCustomizeTest.java +++ b/src/org/labkey/test/tests/SpecimenCustomizeTest.java @@ -20,7 +20,6 @@ import org.labkey.test.BaseWebDriverTest; import org.labkey.test.Locator; import org.labkey.test.TestFileUtils; -import org.labkey.test.categories.Daily; import org.labkey.test.categories.Specimen; import org.labkey.test.components.CustomizeView; import org.labkey.test.components.DomainDesignerPage; @@ -38,7 +37,7 @@ import java.util.Arrays; import java.util.List; -@Category({Daily.class, Specimen.class}) +@Category({Specimen.class}) @BaseWebDriverTest.ClassTimeout(minutes = 7) public class SpecimenCustomizeTest extends SpecimenBaseTest { diff --git a/src/org/labkey/test/tests/SpecimenExportTest.java b/src/org/labkey/test/tests/SpecimenExportTest.java index b5d3633a7f8..0e334bebd90 100644 --- a/src/org/labkey/test/tests/SpecimenExportTest.java +++ b/src/org/labkey/test/tests/SpecimenExportTest.java @@ -20,7 +20,6 @@ import org.labkey.test.Locator; import org.labkey.test.TestFileUtils; import org.labkey.test.TestTimeoutException; -import org.labkey.test.categories.Daily; import org.labkey.test.categories.Specimen; import org.labkey.test.util.FileBrowserHelper; import org.labkey.test.util.LogMethod; @@ -30,7 +29,7 @@ import static org.junit.Assert.assertTrue; -@Category({Daily.class, Specimen.class}) +@Category({Specimen.class}) @BaseWebDriverTest.ClassTimeout(minutes = 6) public class SpecimenExportTest extends SpecimenBaseTest { diff --git a/src/org/labkey/test/tests/SpecimenMultipleImportTest.java b/src/org/labkey/test/tests/SpecimenMultipleImportTest.java index 1fc06941ac7..073c0bd5e6d 100644 --- a/src/org/labkey/test/tests/SpecimenMultipleImportTest.java +++ b/src/org/labkey/test/tests/SpecimenMultipleImportTest.java @@ -19,14 +19,13 @@ import org.junit.experimental.categories.Category; import org.labkey.test.BaseWebDriverTest; import org.labkey.test.Locator; -import org.labkey.test.categories.Daily; import org.labkey.test.categories.Specimen; import org.labkey.test.util.LogMethod; import org.labkey.test.util.StudyHelper; import java.io.File; -@Category({Daily.class, Specimen.class}) +@Category({Specimen.class}) @BaseWebDriverTest.ClassTimeout(minutes = 6) public class SpecimenMultipleImportTest extends StudyBaseTest { diff --git a/src/org/labkey/test/tests/SpecimenTest.java b/src/org/labkey/test/tests/SpecimenTest.java index 6dea72c0af6..0cbbc3af665 100644 --- a/src/org/labkey/test/tests/SpecimenTest.java +++ b/src/org/labkey/test/tests/SpecimenTest.java @@ -24,7 +24,6 @@ import org.labkey.test.Locators; import org.labkey.test.TestTimeoutException; import org.labkey.test.WebTestHelper; -import org.labkey.test.categories.Daily; import org.labkey.test.categories.Specimen; import org.labkey.test.components.CustomizeView; import org.labkey.test.components.dumbster.EmailRecordTable; @@ -59,7 +58,7 @@ import static org.labkey.test.pages.study.specimen.ManageNotificationsPage.SpecimensAttachment; import static org.labkey.test.util.DataRegionTable.DataRegion; -@Category({Daily.class, Specimen.class}) +@Category({Specimen.class}) @BaseWebDriverTest.ClassTimeout(minutes = 20) public class SpecimenTest extends SpecimenBaseTest { From a1d9e413021a300a25e1895b4bdcdf60fdb3470d Mon Sep 17 00:00:00 2001 From: labkey-tchad Date: Wed, 25 Feb 2026 15:08:40 -0800 Subject: [PATCH 3/6] Conditionalize more specimen checks --- .../labkey/test/tests/AbstractAssayTest.java | 7 ++++-- .../test/tests/SpecimenGridExportTest.java | 3 +-- .../labkey/test/tests/SpecimenImportTest.java | 3 +-- src/org/labkey/test/tests/StudyBaseTest.java | 13 ++--------- src/org/labkey/test/tests/TabTest.java | 17 +++++++++----- .../test/tests/flow/FlowSpecimenTest.java | 5 +++-- .../viability/AbstractViabilityTest.java | 22 +++++++++++-------- 7 files changed, 37 insertions(+), 33 deletions(-) diff --git a/src/org/labkey/test/tests/AbstractAssayTest.java b/src/org/labkey/test/tests/AbstractAssayTest.java index 931a79c331f..e65c4d7c704 100644 --- a/src/org/labkey/test/tests/AbstractAssayTest.java +++ b/src/org/labkey/test/tests/AbstractAssayTest.java @@ -193,8 +193,11 @@ protected void setupEnvironment() _containerHelper.createProject(getProjectName(), null); goToProjectHome(getProjectName()); - // Some test use a stand alone specimen file. Before the file can be imported the Specimen module needs to be enabled. - _containerHelper.enableModule("Specimen"); + if (_studyHelper.isSpecimenModulePresent()) + { + // Some test use a stand alone specimen file. Before the file can be imported the Specimen module needs to be enabled. + _containerHelper.enableModule("Specimen"); + } log("Setting up groups, users and initial permissions"); ApiPermissionsHelper permissionsHelper = new ApiPermissionsHelper(this); diff --git a/src/org/labkey/test/tests/SpecimenGridExportTest.java b/src/org/labkey/test/tests/SpecimenGridExportTest.java index 89d7aab9705..2c38160bb65 100644 --- a/src/org/labkey/test/tests/SpecimenGridExportTest.java +++ b/src/org/labkey/test/tests/SpecimenGridExportTest.java @@ -22,7 +22,6 @@ import org.labkey.test.Locator; import org.labkey.test.TestTimeoutException; import org.labkey.test.WebTestHelper; -import org.labkey.test.categories.Daily; import org.labkey.test.categories.Specimen; import org.labkey.test.util.AbstractDataRegionExportOrSignHelper.ColumnHeaderType; @@ -33,7 +32,7 @@ /** * Test exporting rows from a specimen grid (not folder/study specimen export.) */ -@Category({Daily.class, Specimen.class}) +@Category({Specimen.class}) @BaseWebDriverTest.ClassTimeout(minutes = 7) public class SpecimenGridExportTest extends AbstractExportTest { diff --git a/src/org/labkey/test/tests/SpecimenImportTest.java b/src/org/labkey/test/tests/SpecimenImportTest.java index 28f5d15837b..04ae329a35e 100644 --- a/src/org/labkey/test/tests/SpecimenImportTest.java +++ b/src/org/labkey/test/tests/SpecimenImportTest.java @@ -26,7 +26,6 @@ import org.labkey.test.BaseWebDriverTest; import org.labkey.test.Locator; import org.labkey.test.WebTestHelper; -import org.labkey.test.categories.Daily; import org.labkey.test.categories.Specimen; import org.labkey.test.components.ext4.RadioButton; import org.labkey.test.util.DataRegionTable; @@ -43,7 +42,7 @@ import static org.junit.Assert.assertEquals; -@Category({Daily.class, Specimen.class}) +@Category({Specimen.class}) @BaseWebDriverTest.ClassTimeout(minutes = 5) public class SpecimenImportTest extends SpecimenBaseTest { diff --git a/src/org/labkey/test/tests/StudyBaseTest.java b/src/org/labkey/test/tests/StudyBaseTest.java index 450c731e8a2..7dc92b47e5d 100644 --- a/src/org/labkey/test/tests/StudyBaseTest.java +++ b/src/org/labkey/test/tests/StudyBaseTest.java @@ -58,7 +58,6 @@ public abstract class StudyBaseTest extends BaseWebDriverTest { protected static final File ARCHIVE_TEMP_DIR = StudyHelper.getStudyTempDir(); - private static Boolean _specimenModulePresent; protected int datasetCount = getDatasetCount(); protected int visitCount = 65; @@ -76,14 +75,6 @@ protected void setupRequestStatuses() new SpecimenHelper(this).setupRequestStatuses(); } - public boolean isSpecimenModulePresent() - { - if (null == _specimenModulePresent) - _specimenModulePresent = _containerHelper.getAllModules().contains("specimen"); - - return _specimenModulePresent; - } - protected final AuditLogHelper _auditLogHelper = new AuditLogHelper(this); @Override @@ -140,7 +131,7 @@ protected void startSpecimenImport(int completeJobsExpected) protected void startSpecimenImport(int completeJobsExpected, File specimenArchive) { - if (isSpecimenModulePresent()) + if (_studyHelper.isSpecimenModulePresent()) { _specimenImporter = new SpecimenImporter(new File(StudyHelper.getStudySubfolderPath()), specimenArchive, ARCHIVE_TEMP_DIR, getFolderName(), completeJobsExpected); _specimenImporter.startImport(); @@ -149,7 +140,7 @@ protected void startSpecimenImport(int completeJobsExpected, File specimenArchiv protected void waitForSpecimenImport() { - if (isSpecimenModulePresent()) + if (_studyHelper.isSpecimenModulePresent()) { _specimenImporter.waitForComplete(); } diff --git a/src/org/labkey/test/tests/TabTest.java b/src/org/labkey/test/tests/TabTest.java index dd086320a3b..9f73d3482f1 100644 --- a/src/org/labkey/test/tests/TabTest.java +++ b/src/org/labkey/test/tests/TabTest.java @@ -283,7 +283,8 @@ private void doTestContainerTabConversion() goToProjectHome(); _containerHelper.createSubfolder(getProjectName(), COLLAB_FOLDER, "Collaboration"); _containerHelper.createSubfolder(COLLABFOLDER_PATH, STUDY_FOLDER_TAB_NAME, "Study"); - _containerHelper.enableModule("Specimen"); + if (_studyHelper.isSpecimenModulePresent()) + _containerHelper.enableModule("Specimen"); _containerHelper.createSubfolder(COLLABFOLDER_PATH, ASSAY_FOLDER_TAB_NAME, "Assay"); clickFolder(COLLAB_FOLDER); clickFolder(STUDY_FOLDER_TAB_NAME); @@ -317,8 +318,11 @@ private void doTestContainerTabConversion() clickAndWait(Locator.linkWithText(STUDY_FOLDER_TAB_LABEL)); assertTextPresent("Study Overview"); studyContainerTab = PortalTab.finder(getDriver()).withTabText(STUDY_FOLDER_TAB_LABEL).find(); - studyContainerTab.goToTabContainer("Specimen Data"); - assertTextPresent("Vial Search", "Import Specimens"); + if (_studyHelper.isSpecimenModulePresent()) + { + studyContainerTab.goToTabContainer("Specimen Data"); + assertTextPresent("Vial Search", "Import Specimens"); + } clickAndWait(Locator.linkWithText(ASSAY_FOLDER_TAB_LABEL)); assertTextPresent("Assay List", EXTRA_ASSAY_WEBPART); @@ -343,8 +347,11 @@ private void doTestContainerTabConversion() assertTextPresent(STUDY_FOLDER_TAB_LABEL, ASSAY_FOLDER_TAB_LABEL); clickAndWait(Locator.linkWithText(STUDY_FOLDER_TAB_LABEL)); assertTextPresent("Study Overview"); - PortalTab.find(STUDY_FOLDER_TAB_LABEL, getDriver()).goToTabContainer("Specimen Data"); - assertTextPresent("Vial Search", "Import Specimens"); + if (_studyHelper.isSpecimenModulePresent()) + { + PortalTab.find(STUDY_FOLDER_TAB_LABEL, getDriver()).goToTabContainer("Specimen Data"); + assertTextPresent("Vial Search", "Import Specimens"); + } PortalTab.find(ASSAY_FOLDER_TAB_LABEL, getDriver()).activate(); assertTextPresent("Assay List", EXTRA_ASSAY_WEBPART); diff --git a/src/org/labkey/test/tests/flow/FlowSpecimenTest.java b/src/org/labkey/test/tests/flow/FlowSpecimenTest.java index 1ed3a6f6577..ea0834002ec 100644 --- a/src/org/labkey/test/tests/flow/FlowSpecimenTest.java +++ b/src/org/labkey/test/tests/flow/FlowSpecimenTest.java @@ -15,13 +15,13 @@ */ package org.labkey.test.tests.flow; +import org.junit.Assume; import org.junit.BeforeClass; import org.junit.Test; import org.junit.experimental.categories.Category; import org.labkey.test.BaseWebDriverTest; import org.labkey.test.Locator; import org.labkey.test.WebTestHelper; -import org.labkey.test.categories.Daily; import org.labkey.test.categories.Flow; import org.labkey.test.categories.Specimen; import org.labkey.test.components.assay.AssayConstants; @@ -38,7 +38,7 @@ /** * This test checks the flow specimen foreign key behavior from flow.FCSFiles and flow.FCSAnalyses. */ -@Category({Daily.class, Flow.class, Specimen.class}) +@Category({Flow.class, Specimen.class}) @BaseWebDriverTest.ClassTimeout(minutes = 8) public class FlowSpecimenTest extends BaseFlowTest { @@ -62,6 +62,7 @@ public static void initFlowFolders() @LogMethod private void initializeStudyFolder() { + Assume.assumeTrue("Specimen module not present", _studyHelper.isSpecimenModulePresent()); log("** Initialize Study Folder"); _containerHelper.createSubfolder(getProjectName(), getProjectName(), STUDY_FOLDER, "Study", null); _containerHelper.enableModule("Specimen"); diff --git a/src/org/labkey/test/tests/viability/AbstractViabilityTest.java b/src/org/labkey/test/tests/viability/AbstractViabilityTest.java index ebd119d6bba..3e78a6c1b7d 100644 --- a/src/org/labkey/test/tests/viability/AbstractViabilityTest.java +++ b/src/org/labkey/test/tests/viability/AbstractViabilityTest.java @@ -70,7 +70,8 @@ protected void initializeStudyFolder(String... tabs) { log("** Initialize Folder"); _containerHelper.createProject(getProjectName(), null); - _containerHelper.enableModule("Specimen"); + if (_studyHelper.isSpecimenModulePresent()) + _containerHelper.enableModule("Specimen"); _containerHelper.createSubfolder(getProjectName(), getProjectName(), getFolderName(), "Study", tabs, true); log("** Create Study"); @@ -86,14 +87,17 @@ protected void importSpecimens() protected void importSpecimens(String studyFolder, File specimensPath) { - log("** Import specimens"); - clickFolder(studyFolder); - clickAndWait(Locator.linkWithText("Specimen Data")); - waitAndClickAndWait(Locator.linkWithText("Import Specimens")); - waitForElement(Locator.id("tsv")); - setFormElement(Locator.id("tsv"), TestFileUtils.getFileContents(specimensPath)); - submit(); - assertTextPresent("Specimens uploaded successfully"); + if (_studyHelper.isSpecimenModulePresent()) + { + log("** Import specimens"); + clickFolder(studyFolder); + clickAndWait(Locator.linkWithText("Specimen Data")); + waitAndClickAndWait(Locator.linkWithText("Import Specimens")); + waitForElement(Locator.id("tsv")); + setFormElement(Locator.id("tsv"), TestFileUtils.getFileContents(specimensPath)); + submit(); + assertTextPresent("Specimens uploaded successfully"); + } } protected void createViabilityAssay() From 21fc72f5b1dc213a3a4253f4ad81a7823216554f Mon Sep 17 00:00:00 2001 From: labkey-tchad Date: Mon, 24 Aug 2026 12:52:09 -0700 Subject: [PATCH 4/6] GH Issue 877: Gate specimen-module test/tab logic on module presence Drop Daily from the category on SpecimenTest, SpecimenImportTest, SpecimenExportTest, SpecimenCustomizeTest, SpecimenMultipleImportTest, SpecimenGridExportTest, AliquotTest, CustomizeEmailTemplateTest, and FlowSpecimenTest, since these exercise the specimen module directly and shouldn't require it in TeamCity's Daily suite. Guard AbstractAssayTest.setupEnvironment(), StudyBaseTest's specimen-import lifecycle methods (including the previously-ungated setExpectSpecimenImportError), and TabTest's Specimen Data tab checks behind _studyHelper.isSpecimenModulePresent() so calling code stays safe when the module is absent. Skip FlowSpecimenTest.initializeStudyFolder() and ViabilityTest.runUITests() entirely via Assume when the module is absent, since their coverage is fundamentally about specimen-to-assay resolution. --- .../labkey/test/tests/AbstractAssayTest.java | 7 +++++-- src/org/labkey/test/tests/AliquotTest.java | 3 +-- .../tests/CustomizeEmailTemplateTest.java | 4 ++-- .../test/tests/SpecimenCustomizeTest.java | 3 +-- .../labkey/test/tests/SpecimenExportTest.java | 3 +-- .../test/tests/SpecimenGridExportTest.java | 3 +-- .../labkey/test/tests/SpecimenImportTest.java | 3 +-- .../tests/SpecimenMultipleImportTest.java | 3 +-- src/org/labkey/test/tests/SpecimenTest.java | 3 +-- src/org/labkey/test/tests/StudyBaseTest.java | 17 +++++++++++++---- src/org/labkey/test/tests/TabTest.java | 19 ++++++++++++++----- .../test/tests/flow/FlowSpecimenTest.java | 5 +++-- .../viability/AbstractViabilityTest.java | 3 ++- .../test/tests/viability/ViabilityTest.java | 3 +++ 14 files changed, 49 insertions(+), 30 deletions(-) diff --git a/src/org/labkey/test/tests/AbstractAssayTest.java b/src/org/labkey/test/tests/AbstractAssayTest.java index 8a4932c6bdc..9f9122af232 100644 --- a/src/org/labkey/test/tests/AbstractAssayTest.java +++ b/src/org/labkey/test/tests/AbstractAssayTest.java @@ -194,8 +194,11 @@ protected void setupEnvironment() _containerHelper.createProject(getProjectName(), null); goToProjectHome(getProjectName()); - // Some test use a stand alone specimen file. Before the file can be imported the Specimen module needs to be enabled. - _containerHelper.enableModule("Specimen"); + if (_studyHelper.isSpecimenModulePresent()) + { + // Some test use a stand alone specimen file. Before the file can be imported the Specimen module needs to be enabled. + _containerHelper.enableModule("Specimen"); + } log("Setting up groups, users and initial permissions"); ApiPermissionsHelper permissionsHelper = new ApiPermissionsHelper(this); diff --git a/src/org/labkey/test/tests/AliquotTest.java b/src/org/labkey/test/tests/AliquotTest.java index 2730f46f228..81f6ab65be5 100644 --- a/src/org/labkey/test/tests/AliquotTest.java +++ b/src/org/labkey/test/tests/AliquotTest.java @@ -21,7 +21,6 @@ import org.labkey.test.Locator; import org.labkey.test.Locators; import org.labkey.test.TestTimeoutException; -import org.labkey.test.categories.Daily; import org.labkey.test.categories.Specimen; import org.labkey.test.components.html.BootstrapMenu; import org.labkey.test.components.html.OptionSelect; @@ -32,7 +31,7 @@ import java.io.File; -@Category({Daily.class, Specimen.class}) +@Category({Specimen.class}) @BaseWebDriverTest.ClassTimeout(minutes = 8) public class AliquotTest extends SpecimenBaseTest { diff --git a/src/org/labkey/test/tests/CustomizeEmailTemplateTest.java b/src/org/labkey/test/tests/CustomizeEmailTemplateTest.java index 79dd8665a45..28cec7b81f2 100644 --- a/src/org/labkey/test/tests/CustomizeEmailTemplateTest.java +++ b/src/org/labkey/test/tests/CustomizeEmailTemplateTest.java @@ -21,7 +21,7 @@ import org.labkey.test.Locator; import org.labkey.test.Locators; import org.labkey.test.WebTestHelper; -import org.labkey.test.categories.Daily; +import org.labkey.test.categories.Specimen; import org.labkey.test.components.dumbster.EmailRecordTable; import org.labkey.test.util.DataRegionTable; import org.labkey.test.util.LogMethod; @@ -35,7 +35,7 @@ import static org.junit.Assert.assertEquals; -@Category(Daily.class) +@Category({Specimen.class}) @BaseWebDriverTest.ClassTimeout(minutes = 5) public class CustomizeEmailTemplateTest extends SpecimenBaseTest { diff --git a/src/org/labkey/test/tests/SpecimenCustomizeTest.java b/src/org/labkey/test/tests/SpecimenCustomizeTest.java index 3feed6ae409..92909233c88 100644 --- a/src/org/labkey/test/tests/SpecimenCustomizeTest.java +++ b/src/org/labkey/test/tests/SpecimenCustomizeTest.java @@ -20,7 +20,6 @@ import org.labkey.test.BaseWebDriverTest; import org.labkey.test.Locator; import org.labkey.test.TestFileUtils; -import org.labkey.test.categories.Daily; import org.labkey.test.categories.Specimen; import org.labkey.test.components.CustomizeView; import org.labkey.test.components.DomainDesignerPage; @@ -38,7 +37,7 @@ import java.util.Arrays; import java.util.List; -@Category({Daily.class, Specimen.class}) +@Category({Specimen.class}) @BaseWebDriverTest.ClassTimeout(minutes = 7) public class SpecimenCustomizeTest extends SpecimenBaseTest { diff --git a/src/org/labkey/test/tests/SpecimenExportTest.java b/src/org/labkey/test/tests/SpecimenExportTest.java index 077846be306..f773cbc518d 100644 --- a/src/org/labkey/test/tests/SpecimenExportTest.java +++ b/src/org/labkey/test/tests/SpecimenExportTest.java @@ -20,7 +20,6 @@ import org.labkey.test.Locator; import org.labkey.test.TestFileUtils; import org.labkey.test.TestTimeoutException; -import org.labkey.test.categories.Daily; import org.labkey.test.categories.Specimen; import org.labkey.test.util.FileBrowserHelper; import org.labkey.test.util.LogMethod; @@ -30,7 +29,7 @@ import static org.junit.Assert.assertTrue; -@Category({Daily.class, Specimen.class}) +@Category({Specimen.class}) @BaseWebDriverTest.ClassTimeout(minutes = 6) public class SpecimenExportTest extends SpecimenBaseTest { diff --git a/src/org/labkey/test/tests/SpecimenGridExportTest.java b/src/org/labkey/test/tests/SpecimenGridExportTest.java index 1a5cd8faf43..477b417fda8 100644 --- a/src/org/labkey/test/tests/SpecimenGridExportTest.java +++ b/src/org/labkey/test/tests/SpecimenGridExportTest.java @@ -22,7 +22,6 @@ import org.labkey.test.Locator; import org.labkey.test.TestTimeoutException; import org.labkey.test.WebTestHelper; -import org.labkey.test.categories.Daily; import org.labkey.test.categories.Specimen; import org.labkey.test.util.AbstractDataRegionExportOrSignHelper.ColumnHeaderType; @@ -33,7 +32,7 @@ /** * Test exporting rows from a specimen grid (not folder/study specimen export.) */ -@Category({Daily.class, Specimen.class}) +@Category({Specimen.class}) @BaseWebDriverTest.ClassTimeout(minutes = 7) public class SpecimenGridExportTest extends AbstractExportTest { diff --git a/src/org/labkey/test/tests/SpecimenImportTest.java b/src/org/labkey/test/tests/SpecimenImportTest.java index f8fd54a615c..b600603056d 100644 --- a/src/org/labkey/test/tests/SpecimenImportTest.java +++ b/src/org/labkey/test/tests/SpecimenImportTest.java @@ -26,7 +26,6 @@ import org.labkey.test.BaseWebDriverTest; import org.labkey.test.Locator; import org.labkey.test.WebTestHelper; -import org.labkey.test.categories.Daily; import org.labkey.test.categories.Specimen; import org.labkey.test.components.ext4.RadioButton; import org.labkey.test.util.DataRegionTable; @@ -43,7 +42,7 @@ import static org.junit.Assert.assertEquals; -@Category({Daily.class, Specimen.class}) +@Category({Specimen.class}) @BaseWebDriverTest.ClassTimeout(minutes = 5) public class SpecimenImportTest extends SpecimenBaseTest { diff --git a/src/org/labkey/test/tests/SpecimenMultipleImportTest.java b/src/org/labkey/test/tests/SpecimenMultipleImportTest.java index b42742c55f4..39319b2c792 100644 --- a/src/org/labkey/test/tests/SpecimenMultipleImportTest.java +++ b/src/org/labkey/test/tests/SpecimenMultipleImportTest.java @@ -19,14 +19,13 @@ import org.junit.experimental.categories.Category; import org.labkey.test.BaseWebDriverTest; import org.labkey.test.Locator; -import org.labkey.test.categories.Daily; import org.labkey.test.categories.Specimen; import org.labkey.test.util.LogMethod; import org.labkey.test.util.StudyHelper; import java.io.File; -@Category({Daily.class, Specimen.class}) +@Category({Specimen.class}) @BaseWebDriverTest.ClassTimeout(minutes = 6) public class SpecimenMultipleImportTest extends StudyBaseTest { diff --git a/src/org/labkey/test/tests/SpecimenTest.java b/src/org/labkey/test/tests/SpecimenTest.java index bfdad9fdeba..8eb0daf139e 100644 --- a/src/org/labkey/test/tests/SpecimenTest.java +++ b/src/org/labkey/test/tests/SpecimenTest.java @@ -30,7 +30,6 @@ import org.labkey.test.Locators; import org.labkey.test.TestTimeoutException; import org.labkey.test.WebTestHelper; -import org.labkey.test.categories.Daily; import org.labkey.test.categories.Specimen; import org.labkey.test.components.CustomizeView; import org.labkey.test.components.dumbster.EmailRecordTable; @@ -69,7 +68,7 @@ import static org.labkey.test.util.DataRegionTable.DataRegion; import static org.labkey.test.util.PermissionsHelper.READER_ROLE; -@Category({Daily.class, Specimen.class}) +@Category({Specimen.class}) @BaseWebDriverTest.ClassTimeout(minutes = 20) public class SpecimenTest extends SpecimenBaseTest { diff --git a/src/org/labkey/test/tests/StudyBaseTest.java b/src/org/labkey/test/tests/StudyBaseTest.java index c825cc16342..da4f17fbc43 100644 --- a/src/org/labkey/test/tests/StudyBaseTest.java +++ b/src/org/labkey/test/tests/StudyBaseTest.java @@ -130,18 +130,27 @@ protected void startSpecimenImport(int completeJobsExpected) protected void startSpecimenImport(int completeJobsExpected, File specimenArchive) { - _specimenImporter = new SpecimenImporter(new File(StudyHelper.getStudySubfolderPath()), specimenArchive, ARCHIVE_TEMP_DIR, getFolderName(), completeJobsExpected); - _specimenImporter.startImport(); + if (_studyHelper.isSpecimenModulePresent()) + { + _specimenImporter = new SpecimenImporter(new File(StudyHelper.getStudySubfolderPath()), specimenArchive, ARCHIVE_TEMP_DIR, getFolderName(), completeJobsExpected); + _specimenImporter.startImport(); + } } protected void waitForSpecimenImport() { - _specimenImporter.waitForComplete(); + if (_studyHelper.isSpecimenModulePresent()) + { + _specimenImporter.waitForComplete(); + } } protected void setExpectSpecimenImportError(boolean expected) { - _specimenImporter.setExpectError(expected); + if (_studyHelper.isSpecimenModulePresent()) + { + _specimenImporter.setExpectError(expected); + } } protected void runUITests() throws Exception diff --git a/src/org/labkey/test/tests/TabTest.java b/src/org/labkey/test/tests/TabTest.java index 8e306eabfcf..f9cf3064233 100644 --- a/src/org/labkey/test/tests/TabTest.java +++ b/src/org/labkey/test/tests/TabTest.java @@ -283,7 +283,10 @@ private void doTestContainerTabConversion() goToProjectHome(); _containerHelper.createSubfolder(getProjectName(), COLLAB_FOLDER, "Collaboration"); _containerHelper.createSubfolder(COLLABFOLDER_PATH, STUDY_FOLDER_TAB_NAME, "Study"); - _containerHelper.enableModule("Specimen"); + if (_studyHelper.isSpecimenModulePresent()) + { + _containerHelper.enableModule("Specimen"); + } _containerHelper.createSubfolder(COLLABFOLDER_PATH, ASSAY_FOLDER_TAB_NAME, "Assay"); clickFolder(COLLAB_FOLDER); clickFolder(STUDY_FOLDER_TAB_NAME); @@ -317,8 +320,11 @@ private void doTestContainerTabConversion() clickAndWait(Locator.linkWithText(STUDY_FOLDER_TAB_LABEL)); assertTextPresent("Study Overview"); studyContainerTab = PortalTab.finder(getDriver()).withTabText(STUDY_FOLDER_TAB_LABEL).find(); - studyContainerTab.goToTabContainer("Specimen Data"); - assertTextPresent("Vial Search", "Import Specimens"); + if (_studyHelper.isSpecimenModulePresent()) + { + studyContainerTab.goToTabContainer("Specimen Data"); + assertTextPresent("Vial Search", "Import Specimens"); + } clickAndWait(Locator.linkWithText(ASSAY_FOLDER_TAB_LABEL)); assertTextPresent("Assay List", EXTRA_ASSAY_WEBPART); @@ -343,8 +349,11 @@ private void doTestContainerTabConversion() assertTextPresent(STUDY_FOLDER_TAB_LABEL, ASSAY_FOLDER_TAB_LABEL); clickAndWait(Locator.linkWithText(STUDY_FOLDER_TAB_LABEL)); assertTextPresent("Study Overview"); - PortalTab.find(STUDY_FOLDER_TAB_LABEL, getDriver()).goToTabContainer("Specimen Data"); - assertTextPresent("Vial Search", "Import Specimens"); + if (_studyHelper.isSpecimenModulePresent()) + { + PortalTab.find(STUDY_FOLDER_TAB_LABEL, getDriver()).goToTabContainer("Specimen Data"); + assertTextPresent("Vial Search", "Import Specimens"); + } PortalTab.find(ASSAY_FOLDER_TAB_LABEL, getDriver()).activate(); assertTextPresent("Assay List", EXTRA_ASSAY_WEBPART); diff --git a/src/org/labkey/test/tests/flow/FlowSpecimenTest.java b/src/org/labkey/test/tests/flow/FlowSpecimenTest.java index 10af46df22a..ada29e612b3 100644 --- a/src/org/labkey/test/tests/flow/FlowSpecimenTest.java +++ b/src/org/labkey/test/tests/flow/FlowSpecimenTest.java @@ -15,13 +15,13 @@ */ package org.labkey.test.tests.flow; +import org.junit.Assume; import org.junit.BeforeClass; import org.junit.Test; import org.junit.experimental.categories.Category; import org.labkey.test.BaseWebDriverTest; import org.labkey.test.Locator; import org.labkey.test.WebTestHelper; -import org.labkey.test.categories.Daily; import org.labkey.test.categories.Flow; import org.labkey.test.categories.Specimen; import org.labkey.test.components.assay.AssayConstants; @@ -38,7 +38,7 @@ /** * This test checks the flow specimen foreign key behavior from flow.FCSFiles and flow.FCSAnalyses. */ -@Category({Daily.class, Flow.class, Specimen.class}) +@Category({Flow.class, Specimen.class}) @BaseWebDriverTest.ClassTimeout(minutes = 8) public class FlowSpecimenTest extends BaseFlowTest { @@ -62,6 +62,7 @@ public static void initFlowFolders() @LogMethod private void initializeStudyFolder() { + Assume.assumeTrue("Specimen module not present", _studyHelper.isSpecimenModulePresent()); log("** Initialize Study Folder"); _containerHelper.createSubfolder(getProjectName(), getProjectName(), STUDY_FOLDER, "Study", null); _containerHelper.enableModule("Specimen"); diff --git a/src/org/labkey/test/tests/viability/AbstractViabilityTest.java b/src/org/labkey/test/tests/viability/AbstractViabilityTest.java index ec38a5f0b40..0ce38857053 100644 --- a/src/org/labkey/test/tests/viability/AbstractViabilityTest.java +++ b/src/org/labkey/test/tests/viability/AbstractViabilityTest.java @@ -69,7 +69,8 @@ protected void initializeStudyFolder(String... tabs) { log("** Initialize Folder"); _containerHelper.createProject(getProjectName(), null); - _containerHelper.enableModule("Specimen"); + if (_studyHelper.isSpecimenModulePresent()) + _containerHelper.enableModule("Specimen"); _containerHelper.createSubfolder(getProjectName(), getProjectName(), getFolderName(), "Study", tabs, true); log("** Create Study"); diff --git a/src/org/labkey/test/tests/viability/ViabilityTest.java b/src/org/labkey/test/tests/viability/ViabilityTest.java index 949c91e9767..5f49424d1db 100644 --- a/src/org/labkey/test/tests/viability/ViabilityTest.java +++ b/src/org/labkey/test/tests/viability/ViabilityTest.java @@ -16,6 +16,7 @@ package org.labkey.test.tests.viability; +import org.junit.Assume; import org.junit.Test; import org.junit.experimental.categories.Category; import org.labkey.test.BaseWebDriverTest; @@ -67,6 +68,8 @@ protected String getAssayName() @Test public void runUITests() throws Exception { + Assume.assumeTrue("Specimen module not present", _studyHelper.isSpecimenModulePresent()); + // setup a scripting engine to run a java transform script new QCAssayScriptHelper(this).ensureEngineConfig(); From e53828d986a4561ef1f15d4073af157dba0f8b27 Mon Sep 17 00:00:00 2001 From: labkey-tchad Date: Tue, 22 Sep 2026 16:46:52 -0700 Subject: [PATCH 5/6] Add back to daily suites --- src/org/labkey/test/tests/AliquotTest.java | 3 ++- src/org/labkey/test/tests/CustomizeEmailTemplateTest.java | 3 ++- src/org/labkey/test/tests/SpecimenCustomizeTest.java | 3 ++- src/org/labkey/test/tests/SpecimenExportTest.java | 3 ++- src/org/labkey/test/tests/SpecimenGridExportTest.java | 3 ++- src/org/labkey/test/tests/SpecimenImportTest.java | 3 ++- src/org/labkey/test/tests/SpecimenMultipleImportTest.java | 3 ++- src/org/labkey/test/tests/SpecimenTest.java | 3 ++- src/org/labkey/test/tests/flow/FlowSpecimenTest.java | 3 ++- 9 files changed, 18 insertions(+), 9 deletions(-) diff --git a/src/org/labkey/test/tests/AliquotTest.java b/src/org/labkey/test/tests/AliquotTest.java index 81f6ab65be5..2730f46f228 100644 --- a/src/org/labkey/test/tests/AliquotTest.java +++ b/src/org/labkey/test/tests/AliquotTest.java @@ -21,6 +21,7 @@ import org.labkey.test.Locator; import org.labkey.test.Locators; import org.labkey.test.TestTimeoutException; +import org.labkey.test.categories.Daily; import org.labkey.test.categories.Specimen; import org.labkey.test.components.html.BootstrapMenu; import org.labkey.test.components.html.OptionSelect; @@ -31,7 +32,7 @@ import java.io.File; -@Category({Specimen.class}) +@Category({Daily.class, Specimen.class}) @BaseWebDriverTest.ClassTimeout(minutes = 8) public class AliquotTest extends SpecimenBaseTest { diff --git a/src/org/labkey/test/tests/CustomizeEmailTemplateTest.java b/src/org/labkey/test/tests/CustomizeEmailTemplateTest.java index 28cec7b81f2..2f26b959097 100644 --- a/src/org/labkey/test/tests/CustomizeEmailTemplateTest.java +++ b/src/org/labkey/test/tests/CustomizeEmailTemplateTest.java @@ -21,6 +21,7 @@ import org.labkey.test.Locator; import org.labkey.test.Locators; import org.labkey.test.WebTestHelper; +import org.labkey.test.categories.Daily; import org.labkey.test.categories.Specimen; import org.labkey.test.components.dumbster.EmailRecordTable; import org.labkey.test.util.DataRegionTable; @@ -35,7 +36,7 @@ import static org.junit.Assert.assertEquals; -@Category({Specimen.class}) +@Category({Daily.class, Specimen.class}) @BaseWebDriverTest.ClassTimeout(minutes = 5) public class CustomizeEmailTemplateTest extends SpecimenBaseTest { diff --git a/src/org/labkey/test/tests/SpecimenCustomizeTest.java b/src/org/labkey/test/tests/SpecimenCustomizeTest.java index 92909233c88..3feed6ae409 100644 --- a/src/org/labkey/test/tests/SpecimenCustomizeTest.java +++ b/src/org/labkey/test/tests/SpecimenCustomizeTest.java @@ -20,6 +20,7 @@ import org.labkey.test.BaseWebDriverTest; import org.labkey.test.Locator; import org.labkey.test.TestFileUtils; +import org.labkey.test.categories.Daily; import org.labkey.test.categories.Specimen; import org.labkey.test.components.CustomizeView; import org.labkey.test.components.DomainDesignerPage; @@ -37,7 +38,7 @@ import java.util.Arrays; import java.util.List; -@Category({Specimen.class}) +@Category({Daily.class, Specimen.class}) @BaseWebDriverTest.ClassTimeout(minutes = 7) public class SpecimenCustomizeTest extends SpecimenBaseTest { diff --git a/src/org/labkey/test/tests/SpecimenExportTest.java b/src/org/labkey/test/tests/SpecimenExportTest.java index f773cbc518d..077846be306 100644 --- a/src/org/labkey/test/tests/SpecimenExportTest.java +++ b/src/org/labkey/test/tests/SpecimenExportTest.java @@ -20,6 +20,7 @@ import org.labkey.test.Locator; import org.labkey.test.TestFileUtils; import org.labkey.test.TestTimeoutException; +import org.labkey.test.categories.Daily; import org.labkey.test.categories.Specimen; import org.labkey.test.util.FileBrowserHelper; import org.labkey.test.util.LogMethod; @@ -29,7 +30,7 @@ import static org.junit.Assert.assertTrue; -@Category({Specimen.class}) +@Category({Daily.class, Specimen.class}) @BaseWebDriverTest.ClassTimeout(minutes = 6) public class SpecimenExportTest extends SpecimenBaseTest { diff --git a/src/org/labkey/test/tests/SpecimenGridExportTest.java b/src/org/labkey/test/tests/SpecimenGridExportTest.java index 477b417fda8..1a5cd8faf43 100644 --- a/src/org/labkey/test/tests/SpecimenGridExportTest.java +++ b/src/org/labkey/test/tests/SpecimenGridExportTest.java @@ -22,6 +22,7 @@ import org.labkey.test.Locator; import org.labkey.test.TestTimeoutException; import org.labkey.test.WebTestHelper; +import org.labkey.test.categories.Daily; import org.labkey.test.categories.Specimen; import org.labkey.test.util.AbstractDataRegionExportOrSignHelper.ColumnHeaderType; @@ -32,7 +33,7 @@ /** * Test exporting rows from a specimen grid (not folder/study specimen export.) */ -@Category({Specimen.class}) +@Category({Daily.class, Specimen.class}) @BaseWebDriverTest.ClassTimeout(minutes = 7) public class SpecimenGridExportTest extends AbstractExportTest { diff --git a/src/org/labkey/test/tests/SpecimenImportTest.java b/src/org/labkey/test/tests/SpecimenImportTest.java index b600603056d..f8fd54a615c 100644 --- a/src/org/labkey/test/tests/SpecimenImportTest.java +++ b/src/org/labkey/test/tests/SpecimenImportTest.java @@ -26,6 +26,7 @@ import org.labkey.test.BaseWebDriverTest; import org.labkey.test.Locator; import org.labkey.test.WebTestHelper; +import org.labkey.test.categories.Daily; import org.labkey.test.categories.Specimen; import org.labkey.test.components.ext4.RadioButton; import org.labkey.test.util.DataRegionTable; @@ -42,7 +43,7 @@ import static org.junit.Assert.assertEquals; -@Category({Specimen.class}) +@Category({Daily.class, Specimen.class}) @BaseWebDriverTest.ClassTimeout(minutes = 5) public class SpecimenImportTest extends SpecimenBaseTest { diff --git a/src/org/labkey/test/tests/SpecimenMultipleImportTest.java b/src/org/labkey/test/tests/SpecimenMultipleImportTest.java index 39319b2c792..b42742c55f4 100644 --- a/src/org/labkey/test/tests/SpecimenMultipleImportTest.java +++ b/src/org/labkey/test/tests/SpecimenMultipleImportTest.java @@ -19,13 +19,14 @@ import org.junit.experimental.categories.Category; import org.labkey.test.BaseWebDriverTest; import org.labkey.test.Locator; +import org.labkey.test.categories.Daily; import org.labkey.test.categories.Specimen; import org.labkey.test.util.LogMethod; import org.labkey.test.util.StudyHelper; import java.io.File; -@Category({Specimen.class}) +@Category({Daily.class, Specimen.class}) @BaseWebDriverTest.ClassTimeout(minutes = 6) public class SpecimenMultipleImportTest extends StudyBaseTest { diff --git a/src/org/labkey/test/tests/SpecimenTest.java b/src/org/labkey/test/tests/SpecimenTest.java index 8eb0daf139e..bfdad9fdeba 100644 --- a/src/org/labkey/test/tests/SpecimenTest.java +++ b/src/org/labkey/test/tests/SpecimenTest.java @@ -30,6 +30,7 @@ import org.labkey.test.Locators; import org.labkey.test.TestTimeoutException; import org.labkey.test.WebTestHelper; +import org.labkey.test.categories.Daily; import org.labkey.test.categories.Specimen; import org.labkey.test.components.CustomizeView; import org.labkey.test.components.dumbster.EmailRecordTable; @@ -68,7 +69,7 @@ import static org.labkey.test.util.DataRegionTable.DataRegion; import static org.labkey.test.util.PermissionsHelper.READER_ROLE; -@Category({Specimen.class}) +@Category({Daily.class, Specimen.class}) @BaseWebDriverTest.ClassTimeout(minutes = 20) public class SpecimenTest extends SpecimenBaseTest { diff --git a/src/org/labkey/test/tests/flow/FlowSpecimenTest.java b/src/org/labkey/test/tests/flow/FlowSpecimenTest.java index ada29e612b3..11d873df4df 100644 --- a/src/org/labkey/test/tests/flow/FlowSpecimenTest.java +++ b/src/org/labkey/test/tests/flow/FlowSpecimenTest.java @@ -22,6 +22,7 @@ import org.labkey.test.BaseWebDriverTest; import org.labkey.test.Locator; import org.labkey.test.WebTestHelper; +import org.labkey.test.categories.Daily; import org.labkey.test.categories.Flow; import org.labkey.test.categories.Specimen; import org.labkey.test.components.assay.AssayConstants; @@ -38,7 +39,7 @@ /** * This test checks the flow specimen foreign key behavior from flow.FCSFiles and flow.FCSAnalyses. */ -@Category({Flow.class, Specimen.class}) +@Category({Daily.class, Flow.class, Specimen.class}) @BaseWebDriverTest.ClassTimeout(minutes = 8) public class FlowSpecimenTest extends BaseFlowTest { From 81ff3568f83db323c5a93a1d1e6b0d1fc03cdaf8 Mon Sep 17 00:00:00 2001 From: labkey-tchad Date: Fri, 25 Sep 2026 14:11:11 -0700 Subject: [PATCH 6/6] Remove specimen module --- src/org/labkey/test/tests/AliquotTest.java | 326 ----- .../tests/CustomizeEmailTemplateTest.java | 191 --- .../labkey/test/tests/SpecimenBaseTest.java | 166 --- .../test/tests/SpecimenCustomizeTest.java | 381 ----- .../labkey/test/tests/SpecimenExportTest.java | 224 --- .../test/tests/SpecimenGridExportTest.java | 183 --- .../labkey/test/tests/SpecimenImportTest.java | 274 ---- .../tests/SpecimenMultipleImportTest.java | 90 -- src/org/labkey/test/tests/SpecimenTest.java | 1258 ----------------- 9 files changed, 3093 deletions(-) delete mode 100644 src/org/labkey/test/tests/AliquotTest.java delete mode 100644 src/org/labkey/test/tests/CustomizeEmailTemplateTest.java delete mode 100644 src/org/labkey/test/tests/SpecimenBaseTest.java delete mode 100644 src/org/labkey/test/tests/SpecimenCustomizeTest.java delete mode 100644 src/org/labkey/test/tests/SpecimenExportTest.java delete mode 100644 src/org/labkey/test/tests/SpecimenGridExportTest.java delete mode 100644 src/org/labkey/test/tests/SpecimenImportTest.java delete mode 100644 src/org/labkey/test/tests/SpecimenMultipleImportTest.java delete mode 100644 src/org/labkey/test/tests/SpecimenTest.java diff --git a/src/org/labkey/test/tests/AliquotTest.java b/src/org/labkey/test/tests/AliquotTest.java deleted file mode 100644 index 2730f46f228..00000000000 --- a/src/org/labkey/test/tests/AliquotTest.java +++ /dev/null @@ -1,326 +0,0 @@ -/* - * Copyright (c) 2013-2026 LabKey Corporation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.labkey.test.tests; - -import org.junit.experimental.categories.Category; -import org.labkey.test.BaseWebDriverTest; -import org.labkey.test.Locator; -import org.labkey.test.Locators; -import org.labkey.test.TestTimeoutException; -import org.labkey.test.categories.Daily; -import org.labkey.test.categories.Specimen; -import org.labkey.test.components.html.BootstrapMenu; -import org.labkey.test.components.html.OptionSelect; -import org.labkey.test.pages.ImportDataPage; -import org.labkey.test.util.DataRegionTable; -import org.labkey.test.util.LogMethod; -import org.labkey.test.util.StudyHelper; - -import java.io.File; - -@Category({Daily.class, Specimen.class}) -@BaseWebDriverTest.ClassTimeout(minutes = 8) -public class AliquotTest extends SpecimenBaseTest -{ - protected static final String PROJECT_NAME = "AliquotVerifyProject"; - protected static final File SPECIMEN_ARCHIVE_148 = StudyHelper.getSpecimenArchiveFile("lab148.specimens"); - - @Override - protected String getProjectName() - { - return PROJECT_NAME; - } - - @Override - protected void doCleanup(boolean afterTest) throws TestTimeoutException - { - _userHelper.deleteUsers(false, USER1, USER2); - super.doCleanup(afterTest); - } - - @Override - protected BrowserType bestBrowser() - { - return BrowserType.CHROME; - } - - @Override - @LogMethod - protected void doCreateSteps() - { - enableEmailRecorder(); - initializeFolder(); - - clickButton("Create Study"); - setFormElement(Locator.name("label"), getStudyLabel()); - clickButton("Create Study"); - _studyHelper.setupAdvancedRepositoryType(); - setupRequestabilityRules(); - - setPipelineRoot(StudyHelper.getStudySubfolderPath()); - startSpecimenImport(1); - waitForSpecimenImport(); - _studyHelper.createCustomParticipantGroup(getProjectName(), getFolderName(), "Category1", "Participant", null, false, PTIDS[0], PTIDS[1]); - setupRequestStatuses(); - setupActorsAndGroups(); - setupDefaultRequirements(); - setupRequestForm(); - setupActorNotification(); - } - - @Override - @LogMethod - protected void doVerifySteps() - { - createRequests(); - verifyEditableSpecimens(); - } - - @Override - @LogMethod - protected void setupRequestabilityRules() - { - super.setupRequestabilityRules(); - - clickButton("Add Rule", 0); - click(Locator.menuItem("Locked While Processing Check")); - - // Remove "Locked In Request" rule - Locator lockedInRequestRow = Locator.xpath("//tr[contains(@class, 'x4-grid-row')]//div[text()='Locked In Request Check']"); - waitForElement(lockedInRequestRow); - click(lockedInRequestRow); - clickButton("Remove Rule", 0); - - clickButton("Save"); - } - - public static final String ALIQUOT_ONE = "AAA07XK5-03"; - public static final String ALIQUOT_TWO = "EBG002K4-25"; - public static final String ALIQUOT_THREE = "AAA07XK5-01"; - public static final String ALIQUOT_FOUR = "AAA07XK5-04"; - public static final String ALIQUOT_ONE_CHECKBOX = "//input[@id='check_" + ALIQUOT_ONE + "']"; - public static final String ALIQUOT_ONE_SPECIMEN_DETAIL_CHECKBOX = "//td[contains(text(), '" + ALIQUOT_ONE + "')]/../td/input[@type='checkbox' and @title='Select/unselect row']"; - public static final String ALIQUOT_THREE_CHECKBOX = "//input[@id='check_" + ALIQUOT_THREE + "']"; - public static final String ALIQUOT_THREE_SPECIMEN_DETAIL_CHECKBOX = "//td[contains(text(), '" + ALIQUOT_THREE + "')]/../td/input[@type='checkbox' and @title='Select/unselect row']"; - public static final String ALIQUOT_FOUR_CHECKBOX = "//input[@id='check_" + ALIQUOT_FOUR + "']"; - public static final String ALIQUOT_ONE_CHECKBOX_DISABLED = "//input[@id='check_" + ALIQUOT_ONE + "' and @disabled]"; - public static final String UNAVAILABLE_ALIQUOT = "AAQ00032-02"; - public static final String ALIQUOT_TWO_CHECKBOX = "//input[@id='check_" + ALIQUOT_TWO + "']"; - public static final String UNAVAILABLE_ALIQUOT_DISABLED = "//input[@id='check_" + UNAVAILABLE_ALIQUOT + "' and @disabled]"; - - @LogMethod - private void createRequests() - { - goToSpecimenData(); - clickAndWait(Locator.linkWithText("Blood (Whole)")); - - assertElementPresent(Locator.xpath(UNAVAILABLE_ALIQUOT_DISABLED)); - assertElementPresent(Locator.xpath(ALIQUOT_ONE_CHECKBOX)); - checkCheckbox(Locator.xpath(ALIQUOT_ONE_CHECKBOX)); - - createNewRequestFromQueryView(); - assertTextPresent(ALIQUOT_ONE); - assertTextNotPresent("Complete"); - - // Check that aliquot we added is not available - goToSpecimenData(); - clickAndWait(Locator.linkWithText("Blood (Whole)")); - assertElementPresent(Locator.xpath(ALIQUOT_ONE_CHECKBOX_DISABLED)); - assertElementPresent(Locator.xpath(ALIQUOT_ONE_CHECKBOX + "/../../td[contains(text(), 'This vial is unavailable because it is being processed')]")); - - // Now submit that request - viewExistingRequests(); - clickButton("Submit", 0); - assertAlertIgnoreCaseAndSpaces("Once a request is submitted, its specimen list may no longer be modified. Continue?"); - waitForElement(Locator.tag("h3").withText("Your request has been successfully submitted.")); - - clickAndWait(Locator.linkWithText("Update Request")); - selectOptionByText(Locator.name("status"), "Completed"); - clickButton("Save Changes and Send Notifications"); - - // Now verify that that aliquot is available again - goToSpecimenData(); - clickAndWait(Locator.linkWithText("Blood (Whole)")); - - assertElementPresent(Locator.xpath(ALIQUOT_ONE_CHECKBOX)); - checkCheckbox(Locator.xpath(ALIQUOT_ONE_CHECKBOX)); - - createNewRequestFromQueryView(); - assertTextPresent(ALIQUOT_ONE); - assertTextNotPresent("Complete"); - - clickAndWait(Locator.linkWithText("Upload Specimen Ids")); - new ImportDataPage(getDriver()) - .setText(ALIQUOT_TWO) - .submit(); - assertTextPresent(ALIQUOT_ONE, ALIQUOT_TWO); - checkCheckbox(Locator.checkboxByTitle("Select/unselect row")); // all individual item checkboxes have same name/title; should be first one - clickButton("Remove Selected"); - assertTextNotPresent(ALIQUOT_ONE); - assertTextPresent(ALIQUOT_TWO); - clickAndWait(Locator.linkWithText("Upload Specimen Ids")); - new ImportDataPage(getDriver()) - .setText(ALIQUOT_ONE) - .submit(); - assertTextPresent(ALIQUOT_ONE, ALIQUOT_TWO); - } - - @LogMethod - private void verifyEditableSpecimens() - { - // Change repository to editable - clickFolder(getFolderName()); - clickAndWait(Locator.linkWithText("Manage")); - clickAndWait(Locator.linkWithText("Change Repository Type")); - Locator enableEditableSpecimens = Locator.radioButtonByNameAndValue("specimenDataEditable", "true"); - waitForElement(enableEditableSpecimens); - checkRadioButton(enableEditableSpecimens); - clickButton("Submit"); - - verifyDeletingSpecimens(); - verifyEditingSpecimens(); - verifyInsertingSpecimens(); - - verifyIllegalImporting(); - } - - @LogMethod - private void verifyDeletingSpecimens() - { - goToSpecimenData(); - waitAndClickAndWait(Locator.linkWithText("Blood (Whole)").notHidden()); - - // Check that ALIQUOT_ONE cannot be selected for Delete - assertElementPresent(Locator.xpath(ALIQUOT_ONE_CHECKBOX_DISABLED)); - - // There's a request from createRequest(); Submit it and make it completed to free up aliqouts - viewExistingRequests(); - doAndWaitForPageToLoad(() -> { - clickButton("Submit", 0); - assertAlertIgnoreCaseAndSpaces("Once a request is submitted, its specimen list may no longer be modified. Continue?"); - }); - waitForElement(Locator.css("h3").withText("Your request has been successfully submitted.")); - clickAndWait(Locator.linkWithText("Update Request")); - selectOptionByText(Locator.name("status"), "Completed"); - clickButton("Save Changes and Send Notifications"); - - // Now try to delete ALIQUOT_ONE - DataRegionTable dataRegion = navigateToQuery("study", "SpecimenDetail").getDataRegion(); - assertElementPresent(Locator.xpath(ALIQUOT_ONE_SPECIMEN_DETAIL_CHECKBOX)); - dataRegion.doAndWaitForUpdate(() -> checkCheckbox(Locator.xpath(ALIQUOT_ONE_SPECIMEN_DETAIL_CHECKBOX))); - doAndWaitForPageToLoad(() -> { - dataRegion.clickHeaderButton("Delete"); - assertAlertIgnoreCaseAndSpaces("Are you sure you want to delete the selected row?"); - }); - waitForElement(Locators.labkeyError.withText("Specimen may not be deleted because it has been used in a request.")); - clickButton("Back"); - - // Now delete a different aliquot - dataRegion.doAndWaitForUpdate(() -> checkCheckbox(Locator.xpath(ALIQUOT_THREE_SPECIMEN_DETAIL_CHECKBOX))); - dataRegion.deleteSelectedRows(); - waitForElementToDisappear(Locator.xpath(ALIQUOT_THREE_SPECIMEN_DETAIL_CHECKBOX)); - clickFolder(getFolderName()); - } - - @LogMethod - private void verifyEditingSpecimens() - { - clickFolder(getFolderName()); - goToSpecimenData(); - waitAndClickAndWait(Locator.linkWithText("Blood (Whole)").notHidden()); - - // Create request with ALIQUOT_FOUR - checkCheckbox(Locator.xpath(ALIQUOT_FOUR_CHECKBOX)); - createNewRequestFromQueryView(); - assertTextPresent(ALIQUOT_FOUR); - - // Attempt to edit, which should be error - goToSpecimenData(); - waitAndClickAndWait(Locator.linkWithText("Blood (Whole)").notHidden()); - DataRegionTable table = new DataRegionTable("SpecimenDetail", getDriver()); - clickAndWait(table.updateLink(table.getRowIndex("GlobalUniqueId", ALIQUOT_FOUR))); - assertTextNotPresent("Specimen may not be edited when it's in a non-final request."); - clickButton("Submit"); - waitForText("Specimen may not be edited when it's in a non-final request."); - clickButton("Cancel"); - - // Edit another specimen - clickAndWait(table.updateLink(table.getRowIndex("GlobalUniqueId", ALIQUOT_ONE))); - assertTextNotPresent("Specimen may not be edited when it's in a non-final request."); - setFormElement(Locator.xpath("//input[@name='quf_VisitDescription']"), "VisitVisit"); - clickButton("Submit"); - waitForText("VisitVisit"); - } - - @LogMethod - private void verifyInsertingSpecimens() - { - clickFolder(getFolderName()); - goToSpecimenData(); - waitAndClickAndWait(Locator.linkWithText("Blood (Whole)").notHidden()); - - // verify insert new here - DataRegionTable detail = new DataRegionTable("SpecimenDetail", this); - detail.clickInsertNewRow() - .setField("GlobalUniqueId", "Global") - .setField("VisitDescription", "NewVisit") - .setField("SequenceNum", "001") - .setField("ParticipantId", OptionSelect.SelectOption.textOption("618005775")) - .submit(); - assertElementNotPresent(Locator.tagWithClass("*", "labkey-error").withText()); - detail.setFilter("VisitDescription", "Equals", "NewVisit"); - assertTextPresent("NewVisit"); - } - - @LogMethod - private void verifyIllegalImporting() - { - checkErrors(); - navigateToFolder("AliquotVerifyProject", getFolderName()); - startSpecimenImport(2, SPECIMEN_ARCHIVE_148); - setExpectSpecimenImportError(true); - waitForSpecimenImport(); - - // Check there was an error in the specimen merge. - clickAndWait(Locator.linkWithText("ERROR")); - assertTextPresent("With an editable specimen repository, importing may not reference any existing specimen. " + - "8 imported specimen events refer to existing specimens."); - - // Make sure the expected errors have been logged and will not hang up the test later on. - checkExpectedErrors(1); - } - - private void createNewRequestFromQueryView() - { - DataRegionTable specimenTable = new DataRegionTable("SpecimenDetail", this); - specimenTable.clickHeaderMenu("Request Options", "Create New Request"); - selectOptionByText(Locator.name("destinationLocation"), DESTINATION_SITE); - setFormElement(Locator.id("input0"), "Assay Plan"); - setFormElement(Locator.id("input2"), "Comments"); - setFormElement(Locator.id("input1"), "Shipping"); - setFormElement(Locator.id("input3"), "sample last one input"); - clickButton("Create and View Details"); - assertTextPresent(DESTINATION_SITE); - } - - private void viewExistingRequests() - { - new BootstrapMenu(getDriver(), Locator.tagWithClass("div", "lk-menu-drop") - .withDescendant(Locator.tag("span").withText("Request Options")).findElement(getDriver()) - ).clickSubMenu(true, "View Existing Requests"); - } -} diff --git a/src/org/labkey/test/tests/CustomizeEmailTemplateTest.java b/src/org/labkey/test/tests/CustomizeEmailTemplateTest.java deleted file mode 100644 index 2f26b959097..00000000000 --- a/src/org/labkey/test/tests/CustomizeEmailTemplateTest.java +++ /dev/null @@ -1,191 +0,0 @@ -/* - * Copyright (c) 2013-2026 LabKey Corporation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.labkey.test.tests; - -import org.jetbrains.annotations.Nullable; -import org.junit.experimental.categories.Category; -import org.labkey.test.BaseWebDriverTest; -import org.labkey.test.Locator; -import org.labkey.test.Locators; -import org.labkey.test.WebTestHelper; -import org.labkey.test.categories.Daily; -import org.labkey.test.categories.Specimen; -import org.labkey.test.components.dumbster.EmailRecordTable; -import org.labkey.test.util.DataRegionTable; -import org.labkey.test.util.LogMethod; -import org.labkey.test.util.StudyHelper; -import org.openqa.selenium.WebElement; - -import java.util.Arrays; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import static org.junit.Assert.assertEquals; - -@Category({Daily.class, Specimen.class}) -@BaseWebDriverTest.ClassTimeout(minutes = 5) -public class CustomizeEmailTemplateTest extends SpecimenBaseTest -{ - private static final String _projectName = "EmailTemplateProject"; - private static final String _recipient = "notify@emailtemplate.test"; - private static final String _assayPlan = "assay plan"; - private static final String _shipping = "123 main street"; - private static final String _comments = "this is my comment"; - private static final String _studyName = "Study 001"; - private static final String _notificationDivName = "params"; - private static final List replacementParams = Arrays.asList( - "action", - "attachments", - "comments", - "contextPath", - "currentDateTime", - "destinationLocation", - "folderName", - "folderPath", - "folderURL", - "homePageURL", - "modifiedBy", - "organizationName", - "simpleStatus", - "siteShortName", - "specimenRequestNumber", - "status", - "studyName", - "subjectSuffix", - "supportLink", - "systemDescription", - "systemEmail", - "specimenList"); - - @Nullable - @Override - protected String getProjectName() - { - return _projectName; - } - - @Override - protected BrowserType bestBrowser() - { - return BrowserType.CHROME; - } - - @Override - @LogMethod - protected void doCreateSteps() - { - enableEmailRecorder(); - initializeFolder(); - - clickButton("Create Study"); - setFormElement(Locator.name("label"), getStudyLabel()); - clickButton("Create Study"); - _studyHelper.setupAdvancedRepositoryType(); - - setPipelineRoot(StudyHelper.getStudySubfolderPath()); - startSpecimenImport(1); - waitForSpecimenImport(); - setupRequestStatuses(); - setupActorsAndGroups(); - setupRequestForm(); - setupActorNotification(); - setCustomNotificationTemplate(); - createSpecimenRequest(); - } - - private void setCustomNotificationTemplate() - { - clickTab("Manage"); - clickAndWait(Locator.linkWithText("Manage Notifications")); - WebElement newRequestNotifyCheckbox = Locator.checkboxById("newRequestNotifyCheckbox").findElement(getDriver()); - checkCheckbox(newRequestNotifyCheckbox); - checkCheckbox(newRequestNotifyCheckbox); // First try just doesn't stick sometimes - setFormElement(waitForElement(Locator.id("newRequestNotify").notHidden()), _recipient); - clickButton("Save"); - clickAndWait(Locator.linkWithText("Manage Notifications")); - clickAndWait(Locator.linkWithText("Edit Email Template")); - selectOptionByText(Locator.name("templateClass"), "Specimen request notification"); - setFormElement(Locator.id("emailSubject"), "^studyName^"); - setFormElement(Locator.id("emailMessage"), buildTemplateBody()); - clickButton("Save"); - assertElementNotPresent(Locators.labkeyError); - } - - private void createSpecimenRequest() - { - clickTab("Specimen Data"); - waitAndClickAndWait(Locator.linkWithText("By Individual Vial")); - DataRegionTable specimenDetail = new DataRegionTable("SpecimenDetail", this); - specimenDetail.checkCheckbox(0); - specimenDetail.clickHeaderMenu("Request Options", "Create New Request"); - selectOptionByText(Locator.name("destinationLocation"), DESTINATION_SITE); - setFormElement(Locator.id("input0"), _assayPlan); - setFormElement(Locator.id("input2"), _comments); - setFormElement(Locator.id("input1"), _shipping); - setFormElement(Locator.id("input3"), "sample last one input"); - clickButton("Create and View Details"); - - doAndWaitForPageToLoad(()-> { - clickButton("Submit Request", 0); // don't wait for the page load; an assert will come - assertAlertIgnoreCaseAndSpaces("Once a request is submitted, its specimen list may no longer be modified. Continue?"); // dismiss the alert; /then/ wait - }); - } - - @Override - protected void doVerifySteps() throws Exception - { - EmailRecordTable emailRecordTable = goToEmailRecord(); - EmailRecordTable.EmailMessage message = emailRecordTable.getEmailAtTableIndex(1); - emailRecordTable.clickMessage(message); - String[] bodyContents = Locator.name(_notificationDivName).findElement(getDriver()).getText().split("\n"); - Map emailNVPs = new HashMap<>(); - for (String line : bodyContents) - { - String[] nvp = line.split("=="); - if(nvp.length==2) - { - emailNVPs.put(nvp[0].trim(), nvp[1]); - } - if(nvp.length==1) - { - emailNVPs.put(nvp[0].trim(), ""); - } - } - assertEquals(_studyName, message.getSubject()); - assertEquals("New Request", emailNVPs.get("status")); - assertEquals("New Request Created", emailNVPs.get("action")); - assertEquals(WebTestHelper.getContextPath(), emailNVPs.getOrDefault("contextPath", "")); - assertEquals("My Study", emailNVPs.get("folderName")); - assertEquals("/EmailTemplateProject/My Study", emailNVPs.get("folderPath")); - assertEquals(WebTestHelper.getBaseURL(), emailNVPs.get("homePageURL")); - } - - private String buildTemplateBody() - { - String delimiter = ""; - StringBuilder templateBuilder = new StringBuilder(); - templateBuilder.append("
\n"); - for (String param : replacementParams) - { - templateBuilder.append(delimiter); - templateBuilder.append(String.format("^%s|%s==%%s^", param, param)); - delimiter = "
\n"; - } - templateBuilder.append("\n
"); - return templateBuilder.toString(); - } -} diff --git a/src/org/labkey/test/tests/SpecimenBaseTest.java b/src/org/labkey/test/tests/SpecimenBaseTest.java deleted file mode 100644 index 229694fc1a3..00000000000 --- a/src/org/labkey/test/tests/SpecimenBaseTest.java +++ /dev/null @@ -1,166 +0,0 @@ -/* - * Copyright (c) 2013-2026 LabKey Corporation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.labkey.test.tests; - -import org.junit.Assert; -import org.labkey.test.Locator; -import org.labkey.test.TestTimeoutException; -import org.labkey.test.components.html.RadioButton; -import org.labkey.test.util.LogMethod; -import org.labkey.test.util.ext4cmp.Ext4GridRef; - -import static org.labkey.test.components.html.RadioButton.RadioButton; - -public abstract class SpecimenBaseTest extends StudyBaseTest -{ - public static final String SPECIMEN_DETAIL = "SpecimenDetail"; - protected static final String DESTINATION_SITE = "Aurum Health KOSH Lab, Orkney, South Africa (Endpoint Lab, Repository)"; - protected static final String SOURCE_SITE = "Contract Lab Services, Johannesburg, South Africa (Repository, Clinic)"; - protected static final String USER1 = "user1@specimen.test"; - protected static final String USER2 = "user2@specimen.test"; - protected static final String REQUESTABILITY_QUERY = "RequestabilityRule"; - protected static final String UNREQUESTABLE_SAMPLE = "BAA07XNP-02"; - protected static final String[] PTIDS = {"999320396","999320812"}; - protected int _requestId; - - @Override - protected void doCleanup(boolean afterTest) throws TestTimeoutException - { - super.doCleanup(afterTest); - } - - // Callers must click the Save button - @LogMethod - protected void setupRequestabilityRules() - { - // Create custom query to test requestability rules. - goToSchemaBrowser(); - createNewQuery("study", SPECIMEN_DETAIL); - setFormElement(Locator.name("ff_newQueryName"), REQUESTABILITY_QUERY); - clickAndWait(Locator.lkButton("Create and Edit Source")); - setCodeEditorValue("queryText", - "SELECT \n" + - SPECIMEN_DETAIL + ".GlobalUniqueId AS GlobalUniqueId\n" + - "FROM " + SPECIMEN_DETAIL + "\n" + - "WHERE " + SPECIMEN_DETAIL + ".GlobalUniqueId='" + UNREQUESTABLE_SAMPLE + "'"); - clickButton("Save", 0); - waitForElement(Locator.css(".labkey-status-info").withText("Saved")); - - clickFolder(getFolderName()); - waitAndClick(Locator.linkWithText("Manage Study")); - waitAndClick(Locator.linkWithText("Manage Requestability Rules")); - - // Wait for grid to render - waitForElement(Locator.xpath("//table[contains(@class, 'x4-grid-table')]")); - Ext4GridRef gridRef = _ext4Helper.queryOne("panel[title='Active Rules']", Ext4GridRef.class); - - // Expect three rows - int rowCount = gridRef.getRowCount(); - log("How many rows? " + rowCount); - Assert.assertEquals(3, rowCount); - - // Verify that LOCKED_IN_REQUEST is the last rule - log(gridRef.getFieldValue(rowCount, "name").toString()); - Assert.assertEquals("Last requestability rule", "Locked In Request Check", gridRef.getFieldValue(rowCount, "name")); - - click(Locator.xpath("//div[contains(@class, 'x4-grid-cell-inner-row-numberer') and text()='2']")); - - clickButton("Add Rule", 0); - click(Locator.menuItem("Custom Query")); - _ext4Helper.selectComboBoxItem(Locator.id("userQuery_schema"), "study" ); - _ext4Helper.selectComboBoxItem(Locator.id("userQuery_query"), REQUESTABILITY_QUERY ); - _ext4Helper.selectComboBoxItem(Locator.id("userQuery_action"), "Unavailable" ); - clickButton("Submit",0); - } - - @LogMethod - protected void setupActorsAndGroups() - { - clickTab("Manage"); - clickAndWait(Locator.linkWithText("Manage Actors and Groups")); - setFormElement(Locator.name("newLabel"), "SLG"); - selectOptionByText(Locator.name("newPerSite"), "One Per Study"); - clickButton("Save"); - clickAndWait(Locator.linkWithText("Update Members")); - waitForElement(Locator.name("names")); - setFormElement(Locator.name("names"), USER1); - uncheckCheckbox(Locator.checkboxByName("sendEmail")); - clickButton("Update Members"); - setFormElement(Locator.name("newLabel"), "IRB"); - selectOptionByText(Locator.name("newPerSite"), "Multiple Per Study (Location Affiliated)"); - clickButton("Save"); - clickAndWait(Locator.linkWithText("Update Members").index(1)); - clickAndWait(Locator.linkWithText(DESTINATION_SITE)); - waitForElement(Locator.name("names")); - setFormElement(Locator.name("names"), USER2); - uncheckCheckbox(Locator.checkboxByName("sendEmail")); - clickAndWait(Locator.linkWithText("Update Members")); - } - - @LogMethod (quiet = true) - protected void setupDefaultRequirements() - { - clickTab("Manage"); - clickAndWait(Locator.linkWithText("Manage Default Requirements")); - selectOptionByText(Locator.name("originatorActor"), "IRB"); - setFormElement(Locator.name("originatorDescription"), "Originating IRB Approval"); - clickButton("Add Requirement"); - selectOptionByText(Locator.name("providerActor"), "IRB"); - setFormElement(Locator.name("providerDescription"), "Providing IRB Approval"); - clickAndWait(Locator.xpath("//input[@name='providerDescription']/../.." + Locator.lkButton("Add Requirement").toXpath())); - selectOptionByText(Locator.name("receiverActor"), "IRB"); - setFormElement(Locator.name("receiverDescription"), "Receiving IRB Approval"); - clickAndWait(Locator.xpath("//input[@name='receiverDescription']/../.." + Locator.lkButton("Add Requirement").toXpath())); - selectOptionByText(Locator.name("generalActor"), "SLG"); - setFormElement(Locator.name("generalDescription"), "SLG Approval"); - clickAndWait(Locator.xpath("//input[@name='generalDescription']/../.." + Locator.lkButton("Add Requirement").toXpath())); - } - - @LogMethod (quiet = true) - protected void setupRequestForm() - { - clickTab("Manage"); - clickAndWait(Locator.linkWithText("Manage New Request Form")); - clickButton("Add New Input", 0); - setFormElement(Locator.xpath("//descendant::input[@name='title'][4]"), "Last One"); - setFormElement(Locator.xpath("//descendant::input[@name='helpText'][4]"), "A test input"); - click(Locator.xpath("//descendant::input[@name='required'][4]")); - clickButton("Save"); - } - - @LogMethod - protected void setupActorNotification() - { - log("Check Configure Defaults for Actor Notification"); - clickTab("Manage"); - clickAndWait(Locator.linkWithText("Manage Notifications")); - assertTextPresent("Default Email Recipients"); - RadioButton notifyAllRadioButton = RadioButton(Locator.radioButtonByNameAndValue("defaultEmailNotify", "All")).find(getDriver()); - waitFor(() -> { - notifyAllRadioButton.check(); - return notifyAllRadioButton.isChecked(); - }, "Failed to check radio button", WAIT_FOR_JAVASCRIPT); - clickButton("Save"); - - // TODO: Remove check below. This is temporary to investigate intermittent test failures where actors with emails - // aren't checked on the manage requirement page. Verify that setting actually got set. - clickAndWait(Locator.linkWithText("Manage Notifications")); - assertTextPresent("Default Email Recipients"); - assertRadioButtonSelected(Locator.radioButtonByNameAndValue("defaultEmailNotify", "All")); - clickButton("Cancel"); - } -} diff --git a/src/org/labkey/test/tests/SpecimenCustomizeTest.java b/src/org/labkey/test/tests/SpecimenCustomizeTest.java deleted file mode 100644 index 3feed6ae409..00000000000 --- a/src/org/labkey/test/tests/SpecimenCustomizeTest.java +++ /dev/null @@ -1,381 +0,0 @@ -/* - * Copyright (c) 2014-2026 LabKey Corporation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.labkey.test.tests; - -import org.junit.Assert; -import org.junit.experimental.categories.Category; -import org.labkey.test.BaseWebDriverTest; -import org.labkey.test.Locator; -import org.labkey.test.TestFileUtils; -import org.labkey.test.categories.Daily; -import org.labkey.test.categories.Specimen; -import org.labkey.test.components.CustomizeView; -import org.labkey.test.components.DomainDesignerPage; -import org.labkey.test.params.FieldDefinition; -import org.labkey.test.params.FieldDefinition.ColumnType; -import org.labkey.test.util.DataRegionTable; -import org.labkey.test.util.LogMethod; -import org.labkey.test.util.StudyHelper; -import org.openqa.selenium.By; -import org.openqa.selenium.WebElement; -import org.openqa.selenium.support.ui.ExpectedConditions; - -import java.io.File; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -@Category({Daily.class, Specimen.class}) -@BaseWebDriverTest.ClassTimeout(minutes = 7) -public class SpecimenCustomizeTest extends SpecimenBaseTest -{ - protected static final String PROJECT_NAME = "SpecimenCustomizeProject"; - protected static final File SPECIMEN_ARCHIVE = StudyHelper.getSpecimenArchiveFile("Rollup.specimens"); - protected static final String SPECIMEN_AVAILABLE_REASON = "This vial's availability status was set by an administrator. Please contact an administrator for more information."; - protected static final String SPECIMEN_UNAVAILABLE_REASON = "This vial is unavailable because it is not currently held by a repository."; - - @Override - protected String getProjectName() - { - return PROJECT_NAME; - } - - @Override - protected BrowserType bestBrowser() - { - return BrowserType.CHROME; - } - - @Override - protected void doCreateSteps() - { - initializeFolder(); - importFolderFromZip(TestFileUtils.getSampleData("studies/SpecimenCustomizeStudy.folder.zip")); - } - - @Override - @LogMethod - protected void doVerifySteps() - { - configureSpecimenProperties(); - - setPipelineRoot(StudyHelper.getStudySubfolderPath()); - startSpecimenImport(2, SPECIMEN_ARCHIVE); - waitForSpecimenImport(); - - addFieldsToSpecimenView(); - - verifySpecimenDetailContents(); - } - - private void configureSpecimenProperties() - { - goToManageStudy(); - clickAndWait(Locator.linkContainingText("Edit Specimen Event fields")); - - DomainDesignerPage designerPage = new DomainDesignerPage(getDriver()); - designerPage.fieldsPanel().addField(new FieldDefinition("Tally", ColumnType.Integer)); - // Set a couple import aliases to test them below: Issue 39672 - designerPage.fieldsPanel().addField(new FieldDefinition("Note", ColumnType.String).setImportAliases("Comment,Notables")); - designerPage.fieldsPanel().addField(new FieldDefinition("Minutes", ColumnType.Decimal)); - designerPage.fieldsPanel().addField(new FieldDefinition("Flag", ColumnType.Boolean)); - designerPage.clickFinish(); - - clickAndWait(Locator.linkContainingText("Edit Vial fields")); - designerPage = new DomainDesignerPage(getDriver()); - designerPage.fieldsPanel().addField(new FieldDefinition("Tally", ColumnType.Integer)); - designerPage.fieldsPanel().addField(new FieldDefinition("FirstTally", ColumnType.Integer)); - designerPage.fieldsPanel().addField(new FieldDefinition("LatestTally", ColumnType.Integer)); - designerPage.fieldsPanel().addField(new FieldDefinition("LatestNonBlankTally", ColumnType.Integer)); - designerPage.fieldsPanel().addField(new FieldDefinition("CombineTally", ColumnType.Integer)); - designerPage.fieldsPanel().addField(new FieldDefinition("FirstNote", ColumnType.String)); - designerPage.fieldsPanel().addField(new FieldDefinition("LatestNote", ColumnType.String)); - designerPage.fieldsPanel().addField(new FieldDefinition("LatestNonBlankNote", ColumnType.String)); - designerPage.fieldsPanel().addField(new FieldDefinition("CombineNote", ColumnType.String)); - designerPage.fieldsPanel().addField(new FieldDefinition("FirstMinutes", ColumnType.Decimal)); - designerPage.fieldsPanel().addField(new FieldDefinition("LatestMinutes", ColumnType.Decimal)); - designerPage.fieldsPanel().addField(new FieldDefinition("LatestNonBlankMinutes", ColumnType.Decimal)); - designerPage.fieldsPanel().addField(new FieldDefinition("CombineMinutes", ColumnType.Decimal).setFormat("0.####")); - designerPage.fieldsPanel().addField(new FieldDefinition("FirstFlag", ColumnType.Boolean)); - designerPage.fieldsPanel().addField(new FieldDefinition("LatestFlag", ColumnType.Boolean)); - designerPage.fieldsPanel().addField(new FieldDefinition("LatestNonBlankFlag", ColumnType.Boolean)); - designerPage.fieldsPanel().addField(new FieldDefinition("LatestDrawTimestamp", ColumnType.DateAndTime)); - designerPage.fieldsPanel().addField(new FieldDefinition("FirstDrawTimestamp", ColumnType.DateAndTime)); - designerPage.clickFinish(); - - clickAndWait(Locator.linkContainingText("Edit Specimen fields")); - designerPage = new DomainDesignerPage(getDriver()); - designerPage.fieldsPanel().addField(new FieldDefinition("TotalLatestNonBlankTally", ColumnType.Integer)); - designerPage.fieldsPanel().addField(new FieldDefinition("SumOfLatestNonBlankMinutes", ColumnType.Decimal).setFormat("0.####")); - designerPage.fieldsPanel().addField(new FieldDefinition("SumOfCombineMinutes", ColumnType.Decimal).setFormat("0.####")); - designerPage.fieldsPanel().addField(new FieldDefinition("CountLatestNonBlankFlag", ColumnType.Integer)); - designerPage.fieldsPanel().addField(new FieldDefinition("MaxAvailabilityReason", ColumnType.String)); - designerPage.fieldsPanel().addField(new FieldDefinition("MinAvailabilityReason", ColumnType.String)); - designerPage.clickFinish(); - } - - private ArrayList getRowsFromTable(WebElement table) - { - ArrayList rows = new ArrayList<>(); - int i = 1; - for(WebElement row : table.findElements(By.xpath(".//tr"))) - { - rows.add(new PropertyRow(row, i)); - i++; - } - return rows; - } - - class SpecimenPropertyTable - { - List _propertyRows; - String _label; - - public SpecimenPropertyTable(String label) - { - _label = label; - _propertyRows = new ArrayList<>(); - String xPath = "//td[.='" + _label + "']/../..//table[@class='labkey-pad-cells']"; - Locator locator = Locator.xpath(xPath); - WebElement table = locator.findElement(getDriver()); - int i = 1; - for(WebElement row : table.findElements(By.xpath(".//tr"))) - { - _propertyRows.add(new PropertyRow(row, i)); - i++; - } - } - - public void refresh() - { - _propertyRows = new ArrayList<>(); - String xPath = "//td[.='" + _label + "']/../..//table[@class='labkey-pad-cells']"; - Locator locator = Locator.xpath(xPath); - waitForElement(locator); - WebElement table = locator.findElement(getDriver()); - int i = 1; - for(WebElement row : table.findElements(By.xpath(".//tr"))) - { - _propertyRows.add(new PropertyRow(row, i)); - i++; - } - } - - public PropertyRow getPropertyRowByName(String name) - { - PropertyRow theRow = null; - for(int i = 1; i <= _propertyRows.size(); i++) - { - if(name.equals(_propertyRows.get(i).getName())) - { - theRow = _propertyRows.get(i); - return theRow; - } - } - return theRow; - } - - public PropertyRow getPropertyRowByLabel(String label) - { - PropertyRow theRow = null; - for(int i = 1; i < _propertyRows.size(); i++) - { - if(label.equals(_propertyRows.get(i).getLabel())) - { - theRow = _propertyRows.get(i); - } - } - return theRow; - } - } - - //wrapper for element in specimen tables - private class PropertyRow - { - protected WebElement _tr; - protected int _index; - - public PropertyRow(WebElement tr, int index) - { - _tr = tr; - } - - private String getEditableValue() - { - String value = _tr.findElement(By.xpath(".//div//input")).getAttribute("value"); - return _tr.findElement(By.xpath(".//div//input")).getAttribute("value"); - - } - - public String getName() - { - WebElement nameElement = _tr.findElement(By.xpath(".//td[6]/div")); - if(isEditable()) - { - return getEditableValue(); - } - else - { - return nameElement.getText(); - } - } - - public String getLabel() - { - WebElement labelElement = _tr.findElement(By.xpath(".//td[7]/div")); - if(isEditable()) - { - return getEditableValue(); - } - else - { - return labelElement.getText(); - } - } - - public String getType() - { - WebElement typeElement = _tr.findElement(By.xpath(".//td[8]/div")); - if(isEditable()) - { - return getEditableValue(); - } - else - { - return typeElement.getAttribute("value"); - } - } - - public Boolean isEditable() - { - return !_tr.findElements(By.xpath(".//div[contains(@id,'name')]/input")).isEmpty(); - } - - public void editName(String value) - { - //WebElement editableNameElement = _tr.findElement(By.xpath(".//div[contains(@id,'name')]/input")); - WebElement editableNameElement = _tr.findElement(By.xpath(".//td[6]/div/input")); - editableNameElement.click(); - editableNameElement.sendKeys(value); - } - - public void editLabel(String value) - { - _tr.findElement(By.xpath(".//div[contains(@id,'label')]/input")).sendKeys(value); - } - - public void editType(String value) - { - _tr.findElement(By.xpath(".//div[contains(@id,'auto')]/div[contains(@class,'trigger')]")).click(); - waitForElement(Locator.xpath("//div[@class=' x-window x-component ']")); - click(Locator.xpath("//label[text()='" + value + "']")); - click(Locator.buttonContainingText("Apply")); - } - - public void delete() - { - _tr.findElement(By.xpath("//div[contains(@id, 'partdelete']/input")).click(); - } - } - - public void setFormat(String where, String value) - { - String prefix = "//td[text() = '" + where + "']/../.."; - click(Locator.xpath(prefix + "//span[contains(@class,'x-tab-strip-text') and text()='Format']")); - Locator formatLoc = Locator.tagWithId("input", "propertyFormat"); - setFormElement(formatLoc, value); - } - - private void addFieldsToSpecimenView() - { - clickTab("Specimen Data"); - shortWait().until(ExpectedConditions.elementToBeClickable(Locator.linkWithText("By Individual Vial"))); - click(Locator.linkWithText("By Individual Vial")); - waitForText("Vials"); - DataRegionTable specimenTable = new DataRegionTable("SpecimenDetail", this); - CustomizeView specimenTableCustomizer = specimenTable.getCustomizeView(); - specimenTableCustomizer.openCustomizeViewPanel(); - waitForText("Available Fields"); - specimenTableCustomizer.addColumn("MaxAvailabilityReason"); - specimenTableCustomizer.addColumn("MinAvailabilityReason"); - specimenTableCustomizer.addColumn("LatestDrawTimestamp"); - specimenTableCustomizer.addColumn("FirstDrawTimestamp"); - specimenTableCustomizer.saveDefaultView(); - } - - private void importSpecimenArchives() - { - startSpecimenImport(2, SPECIMEN_ARCHIVE); - waitForSpecimenImport(); - } - - private void verifySpecimenDetailContents() - { - clickTab("Specimen Data"); - waitAndClickAndWait(Locator.linkWithText("By Individual Vial")); - DataRegionTable table = new DataRegionTable("SpecimenDetail", this); - - // This tests import aliases, since the "Note" column in Rollup.specimens has the column header "Notables": Issue 39672 - List actual = table.getColumnDataAsText("CombineNote"); - List expected = Arrays.asList("novials1002", "novials1001, novials1003", " ", " ", " ", " ", " ", - "unavailable2", "unavailable1, unavailable22", " ", "note1, note101", "note2", " ", " ", " ", " ", " "); - Assert.assertEquals("CombineNote values incorrect", expected, actual); - - actual = table.getColumnDataAsText("CombineTally"); - expected = Arrays.asList("1002", "2004", " ", " ", " ", " ", " ", - "12", "33", " ", "102", "2", " ", " ", " ", " ", " "); - Assert.assertEquals("CombineTally values incorrect", expected, actual); - - actual = table.getColumnDataAsText("SumOfLatestNonBlankMinutes"); - expected = Arrays.asList("100.2", "100.3", " ", " ", " ", " ", "47.12", - "47.12", "47.12", "47.12", "5.794", "5.794", "5.794", "5.794", " ", " ", " "); - Assert.assertEquals("SumOfLatestNonBlankMinutes values incorrect", expected, actual); - - actual = table.getColumnDataAsText("SumOfCombineMinutes"); - expected = Arrays.asList("100.2", "200.4", " ", " ", " ", " ", "59.46", - "59.46", "59.46", "59.46", "7.024", "7.024", "7.024", "7.024", " ", " ", " "); - Assert.assertEquals("SumOfCombineMinutes values incorrect", expected, actual); - - /* - Because text sorting differs, slightly, on Postgres Windows vs. Mac/Linux, this ordering is not consistent, (Because Vial's vs. Vial is) - We can't do this comparison in the tests. If we want to add back a Max/Min test, we need to use a new or different text field and control the text. - - actual = table.getColumnDataAsText("MaxAvailabilityReason"); - expected = Arrays.asList(SPECIMEN_AVAILABLE_REASON, SPECIMEN_AVAILABLE_REASON, SPECIMEN_UNAVAILABLE_REASON, SPECIMEN_UNAVAILABLE_REASON, - SPECIMEN_UNAVAILABLE_REASON, SPECIMEN_UNAVAILABLE_REASON, SPECIMEN_AVAILABLE_REASON, SPECIMEN_AVAILABLE_REASON, SPECIMEN_AVAILABLE_REASON, - SPECIMEN_AVAILABLE_REASON, SPECIMEN_AVAILABLE_REASON, SPECIMEN_AVAILABLE_REASON, SPECIMEN_AVAILABLE_REASON, SPECIMEN_AVAILABLE_REASON, " ", " ", - SPECIMEN_UNAVAILABLE_REASON); - Assert.assertEquals("MaxAvailabilityReason values incorrect", expected, actual); - - actual = table.getColumnDataAsText("MinAvailabilityReason"); - expected = Arrays.asList(SPECIMEN_AVAILABLE_REASON, SPECIMEN_AVAILABLE_REASON, SPECIMEN_UNAVAILABLE_REASON, SPECIMEN_UNAVAILABLE_REASON, - SPECIMEN_UNAVAILABLE_REASON, SPECIMEN_UNAVAILABLE_REASON, SPECIMEN_UNAVAILABLE_REASON, SPECIMEN_UNAVAILABLE_REASON, SPECIMEN_UNAVAILABLE_REASON, - SPECIMEN_UNAVAILABLE_REASON, SPECIMEN_AVAILABLE_REASON, SPECIMEN_AVAILABLE_REASON, SPECIMEN_AVAILABLE_REASON, SPECIMEN_AVAILABLE_REASON, " ", " ", - SPECIMEN_UNAVAILABLE_REASON); - Assert.assertEquals("MinAvailabilityReason values incorrect", expected, actual); - */ - - actual = table.getColumnDataAsText("LatestDrawTimestamp"); - expected = Arrays.asList("2009-01-07 00:00", "2009-01-06 00:00", "2008-09-17 00:00", "2008-09-17 00:00", "2008-09-17 00:00", "2008-09-17 00:00", "2008-07-30 00:00", "2008-07-30 00:00", "2008-07-30 00:00", - "2008-07-30 00:00", "2009-03-16 00:00", "2009-03-16 00:00", "2009-03-16 00:00", "2009-03-16 00:00", "2009-06-15 00:00", "2009-06-15 00:00", "2009-05-09 00:00"); - Assert.assertEquals("LatestDrawTimestamp values incorrect", expected, actual); - - actual = table.getColumnDataAsText("FirstDrawTimestamp"); - expected = Arrays.asList("2009-01-06 00:00", "2009-01-06 00:00", "2008-09-17 00:00", "2008-09-17 00:00", "2008-09-17 00:00", "2008-09-17 00:00", "2008-07-30 00:00", "2008-07-30 00:00", "2008-07-30 00:00", - "2008-07-30 00:00", "2009-03-16 00:00", "2009-03-16 00:00", "2009-03-16 00:00", "2009-03-16 00:00", "2009-06-15 00:00", "2009-06-15 00:00", "2009-05-09 00:00"); - Assert.assertEquals("FirstDrawTimestamp values incorrect", expected, actual); - } -} diff --git a/src/org/labkey/test/tests/SpecimenExportTest.java b/src/org/labkey/test/tests/SpecimenExportTest.java deleted file mode 100644 index 077846be306..00000000000 --- a/src/org/labkey/test/tests/SpecimenExportTest.java +++ /dev/null @@ -1,224 +0,0 @@ -/* - * Copyright (c) 2013-2026 LabKey Corporation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.labkey.test.tests; - -import org.junit.experimental.categories.Category; -import org.labkey.test.BaseWebDriverTest; -import org.labkey.test.Locator; -import org.labkey.test.TestFileUtils; -import org.labkey.test.TestTimeoutException; -import org.labkey.test.categories.Daily; -import org.labkey.test.categories.Specimen; -import org.labkey.test.util.FileBrowserHelper; -import org.labkey.test.util.LogMethod; -import org.labkey.test.util.StudyHelper; - -import java.io.File; - -import static org.junit.Assert.assertTrue; - -@Category({Daily.class, Specimen.class}) -@BaseWebDriverTest.ClassTimeout(minutes = 6) -public class SpecimenExportTest extends SpecimenBaseTest -{ - protected static final String PROJECT_NAME = "SpecimenExportVerifyProject"; - - @Override - protected String getProjectName() - { - return PROJECT_NAME; - } - - @Override - protected void doCleanup(boolean afterTest) throws TestTimeoutException - { - deleteUsersIfPresent(USER1, USER2); - super.doCleanup(afterTest); - } - - @Override - protected BrowserType bestBrowser() - { - return BrowserType.CHROME; - } - - @Override - @LogMethod - protected void doCreateSteps() - { - enableEmailRecorder(); - initializeFolder(); - - clickButton("Create Study"); - setFormElement(Locator.name("label"), getStudyLabel()); - clickButton("Create Study"); - - _studyHelper.setupRepositoryType(true, true, true); - setPipelineRoot(StudyHelper.getStudySubfolderPath()); - startSpecimenImport(1); - waitForSpecimenImport(); - setPipelineRootToDefault(); - - setupRequestStatuses(); - setupActorsAndGroups(); - setupDefaultRequirements(); - setupWebpartGroupings(); - setupLocationTypes(); - // UNDONE: enable this once settings included in study archive - setupRequestabilityRules(); - // UNDONE: enable this once settings included in study archive - setupRequestForm(); - // UNDONE: enable this once settings included in study archive - setupActorNotification(); - } - - @Override - @LogMethod - protected void doVerifySteps() - { - // verify the specimen settings roundtrip by 1. exporting folder zip, 2. deleting the study, - // 3. importing folder zip, 4. exporting folder expanded, and verifying settings in the XML (instead of in the UI) - exportStudy(true); - deleteStudy(); - importFromZipExport(); - exportStudy(false); - verifySpecimenSettingsInArchive(); - } - - private void setupWebpartGroupings() - { - log("Setup specimen webpart groupings"); - clickTab("Manage"); - clickAndWait(Locator.linkWithText("Configure Specimen Groupings")); - waitForElement(Locator.tagContainingText("h3","Configure Specimen Web Part")); - _ext4Helper.selectComboBoxItemById("combo11", "Processing Location"); - _ext4Helper.selectComboBoxItemById("combo12", "Processing Location"); - _ext4Helper.selectComboBoxItemById("combo13", "Processing Location"); - _ext4Helper.selectComboBoxItemById("combo21", "Tube Type"); - _ext4Helper.selectComboBoxItemById("combo22", "Tube Type"); - _ext4Helper.selectComboBoxItemById("combo23", "Tube Type"); - clickButton("Save"); - } - - private void setupLocationTypes() - { - log("Setup location types"); - clickTab("Manage"); - clickAndWait(Locator.linkWithText("Manage Location Types")); - waitForElement(Locator.tagContainingText("h3","Manage Location Types")); - _ext4Helper.checkCheckbox("Repository"); - _ext4Helper.uncheckCheckbox("Clinic"); - _ext4Helper.uncheckCheckbox("Site Affiliated Lab"); - _ext4Helper.checkCheckbox("Endpoint Lab"); - clickButton("Save"); - } - - private void importFromZipExport() - { - log("Import folder zip archive from pipeline"); - goToFolderManagement(); - clickAndWait(Locator.linkWithText("Import")); - clickButtonContainingText("Use Pipeline"); - _fileBrowserHelper.selectFileBrowserItem("/export/"); - waitAndClick(Locator.tag("tr").withClass("x4-grid-data-row").withAttributeContaining("data-recordid", FileBrowserHelper.encodeFileNodeIdPart("My Study_"))); - _fileBrowserHelper.selectImportDataAction("Import Folder"); - clickButton("Start Import"); // Validate queries page - waitForPipelineJobsToComplete(2, "Folder import", false); - } - - private void verifySpecimenSettingsInArchive() - { - log("verify specimen settings in study.xml"); - File studyXml = new File(TestFileUtils.getDefaultFileRoot(getProjectName() + "/" + getFolderName()), "export/study/study.xml"); - waitFor(studyXml::exists, "Couldn't find exported study: " + studyXml, WAIT_FOR_JAVASCRIPT); - String studyXmlText = TestFileUtils.getFileContents(studyXml).replaceAll(" *\r*\n *", "\n").replaceAll(" +", " "); - assertTrue("study.xml did not include expected element: " + studyXmlText, studyXmlText.contains("")); - - log("verify specimen_settings.xml"); - File specimenSettingsXml = new File(TestFileUtils.getDefaultFileRoot(getProjectName() + "/" + getFolderName()), "export/study/specimens/specimen_settings.xml"); - String specimenSettingsXmlText = TestFileUtils.getFileContents(specimenSettingsXml).replaceAll(" *\r*\n *", "\n").replaceAll(" +", " "); - - assertTrue(specimenSettingsXmlText.contains("\n"+ - "\n"+ - "Processing Location\n"+ - "Processing Location\n"+ - "Processing Location\n"+ - "\n"+ - "\n"+ - "Tube Type\n"+ - "Tube Type\n"+ - "Tube Type\n"+ - "\n"+ - "")); - assertTrue(specimenSettingsXmlText.contains( - "\n" + - "\n" + - "\n" + - "\n" + - "\n" + - "")); - assertTrue(specimenSettingsXmlText.contains( - "\n" + - "\n" + - "\n" + - "\n" + - "\n" + - "")); - assertTrue(specimenSettingsXmlText.contains( - "\n" + - "\n" + - "\n" + - "\n" + - "\n" + - "\n" + - "\n" + - "\n" + - "\n" + - "\n" + - "\n" + - "\n" + - "\n" + - "\n" + - "\n" + - "\n" + - "\n" + - "\n" + - "\n" + - "")); - assertTrue(specimenSettingsXmlText.contains( - "\n" + - "\n" + - "\n" + - "Originating IRB Approval\n" + - "\n" + - "\n" + - "\n" + - "\n" + - "Providing IRB Approval\n" + - "\n" + - "\n" + - "\n" + - "\n" + - "Receiving IRB Approval\n" + - "\n" + - "\n" + - "\n" + - "\n" + - "SLG Approval\n" + - "\n" + - "\n" + - "")); - } -} diff --git a/src/org/labkey/test/tests/SpecimenGridExportTest.java b/src/org/labkey/test/tests/SpecimenGridExportTest.java deleted file mode 100644 index 1a5cd8faf43..00000000000 --- a/src/org/labkey/test/tests/SpecimenGridExportTest.java +++ /dev/null @@ -1,183 +0,0 @@ -/* - * Copyright (c) 2014-2026 LabKey Corporation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.labkey.test.tests; - -import org.jetbrains.annotations.Nullable; -import org.junit.BeforeClass; -import org.junit.experimental.categories.Category; -import org.labkey.test.BaseWebDriverTest; -import org.labkey.test.Locator; -import org.labkey.test.TestTimeoutException; -import org.labkey.test.WebTestHelper; -import org.labkey.test.categories.Daily; -import org.labkey.test.categories.Specimen; -import org.labkey.test.util.AbstractDataRegionExportOrSignHelper.ColumnHeaderType; - -import java.util.Arrays; -import java.util.List; -import java.util.Map; - -/** - * Test exporting rows from a specimen grid (not folder/study specimen export.) - */ -@Category({Daily.class, Specimen.class}) -@BaseWebDriverTest.ClassTimeout(minutes = 7) -public class SpecimenGridExportTest extends AbstractExportTest -{ - public static final String SPECIMEN_DATA = - "Vial Id\tDraw Date\tParticipant\tVolume\tUnits\tSpecimen Type\tDerivative Type\tAdditive Type\n" + - "Sample_001\t11/13/12\tP7310\t200\tml\t\t\t\n" + - "Sample_002\t11/13/12\tP7311\t200\tml\t\t\t\n" + - "Sample_003\t11/13/12\tP7312\t200\tml\t\t\t\n" + - "Sample_004\t11/13/12\tP7313\t200\tml\t\t\t\n" + - "Sample_005\t11/13/12\tP7314\t200\tml\t\t\t\n" + - "Sample_006\t11/13/12\tP7315\t200\tml\t\t\t\n"; - - @BeforeClass - public static void doSetup() throws Exception - { - SpecimenGridExportTest initTest = getCurrentTest(); - - initTest._containerHelper.createProject(initTest.getProjectName(), "Study"); - initTest._containerHelper.enableModule("Specimen"); - initTest.importSpecimens(); - } - - private void importSpecimens() - { - clickButton("Create Study"); - //use date-based study - click(Locator.xpath("(//input[@name='timepointType'])[1]")); - setFormElement(Locator.xpath("//input[@name='startDate']"), "2012-01-01"); - clickButton("Create Study"); - - log("** Import specimens"); - clickTab("Specimen Data"); - waitAndClickAndWait(Locator.linkWithText("Import Specimens")); - setFormElementJS(Locator.id("tsv"), SPECIMEN_DATA); - clickButton("Submit"); - assertTextPresent("Specimens uploaded successfully"); - } - - @Override - protected void doCleanup(boolean afterTest) throws TestTimeoutException - { - super.doCleanup(afterTest); - } - - @Nullable - @Override - protected String getProjectName() - { - return SpecimenGridExportTest.class.getSimpleName(); - } - - @Override - protected boolean hasSelectors() - { - return true; - } - - @Override - protected String getTestColumnTitle() - { - return "Participant Id"; - } - - @Override - protected String getTestLookUpColumnHeader() - { - return null; - } - - @Override - protected int getTestLookUpColumnIndex() - { - return 0; - } - - @Override - protected int getTestColumnIndex() - { - return 0; - } - - @Override - protected String getExportedXlsTestColumnHeader(ColumnHeaderType exportType) - { - switch (exportType) - { - case FieldKey: - return "ParticipantId"; - default: - return "Participant Id"; - } - } - - @Override - protected String getExportedTsvTestColumnHeader(ColumnHeaderType exportType) - { - switch (exportType) - { - case FieldKey: - return "ParticipantId"; - default: - return "Participant Id"; - } - } - - @Override - protected String getDataRegionColumnName() - { - return "ProtocolNumber"; - } - - @Override - protected String getDataRegionSchemaName() - { - return "study"; - } - - @Override - protected String getDataRegionQueryName() - { - return "SpecimenSummary"; - } - - @Override - protected String getExportedFilePrefixRegex() - { - return "SpecimenSummary"; - } - - @Override - protected String getDataRegionId() - { - return "SpecimenSummary"; - } - - @Override - protected void goToDataRegionPage() - { - beginAt(WebTestHelper.buildURL("specimen", getProjectName(), "specimens", Map.of("showVials", false))); - } - - @Override - public List getAssociatedModules() - { - return Arrays.asList("study"); - } -} diff --git a/src/org/labkey/test/tests/SpecimenImportTest.java b/src/org/labkey/test/tests/SpecimenImportTest.java deleted file mode 100644 index f8fd54a615c..00000000000 --- a/src/org/labkey/test/tests/SpecimenImportTest.java +++ /dev/null @@ -1,274 +0,0 @@ -/* - * Copyright (c) 2013-2026 LabKey Corporation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.labkey.test.tests; - -import org.apache.hc.core5.http.HttpStatus; -import org.junit.Assert; -import org.junit.experimental.categories.Category; -import org.labkey.remoteapi.CommandException; -import org.labkey.remoteapi.Connection; -import org.labkey.remoteapi.query.SelectRowsCommand; -import org.labkey.remoteapi.query.SelectRowsResponse; -import org.labkey.test.BaseWebDriverTest; -import org.labkey.test.Locator; -import org.labkey.test.WebTestHelper; -import org.labkey.test.categories.Daily; -import org.labkey.test.categories.Specimen; -import org.labkey.test.components.ext4.RadioButton; -import org.labkey.test.util.DataRegionTable; -import org.labkey.test.util.Ext4Helper; -import org.labkey.test.util.LogMethod; -import org.openqa.selenium.support.ui.ExpectedConditions; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import static org.junit.Assert.assertEquals; - -@Category({Daily.class, Specimen.class}) -@BaseWebDriverTest.ClassTimeout(minutes = 5) -public class SpecimenImportTest extends SpecimenBaseTest -{ - private static final String noVisitIdTSV = - """ - Global Unique Id\tSample Id\tDraw Timestamp\tVisit\tParticipant Id - 1\t1\t\t\t1 - 2\t2\t\t\t2 - 3\t3\t\t\t - 4\t4\t\t\t"""; - - private static final String noPtidsTSV = - """ - Global Unique Id\tSample Id\tDraw Timestamp\tVisit\tParticipant - \t\t\t1\t - \t\t\t2\t - \t\t\t3\t - \t\t\t4\t"""; - private static final String cleanEntry = - """ - Global Unique Id\tSample Id\tDraw Timestamp\tVisit\tParticipant Id - 1\t1\t\t1\t1 - 2\t2\t\t2\t2 - 3\t3\t\t3\t - 4\t4\t\t4\t"""; - - @Override - @LogMethod - protected void doCreateSteps() - { - initializeFolder(); - - checkRequiredFields(false); - changeTimepointType(); - - waitForText("General Study Settings"); - checkRequiredFields(true); - doUploads(); - - assertIdsSet(); - - assertSampleTypeData(); - } - - @Override - protected void doVerifySteps() - { - //Do Nothing - } - - protected void goToImport() - { - clickTab("Specimen Data"); - waitForText("No specimens found"); - waitAndClickAndWait(Locator.linkContainingText("Import Specimens")); - } - - protected void checkRequiredFields(boolean visit) - { - goToImport(); - waitAndClick(Locator.linkContainingText("Show Expected Data Fields")); - assertTextPresent("Global Unique Id","Sample Id", "Participant Id", "Volume", "Volume Units", "Primary Type", "Derivative Type", "Additive Type"); - if(!visit) - { - assertTextNotPresent("Visit"); - assertTextPresent("Draw Timestamp"); - } - else - { - assertTextPresent("Visit"); - } - } - - protected void changeTimepointType() - { - clickTab("Manage"); - waitAndClickAndWait(Locator.linkContainingText("Study Properties")); - new RadioButton(Locator.id("visit").waitForElement(getDriver(), WAIT_FOR_JAVASCRIPT)).check(); - clickAndWait(Ext4Helper.Locators.ext4Button("Submit")); - } - protected void doUploads() - { - setFormElementJS(Locator.name("tsv"), noVisitIdTSV); - clickButton("Submit"); - waitForText("Error: row 1 does not contain a value for field Visit"); - setFormElementJS(Locator.name("tsv"), noPtidsTSV); - clickButton("Submit"); - waitForText("Error in row 1: required field Participant was not supplied"); - assertTextPresent("Error in row 1: missing Global Unique Id"); - setFormElementJS(Locator.name("tsv"), cleanEntry); - clickButton("Submit"); - waitForText("Specimens uploaded successfully."); - } - - protected void assertIdsSet() - { - clickTab("Specimen Data"); - clickAndWait(shortWait().until(ExpectedConditions.elementToBeClickable( - Locator.linkContainingText("By Individual Vial")))); - DataRegionTable region = new DataRegionTable("SpecimenDetail", this); - assertEquals("Failed to find Participant ID 1", 0, region.getRowIndex("Participant Id", "1")); - assertEquals("Failed to find Global Unique ID 1", 0, region.getRowIndex("Global Unique Id", "1")); - assertEquals("Failed to find Participant ID 3", 2, region.getRowIndex("Participant Id", "3")); - assertEquals("Failed to find Global Unique ID 3", 2, region.getRowIndex("Global Unique Id", "3")); - } - - // Checking for regression like the one that occurred in issue 36863: specimen importer doesn't create rows in provisioned table. - protected void assertSampleTypeData() - { - String folderPath = "/" + getProjectName() + "/" + getFolderName(); - List fields = Arrays.asList("Name", "Run", "Flag/Comment"); - - List> sampleTypeData = getSampleDataFromDB(folderPath, "Study Specimens", fields); - - Assert.assertNotEquals("There are no rows in the \"Study Specimens\" sample type.", 0, sampleTypeData.size()); - - List expectedNames = Arrays.asList("1", "2", "3", "4"); - - boolean pass = true; - if(sampleTypeData.size() != expectedNames.size()) - { - pass = false; - log("\n*************** ERROR ***************\nThe number of records returned is not as expected. Expected: " + expectedNames.size() + " found: " + sampleTypeData.size() + "\n*************** ERROR ***************"); - } - - for (String expectedName : expectedNames) - { - boolean found = false; - for (Map sampleTypeRow : sampleTypeData) - { - if (expectedName.trim().equalsIgnoreCase(sampleTypeRow.get("Name").trim())) - { - found = true; - break; - } - } - - if (!found) - { - pass = false; - log("\n*************** ERROR ***************\nDid not find the expected name '" + expectedName.trim() + "' in the returned data.\n*************** ERROR ***************"); - } - } - - if(!pass) - { - log("\n*************** ERROR ***************\nExpected values: " + expectedNames + "\nValues returned: " + sampleTypeData + "\n*************** ERROR ***************"); - Assert.fail("Sample Type data not as expected."); - } - } - - protected List> getSampleDataFromDB(String folderPath, String sampleTypeName, List fields) - { - List> results = new ArrayList<>(6); - Map tempRow; - - Connection cn = WebTestHelper.getRemoteApiConnection(); - SelectRowsCommand cmd = new SelectRowsCommand("samples", sampleTypeName); - cmd.setColumns(fields); - - try - { - SelectRowsResponse response = cmd.execute(cn, folderPath); - - for (Map row : response.getRows()) - { - - tempRow = new HashMap<>(); - - for(String key : row.keySet()) - { - - if (fields.contains(key)) - { - - String tmpFlag = key; - - if(key.equalsIgnoreCase("Flag/Comment")) - tmpFlag = "Flag"; - - if (null == row.get(key)) - { - tempRow.put(tmpFlag, ""); - } - else - { - tempRow.put(tmpFlag, row.get(key).toString()); - } - - } - - } - - results.add(tempRow); - } - - } - catch(CommandException | IOException excp) - { - Assert.fail(excp.getMessage()); - } - - return results; - } - - @Override - protected void initializeFolder() - { - int response = WebTestHelper.getHttpResponse(WebTestHelper.buildURL("project", getProjectName(), "begin")).getResponseCode(); - - if (HttpStatus.SC_OK != response) - { - _containerHelper.createProject(getProjectName(), null); - } - - _containerHelper.createSubfolder(getProjectName(), getProjectName(), getFolderName(), "Study", null, true); - _containerHelper.enableModule("Specimen"); - clickButton("Create Study"); - click(Locator.radioButtonById("dateTimepointType")); - clickButton("Create Study"); - } - - @Override - protected BrowserType bestBrowser() - { - return BrowserType.CHROME; - } -} diff --git a/src/org/labkey/test/tests/SpecimenMultipleImportTest.java b/src/org/labkey/test/tests/SpecimenMultipleImportTest.java deleted file mode 100644 index b42742c55f4..00000000000 --- a/src/org/labkey/test/tests/SpecimenMultipleImportTest.java +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright (c) 2013-2026 LabKey Corporation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.labkey.test.tests; - -import org.junit.experimental.categories.Category; -import org.labkey.test.BaseWebDriverTest; -import org.labkey.test.Locator; -import org.labkey.test.categories.Daily; -import org.labkey.test.categories.Specimen; -import org.labkey.test.util.LogMethod; -import org.labkey.test.util.StudyHelper; - -import java.io.File; - -@Category({Daily.class, Specimen.class}) -@BaseWebDriverTest.ClassTimeout(minutes = 6) -public class SpecimenMultipleImportTest extends StudyBaseTest -{ - protected static final String PROJECT_NAME = "AliquotVerifyProject"; - - protected static final File SPECIMEN_ARCHIVE_15 = StudyHelper.getSpecimenArchiveFile("lab15.specimens"); - protected static final File SPECIMEN_ARCHIVE_19 = StudyHelper.getSpecimenArchiveFile("lab19.specimens"); - protected static final File SPECIMEN_ARCHIVE_20 = StudyHelper.getSpecimenArchiveFile("lab20.specimens"); - protected static final File SPECIMEN_ARCHIVE_21 = StudyHelper.getSpecimenArchiveFile("lab21.specimens"); - protected static final File SPECIMEN_ARCHIVE_22 = StudyHelper.getSpecimenArchiveFile("lab22.specimens"); - - @Override - protected String getProjectName() - { - return PROJECT_NAME; - } - - @Override - protected BrowserType bestBrowser() - { - return BrowserType.CHROME; - } - - @Override - @LogMethod - protected void doCreateSteps() - { - enableEmailRecorder(); - initializeFolder(); - - clickButton("Create Study"); - setFormElement(Locator.name("label"), getStudyLabel()); - clickButton("Create Study"); - _studyHelper.setupAdvancedRepositoryType(); - - setPipelineRoot(StudyHelper.getStudySubfolderPath()); - - startSpecimenImport(1, SPECIMEN_ARCHIVE_15); - startSpecimenImport(2, SPECIMEN_ARCHIVE_19); - startSpecimenImport(3, SPECIMEN_ARCHIVE_20); - startSpecimenImport(4, SPECIMEN_ARCHIVE_21); - startSpecimenImport(5, SPECIMEN_ARCHIVE_22); - - waitForSpecimenImport(); - } - - @Override - @LogMethod - protected void doVerifySteps() - { - clickFolder(getFolderName()); - goToSpecimenData(); - waitAndClickAndWait(Locator.linkWithText("Blood (Whole)").notHidden()); - - // check for number of specimens in import, total volume is a good identifier for everything - assertTextPresent("75,990,002.5"); - - // look for a specimen that came from 1st and 3rd file - assertTextPresent("999320895", "999320422"); - } -} diff --git a/src/org/labkey/test/tests/SpecimenTest.java b/src/org/labkey/test/tests/SpecimenTest.java deleted file mode 100644 index bfdad9fdeba..00000000000 --- a/src/org/labkey/test/tests/SpecimenTest.java +++ /dev/null @@ -1,1258 +0,0 @@ -/* - * Copyright (c) 2008-2026 LabKey Corporation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.labkey.test.tests; - -import org.apache.commons.lang3.StringUtils; -import org.apache.hc.core5.http.HttpStatus; -import org.json.JSONObject; -import org.junit.Assert; -import org.junit.experimental.categories.Category; -import org.labkey.remoteapi.CommandException; -import org.labkey.remoteapi.CommandResponse; -import org.labkey.remoteapi.Connection; -import org.labkey.remoteapi.SimplePostCommand; -import org.labkey.test.BaseWebDriverTest; -import org.labkey.test.Locator; -import org.labkey.test.Locators; -import org.labkey.test.TestTimeoutException; -import org.labkey.test.WebTestHelper; -import org.labkey.test.categories.Daily; -import org.labkey.test.categories.Specimen; -import org.labkey.test.components.CustomizeView; -import org.labkey.test.components.dumbster.EmailRecordTable; -import org.labkey.test.components.html.BootstrapMenu; -import org.labkey.test.pages.ImportDataPage; -import org.labkey.test.pages.study.specimen.ManageNotificationsPage; -import org.labkey.test.util.ApiPermissionsHelper; -import org.labkey.test.util.DataRegionTable; -import org.labkey.test.util.LogMethod; -import org.labkey.test.util.LoggedParam; -import org.labkey.test.util.PasswordUtil; -import org.labkey.test.util.PermissionsHelper; -import org.labkey.test.util.PortalHelper; -import org.labkey.test.util.StudyHelper; -import org.labkey.test.util.TextSearcher; -import org.labkey.test.util.ext4cmp.Ext4FieldRef; -import org.openqa.selenium.By; -import org.openqa.selenium.WebElement; - -import java.io.File; -import java.io.IOException; -import java.text.SimpleDateFormat; -import java.util.Arrays; -import java.util.Date; -import java.util.HashSet; -import java.util.Hashtable; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; -import static org.labkey.test.pages.study.specimen.ManageNotificationsPage.SpecimensAttachment; -import static org.labkey.test.util.DataRegionTable.DataRegion; -import static org.labkey.test.util.PermissionsHelper.READER_ROLE; - -@Category({Daily.class, Specimen.class}) -@BaseWebDriverTest.ClassTimeout(minutes = 20) -public class SpecimenTest extends SpecimenBaseTest -{ - protected static final String PROJECT_NAME = "SpecimenVerifyProject"; - private final File REQUEST_ATTACHMENT = StudyHelper.getSpecimenArchiveFile("labs.txt"); - private final PortalHelper _portalHelper = new PortalHelper(this); - private final String[] SPECIMEN_IDS = {"AAA07XK5-01", "AAA07XK5-02"}; - - @Override - protected String getProjectName() - { - return PROJECT_NAME; - } - - @Override - protected void doCleanup(boolean afterTest) throws TestTimeoutException - { - deleteUsersIfPresent(USER1, USER2); - super.doCleanup(afterTest); - } - - @Override - protected BrowserType bestBrowser() - { - return BrowserType.CHROME; - } - - @Override - @LogMethod - protected void doCreateSteps() - { - enableEmailRecorder(); - initializeFolder(); - - clickButton("Create Study"); - setFormElement(Locator.name("label"), getStudyLabel()); - clickButton("Create Study"); - _studyHelper.setupAdvancedRepositoryType(); - setupRequestabilityRules(); - - setPipelineRoot(StudyHelper.getStudySubfolderPath()); - startSpecimenImport(1); - waitForSpecimenImport(); - checkSpecimenReport(); - _studyHelper.createCustomParticipantGroup(getProjectName(), getFolderName(), "Category1", "Participant", null, false, PTIDS[0], PTIDS[1]); - checkTubeType(); - setupRequestStatuses(); - setupActorsAndGroups(); - setupDefaultRequirements(); - setupRequestForm(); - setupActorNotification(); - uploadSpecimensFromFile(); - } - - @Override - protected void setupRequestabilityRules() - { - super.setupRequestabilityRules(); - clickButton("Save"); - } - - @Override - @LogMethod - protected void doVerifySteps() throws IOException, CommandException - { - verifyActorDetails(); - verifySpecimenEventsRedirect(); - createRequestWithApi(); - createRequest(); - verifyViews(); - verifyAdditionalRequestFields(); - verifyNotificationEmails(); - verifyInactiveUsersInRequests(); - verifyRequestCancel(); - verifyReports(); - exportSpecimenTest(); - verifyRequestingLocationRestriction(); - verifySpecimenTableAttachments(); - searchTest(); - verifySpecimenGroupings(); - verifyRequestEnabled(); - disableRequests(); - verifyRequestsDisabled(); - verifyDrawTimestamp(); - } - - private void checkSpecimenReport() - { - clickFolder ("My Study"); - PortalHelper portalHelper = new PortalHelper(this); - portalHelper.addWebPart("Specimen Report"); - clickButton ("Submit"); - portalHelper.clickWebpartMenuItem ("Specimen Report: Type Summary Report", "Customize"); - selectOptionByText (Locator.name("reportType"), "Type by Participant"); - clickButton ("Submit"); - portalHelper.clickWebpartMenuItem ("Specimen Report: Type by Participant", "Customize"); - selectOptionByText (Locator.name("reportType"), "Type by Cohort"); - clickButton ("Submit"); - portalHelper.clickWebpartMenuItem ("Specimen Report: Type by Cohort", "Customize"); - selectOptionByText (Locator.name("reportType"), "Requested Summary"); - clickButton ("Submit"); - portalHelper.clickWebpartMenuItem ("Specimen Report: Requested Summary", "Customize"); - selectOptionByText (Locator.name("reportType"), "Requested by Requesting Location"); - clickButton ("Submit"); - portalHelper.clickWebpartMenuItem ("Specimen Report: Requested by Requesting Location", "Customize"); - selectOptionByText (Locator.name("reportType"), "Requested by Enrollment Location"); - clickButton ("Submit"); - portalHelper.clickWebpartMenuItem ("Specimen Report: Requested by Enrollment Location", "Customize"); - selectOptionByText (Locator.name("reportType"), "Requested by Participant"); - clickButton ("Submit"); - portalHelper.clickWebpartMenuItem ("Specimen Report: Requested by Participant", "Customize"); - selectOptionByText (Locator.name("reportType"), "Participant Summary"); - clickButton ("Submit"); - portalHelper.clickWebpartMenuItem ("Specimen Report: Participant Summary", "Customize"); - selectOptionByText (Locator.name("reportType"), "Participant by Specimen Type"); - clickButton ("Submit"); - portalHelper.clickWebpartMenuItem ("Specimen Report: Participant by Specimen Type", "Customize"); - selectOptionByText (Locator.name("reportType"), "Participant by Enrollment Location"); - clickButton ("Submit"); - portalHelper.clickWebpartMenuItem ("Specimen Report: Participant by Enrollment Location", "Customize"); - - } - - private void disableRequests() - { - clickFolder(getFolderName()); - assertTextPresent("Specimen Requests"); - waitAndClick(Locator.linkWithText("Manage Study")); - waitAndClick(Locator.linkWithText("Change Repository Type")); - Locator disableRequestsRadio = Locator.radioButtonByNameAndValue("enableRequests", "false"); - waitForElement(disableRequestsRadio); - checkRadioButton(disableRequestsRadio); - clickButton("Submit"); - } - - private static final String[] requestColumns = {"Locked In Request", "Requestable", "Available", "Availability Reason", "Locked In Request Count", "Available Count", "Expected Available Count"}; - - private void verifyRequestEnabled() - { - clickFolder(getFolderName()); - waitForElement(Locator.linkWithText("By Individual Vial")); - assertTextPresent("Specimen Requests"); - clickAndWait(Locator.linkWithText("By Individual Vial")); - assertElementPresent(Locator.lkButton("Request Options")); - DataRegionTable specimenTable = new DataRegionTable("SpecimenDetail", this); - List columnHeaders = specimenTable.getColumnLabels(); - for (String column : requestColumns) - { - assertTrue("Request column not found: " + column, columnHeaders.contains(column)); - } - clickAndWait(Locator.linkWithText("Reports")); - assertTextPresent("Requested Vials by Type and Timepoint", "Requested Summary"); - clickButton("View"); - assertTextPresent("Availability status"); - } - - private void verifyRequestsDisabled() - { - clickFolder(getFolderName()); - waitForElement(Locator.linkWithText("By Individual Vial")); - assertTextNotPresent("Specimen Requests"); - clickAndWait(Locator.linkWithText("By Individual Vial")); - assertElementNotPresent(Locator.lkButton("Request Options")); - DataRegionTable specimenTable = new DataRegionTable("SpecimenDetail", this); - List columnHeaders = specimenTable.getColumnLabels(); - for (String column : requestColumns) - { - assertFalse("Request column found when requests are disabled: " + column, columnHeaders.contains(column)); - } - clickAndWait(Locator.linkWithText("Reports")); - assertTextNotPresent("Requested Vials by Type and Timepoint", "Requested Summary"); - clickButton("View"); - assertTextNotPresent("Availability status"); - } - - @LogMethod - private void checkTubeType() - { - // Field check for Tube Type column (including conflict) - clickTab("Overview"); - _portalHelper.addWebPart("Specimens"); - waitAndClickAndWait(Locator.linkWithText("By Individual Vial")); - (new DataRegionTable(SPECIMEN_DETAIL, this)).setFilter("PrimaryType", "Is Blank"); - // Verify that there's only one vial of unknown type: - assertElementPresent(Locator.linkWithText("[history]"), 1); - // There's a conflict in TubeType for this vial's events; verify that no TubeType is populated at the vial level - assertTextNotPresent("Cryovial"); - clickAndWait(Locator.linkWithText("[history]")); - // This vial has three events, each of which list a different tube type: - assertTextPresent( - "15ml Cryovial", "20ml Cryovial", - "25ml Cryovial"); - clickAndWait(Locator.linkWithText("Specimen Overview")); - waitAndClick(Locator.xpath("//span[text()='Vials by Derivative Type']/../img")); - waitAndClickAndWait(Locator.linkWithText("Tear Flo Strips")); - // For these three vials, there should be no conflict in TubeType, so we should see the text once for each of three vials: - assertElementPresent(Locator.linkWithText("[history]"), 3); - assertTextPresent("15ml Cryovial", 3); - } - - @LogMethod - private void uploadSpecimensFromFile() - { - log("Check Upload Specimen List from file"); - goToSpecimenData(); - click(Locator.tagWithAttribute("img", "alt", "[New Request Icon]")); - waitForElement(Locator.name("destinationLocation")); - selectOptionByText(Locator.name("destinationLocation"), DESTINATION_SITE); - setFormElement(Locator.id("input0"), "Assay Plan"); - setFormElement(Locator.id("input2"), "Comments"); - setFormElement(Locator.id("input1"), "Shipping"); - setFormElement(Locator.id("input3"), "Last one"); - clickButton("Create and View Details"); - - clickAndWait(Locator.linkWithText("Upload Specimen Ids")); - - new ImportDataPage(getDriver()) - .setText(SPECIMEN_IDS[0]) - .submit(); - - waitAndClickAndWait(Locator.linkWithText("Upload Specimen Ids")); - - ImportDataPage importDataPage = new ImportDataPage(getDriver()); - importDataPage.setText(SPECIMEN_IDS[0]); - importDataPage.submitExpectingErrorContaining("Specimen " + SPECIMEN_IDS[0] + " is unavailable"); - - importDataPage.setText(SPECIMEN_IDS[1]); - importDataPage.submitExpectingErrorContaining( "Specimen " + SPECIMEN_IDS[1] + " is unavailable"); - - importDataPage.setText("AAA07XK5-04\nAAA07XK5-06\nAAA07XSF-03"); // add different ones - importDataPage.submit(); - } - - @LogMethod (quiet = true) - private void verifyActorDetails() - { - // Check each Actor's Details for "Default Actor Notification" feature; - // In Details, for each actor the ether Notify checkbox should be set or disabled, because we set Notifications to All - Locator detailsLink = Locator.xpath("//td[a='Details']/a"); - int linkCount = detailsLink.findElements(getDriver()).size(); - for (int i = 0; i < linkCount; i++) - { - clickAndWait(detailsLink.index(i)); - int allCheckBoxes = Locator.xpath("//input[@type='checkbox' and @name='notificationIdPairs']").findElements(getDriver()).size(); - int checkedCheckBoxes = Locator.xpath("//input[@type='checkbox' and @name='notificationIdPairs' and @checked]").findElements(getDriver()).size(); - int disabledCheckBoxes = Locator.xpath("//input[@type='checkbox' and @name='notificationIdPairs' and @disabled]").findElements(getDriver()).size(); - assertEquals("Actor Notification: All actors should be notified if addresses configured.", allCheckBoxes, checkedCheckBoxes + disabledCheckBoxes); - clickButton("Cancel"); - } - - waitForElement(Locator.css("span.labkey-wp-title-text").withText("Associated Specimens")); - assertTextPresent(SPECIMEN_IDS[0], "AAA07XK5-04", "AAA07XK5-06", "AAA07XSF-03"); - - doAndWaitForPageToLoad(() -> - { - clickButton("Cancel Request", 0); - assertAlertIgnoreCaseAndSpaces("Canceling will permanently delete this pending request. Continue?"); - }); - DataRegion(getDriver()).withName("SpecimenRequest").waitFor(); - } - - // Simulate SpecimenForeignKey redirect behavior - @LogMethod - private void verifySpecimenEventsRedirect() - { - String targetStudyId = getContainerId(); - - // Create an empty second folder (doesn't need to be a study) with guest read. We'll attempt to invoke the - // redirect action from this folder. - String folderName = "Another Study"; - _containerHelper.createSubfolder(getProjectName(), folderName, "Study"); - new ApiPermissionsHelper(this).setSiteGroupPermissions("Guests", "Reader"); - - // Happy path - admin should redirect - String baseUrl = WebTestHelper.getBaseURL() + "/" + getProjectName() + "/" + folderName + "/specimen-specimenEventsRedirect.view?targetStudy=" + targetStudyId + "&id="; - String url = baseUrl + "AAA07XK5-01"; - beginAt(url); - assertTextPresent("Vial History", "999320812", "350V0600294A"); - - // Guest has access in Another Study but not in the target study (My Study), so should not redirect - signOut(); - beginAt(baseUrl + "abcdefg_123456"); // Bogus ID and user doesn't have read permission - assertTextPresent("Unable to resolve the Specimen ID and target Study"); - beginAt(url); // Valid ID, but user doesn't have read permission to target study, so same error - assertTextPresent("Unable to resolve the Specimen ID and target Study"); - - // Sign in and back to the main study - signIn(); - goToProjectHome(); - clickFolder(getFolderName()); - } - - @LogMethod - private void createRequestWithApi() throws IOException, CommandException - { - // Create an empty specimen request as admin user - goToSpecimenData(); - click(Locator.tag("img").withAttributeContaining("alt", "[New Request Icon]")); - selectOptionByText(Locator.name("destinationLocation"), DESTINATION_SITE); - setFormElement(Locator.id("input0"), "Assay Plan"); - setFormElement(Locator.id("input1"), "Shipping"); - setFormElement(Locator.id("input3"), "Comments"); - clickButton("Create and View Details"); - int requestId = Integer.parseInt(getUrlParam("id")); - - // Create commands to add vials, remove vials, add specimens, and cancel the request - JSONObject vialParameters = new JSONObject( - Map.of( - "requestId", requestId, - "idType", "GlobalUniqueId", - "vialIds", new String[]{"ABH00LT8-01"} - ) - ); - SimplePostCommand addVialsCommand = new SimplePostCommand("specimen-api", "addVialsToRequest"); - addVialsCommand.setJsonObject(vialParameters); - SimplePostCommand removeVialsCommand = new SimplePostCommand("specimen-api", "removeVialsFromRequest"); - removeVialsCommand.setJsonObject(vialParameters); - SimplePostCommand addSpecimenCommand = new SimplePostCommand("specimen-api", "addSpecimensToRequest"); - addSpecimenCommand.setJsonObject(new JSONObject( - Map.of( - "requestId", requestId, - "specimenHashes", new String[]{"FakeSpecimenHashThatDoesntMatter"} - ) - )); - SimplePostCommand cancelRequestCommand = new SimplePostCommand("specimen-api", "cancelRequest"); - cancelRequestCommand.setJsonObject(new JSONObject( - Map.of( - "requestId", requestId - ) - )); - - // Assign "Specimen Requester" role to USER1 - String containerPath = getCurrentContainerPath(); - log(containerPath); - ApiPermissionsHelper helper = new ApiPermissionsHelper(containerPath); - helper.uncheckInheritedPermissions(); // Uses UI to un-inherit and save... - clickButton("Cancel"); // ...so click button to return to specimen page - helper.addMemberToRole(USER1, READER_ROLE, PermissionsHelper.MemberType.user, containerPath); - helper.addMemberToRole(USER1, "Specimen Requester", PermissionsHelper.MemberType.user, containerPath); - Connection conn = createDefaultConnection(); - - // Impersonate USER1. Specimen Requester who doesn't own the request shouldn't be able to modify it. - impersonate(USER1); - Assert.assertThrows("Request " + requestId + " was not found or the current user does not have permissions to access it.", - CommandException.class, - () -> addVialsCommand.execute(conn, containerPath) - ); - Assert.assertThrows("Request " + requestId + " was not found or the current user does not have permissions to access it.", - CommandException.class, - () -> addSpecimenCommand.execute(conn, containerPath) - ); - Assert.assertThrows("Request " + requestId + " was not found or the current user does not have permissions to access it.", - CommandException.class, - () -> cancelRequestCommand.execute(conn, containerPath) - ); - stopImpersonating(false); - - // Let's have the "Specimen Requester" owner add a vial so USER1 has something to (attempt to) delete - impersonateRoles(READER_ROLE, "Specimen Requester"); - CommandResponse response = addVialsCommand.execute(conn, containerPath); - assertEquals(HttpStatus.SC_OK, response.getStatusCode()); - //noinspection unchecked - assertEquals(1, ((List)response.getParsedData().get("vials")).size()); - stopImpersonating(false); - - // Attempt to remove the just-added vial as "Specimen Requester" non-owner - impersonate(USER1); - Assert.assertThrows("Request " + requestId + " was not found or the current user does not have permissions to access it.", - CommandException.class, - () -> removeVialsCommand.execute(conn, containerPath) - ); - stopImpersonating(false); - - // "Specimen Requester" owner should be able to remove vials and add via specimen hash. This hash won't match - // any vials, but we're just checking permissions. - impersonateRoles(READER_ROLE, "Specimen Requester"); - response = removeVialsCommand.execute(conn, containerPath); - assertEquals(HttpStatus.SC_OK, response.getStatusCode()); - //noinspection unchecked - assertEquals(0, ((List)response.getParsedData().get("vials")).size()); - response = addSpecimenCommand.execute(conn, containerPath); - assertEquals(HttpStatus.SC_OK, response.getStatusCode()); - stopImpersonating(false); - - // Now give USER1 the (more powerful) "Specimen Coordinator" role and verify they can now modify the request - // that they don't own, including canceling it. - helper.addMemberToRole(USER1, "Specimen Coordinator", PermissionsHelper.MemberType.user, containerPath); - impersonate(USER1); - assertEquals(HttpStatus.SC_OK, addVialsCommand.execute(conn, containerPath).getStatusCode()); - assertEquals(HttpStatus.SC_OK, removeVialsCommand.execute(conn, containerPath).getStatusCode()); - assertEquals(HttpStatus.SC_OK, addSpecimenCommand.execute(conn, containerPath).getStatusCode()); - assertEquals(HttpStatus.SC_OK, cancelRequestCommand.execute(conn, containerPath).getStatusCode()); - stopImpersonating(false); - - // Restore permissions back to inherit - helper.checkInheritedPermissions(); - } - - @LogMethod - private void createRequest() - { - goToSpecimenData(); - click(Locator.xpath("//span[text()='Vials by Derivative Type']/../img")); - waitForElement(Locator.linkWithText("Plasma, Unknown Processing")); - clickAndWait(Locator.linkWithText("Plasma, Unknown Processing")); - // Verify unavailable sample - assertElementPresent(Locator.xpath("//input[@id='check_" + UNREQUESTABLE_SAMPLE + "' and @disabled]")); - assertElementPresent(Locator.xpath("//input[@id='check_" + UNREQUESTABLE_SAMPLE + "']/../../td[contains(text(), 'This vial is unavailable because it was found in the set called \"" + REQUESTABILITY_QUERY + "\".')]")); -// TODO ONMOUSEOVER assertElementPresent(Locator.xpath("//input[@id='check_" + UNREQUESTABLE_SAMPLE + "']/../a[contains(@onmouseover, 'This vial is unavailable because it was found in the set called \\\"" + REQUESTABILITY_QUERY + "\\\".')]")); - new DataRegionTable.DataRegionFinder(getDriver()).find() - .checkAllOnPage(); - - clickAndWait(Locator.linkContainingText("history")); - assertTextPresent("Vial History"); - goBack(); - - BootstrapMenu.find(getDriver(), "Request Options").clickSubMenu(true, "Create New Request"); - selectOptionByText(Locator.name("destinationLocation"), DESTINATION_SITE); - setFormElement(Locator.id("input0"), "Assay Plan"); - setFormElement(Locator.id("input2"), "Comments"); - setFormElement(Locator.id("input1"), "Shipping"); - clickButton("Create and View Details"); - assertTextPresent("Please provide all required input."); - setFormElement(Locator.id("input3"), "sample last one input"); - clickButton("Create and View Details"); - assertTextPresent("sample last one input", "IRB", "KCMC, Moshi, Tanzania", "Originating IRB Approval", - SOURCE_SITE, "Providing IRB Approval", DESTINATION_SITE, "Receiving IRB Approval", "SLG", - "SLG Approval", "BAA07XNP-01"); - assertTextNotPresent( - UNREQUESTABLE_SAMPLE, - // verify that the swab specimen isn't present yet - "DAA07YGW-01", "Complete"); - - // add additional specimens - goToSpecimenData(); - click(Locator.xpath("//span[text()='Vials by Derivative Type']/../img")); - waitAndClickAndWait(Locator.linkWithText("Swab")); - new DataRegionTable.DataRegionFinder(getDriver()).find() - .checkAllOnPage(); - BootstrapMenu.find(getDriver(), "Request Options").clickSubMenu(false, "Add To Existing Request"); - _extHelper.waitForExtDialog("Request Vial", WAIT_FOR_JAVASCRIPT); - waitForElement(Locator.css("#request-vial-details .x-grid3-row")); - clickButton("Add 8 Vials to Request", 0); - _extHelper.waitForExtDialog("Success", WAIT_FOR_JAVASCRIPT * 5); - clickButton("OK", 0); - BootstrapMenu.find(getDriver(), "Request Options").clickSubMenu(false, "View Existing Requests"); - clickButton("Details"); - assertTextPresent("sample last one input", "IRB", "KCMC, Moshi, Tanzania", "Originating IRB Approval", - SOURCE_SITE, "Providing IRB Approval", DESTINATION_SITE, "Receiving IRB Approval", "SLG", - "SLG Approval", "BAA07XNP-01", "DAA07YGW-01"); - - // submit request - assertTextPresent("Not Yet Submitted"); - assertTextNotPresent("New Request"); - doAndWaitForPageToLoad(() -> - { - clickButton("Submit Request", 0); - assertAlertIgnoreCaseAndSpaces("Once a request is submitted, its specimen list may no longer be modified. Continue?"); - }); - waitForText("New Request"); - assertTextNotPresent("Not Yet Submitted"); - - // Add request attachment - click(Locator.linkWithText("Update Request")); - waitForElement(Locator.name("formFiles[0]")); - setFormElement(Locator.name("formFiles[0]"), REQUEST_ATTACHMENT); - clickButton("Save Changes and Send Notifications"); - waitForElement(Locator.linkContainingText(REQUEST_ATTACHMENT.getName())); - - // modify request - selectOptionByText(Locator.name("newActor"), "SLG"); - setFormElement(Locator.name("newDescription"), "Other SLG Approval"); - clickButton("Add Requirement"); - clickAndWait(Locator.linkWithText("Details")); - checkCheckbox(Locator.checkboxByName("complete")); - checkCheckbox(Locator.checkboxByName("notificationIdPairs")); - checkCheckbox(Locator.checkboxByName("notificationIdPairs").index(1)); - clickButton("Save Changes and Send Notifications"); - waitForElement(Locator.css(".labkey-message").withText("Complete")); - } - - @LogMethod - private void verifyViews() - { - clickAndWait(Locator.linkWithText("View History")); - assertTextPresent("Request submitted for processing.", USER1, USER2); - assertTextPresent("Notification Sent", 2); - clickAndWait(Locator.linkWithText("View Request")); - clickAndWait(Locator.linkWithText("Originating Location Specimen Lists")); - // Ordering of locations is nondeterministic - if (isPresentInThisOrder("The McMichael Lab, Oxford, UK", "KCMC, Moshi, Tanzania") == null) - { - checkCheckbox(Locator.checkboxByName("notify")); - _specimen_McMichael = getText(Locator.xpath("//tr[@class = 'labkey-alternate-row']/td[3]//td")); - checkCheckbox(Locator.checkboxByName("notify").index(4)); - _specimen_KCMC = getText(Locator.xpath("//tr[@class = 'labkey-row']/td[3]//td")); - } - else - { - checkCheckbox(Locator.checkboxByName("notify").index(1)); - _specimen_KCMC = getText(Locator.xpath("//tr[@class = 'labkey-alternate-row']/td[3]//td")); - checkCheckbox(Locator.checkboxByName("notify").index(3)); - _specimen_McMichael = getText(Locator.xpath("//tr[@class = 'labkey-row']/td[3]//td")); - } - checkCheckbox(Locator.checkboxByName("sendXls")); - checkCheckbox(Locator.checkboxByName("sendTsv")); - clickButton("Send Email"); - _requestId = Integer.parseInt(getUrlParam("id")); - clickAndWait(Locator.linkWithText("Providing Location Specimen Lists")); - assertTextPresent(SOURCE_SITE); - clickButton("Cancel"); - } - - @LogMethod - private void verifyAdditionalRequestFields() - { - log("verifying additional freezer fields from the exports"); - clickAndWait(Locator.linkWithText("Originating Location Specimen Lists")); - - File txtFile = doAndWaitForDownload(() -> click(Locator.linkContainingText("Export to text file"))); - TextSearcher txtSearcher = new TextSearcher(txtFile); - - // verify the additional columns - assertTextPresent(txtSearcher, "Freezer", "Fr Container", "Fr Position", "Fr Level1", "Fr Level2"); - - // customize the locationSpecimenListTable then make sure changes are propagated to the exported lists - log("customizing the locationSpecimenList default view"); - pushLocation(); - { - goToSchemaBrowser(); - viewQueryData("study", "LocationSpecimenList"); - - DataRegionTable region = new DataRegionTable("query", getDriver()); - CustomizeView customizeView = region.getCustomizeView(); - customizeView.openCustomizeViewPanel(); - customizeView.removeColumn("Freezer"); - customizeView.removeColumn("Fr_Container"); - customizeView.removeColumn("Fr_Position"); - customizeView.removeColumn("Fr_Level1"); - customizeView.saveCustomView(); - } - popLocation(); - - log("verifying column changes"); - goToSpecimenData(); - click(Locator.xpath("//span[text() = 'Specimen Requests']/../img")); // expand node in Specimens webpart - waitForElement(Locator.linkWithText("View Current Requests")); - clickAndWait(Locator.linkWithText("View Current Requests")); - - clickButton("Details"); - clickAndWait(Locator.linkWithText("Originating Location Specimen Lists")); - - File formattedFile = doAndWaitForDownload(() -> click(Locator.linkContainingText("Export to text file"))); - TextSearcher fileSearcher = new TextSearcher(formattedFile); - - // verify the additional columns - assertTextNotPresent(fileSearcher, "Freezer", "Fr Container", "Fr Position", "Fr Level1"); - assertTextPresent(fileSearcher, "Fr Level2"); - - clickButton("Cancel"); - clickAndWait(Locator.linkWithText("Providing Location Specimen Lists")); - - File locationSpecimens = doAndWaitForDownload(() -> click(Locator.linkContainingText("Export to text file"))); - TextSearcher locationFileSearcher = new TextSearcher(locationSpecimens); - - // verify the additional columns - assertTextNotPresent(locationFileSearcher, "Freezer", "Fr Container", "Fr Position", "Fr Level1"); - assertTextPresent(locationFileSearcher, "Fr Level2"); - - clickButton("Cancel"); - } - - private String _specimen_McMichael; - private String _specimen_KCMC; - private final static String ATTACHMENT1 = "KCMC_Moshi_Ta_to_Aurum_Health_.tsv"; - private final static String ATTACHMENT2 = "KCMC_Moshi_Ta_to_Aurum_Health_KO_%s.xls"; // Params: date(yyyy-MM-dd) - private final static String NOTIFICATION_TEMPLATE = // Params: Study Name, requestId, Study Name, requestId, Username, Date(yyyy-MM-dd) - "Specimen request #%s was updated in %s.\n" + - "Request Details\n" + - "Specimen Request %s\n" + - "Destination " + DESTINATION_SITE+"\n" + - "Status New Request\n" + - "Modified by %s\n" + - "Action Originating location notification of specimen shipment to "+DESTINATION_SITE+"\n" + - "Attachments KCMC_Moshi_Ta_to_Aurum_Health_.tsv\n" + - "KCMC_Moshi_Ta_to_Aurum_Health_KO_%s.xls\n" + - "Assay Plan:\n" + - "Assay Plan\n" + - "Shipping Information:\n" + - "Shipping\n" + - "Comments:\n" + - "Comments\n" + - "Last One:\n" + - "sample last one input\n" + - "Specimen List (Request Link)\n" + - "Participant Id Global Unique Id Visit Description Sequence Num Visit Volume Volume Units Primary Type Derivative Type Additive Type Derivative Type2 Sub Additive Derivative Draw Timestamp Draw Date Draw Time Clinic Processing Location First Processed By Initials Sal Receipt Date Class Id Protocol Number Primary Volume Primary Volume Units Total Cell Count Tube Type Comments Locked In Request Requestable Site Name Site Ldms Code At Repository Available Availability Reason Quality Control Flag Quality Control Comments Collection Cohort Vial Count Locked In Request Count At Repository Count Available Count Expected Available Count\n" + - "1 999320824 BAA07XNP-01 Vst 501 501.0000 1.0 ML Blood (Whole) Plasma, Unknown Processing EDTA N/A 2005-12-23 10:05 2005-12-23 10:05:00 KCMC, Moshi, Tanzania Contract Lab Services, Johannesburg, South Africa LK 2005-12-23 00:00 LABK 39 15ml Cryovial true Contract Lab Services, Johannesburg, South Africa 350 true false This vial is unavailable because it is locked in a specimen request. false 2 1 2 0 1\n" + - "2 999320087 CAA07XN8-01 Vst 301 301.0000 1.0 ML Vaginal Swab Swab None N/A 2005-12-22 12:50 2005-12-22 12:50:00 KCMC, Moshi, Tanzania Contract Lab Services, Johannesburg, South Africa LK 2005-12-22 00:00 LABK 39 15ml Cryovial true Contract Lab Services, Johannesburg, South Africa 350 true false This vial is unavailable because it is locked in a specimen request. false 1 1 1 0 0\n" + - "3 999320706 DAA07YGW-01 Vst 301 301.0000 1.0 ML Vaginal Swab Swab None N/A 2006-01-05 10:00 2006-01-05 10:00:00 KCMC, Moshi, Tanzania Contract Lab Services, Johannesburg, South Africa LK 2006-01-05 00:00 LABK 39 15ml Cryovial true Contract Lab Services, Johannesburg, South Africa 350 true false This vial is unavailable because it is locked in a specimen request. false 1 1 1 0 0\n" + - "4 999320898 FAA07XLJ-01 Vst 301 301.0000 1.0 ML Vaginal Swab Swab None N/A 2005-12-20 12:05 2005-12-20 12:05:00 KCMC, Moshi, Tanzania Contract Lab Services, Johannesburg, South Africa LK 2005-12-20 00:00 LABK 39 15ml Cryovial true Contract Lab Services, Johannesburg, South Africa 350 true false This vial is unavailable because it is locked in a specimen request. false 1 1 1 0 0\n" + - "5 999320264 FAA07YSC-01 Vst 201 201.0000 1.0 ML Vaginal Swab Swab None N/A 2006-01-13 12:10 2006-01-13 12:10:00 KCMC, Moshi, Tanzania Contract Lab Services, Johannesburg, South Africa LK 2006-01-13 00:00 LABK 39 15ml Cryovial true Contract Lab Services, Johannesburg, South Africa 350 true false This vial is unavailable because it is locked in a specimen request. false 1 1 1 0 0\n" + - "6 999320520 FAA07YXY-01 Vst 501 501.0000 1.0 ML Vaginal Swab Swab None N/A 2005-12-15 10:30 2005-12-15 10:30:00 KCMC, Moshi, Tanzania Contract Lab Services, Johannesburg, South Africa LK 2006-01-15 00:00 LABK 39 15ml Cryovial true Contract Lab Services, Johannesburg, South Africa 350 true false This vial is unavailable because it is locked in a specimen request. false 1 1 1 0 0\n" + - "7 999320498 JAA07YJB-01 Vst 501 501.0000 1.0 ML Vaginal Swab Swab None N/A 2006-01-05 09:30 2006-01-05 09:30:00 KCMC, Moshi, Tanzania Contract Lab Services, Johannesburg, South Africa LK 2006-01-11 00:00 LABK 39 15ml Cryovial true Contract Lab Services, Johannesburg, South Africa 350 true false This vial is unavailable because it is locked in a specimen request. false 1 1 1 0 0\n" + - "8 999320476 JAA07YSQ-01 Vst 301 301.0000 1.0 ML Vaginal Swab Swab None N/A 2006-01-11 10:20 2006-01-11 10:20:00 KCMC, Moshi, Tanzania Contract Lab Services, Johannesburg, South Africa LK 2006-01-11 00:00 LABK 39 15ml Cryovial true Contract Lab Services, Johannesburg, South Africa 350 true false This vial is unavailable because it is locked in a specimen request. false 1 1 1 0 0\n" + - "9 999320980 KAA07YV1-01 Vst 301 301.0000 1.0 ML Vaginal Swab Swab None N/A 2006-01-17 08:30 2006-01-17 08:30:00 KCMC, Moshi, Tanzania Contract Lab Services, Johannesburg, South Africa LK 2006-01-17 00:00 LABK 39 15ml Cryovial true Contract Lab Services, Johannesburg, South Africa 350 true false This vial is unavailable because it is locked in a specimen request. false 1 1 1 0 0\n" + - "10 999320520 KAA07YY0-01 Vst 501 501.0000 1.0 ML Blood (Whole) Plasma, Unknown Processing EDTA N/A 2005-12-15 10:30 2005-12-15 10:30:00 KCMC, Moshi, Tanzania Contract Lab Services, Johannesburg, South Africa LK 2006-01-15 00:00 LABK 39 15ml Cryovial true Contract Lab Services, Johannesburg, South Africa 350 true false This vial is unavailable because it is locked in a specimen request. false 2 2 2 0 0\n" + - "11 999320520 KAA07YY0-02 Vst 501 501.0000 1.0 ML Blood (Whole) Plasma, Unknown Processing EDTA N/A 2005-12-15 10:30 2005-12-15 10:30:00 KCMC, Moshi, Tanzania Contract Lab Services, Johannesburg, South Africa LK 2006-01-15 00:00 LABK 39 15ml Cryovial true Contract Lab Services, Johannesburg, South Africa 350 true false This vial is unavailable because it is locked in a specimen request. false 2 2 2 0 0"; - @LogMethod - private void verifyNotificationEmails() - { - String date = new SimpleDateFormat("yyyy-MM-dd").format(new Date()); - String notification = String.format(NOTIFICATION_TEMPLATE, _requestId, getStudyLabel(), _requestId, PasswordUtil.getUsername(), date); - - log("Check notification emails"); - goToHome(); - goToModule("Dumbster"); - assertTextPresent("Specimen Request Notification", 8); - assertTextPresent(USER1, 4); - assertTextPresent(USER2, 4); - - log("Check for correct data in notification emails"); - EmailRecordTable mailTable = new EmailRecordTable(this); - List messages = getWrappedDriver().findElements(By.linkText("Study 001: Specimen Request Notification")); - for(WebElement message : messages){message.click();} - List emailMessages1 = mailTable.getMessagesByHeaderAndText("To", USER1); - List emailMessages2 = mailTable.getMessagesByHeaderAndText("To", USER2); - assertFalse(emailMessages1.getFirst().getBody().contains(_specimen_KCMC)); - assertTrue(emailMessages1.getFirst().getBody().contains(_specimen_McMichael)); - assertNotNull("No message found", emailMessages1); - String messageBody = emailMessages2.getFirst().getBody().replaceFirst("-*=_Part_\\d{3}_\\d*.\\d*\\n",""); - messageBody = messageBody.replace("Content-Type: text/html; charset=UTF-8\n",""); - messageBody = messageBody.replace("Content-Transfer-Encoding: 7bit\n", ""); - assertTrue("Notification was not as expected.\nExpected:\n" + notification + "\n\nActual:\n" + messageBody, messageBody.contains(notification)); - - String attachment1 = getAttribute(Locator.linkWithText(ATTACHMENT1), "href"); - String attachment2 = getAttribute(Locator.linkWithText(String.format(ATTACHMENT2, date)), "href"); - - assertEquals("Bad link to attachment: " + ATTACHMENT1, HttpStatus.SC_OK, WebTestHelper.getHttpResponse(attachment1).getResponseCode()); - assertEquals("Bad link to attachment: " + String.format(ATTACHMENT2, date), HttpStatus.SC_OK, WebTestHelper.getHttpResponse(attachment2).getResponseCode()); - - clickAndWait(Locator.linkWithText("Request Link")); - assertTextPresent("Specimen Request " + _requestId); - } - - @LogMethod - private void verifyRequestCancel() - { - goToProjectHome(); - clickFolder(getFolderName()); - - waitForElement(Locator.linkWithText("By Individual Vial")); - waitAndClick(Locator.xpath("//span[text() = 'Specimen Requests']/../../a")); - waitAndClick(Locator.linkWithText("View Current Requests")); - - DataRegion(getDriver()).withName("SpecimenRequest").waitFor(); - clickButton("Details"); - - clickAndWait(Locator.linkWithText("Update Request")); - selectOptionByText(Locator.name("status"), "Not Yet Submitted"); - clickButton("Save Changes and Send Notifications"); - doAndWaitForPageToLoad(() -> - { - clickButton("Cancel Request", 0); - assertAlertIgnoreCaseAndSpaces("Canceling will permanently delete this pending request. Continue?"); - }); - waitForText("No data to show."); - goToSpecimenData(); - click(Locator.xpath("//span[text()='Vials by Derivative Type']/../img")); - waitForElement(Locator.linkWithText("Swab")); - clickAndWait(Locator.linkWithText("Swab")); - new DataRegionTable.DataRegionFinder(getDriver()).find() - .checkAllOnPage(); - BootstrapMenu.find(getDriver(), "Request Options").clickSubMenu(true, "Create New Request"); - clickButton("Cancel"); - } - - @LogMethod - private void verifyReports() - { - log("check reports by participant group"); - goToSpecimenData(); - clickAndWait(Locator.linkWithText("Blood (Whole)")); - pushLocation(); - clickAndWait(Locator.linkWithText("Reports")); - clickButton("View"); // Summary Report - //Verify by vial count - assertElementPresent(Locator.xpath("//a[number(text()) > 0]"), 36); - selectOptionByText(Locator.name("participantGroupFilter"), "Category1"); - clickButton("Refresh"); - assertElementNotPresent(Locator.xpath("//a[number(text()) > 6]")); - assertElementPresent(Locator.xpath("//a[number(text()) <= 6]"), 8); - selectOptionByText(Locator.name("participantGroupFilter"), "All Groups"); - clickButton("Refresh"); - assertElementPresent(Locator.xpath("//a[number(text()) > 0]"), 36); - //Verify by ptid list - checkCheckbox(Locator.checkboxByName("viewPtidList")); - uncheckCheckbox(Locator.checkboxByName("viewVialCount")); - clickButton("Refresh"); - assertElementPresent(Locator.linkWithText(PTIDS[0]), 3); - assertElementPresent(Locator.linkWithText(PTIDS[1]), 5); - selectOptionByText(Locator.name("participantGroupFilter"), "Category1"); - clickButton("Refresh"); - assertElementPresent(Locator.linkWithText(PTIDS[0]), 3); - assertElementPresent(Locator.linkWithText(PTIDS[1]), 5); - } - - @LogMethod - private void verifyRequestingLocationRestriction() - { - goToProjectHome(); - clickFolder(getFolderName()); - - verifyRequestingLocationCounts(StudyLocationType.values()); // All locations should be enabled by default - - enableAndVerifyRequestingLocationTypes(); - enableAndVerifyRequestingLocationTypes(StudyLocationType.CLINIC); - enableAndVerifyRequestingLocationTypes(StudyLocationType.ENDPOINT); - enableAndVerifyRequestingLocationTypes(StudyLocationType.REPOSITORY); - enableAndVerifyRequestingLocationTypes(StudyLocationType.SAL); - enableAndVerifyRequestingLocationTypes(StudyLocationType.REPOSITORY, StudyLocationType.CLINIC); - enableAndVerifyRequestingLocationTypes(StudyLocationType.values()); - } - - @LogMethod - private void verifySpecimenTableAttachments() - { - enableEmailRecorder(); // Clear out previous notifications - goToProjectHome(); - clickFolder(getFolderName()); - - log("Setup Excel specimen attachment"); - waitAndClickAndWait(Locator.linkWithText("Manage")); - waitAndClickAndWait(Locator.linkWithText("Manage Notifications")); - ManageNotificationsPage manageNotificationsPage = new ManageNotificationsPage(getDriver()); - manageNotificationsPage.setNotificationUsers(List.of(PasswordUtil.getUsername())); - manageNotificationsPage.setSpecimenAttachmentType(SpecimensAttachment.EXCEL); - manageNotificationsPage.clickSave(); - // Temporary check while tracking down intermittent failure with attachment type - verifySpecimenAttachmentOptionChecked(SpecimensAttachment.EXCEL); - - log("Create request with excel specimen attachment"); - goToSpecimenData(); - clickAndWait(Locator.linkWithText("Urine")); - new DataRegionTable("SpecimenDetail", getDriver()).checkCheckbox(0); - BootstrapMenu.find(getDriver(), "Request Options").clickSubMenu(true, "Create New Request"); - selectOptionByText(Locator.name("destinationLocation"), DESTINATION_SITE); - setFormElement(Locator.id("input0"), "Assay Plan"); - setFormElement(Locator.id("input1"), "Shipping"); - setFormElement(Locator.id("input3"), "Comments"); - clickButton("Create and View Details"); - doAndWaitForPageToLoad(() -> { - clickButton("Submit Request", 0); - acceptAlert(); - }); - waitForElement(Locator.css("h3").withText("Your request has been successfully submitted.")); - - log("Verify specimen xls attachment"); - EmailRecordTable emailRecordTable = goToEmailRecord(); - - emailRecordTable.clickSubject("Study 001: Specimen Request Notification"); - waitForElement(Locator.linkWithText("SpecimenDetail.xls")); - - // Each notification should have only the specimen request details, no specimen list - assertElementPresent(Locator.css("#email_body_1 > table"), 1); - - enableEmailRecorder(); // Clear out previous notifications - log("Setup text specimen attachment"); - goToProjectHome(); - clickFolder(getFolderName()); - waitAndClickAndWait(Locator.linkWithText("Manage")); - waitAndClickAndWait(Locator.linkWithText("Manage Notifications")); - manageNotificationsPage = new ManageNotificationsPage(getDriver()); - manageNotificationsPage.setSpecimenAttachmentType(SpecimensAttachment.TEXT); - manageNotificationsPage.clickSave(); - // Temporary check while tracking down intermittent failure with attachment type - verifySpecimenAttachmentOptionChecked(SpecimensAttachment.TEXT); - - log("Create request with text specimen attachment"); - goToSpecimenData(); - clickAndWait(Locator.linkWithText("Urine")); - new DataRegionTable("SpecimenDetail", getDriver()).checkCheckbox(1); - BootstrapMenu.find(getDriver(), "Request Options").clickSubMenu(true, "Create New Request"); - selectOptionByText(Locator.name("destinationLocation"), DESTINATION_SITE); - setFormElement(Locator.id("input0"), "Assay Plan"); - setFormElement(Locator.id("input1"), "Shipping"); - setFormElement(Locator.id("input3"), "Comments"); - clickButton("Create and View Details"); - doAndWaitForPageToLoad(() -> { - clickButton("Submit Request", 0); - acceptAlert(); - }); - waitForElement(Locator.css("h3").withText("Your request has been successfully submitted.")); - - log("Verify specimen tsv attachment"); - emailRecordTable = goToEmailRecord(); - - emailRecordTable.clickSubject("Study 001: Specimen Request Notification"); - waitForElement(Locator.linkWithText("SpecimenDetail.tsv")); - - // Each notification should have only the specimen request details, no specimen list - assertElementPresent(Locator.css("#email_body_1 > table"), 1); - } - - private void verifySpecimenAttachmentOptionChecked(SpecimensAttachment option) - { - assertTitleContains("Manage Study: /" + getProjectName() + "/" + getFolderName()); - waitAndClickAndWait(Locator.linkWithText("Manage Notifications")); - ManageNotificationsPage manageNotificationsPage = new ManageNotificationsPage(getDriver()); - assertTrue(manageNotificationsPage.isSpecimenAttachmentTypeChecked(option)); - } - - @LogMethod - private void verifyInactiveUsersInRequests() - { - enableEmailRecorder(); // clear email recorder - goToSiteUsers(); - DataRegionTable usersTable = new DataRegionTable("Users", this); - int row = usersTable.getRowIndex("Email", USER2); - usersTable.checkCheckbox(row); - clickButton("Deactivate"); - clickButton("Deactivate"); - assertTextNotPresent(USER2); - - goToProjectHome(); - clickFolder(getFolderName()); - - waitAndClick(Locator.xpath("//span[text() = 'Specimen Requests']/../../a")); - waitAndClick(Locator.linkWithText("View Current Requests")); - - DataRegion(getDriver()).withName("SpecimenRequest").waitFor(); - clickButton("Details"); - - waitAndClick(Locator.linkWithText("Update Request")); - - waitForElement(Locators.bodyTitle().withText("Update Request")); - checkCheckbox(Locator.checkboxByName("notificationIdPairs")); - click(Locator.css(".labkey-help-pop-up")); - waitForElement(Locator.xpath("id('helpDivBody')").containing(USER1)); - - checkCheckbox(Locator.checkboxByName("notificationIdPairs").index(1)); - click(Locator.css(".labkey-help-pop-up").index(1)); - waitForElement(Locator.xpath("id('helpDivBody')/del").withText(USER2)); - - setFormElement(Locator.name("requestDescription"), "Just one notification."); - pushLocation(); - clickButton("Save Changes and Send Notifications"); - - popLocation(); - - waitForElement(Locators.bodyTitle().withText("Update Request")); - checkCheckbox(Locator.checkboxByName("notificationIdPairs")); - checkCheckbox(Locator.checkboxByName("notificationIdPairs").index(1)); - checkCheckbox(Locator.checkboxByName("emailInactiveUsers")); - setFormElement(Locator.name("requestDescription"), "Two notifications."); - clickButton("Save Changes and Send Notifications"); - - EmailRecordTable emailRecordTable = goToEmailRecord(); - List tos = emailRecordTable.getColumnDataAsText("To"); - assertEquals("Active user should have received both notifications.", 2, tos.stream().filter(s -> s.equals(USER1)).count()); - assertEquals("Inactive user should have received a notification when explicitly requested.", 1, tos.stream().filter(s -> s.equals(USER2)).count()); - } - - /** - * Allow all provided location types to make requests, disallow all others - * @param types List of location types to allow to be requesting locations - */ - @LogMethod - private void enableAndVerifyRequestingLocationTypes(@LoggedParam StudyLocationType... types) - { - clickTab("Manage"); - waitAndClick(Locator.linkWithText("Manage Location Types")); - waitForElement(Locators.bodyTitle().withText("Manage Location Types")); - - for (StudyLocationType type : StudyLocationType.values()) - { - if (Arrays.asList(types).contains(type)) - _ext4Helper.checkCheckbox(type.toString()); - else - _ext4Helper.uncheckCheckbox(type.toString()); - } - - clickButton("Save", 0); - waitForElement(Locators.bodyTitle().withText("Manage Study")); - - verifyRequestingLocationCounts(types); - } - - /** - * Verify that only permitted locations can submit specimen requests - * Location count algorithm is valid only for locations defined in sample_a.specimens - */ - private void verifyRequestingLocationCounts(StudyLocationType... types) - { - goToSpecimenData(); - click(Locator.tag("img").withAttributeContaining("alt", "[New Request Icon]")); - waitForElement(Locators.bodyTitle().withText("New Specimen Request")); - int expectedLocationCount = StudyLocationType.untypedSites(); - - int additionalLocations = (int) Math.round(Math.pow(2, StudyLocationType.values().length - 1)); - - for (StudyLocationType type : StudyLocationType.values()) - { - if (Arrays.asList(types).contains(type)) - { - assertElementPresent(Locator.xpath("id('destinationLocation')/option").containing(type.toString()), type.siteCount()); - expectedLocationCount += additionalLocations; - additionalLocations = additionalLocations / 2; // Each additional Location type adds less unique locations - } - } - - assertElementPresent(Locator.css("#destinationLocation option"), expectedLocationCount + 1); // +1 for blank select option - - clickButton("Cancel", 0); - waitForElement(Locators.bodyTitle().withText("Specimen Requests")); - } - - /** - * Verify changing the specimen groupings that appear on the specimen web part - */ - @LogMethod - private void verifySpecimenGroupings() - { - goToProjectHome(); - clickFolder(getFolderName()); - clickTab("Manage"); - waitAndClick(Locator.linkWithText("Configure Specimen Groupings")); - waitForElement(Locators.bodyTitle().withText("Configure Specimen Web Part")); - _ext4Helper.selectComboBoxItemById("combo11", "Processing Location"); - _ext4Helper.selectComboBoxItemById("combo12", "Primary Type"); - _ext4Helper.selectComboBoxItemById("combo13", "Site Name"); - _ext4Helper.selectComboBoxItemById("combo21", "Additive Type"); - _ext4Helper.selectComboBoxItemById("combo22", "Derivative Type"); - _ext4Helper.selectComboBoxItemById("combo23", "Tube Type"); - clickButton("Save"); - waitForElement(Locators.bodyTitle().withText("Manage Study")); - goToSpecimenData(); - assertTextPresent("Vials by Processing Location", "Vials by Additive Type", "The McMichael Lab"); - assertTextPresent("NICD - Joberg", 2); - clickAndWait(Locator.linkContainingText("The McMichael Lab, Oxford")); - assertTextPresent("Vials", "ProcessingLocation.Label = 'The McMichael Lab, Oxford, UK'"); - - // Put groupings back for other tests - clickTab("Manage"); - waitAndClick(Locator.linkWithText("Configure Specimen Groupings")); - waitForElement(Locators.bodyTitle().withText("Configure Specimen Web Part")); - _ext4Helper.selectComboBoxItemById("combo11", "Primary Type"); - _ext4Helper.selectComboBoxItemById("combo12", "Derivative Type"); - _ext4Helper.selectComboBoxItemById("combo13", "Additive Type"); - _ext4Helper.selectComboBoxItemById("combo21", "Derivative Type"); - _ext4Helper.selectComboBoxItemById("combo22", "Additive Type"); - - clickButton("Save"); - } - - /** - * Provides info about locations defined in sample_a.specimens - */ - private enum StudyLocationType - { - REPOSITORY("Repository", 8), - CLINIC("Clinic", 8), - SAL("Site Affiliated Lab", 8), - ENDPOINT("Endpoint Lab", 8); - - private final String _type; - private final int _count; - - StudyLocationType(String type, int count) - { - _type=type; - _count=count; - } - - public String toString() - { - return _type; - } - - public int siteCount() - { - return _count; - } - - public static int untypedSites() - { - return 9; - } - } - - @LogMethod - private void searchTest() - { - goToProjectHome(); - clickFolder(getFolderName()); - goToSpecimenData(); - Ext4FieldRef additiveType = Ext4FieldRef.getForLabel(this, "Additive Type"); - additiveType.setValue("Heparin"); - Ext4FieldRef.getForLabel(this, "Participant").setValue("999320812"); - clickButtonContainingText("Search"); - assertTextNotPresent("Serum Separator"); - assertTextPresent("ParticipantId.ParticipantId = 999320812","AdditiveType.Description = Heparin" ); - - goToSpecimenData(); - additiveType.setValue(new String[] {"Heparin", "Ammounium Heparin"}); - clickButtonContainingText("Search"); - assertTextPresent("ONE OF"); - - goToSpecimenData(); - additiveType.setValue(new String[] {"Ammonium Heparin","Cell Preparation Tube Heparin","Cell Preparation Tube SCI","Citrate Phosphate Dextrose","EDTA","Fetal Fibronectin Buffer","Guanidine Isothiocyanate (GITC)","Heparin","Liquid Potassium EDTA","Liquid Sodium EDTA","Lithium Heparin","Lithium Heparin and Gel for Plasma","None","Normal Saline","Optimum Cutting Temperature Medium","Orasure Collection Container","Other","PAXgene Blood RNA tube","Phosphate Buffered Saline","Plasma Preparation Tube","PLP Fixative","Port-a-cul Transport Tube","Potassium EDTA","RNA Later","Serum Separator","Sodium Citrate","Sodium EDTA","Sodium Fluoride","Sodium Fluoride/Potassium Oxalate","Sodium Heparin","Sodium Polyanetholesulfonate","Spray Dried Potassium EDTA","Spray Dried Sodium EDTA","Thrombin","Tissue Freezing Medium","Unknown Additive","Viral Transport Media"}); - clickButtonContainingText("Search"); - assertTextPresent("IS NOT ANY OF "); - } - - @LogMethod - private void exportSpecimenTest() - { - popLocation(); - addUrlParameter("&exportType=excelWebQuery"); - assertTextPresent("org.labkey.specimen.query.SpecimenRequestDisplayColumn"); - goBack(); - - goToAdminConsole().clickAuditLog(); - selectOptionByText(Locator.name("view"), "Query export events"); - - DataRegionTable auditTable = new DataRegionTable("query", this); - String[][] columnAndValues = new String[][] {{"Created By", getDisplayName()}, - {"Project", PROJECT_NAME}, {"Container", getFolderName()}, {"SchemaName", "study"}, - {"QueryName", SPECIMEN_DETAIL}, {"Comment", "Exported to Excel Web Query data"}}; - for(String[] columnAndValue : columnAndValues) - { - log("Checking column: "+ columnAndValue[0]); - assertEquals(columnAndValue[1], auditTable.getDataAsText(0, columnAndValue[0])); - } - } - - private final Hashtable _drawTimestampConflicts = new Hashtable<>(); - private boolean _spotCheckNoConflict; - - @LogMethod - private void verifyDrawTimestamp() - { - File SPECIMEN_ARCHIVE_DTS = StudyHelper.getSpecimenArchiveFile("dts.specimens"); - startSpecimenImport(2, SPECIMEN_ARCHIVE_DTS); - waitForSpecimenImport(); - - // load our expected results - _drawTimestampConflicts.put("526455390.2504.346", "Conflicts found: DrawDate"); - _drawTimestampConflicts.put("526515315.6304.370", "Conflicts found: DrawTime"); - _drawTimestampConflicts.put("526515315.6304.375", "Conflicts found: DrawDate, DrawTime"); - _drawTimestampConflicts.put("526515651.3704.363", "Conflicts found: DrawDate, DrawTime"); - _spotCheckNoConflict = true; - - goToSpecimenData(); - clickAndWait(Locator.linkWithText("By Individual Vial")); - - DataRegionTable table = new DataRegionTable("SpecimenDetail", getDriver()); - - int rowCount = 21; - assertEquals("Wrong number of vials in dts.specimens archive", rowCount, table.getDataRowCount()); - assertEquals("Wrong number of conflicts in dts.specimens archive", _drawTimestampConflicts.size(), Locator.css(".labkey-error-row").findElements(table).size()); - for (int i = 0; i < rowCount; i ++) - { - String drawTimestamp = table.getDataAsText(i, "Draw Timestamp"); - String drawDate = table.getDataAsText(i, "Draw Date"); - String drawTime = table.getDataAsText(i, "Draw Time"); - String qcControlComments = table.getDataAsText(i, "Quality Control Comments"); - String id = table.getDataAsText(i, "Global Unique Id"); - - log("Verify vial: " + id); - - verifyDrawTimestampConflict(qcControlComments, drawTimestamp, drawDate, drawTime); - verifyDrawTimestampExpectedConflict(id, qcControlComments); - - if (doSpecimenEventCheck(qcControlComments)) - { - verifyHistory(i, qcControlComments); - } - } - } - - // spot check the specimen events for all conflicts and only for one non-conflict - private boolean doSpecimenEventCheck(String qcControlComments) - { - if (StringUtils.isNotBlank(qcControlComments)) - return true; - - if (_spotCheckNoConflict) - { - _spotCheckNoConflict = false; - return true; - } - - return false; - } - - private void verifyDrawTimestampExpectedConflict(String id, String qcControlComments) - { - if (!_drawTimestampConflicts.containsKey(id)) - { - assertTrue(id + " should not have a QC conflict. Found: " + qcControlComments, StringUtils.isBlank(qcControlComments)); - } - else - { - assertFalse(id + " should have a QC conflict: " + _drawTimestampConflicts.get(id), StringUtils.isBlank(qcControlComments)); - String expectedComment = _drawTimestampConflicts.get(id); - Set expectedConflicts = getConflictedColumnsFromQCComment(expectedComment); - Set actualConflicts = getConflictedColumnsFromQCComment(qcControlComments); - assertEquals(id + " did not have the expected conflict(s)", expectedConflicts, actualConflicts); - } - } - - private Set getConflictedColumnsFromQCComment(String qcControlComment) - { - String columns = qcControlComment.split(": ")[1]; - return new HashSet<>(Arrays.asList(columns.toLowerCase().split(", "))); - } - - private void verifyDrawTimestampConflict(String qcControl, String timestamp, String date, String time) - { - if (StringUtils.isBlank(qcControl)) - { - // no conflict, so all three fields should be valid - assertTrue(StringUtils.isNotBlank(timestamp)); - assertTrue(StringUtils.isNotBlank(time)); - assertTrue(StringUtils.isNotBlank(date)); - assertTrue(timestamp.contains(date)); - - // timestamp does not contain seconds but the time field does - assertTrue(timestamp.contains(time.substring(0, time.lastIndexOf(":")))); - } - else - { - // All of the specimens in dts specimens table should only have Draw Timestamp related - // conflicts. If there is a conflict, then the timestamp should be blank - assertTrue(StringUtils.isBlank(timestamp)); - - if (qcControl.contains("DrawDate")) - assertTrue(StringUtils.isBlank(date)); - else - assertFalse(StringUtils.isBlank(date)); - - if(qcControl.contains("DrawTime")) - assertTrue(StringUtils.isBlank(time)); - else - assertFalse(StringUtils.isBlank(time)); - } - } - - @LogMethod (quiet = true) - private void verifyHistory(int vialIndex, @LoggedParam String qcControl) - { - final WebElement historyLink = Locator.linkContainingText("[history]").index(vialIndex).findElement(getDriver()); - scrollIntoView(historyLink); - clickAndWait(historyLink); - - DataRegionTable table = new DataRegionTable("SpecimenEvent", getDriver()); - - String prevDrawTimestamp = null; - String drawTimestamp; - boolean foundConflict = false; - - for (int i = 0; i < table.getDataRowCount(); i++) - { - drawTimestamp = table.getDataAsText(i, "Draw Timestamp"); - - if (null == prevDrawTimestamp) - { - prevDrawTimestamp = drawTimestamp; - } - else - if (!prevDrawTimestamp.equalsIgnoreCase(drawTimestamp)) - { - foundConflict = true; - break; - } - } - - if (foundConflict) - assertTrue(StringUtils.isNotBlank(qcControl)); - else - assertTrue(StringUtils.isBlank(qcControl)); - - goBack(); - DataRegion(getDriver()).withName("SpecimenDetail").waitFor(); - } -}