From 90957389ea50ec6ef4b9721412cec439b0dca299 Mon Sep 17 00:00:00 2001 From: labkey-jeckels Date: Sat, 18 Oct 2025 08:52:35 -0700 Subject: [PATCH 1/9] More file path improvements, mostly around pipeline jobs --- src/org/labkey/test/TestFileUtils.java | 85 +++++++------------ .../labkey/test/teamcity/TeamCityUtils.java | 2 +- .../labkey/test/testpicker/TestHelper.java | 2 +- 3 files changed, 33 insertions(+), 56 deletions(-) diff --git a/src/org/labkey/test/TestFileUtils.java b/src/org/labkey/test/TestFileUtils.java index 807a928b10..b72bc9a74c 100644 --- a/src/org/labkey/test/TestFileUtils.java +++ b/src/org/labkey/test/TestFileUtils.java @@ -38,6 +38,7 @@ import org.bouncycastle.openpgp.operator.jcajce.JcePBEDataDecryptorFactoryBuilder; import org.bouncycastle.util.io.Streams; import org.jetbrains.annotations.NotNull; +import org.labkey.api.util.FileUtil; import org.jetbrains.annotations.Nullable; import org.openqa.selenium.NotFoundException; @@ -97,7 +98,7 @@ public abstract class TestFileUtils public static String getFileContents(String rootRelativePath) { - return getFileContents(Paths.get(getLabKeyRoot(), rootRelativePath)); + return getFileContents(getLabKeyRoot().toPath().resolve(rootRelativePath)); } public static String getFileContents(final File file) @@ -137,7 +138,7 @@ public static String getStreamContentsAsString(InputStream is) throws IOExceptio return StringUtils.join(IOUtils.readLines(is, Charset.defaultCharset()).toArray(), System.lineSeparator()); } - public static String getLabKeyRoot() + public static File getLabKeyRoot() { if (_labkeyRoot == null) { @@ -151,7 +152,7 @@ public static String getLabKeyRoot() { throw new IllegalStateException("Specified LabKey root does not exist [" + _labkeyRoot + "]. Configure this by passing VM arg labkey.root={yourroot}"); } - if (!new File(_labkeyRoot, "server").exists()) + if (!FileUtil.appendName(_labkeyRoot, "server").exists()) { throw new IllegalStateException("Specified LabKey root exists [" + _labkeyRoot + "] but isn't the root of a LabKey enlistment. Configure this by passing VM arg labkey.root={yourroot}"); } @@ -167,25 +168,25 @@ public static String getLabKeyRoot() _labkeyRoot = _labkeyRoot.getParentFile().getParentFile(); // Working directory is in '{labkey.root}/server'; otherwise is in enlistment root else if (_labkeyRoot.getName().equals("server")) _labkeyRoot = _labkeyRoot.getParentFile(); // Working directory is in '{labkey.root}/server'; otherwise is in enlistment root - else if (!new File(_labkeyRoot, "server").exists()) + else if (!FileUtil.appendName(_labkeyRoot, "server").exists()) { throw new IllegalStateException("Unable to locate enlistment. Working directory [" + _labkeyRoot + "] isn't a recognized location. Configure manually with passing VM arg labkey.root={yourroot}"); } } } - return _labkeyRoot.toString(); + return _labkeyRoot; } public static File getServerLogDir() { - return new File(getDefaultDeployDir(), "embedded/logs"); + return FileUtil.appendName(FileUtil.appendName(getDefaultDeployDir(), "embedded"), "logs"); } public static File getTestRoot() { if (_testRoot == null) { - _testRoot = new File(getLabKeyRoot(), "server/testAutomation"); + _testRoot = FileUtil.appendName(FileUtil.appendName(getLabKeyRoot(), "server"), "testAutomation"); } return _testRoot; } @@ -199,7 +200,7 @@ public static File getTestBuildDir() { if (_buildDir == null) { - _buildDir = new File(getLabKeyRoot(), "build/modules/" + getTestProjectName()); // Gradle + _buildDir = FileUtil.appendPath(getLabKeyRoot(), org.labkey.api.util.Path.parse("build/modules/" + getTestProjectName())); // Gradle } return _buildDir; } @@ -207,12 +208,12 @@ public static File getTestBuildDir() public static File getBaseFileRoot() { // Files are a sibling of the modules directory - return new File(getModulesDir().getParentFile(), "files"); + return FileUtil.appendName(getModulesDir().getParentFile(), "files"); } public static File getGradleReportDir() { - return new File(getTestBuildDir(), "test/logs/reports"); + return FileUtil.appendPath(getTestBuildDir(), org.labkey.api.util.Path.parse("test/logs/reports")); } /** @@ -221,7 +222,7 @@ public static File getGradleReportDir() */ static File getDefaultDeployDir() { - return new File(getLabKeyRoot(), "build/deploy"); + return FileUtil.appendPath(getLabKeyRoot(), org.labkey.api.util.Path.parse("build/deploy")); } public static File getModulesDir() @@ -229,10 +230,10 @@ public static File getModulesDir() if (_modulesDir == null) { // Module root when deploying from embedded distribution - _modulesDir = new File(getDefaultDeployDir(), "embedded/modules"); + _modulesDir = FileUtil.appendPath(getDefaultDeployDir(), org.labkey.api.util.Path.parse("embedded/modules")); if (!_modulesDir.isDirectory()) { - _modulesDir = new File(getDefaultDeployDir(), "modules"); + _modulesDir = FileUtil.appendName(getDefaultDeployDir(), "modules"); } } return _modulesDir; @@ -240,16 +241,16 @@ public static File getModulesDir() public static File getDefaultFileRoot(String containerPath) { - return new File(getBaseFileRoot(), containerPath + "/@files"); + return FileUtil.appendPath(getBaseFileRoot(), org.labkey.api.util.Path.parse(containerPath + "/@files")); } public static String getDefaultWebAppRoot() { - File path = new File(getModulesDir().getParentFile(), "labkeyWebapp"); + File path = FileUtil.appendName(getModulesDir().getParentFile(), "labkeyWebapp"); if (!path.isDirectory()) { // Casing is different when deployed from an embedded distribution - path = new File(getModulesDir().getParentFile(), "labkeywebapp"); + path = FileUtil.appendName(getModulesDir().getParentFile(), "labkeywebapp"); } return path.toString(); } @@ -300,7 +301,7 @@ public static List getSampleDatas(String relativePath) for (File sampledataDir : sampledataDirs) { - File checkFile = new File(sampledataDir, relativePath); + File checkFile = FileUtil.appendPath(sampledataDir, org.labkey.api.util.Path.parse(relativePath)); if (checkFile.exists()) { foundFiles.add(checkFile); @@ -317,7 +318,7 @@ public static Set getSampleDataDirs() { _sampledataDirs = new TreeSet<>(); - File sampledataDirsFile = new File(getTestBuildDir(), "sampledata.dirs"); + File sampledataDirsFile = FileUtil.appendName(getTestBuildDir(), "sampledata.dirs"); if (sampledataDirsFile.exists()) { String path = getFileContents(sampledataDirsFile); @@ -325,8 +326,8 @@ public static Set getSampleDataDirs() } else { - _sampledataDirs.add(new File(getTestRoot(), "data")); - Path modulesDir = new File(getLabKeyRoot(), "server/modules").toPath(); + _sampledataDirs.add(FileUtil.appendName(getTestRoot(), "data")); + Path modulesDir = FileUtil.appendPath(getLabKeyRoot(), org.labkey.api.util.Path.parse("server/modules")).toPath(); try { // We know where the modules live; no reason to insist that sampledata.dirs exists. @@ -363,8 +364,8 @@ public static Set getSampleDataDirs() public static File getTestTempDir() { - File buildDir = new File(getLabKeyRoot(), "build"); - return new File(buildDir, "testTemp"); + File buildDir = FileUtil.appendName(getLabKeyRoot(), "build"); + return FileUtil.appendName(buildDir, "testTemp"); } /** @@ -378,7 +379,7 @@ public static File ensureTestTempDir(String... children) throws IOException File file = getTestTempDir(); for (String child : children) { - file = new File(file, child); + file = FileUtil.appendName(file, child); } FileUtils.forceMkdir(file); @@ -398,7 +399,7 @@ public static File ensureTestTempFile(String... children) throws IOException for (String child : children) { - file = new File(file, child); + file = FileUtil.appendName(file, child); } if (file.toString().length() == getTestTempDir().toString().length()) @@ -448,7 +449,7 @@ private static void checkFileLocation(File file) { try { - if (!FileUtils.directoryContains(new File(getLabKeyRoot()), file)) + if (!FileUtils.directoryContains(getLabKeyRoot(), file)) { // TODO: Consider throwing IllegalArgumentException LOG.info("DEBUG: Attempting to delete a file outside of test enlistment: " + getLabKeyRoot()); @@ -457,30 +458,6 @@ private static void checkFileLocation(File file) catch (IOException ignore) { } } - /** - * - * @param dir Location to create new file - * @param fileName Name of file to be created - * @param contents Text contents of file - * @return File object pointing to new file - * @deprecated Use {@link #writeFile(File, String)} or {@link #writeTempFile(String, String)} - */ - @Deprecated - public static File saveFile(File dir, String fileName, String contents) - { - File tsvFile = new File(dir, fileName); - - try - { - return writeFile(tsvFile, contents); - } - catch (IOException e) - { - e.printStackTrace(System.err); - return null; - } - } - /** * Write text to a file in the test temp directory. Temp directory will be created if it does not exist. * @param name Name of the file to be created. An existing file will be overwritten @@ -490,7 +467,7 @@ public static File saveFile(File dir, String fileName, String contents) */ public static File writeTempFile(String name, InputStream contents) throws IOException { - File file = new File(getTestTempDir(), name); + File file = FileUtil.appendPath(getTestTempDir(), org.labkey.api.util.Path.parse(name)); FileUtils.forceMkdirParent(file); FileUtils.copyInputStreamToFile(contents, file); @@ -506,7 +483,7 @@ public static File writeTempFile(String name, InputStream contents) throws IOExc */ public static File writeTempFile(String name, String contents) throws IOException { - File file = new File(getTestTempDir(), name); + File file = FileUtil.appendPath(getTestTempDir(), org.labkey.api.util.Path.parse(name)); FileUtils.forceMkdirParent(file); return writeFile(file, contents); @@ -587,7 +564,7 @@ public static List unzipToDirectory(File sourceZip, File unzipDir) throws while (null != (entry = zis.getNextEntry())) { - File destFile = new File(unzipDir, entry.getName()); + File destFile = FileUtil.appendName(unzipDir, entry.getName()); if (!destFile.getCanonicalPath().startsWith(unzipDir.getCanonicalPath() + File.separator)) { throw new IOException("Zip entry is outside of the target dir: " + entry.getName()); @@ -641,7 +618,7 @@ private static List unTar(final File inputFile, final File outputDir) thro while ((entry = inputStream.getNextEntry()) != null) { - final File outputFile = new File(outputDir, entry.getName()); + final File outputFile = FileUtil.appendPath(outputDir, org.labkey.api.util.Path.parse(entry.getName())); if (!outputFile.toPath().normalize().startsWith(normalizedOutputPath)) throw new IOException("Bad zip entry (" + entry.getName() + ") in " + inputFile.getAbsolutePath()); @@ -675,7 +652,7 @@ private static List unTar(final File inputFile, final File outputDir) thro */ private static File unGzip(final File inputFile, final File outputDir) throws IOException { - final File outputFile = new File(outputDir, inputFile.getName().substring(0, inputFile.getName().length() - 3)); + final File outputFile = FileUtil.appendName(outputDir, inputFile.getName().substring(0, inputFile.getName().length() - 3)); try (GZIPInputStream in = new GZIPInputStream(new FileInputStream(inputFile)); FileOutputStream out = new FileOutputStream(outputFile)) diff --git a/src/org/labkey/test/teamcity/TeamCityUtils.java b/src/org/labkey/test/teamcity/TeamCityUtils.java index a90f3d6070..07f67f67a9 100644 --- a/src/org/labkey/test/teamcity/TeamCityUtils.java +++ b/src/org/labkey/test/teamcity/TeamCityUtils.java @@ -117,7 +117,7 @@ public static void publishArtifact(File file, @Nullable String destination) { if (file != null && file.exists()) { - String labkeyRoot = new File(TestFileUtils.getLabKeyRoot()).getAbsolutePath(); + String labkeyRoot = TestFileUtils.getLabKeyRoot().getAbsolutePath(); String filePath = file.getAbsoluteFile().toPath().normalize().toString(); if (filePath.startsWith(labkeyRoot)) { diff --git a/src/org/labkey/test/testpicker/TestHelper.java b/src/org/labkey/test/testpicker/TestHelper.java index a117ea6ebd..7df41c79c8 100644 --- a/src/org/labkey/test/testpicker/TestHelper.java +++ b/src/org/labkey/test/testpicker/TestHelper.java @@ -55,7 +55,7 @@ public class TestHelper public static final String DEFAULT_PORT = WebTestHelper.getWebPort().toString(); public static final String DEFAULT_CONTEXT_PATH = WebTestHelper.getContextPath(); public static final String DEFAULT_SERVER = WebTestHelper.getTargetServer(); - public static final String DEFAULT_ROOT = TestFileUtils.getLabKeyRoot(); + public static final String DEFAULT_ROOT = TestFileUtils.getLabKeyRoot().toString(); private static Thread awtThread = null; private static final String _saveFileName = "savedConfigs.idx"; From 4661d219ace4d2e474f4b64a36698d7af1fa43d5 Mon Sep 17 00:00:00 2001 From: labkey-jeckels Date: Mon, 20 Oct 2025 17:56:03 -0700 Subject: [PATCH 2/9] Test fix --- src/org/labkey/test/tests/SimpleModuleTest.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/org/labkey/test/tests/SimpleModuleTest.java b/src/org/labkey/test/tests/SimpleModuleTest.java index 42766be2a4..6242bab5a2 100644 --- a/src/org/labkey/test/tests/SimpleModuleTest.java +++ b/src/org/labkey/test/tests/SimpleModuleTest.java @@ -132,7 +132,7 @@ public class SimpleModuleTest extends BaseWebDriverTest TestFileUtils.getSampleData("SimpleAndRestrictedModule/FolderWithRestricted.folder.zip"); private static final String THUMBNAIL_FOLDER = "thumbnails/"; - private static final String THUMBNAIL_FILENAME = "/Thumbnail.png"; + private static final String THUMBNAIL_FILENAME = "Thumbnail.png"; private static final String ICON_FILENAME = "/SmallThumbnail.png"; private static final String KNITR_PEOPLE = "Knitr People"; @@ -1204,7 +1204,7 @@ private void doTestReportIcon() throws IOException setFormElement(Locator.xpath("//table[contains(@class, 'dataset-search')]//input"), KNITR_PEOPLE); waitForElementToDisappear(Locator.tag("tr").withClass("x4-grid-row").containing(WANT_TO_BE_COOL).notHidden()); - File expectedIconFile = TestFileUtils.getSampleData(THUMBNAIL_FOLDER + KNITR_PEOPLE + ICON_FILENAME); + File expectedIconFile = TestFileUtils.getSampleData(THUMBNAIL_FOLDER + KNITR_PEOPLE + "/" + ICON_FILENAME); WebElement img = waitForElement(Locator.tag("img").withClass("dataview-icon").withoutClass("x4-tree-icon-parent").notHidden()); String backgroundImage = StringUtils.trimToEmpty(img.getCssValue("background-image")); @@ -1214,7 +1214,7 @@ private void doTestReportIcon() throws IOException Assert.fail("Module report icon style is not as expected: " + img.getDomAttribute("style")); } String iconUrl = matcher.group(1); - File downloadedIcon = new SimpleHttpRequest(iconUrl).getResponseAsFile(TestFileUtils.ensureTestTempFile(KNITR_PEOPLE + ICON_FILENAME)); + File downloadedIcon = new SimpleHttpRequest(iconUrl).getResponseAsFile(TestFileUtils.ensureTestTempFile(KNITR_PEOPLE, ICON_FILENAME)); Assertions.assertThat(downloadedIcon).as("Module report icon is not as expected") .hasSameBinaryContentAs(expectedIconFile); @@ -1232,13 +1232,13 @@ private void doTestReportCreatedDate() @LogMethod private void verifyReportThumbnail(@LoggedParam String reportTitle) throws IOException { - File expectedThumbnailFile = TestFileUtils.getSampleData(THUMBNAIL_FOLDER + reportTitle + THUMBNAIL_FILENAME); + File expectedThumbnailFile = TestFileUtils.getSampleData(THUMBNAIL_FOLDER + reportTitle + "/" + THUMBNAIL_FILENAME); WebElement reportLink = waitForElement(Locator.xpath("//a[text()='" + reportTitle + "']")); mouseOver(reportLink); WebElement thumbnail = waitForElement(Locator.xpath("//div[@class='thumbnail']/img").notHidden()); File downloadedThumbnail = new SimpleHttpRequest(thumbnail.getDomProperty("src")) - .getResponseAsFile(TestFileUtils.ensureTestTempFile(reportTitle + THUMBNAIL_FILENAME)); + .getResponseAsFile(TestFileUtils.ensureTestTempFile(reportTitle, THUMBNAIL_FILENAME)); Assertions.assertThat(downloadedThumbnail).as("Module report thumbnail is not as expected") .hasSameBinaryContentAs(expectedThumbnailFile); From ac3cea78991edd1efd138c78b1f15e936840c4a0 Mon Sep 17 00:00:00 2001 From: labkey-jeckels Date: Tue, 21 Oct 2025 09:57:22 -0700 Subject: [PATCH 3/9] Test fixes --- .../test/tests/AdvancedImportOptionsTest.java | 88 +++++-------------- .../test/tests/FileBasedPipelineTest.java | 4 +- 2 files changed, 23 insertions(+), 69 deletions(-) diff --git a/src/org/labkey/test/tests/AdvancedImportOptionsTest.java b/src/org/labkey/test/tests/AdvancedImportOptionsTest.java index d2b914aa4d..eb4bb66447 100644 --- a/src/org/labkey/test/tests/AdvancedImportOptionsTest.java +++ b/src/org/labkey/test/tests/AdvancedImportOptionsTest.java @@ -115,18 +115,16 @@ public void doCleanup(boolean afterTest) throws TestTimeoutException _userHelper.deleteUser(LIMITED_USER); } - // This test class has no @Before or @BeforeClass. Each of the test cases, creates its own project to be used for importing. + // This test class has no @Before or @BeforeClass. Each of the test cases creates its own project to be used for importing. @Test public void testBasicImportFromFile() { - File zipFile = IMPORT_STUDY_FILE; - log("Create a new project to import the existing data."); _containerHelper.createProject(IMPORT_PROJECT_FILE01, "Study"); log("Get to the import page and validate that is looks as expected."); - StartImportPage importPage = StartImportPage.startImportFromFile(this, zipFile, true); + StartImportPage importPage = StartImportPage.startImportFromFile(this, IMPORT_STUDY_FILE, true); importPage.setSelectSpecificImportOptions(true); assertTrue("The 'Select specific objects to import' is not visible, and it should be in this case.", importPage.isSelectSpecificImportOptionsVisible()); @@ -176,54 +174,19 @@ private void validateFileImportResults() @Test public void testFilteredImportFromFile() { - File zipFile = IMPORT_STUDY_FILE; - log("Create a new project to import the existing data."); _containerHelper.createProject(IMPORT_PROJECT_FILE02); log("Get to the import page and validate that is looks as expected."); - StartImportPage importPage = StartImportPage.startImportFromFile(this, zipFile, true); + StartImportPage importPage = StartImportPage.startImportFromFile(this, IMPORT_STUDY_FILE, true); importPage.setSelectSpecificImportOptions(true); - assertTrue("The 'Select specific objects to import' is not visible, and it should be in this case.", importPage.isSelectSpecificImportOptionsVisible()); - - boolean chkSet = false; - Map myList = new HashMap<>(); - myList.put(StartImportPage.AdvancedOptionsCheckBoxes.AssaySchedule, chkSet); - myList.put(StartImportPage.AdvancedOptionsCheckBoxes.CohortSettings, chkSet); - myList.put(StartImportPage.AdvancedOptionsCheckBoxes.TreatmentData, chkSet); - myList.put(StartImportPage.AdvancedOptionsCheckBoxes.WikisAndTheirAttachments, chkSet); - - log("Uncheck a few of the options."); - importPage.setAdvancedOptionCheckBoxes(myList); - - log("Start the import"); - importPage.clickStartImport(); - - waitForText("Data Pipeline"); - waitForPipelineJobsToComplete(EXPECTED_COMPLETED_IMPORT_JOBS, "Folder import", EXPECTED_IMPORT_ERRORS, IMPORT_WAIT_TIME); - - goToProjectHome(IMPORT_PROJECT_FILE02); - - log("Validate that the expected data has been imported."); - - log("Validate assay schedule."); - clickTab("Assays"); - AssayScheduleWebpart assayScheduleWebpart = new AssayScheduleWebpart(getDriver()); - assertTrue(assayScheduleWebpart.isEmpty()); - - log("Validate Immunizations."); - clickTab("Immunizations"); - ImmunizationScheduleWebpart immunizationScheduleWebpart = new ImmunizationScheduleWebpart(getDriver()); - assertTrue(immunizationScheduleWebpart.isEmpty()); - - log("Validate Vaccine Design."); - clickTab("Vaccine Design"); - VaccineDesignWebpart vaccineDesignWebpart = new VaccineDesignWebpart(getDriver()); - assertTrue(vaccineDesignWebpart.isEmpty()); - - log("Validate that Locations have been imported unchanged."); - clickTab("Manage"); + configureAndValidateFilteredImport(importPage, IMPORT_PROJECT_FILE02); clickAndWait(Locator.linkWithText("Manage Locations")); + validateQCStatesAndWiki(IMPORT_PROJECT_FILE02); + } + + private void validateQCStatesAndWiki(String projectName) + { assertTextPresent("Jimmy Neutron Lab", "Dexter's Lab"); log("Validate QC State."); @@ -233,22 +196,27 @@ public void testFilteredImportFromFile() assertEquals("Wrong QC states imported", expectedStates, states); log("Validate wiki content are not imported"); - goToProjectHome(IMPORT_PROJECT_FILE02); + goToProjectHome(projectName); assertTextPresent("WikiPage01", "This folder does not currently contain any wiki pages to display."); assertElementNotPresent(Locator.xpath("//div[@class='labkey-wiki']//p[text() = 'This is a very basic wiki page.']")); - } @Test public void testFilteredImportFromPipeline() { - File zipFile = IMPORT_STUDY_FILE; - log("Create a new project to import the existing data."); _containerHelper.createProject(IMPORT_PROJECT_FILE03); log("Get to the import page and validate that is looks as expected."); - StartImportPage importPage = StartImportPage.startImportFromPipeline(this, zipFile, true, true); + StartImportPage importPage = StartImportPage.startImportFromPipeline(this, IMPORT_STUDY_FILE, true, true); + configureAndValidateFilteredImport(importPage, IMPORT_PROJECT_FILE03); + clickAndWait(Locator.linkWithText("Manage Locations"), WAIT_FOR_PAGE); + validateQCStatesAndWiki(IMPORT_PROJECT_FILE03); + + } + + private void configureAndValidateFilteredImport(StartImportPage importPage, String projectName) + { assertTrue("The 'Select specific objects to import' is not visible, and it should be in this case.", importPage.isSelectSpecificImportOptionsVisible()); boolean chkSet = false; @@ -267,7 +235,7 @@ public void testFilteredImportFromPipeline() waitForText("Data Pipeline"); waitForPipelineJobsToComplete(EXPECTED_COMPLETED_IMPORT_JOBS, "Folder import", EXPECTED_IMPORT_ERRORS, IMPORT_WAIT_TIME); - goToProjectHome(IMPORT_PROJECT_FILE03); + goToProjectHome(projectName); log("Validate that the expected data has been imported."); @@ -288,20 +256,6 @@ public void testFilteredImportFromPipeline() log("Validate that Locations have been imported unchanged."); clickTab("Manage"); - clickAndWait(Locator.linkWithText("Manage Locations"), WAIT_FOR_PAGE); - assertTextPresent("Jimmy Neutron Lab", "Dexter's Lab"); - - log("Validate QC State."); - ManageDatasetQCStatesPage manageDatasetQCStatesPage = goToManageStudy().manageDatasetQCStates(); - List expectedStates = Arrays.asList("[none]", "QC State Name 01"); - List states = manageDatasetQCStatesPage.getStateRows().stream().map(QCStateTableRow::getState).collect(Collectors.toList()); - assertEquals("Wrong QC states imported", expectedStates, states); - - log("Validate wiki content are not imported"); - goToProjectHome(IMPORT_PROJECT_FILE03); - assertTextPresent("WikiPage01", "This folder does not currently contain any wiki pages to display."); - assertElementNotPresent(Locator.xpath("//div[@class='labkey-wiki']//p[text() = 'This is a very basic wiki page.']")); - } @Test @@ -376,7 +330,7 @@ public void testImportToMultipleFolders() waitForText("Data Pipeline"); log("Verify the container filter has been set to see multiple import jobs"); - // if the container filter has been set correctly we should see all 2 pipeline jobs + // if the container filter has been set correctly, we should see all 2 pipeline jobs waitForPipelineJobsToComplete(EXPECTED_COMPLETED_MULTI_FOLDER_JOBS, "Folder import", EXPECTED_IMPORT_ERRORS, IMPORT_WAIT_TIME * EXPECTED_COMPLETED_IMPORT_JOBS); log("Validate that the expected data has been imported."); diff --git a/src/org/labkey/test/tests/FileBasedPipelineTest.java b/src/org/labkey/test/tests/FileBasedPipelineTest.java index 7791a439a4..131c0d7b07 100644 --- a/src/org/labkey/test/tests/FileBasedPipelineTest.java +++ b/src/org/labkey/test/tests/FileBasedPipelineTest.java @@ -130,7 +130,7 @@ public void testRCopyInlinePipeline() goToModule("FileContent"); _fileBrowserHelper.uploadFile(SAMPLE_FILE); - final String jobDescription = "@files/sample (InlineRCopy)"; + final String jobDescription = "sample (InlineRCopy)"; pipelineAnalysis.runPipelineAnalysis(importAction, targetFiles, protocolProperties, "Duplicate File(s)", true); pipelineAnalysis.verifyPipelineAnalysis(pipelineName, protocolName, jobDescription, null, fileRoot, outputFiles); @@ -239,7 +239,7 @@ public void testWithOutputLocation() goToModule("FileContent"); _fileBrowserHelper.uploadFile(SAMPLE_FILE); - final String jobDescription = "@files/sample (with_output_location)"; + final String jobDescription = "sample (with_output_location)"; pipelineAnalysis.runPipelineAnalysis(importAction, targetFiles, protocolProperties); pipelineAnalysis.verifyPipelineAnalysis(pipelineName, protocolName, null, jobDescription, fileRoot, outputFiles); From 7e8605f2a856f5f71fcf6f89bae45e67134146a0 Mon Sep 17 00:00:00 2001 From: labkey-jeckels Date: Tue, 21 Oct 2025 13:03:58 -0700 Subject: [PATCH 4/9] Update job description --- src/org/labkey/test/tests/RlabkeyTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/org/labkey/test/tests/RlabkeyTest.java b/src/org/labkey/test/tests/RlabkeyTest.java index 716499192a..498c6da5ad 100644 --- a/src/org/labkey/test/tests/RlabkeyTest.java +++ b/src/org/labkey/test/tests/RlabkeyTest.java @@ -211,7 +211,7 @@ public void testRlabkeyPipelineApi() throws Exception // verify the expected pipeline jobs where run and completed goToProjectHome(); PipelineStatusTable pipelineStatusTable = goToDataPipeline(); - assertEquals("COMPLETE", pipelineStatusTable.getJobStatus("@files/sample (Rlabkey RCopy Test 1) (sample.txt)")); + assertEquals("COMPLETE", pipelineStatusTable.getJobStatus("sample (Rlabkey RCopy Test 1) (sample.txt)")); assertEquals("COMPLETE", pipelineStatusTable.getJobStatus("test pipe desc")); } From dd698161065aa0a8c0cc61d9076f8447656dfb04 Mon Sep 17 00:00:00 2001 From: labkey-jeckels Date: Wed, 22 Oct 2025 09:09:16 -0700 Subject: [PATCH 5/9] Test fixes --- src/org/labkey/test/tests/SimpleModuleTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/org/labkey/test/tests/SimpleModuleTest.java b/src/org/labkey/test/tests/SimpleModuleTest.java index 6242bab5a2..05eadd292e 100644 --- a/src/org/labkey/test/tests/SimpleModuleTest.java +++ b/src/org/labkey/test/tests/SimpleModuleTest.java @@ -133,7 +133,7 @@ public class SimpleModuleTest extends BaseWebDriverTest private static final String THUMBNAIL_FOLDER = "thumbnails/"; private static final String THUMBNAIL_FILENAME = "Thumbnail.png"; - private static final String ICON_FILENAME = "/SmallThumbnail.png"; + private static final String ICON_FILENAME = "SmallThumbnail.png"; private static final String KNITR_PEOPLE = "Knitr People"; private static final String SUPER_COOL_R_REPORT = "Super Cool R Report"; From 595ff767ff434e00b810a6100afc9f604caffdba Mon Sep 17 00:00:00 2001 From: labkey-jeckels Date: Thu, 23 Oct 2025 10:03:43 -0700 Subject: [PATCH 6/9] Removed unused variables, improve test credential handling, refresh blob metadata on OutputStream close --- src/org/labkey/test/TestCredentials.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/org/labkey/test/TestCredentials.java b/src/org/labkey/test/TestCredentials.java index 5602121dba..342d9ba86e 100644 --- a/src/org/labkey/test/TestCredentials.java +++ b/src/org/labkey/test/TestCredentials.java @@ -46,7 +46,12 @@ public static File getCredentialsFile() { if (null == credentialsFile) { - setCredentialsFile(new File(System.getProperty("test.credentials.file", TestFileUtils.getTestRoot() + "/test.credentials.json"))); + String credentialsFileLocation = System.getProperty("test.credentials.file"); + if (credentialsFileLocation == null || credentialsFileLocation.isEmpty()) + { + credentialsFileLocation = TestFileUtils.getTestRoot() + "/test.credentials.json"; + } + setCredentialsFile(new File(credentialsFileLocation)); } return credentialsFile; } From f043b037da965a742feae82892d20e78b3fca902 Mon Sep 17 00:00:00 2001 From: labkey-jeckels Date: Mon, 27 Oct 2025 16:53:23 -0700 Subject: [PATCH 7/9] Test coverage for 54156, test code cleanup --- .../test/components/assay/AssayConstants.java | 3 +- .../test/tests/SampleTypeRemoteAPITest.java | 3 +- .../assay/AbstractAssayTransformTest.java | 46 ++++++++++ .../tests/assay/AssayMissingValuesTest.java | 4 +- .../assay/AssayTransformImportUpdateTest.java | 57 +++--------- .../AssayTransformMissingParentDirTest.java | 89 +++++++++++++++++++ .../assay/AssayTransformWarningTest.java | 11 +-- .../pipeline/PipelineProtocolArchiveTest.java | 4 +- .../tests/study/StudyMissingValuesTest.java | 2 +- src/org/labkey/test/util/DataRegion.java | 6 -- 10 files changed, 160 insertions(+), 65 deletions(-) create mode 100644 src/org/labkey/test/tests/assay/AbstractAssayTransformTest.java create mode 100644 src/org/labkey/test/tests/assay/AssayTransformMissingParentDirTest.java diff --git a/src/org/labkey/test/components/assay/AssayConstants.java b/src/org/labkey/test/components/assay/AssayConstants.java index 71ead8ea20..56db57c16a 100644 --- a/src/org/labkey/test/components/assay/AssayConstants.java +++ b/src/org/labkey/test/components/assay/AssayConstants.java @@ -12,5 +12,6 @@ public class AssayConstants public static final Locator COMMENTS_FIELD_LOCATOR = Locator.name("Comments"); public static final Locator TARGET_STUDY_FIELD_LOCATOR = Locator.name(TARGET_STUDY_FIELD_NAME); public static final Locator TEXT_AREA_DATA_PROVIDER_LOCATOR = Locator.xpath("//input[@value='textAreaDataProvider']"); - public static final Locator TEXT_AREA_DATA_COLLECTOR_LOCATOR = Locator.textarea("TextAreaDataCollector.textArea"); + public static final String TEXT_AREA_DATA_COLLECTOR_TEXT_AREA_NAME = "TextAreaDataCollector.textArea"; + public static final Locator TEXT_AREA_DATA_COLLECTOR_LOCATOR = Locator.textarea(TEXT_AREA_DATA_COLLECTOR_TEXT_AREA_NAME); } diff --git a/src/org/labkey/test/tests/SampleTypeRemoteAPITest.java b/src/org/labkey/test/tests/SampleTypeRemoteAPITest.java index 1b146282f3..c90a58c629 100644 --- a/src/org/labkey/test/tests/SampleTypeRemoteAPITest.java +++ b/src/org/labkey/test/tests/SampleTypeRemoteAPITest.java @@ -37,6 +37,7 @@ import org.labkey.test.TestTimeoutException; import org.labkey.test.categories.Daily; import org.labkey.test.components.CustomizeView; +import org.labkey.test.components.assay.AssayConstants; import org.labkey.test.components.domain.DomainFormPanel; import org.labkey.test.pages.ReactAssayDesignerPage; import org.labkey.test.pages.assay.AssayImportPage; @@ -766,7 +767,7 @@ private void insertAssayData(String assayName, List dataGener for(TestDataGenerator dataGen : dataGenerators) { AssayImportPage page = new AssayImportPage(getDriver()) - .setNamedTextAreaValue("TextAreaDataCollector.textArea", + .setNamedTextAreaValue(AssayConstants.TEXT_AREA_DATA_COLLECTOR_TEXT_AREA_NAME, dataGen.getDataAsTsv()); imported++; diff --git a/src/org/labkey/test/tests/assay/AbstractAssayTransformTest.java b/src/org/labkey/test/tests/assay/AbstractAssayTransformTest.java new file mode 100644 index 0000000000..3b9190a1da --- /dev/null +++ b/src/org/labkey/test/tests/assay/AbstractAssayTransformTest.java @@ -0,0 +1,46 @@ +package org.labkey.test.tests.assay; + +import org.junit.BeforeClass; +import org.labkey.test.BaseWebDriverTest; +import org.labkey.test.util.RReportHelper; + +import java.util.Collections; +import java.util.List; + +/** + * Shared setup/cleanup helpers for assay transform-related WebDriver tests. + * Consolidates common project creation, R configuration, and project cleanup. + */ +public abstract class AbstractAssayTransformTest extends BaseWebDriverTest +{ + @BeforeClass + public static void setupProject() + { + AbstractAssayTransformTest init = getCurrentTest(); + init.doSetup(); + } + + protected void doSetup() + { + new RReportHelper(this).ensureRConfig(); + _containerHelper.createProject(getProjectName(), "Assay"); + } + + @Override + protected void doCleanup(boolean afterTest) + { + _containerHelper.deleteProject(getProjectName(), afterTest); + } + + @Override + protected String getProjectName() + { + return getClass().getSimpleName() + " Project"; + } + + @Override + public List getAssociatedModules() + { + return Collections.emptyList(); + } +} diff --git a/src/org/labkey/test/tests/assay/AssayMissingValuesTest.java b/src/org/labkey/test/tests/assay/AssayMissingValuesTest.java index 974397525b..e8115ffa23 100644 --- a/src/org/labkey/test/tests/assay/AssayMissingValuesTest.java +++ b/src/org/labkey/test/tests/assay/AssayMissingValuesTest.java @@ -97,12 +97,12 @@ public void testAssayMV() setFormElement(AssayConstants.ASSAY_NAME_FIELD_LOCATOR, ASSAY_RUN_SINGLE_COLUMN); click(AssayConstants.TEXT_AREA_DATA_PROVIDER_LOCATOR); - setFormElement(Locator.name("TextAreaDataCollector.textArea"), TEST_DATA_SINGLE_COLUMN_ASSAY_BAD); + setFormElement(AssayConstants.TEXT_AREA_DATA_COLLECTOR_LOCATOR, TEST_DATA_SINGLE_COLUMN_ASSAY_BAD); clickButton("Save and Finish"); assertLabKeyErrorPresent(); click(AssayConstants.TEXT_AREA_DATA_PROVIDER_LOCATOR); - setFormElement(Locator.name("TextAreaDataCollector.textArea"), TEST_DATA_SINGLE_COLUMN_ASSAY); + setFormElement(AssayConstants.TEXT_AREA_DATA_COLLECTOR_LOCATOR, TEST_DATA_SINGLE_COLUMN_ASSAY); clickButton("Save and Finish"); assertNoLabKeyErrors(); clickAndWait(Locator.linkWithText(ASSAY_RUN_SINGLE_COLUMN)); diff --git a/src/org/labkey/test/tests/assay/AssayTransformImportUpdateTest.java b/src/org/labkey/test/tests/assay/AssayTransformImportUpdateTest.java index 15b9814577..366aaf8390 100644 --- a/src/org/labkey/test/tests/assay/AssayTransformImportUpdateTest.java +++ b/src/org/labkey/test/tests/assay/AssayTransformImportUpdateTest.java @@ -2,7 +2,6 @@ import org.assertj.core.api.Assertions; import org.junit.Assume; -import org.junit.BeforeClass; import org.junit.Test; import org.junit.experimental.categories.Category; import org.labkey.test.BaseWebDriverTest; @@ -11,6 +10,7 @@ import org.labkey.test.WebTestHelper; import org.labkey.test.categories.Assays; import org.labkey.test.categories.Daily; +import org.labkey.test.components.assay.AssayConstants; import org.labkey.test.pages.ReactAssayDesignerPage; import org.labkey.test.pages.admin.UsageStatisticsPage; import org.labkey.test.pages.assay.AssayImportPage; @@ -19,13 +19,10 @@ import org.labkey.test.pages.pipeline.PipelineStatusDetailsPage; import org.labkey.test.params.FieldDefinition; import org.labkey.test.params.assay.GeneralAssayDesign; -import org.labkey.test.util.PipelineStatusTable; -import org.labkey.test.util.RReportHelper; import java.io.File; import java.time.Duration; import java.time.Instant; -import java.util.Arrays; import java.util.List; import static org.labkey.test.pages.ReactAssayDesignerPage.ScriptFileEvent.Edit; @@ -34,29 +31,8 @@ @Category({Assays.class, Daily.class}) @BaseWebDriverTest.ClassTimeout(minutes = 4) -public class AssayTransformImportUpdateTest extends BaseWebDriverTest +public class AssayTransformImportUpdateTest extends AbstractAssayTransformTest { - - @Override - protected void doCleanup(boolean afterTest) - { - _containerHelper.deleteProject(getProjectName(), afterTest); - } - - @BeforeClass - public static void setupProject() - { - AssayTransformImportUpdateTest init = getCurrentTest(); - - init.doSetup(); - } - - private void doSetup() - { - new RReportHelper(this).ensureRConfig(); - _containerHelper.createProject(getProjectName(), "Assay"); - } - @Test public void testEnableTransformForUpdate() throws Exception { @@ -89,6 +65,7 @@ public void testEnableTransformForUpdate() throws Exception var assayDesignerPage = ReactAssayDesignerPage.beginAt(this, getProjectName(), protocolResponse.getProtocolId(), "general", getURL().toString()); assayDesignerPage.addTransformScript(transformFile, true); + assayDesignerPage.goToBatchFields().removeAllFields(true); checker().verifyTrue("expect run on import to be enabled by default", assayDesignerPage.isScriptActionCheckboxEnabled(insertOrUpdateTransform, Import)); @@ -129,11 +106,10 @@ public void testEnableTransformForUpdate() throws Exception """; clickAndWait(Locator.linkWithText(insertOrUpdateTransformAssay)); - new AssayRunsPage(getDriver()).getTable().clickHeaderButton("Import Data"); - clickButton("Next"); + new AssayRunsPage(getDriver()).getTable().clickHeaderButtonAndWait("Import Data"); var importPage = new AssayImportPage(getDriver()); importPage.setNamedInputText("Name", "transformTestImport"); - importPage.setNamedTextAreaValue("TextAreaDataCollector.textArea", importData); + importPage.setNamedTextAreaValue(AssayConstants.TEXT_AREA_DATA_COLLECTOR_TEXT_AREA_NAME, importData); importPage.clickSaveAndFinish(); var assayDataPage = new AssayRunsPage(getDriver()).clickAssayIdLink("transformTestImport"); @@ -166,11 +142,10 @@ public void testEnableTransformForUpdate() throws Exception // now import some data to a new run called non_transform_import goToProjectHome(); clickAndWait(Locator.linkWithText(insertOrUpdateTransformAssay)); - new AssayRunsPage(getDriver()).getTable().clickHeaderButton("Import Data"); - clickButton("Next"); + new AssayRunsPage(getDriver()).getTable().clickHeaderButtonAndWait("Import Data"); importPage = new AssayImportPage(getDriver()); importPage.setNamedInputText("Name", "non_transform_import"); - importPage.setNamedTextAreaValue("TextAreaDataCollector.textArea", importData); + importPage.setNamedTextAreaValue(AssayConstants.TEXT_AREA_DATA_COLLECTOR_TEXT_AREA_NAME, importData); importPage.clickSaveAndFinish(); var assayDataPage2 = new AssayRunsPage(getDriver()).clickAssayIdLink("non_transform_import"); @@ -270,6 +245,7 @@ public void testCancelAsyncAssayTransformJob() throws Exception var assayDesignerPage = ReactAssayDesignerPage.beginAt(this, getProjectName(), protocolResponse.getProtocolId(), "general", getURL().toString()); assayDesignerPage.addTransformScript(transformFile, true); + assayDesignerPage.goToBatchFields().removeAllFields(true); assayDesignerPage.setBackgroundImport(true); assayDesignerPage.clickSave(); @@ -278,11 +254,10 @@ public void testCancelAsyncAssayTransformJob() throws Exception importDataBuilder.append(String.format("%d\t%d\tComment-%d\n", i, i, i)); clickAndWait(Locator.linkWithText(importCancelTransformAssay)); - new AssayRunsPage(getDriver()).getTable().clickHeaderButton("Import Data"); - clickButton("Next"); + new AssayRunsPage(getDriver()).getTable().clickHeaderButtonAndWait("Import Data"); var importPage = new AssayImportPage(getDriver()); importPage.setNamedInputText("Name", "cancelTransformTestImport"); - importPage.setNamedTextAreaValue("TextAreaDataCollector.textArea", importDataBuilder.toString()); + importPage.setNamedTextAreaValue(AssayConstants.TEXT_AREA_DATA_COLLECTOR_TEXT_AREA_NAME, importDataBuilder.toString()); Instant before = Instant.now(); importPage.clickSaveAndFinish(); @@ -311,16 +286,4 @@ public void testCancelAsyncAssayTransformJob() throws Exception resetErrors(); } - - @Override - protected String getProjectName() - { - return "AssayTransformImportUpdateTest Project"; - } - - @Override - public List getAssociatedModules() - { - return Arrays.asList(); - } } diff --git a/src/org/labkey/test/tests/assay/AssayTransformMissingParentDirTest.java b/src/org/labkey/test/tests/assay/AssayTransformMissingParentDirTest.java new file mode 100644 index 0000000000..f96fb6f5ef --- /dev/null +++ b/src/org/labkey/test/tests/assay/AssayTransformMissingParentDirTest.java @@ -0,0 +1,89 @@ +package org.labkey.test.tests.assay; + +import org.junit.Test; +import org.junit.experimental.categories.Category; +import org.labkey.api.util.FileUtil; +import org.labkey.test.Locator; +import org.labkey.test.TestFileUtils; +import org.labkey.test.categories.Assays; +import org.labkey.test.components.assay.AssayConstants; +import org.labkey.test.pages.ReactAssayDesignerPage; +import org.labkey.test.pages.assay.AssayImportPage; +import org.labkey.test.pages.assay.AssayRunsPage; +import org.labkey.test.params.assay.GeneralAssayDesign; + +import java.io.File; +import java.nio.file.Files; +import java.nio.file.Path; + +/** + * Issue 54156: Regression test to ensure a reasonable error message is shown when an assay design references + * a transform script whose parent directory has since been deleted, and that the assay design can be fixed by removing the script. + */ +@Category({Assays.class}) +public class AssayTransformMissingParentDirTest extends AbstractAssayTransformTest +{ + @Test + public void testMissingParentDirectoryRegression() throws Exception + { + // Create a nested directory and an R transform script within it + String assayName = "missingParentDirAssay"; + Path parentDir = Files.createTempDirectory("assay-transform-parent-"); + Path nestedDir = FileUtil.createDirectories(parentDir.resolve("child"), false); + String scriptName = "transformMissingParent.R"; + String transformContent = "library(Rlabkey);"; + File transformFile = nestedDir.resolve(scriptName).toFile(); + TestFileUtils.writeFile(transformFile, transformContent); + + // Create a General assay and add the transform by absolute path (not upload) + var protocolResponse = new GeneralAssayDesign(assayName).createAssay(getProjectName(), createDefaultConnection()); + var assayDesignerPage = ReactAssayDesignerPage.beginAt(this, getProjectName(), protocolResponse.getProtocolId(), + "general", getURL().toString()); + assayDesignerPage.goToBatchFields().removeAllFields(true); + // add by path so the absolute path is stored; this allows reproducing the missing parent dir scenario + assayDesignerPage.addTransformScript(transformFile); + assayDesignerPage.clickSave(); + + // Now delete the parent dir to ensure we handle it reasonably + TestFileUtils.deleteDir(parentDir.toFile()); + + // Attempt to import data and verify a reasonable error message is shown + String importData = """ + VisitID\tParticipantID\tComment + 1\tP1\timport after parent deleted + """; + + clickAndWait(Locator.linkWithText(assayName)); + new AssayRunsPage(getDriver()).getTable().clickHeaderButtonAndWait("Import Data"); + var importPage = new AssayImportPage(getDriver()); + importPage.setNamedInputText("Name", "missingParentImport"); + importPage.setNamedTextAreaValue(AssayConstants.TEXT_AREA_DATA_COLLECTOR_TEXT_AREA_NAME, importData); + importPage.clickSaveAndFinish(); + + // Expect an error page/message indicating the transform script path cannot be used + // Be tolerant to platform-specific phrasing; assert any of these appear + String expectedPath = transformFile.getAbsolutePath(); + checker().withScreenshot("missing-parent-error") + .verifyTrue("Expect an error message about the transform script path not being found", + isTextPresent("transformMissingParent.R, configured for this assay does not exist.")); + + // Fix the assay design by removing the transform script + goToProjectHome(); + assayDesignerPage = ReactAssayDesignerPage.beginAt(this, getProjectName(), protocolResponse.getProtocolId(), + "general", getURL().toString()); + assayDesignerPage.removeTransformScript(scriptName); + assayDesignerPage.clickSave(); + + // Retry the import and verify it succeeds without the transform + clickAndWait(Locator.linkWithText(assayName)); + new AssayRunsPage(getDriver()).getTable().clickHeaderButtonAndWait("Import Data"); + importPage = new AssayImportPage(getDriver()); + importPage.setNamedInputText("Name", "fixedAssayImport"); + importPage.setNamedTextAreaValue(AssayConstants.TEXT_AREA_DATA_COLLECTOR_TEXT_AREA_NAME, importData); + importPage.clickSaveAndFinish(); + + // Verify we land on the run details page and can see the run name (no transform needed) + new AssayRunsPage(getDriver()).clickAssayIdLink("fixedAssayImport"); + } + +} diff --git a/src/org/labkey/test/tests/assay/AssayTransformWarningTest.java b/src/org/labkey/test/tests/assay/AssayTransformWarningTest.java index 949f22c58b..4320312e53 100644 --- a/src/org/labkey/test/tests/assay/AssayTransformWarningTest.java +++ b/src/org/labkey/test/tests/assay/AssayTransformWarningTest.java @@ -26,6 +26,7 @@ import org.labkey.test.TestTimeoutException; import org.labkey.test.categories.Assays; import org.labkey.test.categories.Daily; +import org.labkey.test.components.assay.AssayConstants; import org.labkey.test.pages.ReactAssayDesignerPage; import org.labkey.test.pages.files.WebDavPage; import org.labkey.test.params.FieldDefinition; @@ -113,7 +114,7 @@ public void testJavaTransformWarning() throws Exception clickButton("Import Data"); clickButton("Next"); setFormElement(ASSAY_NAME_FIELD_LOCATOR, runName); - setFormElement(Locator.name("TextAreaDataCollector.textArea"), importData); + setFormElement(AssayConstants.TEXT_AREA_DATA_COLLECTOR_LOCATOR, importData); clickButton("Save and Finish"); assertElementPresent(Locators.labkeyError.containing("Inline warning from Java transform.")); @@ -156,7 +157,7 @@ public void testRTransformWarning() // Use this file as a sample upload file parameter setFormElement(Locator.name("myFile"), JAVA_TRANSFORM_SCRIPT); - setFormElement(Locator.name("TextAreaDataCollector.textArea"), importData); + setFormElement(AssayConstants.TEXT_AREA_DATA_COLLECTOR_LOCATOR, importData); clickButton("Save and Finish"); assertElementPresent(Locators.labkeyError.containing("Inline warning from R transform.")); @@ -216,7 +217,7 @@ public void testRTransformUpdateWarning() throws Exception clickButton("Import Data"); clickButton("Next"); setFormElement(ASSAY_NAME_FIELD_LOCATOR, runName); - setFormElement(Locator.name("TextAreaDataCollector.textArea"), importData); + setFormElement(AssayConstants.TEXT_AREA_DATA_COLLECTOR_LOCATOR, importData); clickButton("Save and Finish"); // edit the result, expect warning @@ -251,7 +252,7 @@ public void testRTransformError() clickButton("Next"); setFormElement(ASSAY_NAME_FIELD_LOCATOR, runName); - setFormElement(Locator.name("TextAreaDataCollector.textArea"), importData); + setFormElement(AssayConstants.TEXT_AREA_DATA_COLLECTOR_LOCATOR, importData); clickButton("Save and Finish"); assertTextPresent("There are errors in the input file"); @@ -287,7 +288,7 @@ public void testTransformErrorOnUpdate() throws Exception clickButton("Import Data"); clickButton("Next"); setFormElement(ASSAY_NAME_FIELD_LOCATOR, runName); - setFormElement(Locator.name("TextAreaDataCollector.textArea"), importData); + setFormElement(AssayConstants.TEXT_AREA_DATA_COLLECTOR_LOCATOR, importData); clickButton("Save and Finish"); diff --git a/src/org/labkey/test/tests/pipeline/PipelineProtocolArchiveTest.java b/src/org/labkey/test/tests/pipeline/PipelineProtocolArchiveTest.java index 15c836c84b..df367e5bc9 100644 --- a/src/org/labkey/test/tests/pipeline/PipelineProtocolArchiveTest.java +++ b/src/org/labkey/test/tests/pipeline/PipelineProtocolArchiveTest.java @@ -160,7 +160,7 @@ private void archiveSelected(DataRegionTable protocols) { doAndWaitForPageToLoad(()-> { - protocols.clickHeaderButtonByText("archive"); + protocols.clickHeaderButton("archive"); assertAlert("Are you sure you want to archive the selected protocol?"); }); } @@ -169,7 +169,7 @@ private void unarchiveSelected(DataRegionTable protocols) { doAndWaitForPageToLoad(()-> { - protocols.clickHeaderButtonByText("unarchive"); + protocols.clickHeaderButton("unarchive"); assertAlert("Are you sure you want to unarchive the selected protocol?"); }); } diff --git a/src/org/labkey/test/tests/study/StudyMissingValuesTest.java b/src/org/labkey/test/tests/study/StudyMissingValuesTest.java index 41fb42bb0b..13c708c3f9 100644 --- a/src/org/labkey/test/tests/study/StudyMissingValuesTest.java +++ b/src/org/labkey/test/tests/study/StudyMissingValuesTest.java @@ -207,7 +207,7 @@ public void testAssayLinkToStudyMV() clickButton("Next"); setFormElement(AssayConstants.ASSAY_NAME_FIELD_LOCATOR, ASSAY_RUN_SINGLE_COLUMN); click(AssayConstants.TEXT_AREA_DATA_PROVIDER_LOCATOR); - setFormElement(Locator.name("TextAreaDataCollector.textArea"), TEST_DATA_SINGLE_COLUMN_ASSAY); + setFormElement(AssayConstants.TEXT_AREA_DATA_COLLECTOR_LOCATOR, TEST_DATA_SINGLE_COLUMN_ASSAY); clickButton("Save and Finish"); assertNoLabKeyErrors(); diff --git a/src/org/labkey/test/util/DataRegion.java b/src/org/labkey/test/util/DataRegion.java index 83304f6299..4ff3baabaf 100644 --- a/src/org/labkey/test/util/DataRegion.java +++ b/src/org/labkey/test/util/DataRegion.java @@ -229,12 +229,6 @@ protected String replaceParameter(String param, String newValue) return url.getFile(); } - @Deprecated - public void clickHeaderButtonByText(String buttonText) - { - clickHeaderButton(buttonText); - } - public void clickHeaderButtonAndWait(String buttonText) { getWrapper().clickAndWait(elementCache().getHeaderButton(buttonText)); From bb9a5cecf85c92534c6a0b4e9e16168469a28398 Mon Sep 17 00:00:00 2001 From: labkey-jeckels Date: Mon, 27 Oct 2025 16:54:23 -0700 Subject: [PATCH 8/9] Include in daily suite --- .../test/tests/assay/AssayTransformMissingParentDirTest.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/org/labkey/test/tests/assay/AssayTransformMissingParentDirTest.java b/src/org/labkey/test/tests/assay/AssayTransformMissingParentDirTest.java index f96fb6f5ef..69c8a94f29 100644 --- a/src/org/labkey/test/tests/assay/AssayTransformMissingParentDirTest.java +++ b/src/org/labkey/test/tests/assay/AssayTransformMissingParentDirTest.java @@ -6,6 +6,7 @@ import org.labkey.test.Locator; import org.labkey.test.TestFileUtils; import org.labkey.test.categories.Assays; +import org.labkey.test.categories.Daily; import org.labkey.test.components.assay.AssayConstants; import org.labkey.test.pages.ReactAssayDesignerPage; import org.labkey.test.pages.assay.AssayImportPage; @@ -20,7 +21,7 @@ * Issue 54156: Regression test to ensure a reasonable error message is shown when an assay design references * a transform script whose parent directory has since been deleted, and that the assay design can be fixed by removing the script. */ -@Category({Assays.class}) +@Category({Assays.class, Daily.class}) public class AssayTransformMissingParentDirTest extends AbstractAssayTransformTest { @Test From 498b8a7c852c021d9192abeac1ef9f9257dfea02 Mon Sep 17 00:00:00 2001 From: labkey-jeckels Date: Tue, 4 Nov 2025 16:31:52 -0800 Subject: [PATCH 9/9] Misc cleanup, longer timeout --- src/org/labkey/test/LabKeySiteWrapper.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/org/labkey/test/LabKeySiteWrapper.java b/src/org/labkey/test/LabKeySiteWrapper.java index 2abd3f59fc..a118aece2c 100644 --- a/src/org/labkey/test/LabKeySiteWrapper.java +++ b/src/org/labkey/test/LabKeySiteWrapper.java @@ -1593,7 +1593,7 @@ public void waitForPipelineJobsToComplete(final int finishedJobsExpected, final * @param timeoutMilliseconds Maximum time to wait for pipeline jobs to finish (default 10 minutes) */ @LogMethod - public void waitForPipelineJobsToComplete(@LoggedParam final int finishedJobsExpected, @LoggedParam final String description, final boolean expectError, int timeoutMilliseconds) + public void waitForPipelineJobsToComplete(@LoggedParam final int finishedJobsExpected, @LoggedParam final String description, final boolean expectError, long timeoutMilliseconds) { final List statusValues = waitForPipelineJobsToFinish(finishedJobsExpected, Duration.ofMillis(timeoutMilliseconds));