From 7ca29600d4f8d00c246686c0c5bc29101938070b Mon Sep 17 00:00:00 2001 From: labkey-jeckels Date: Fri, 18 Jul 2025 11:09:56 -0700 Subject: [PATCH 1/3] Test coverage for container aliases --- .../test/pages/admin/FolderAliasesPage.java | 70 ++++++++++++++++++ .../pages/admin/FolderManagementPage.java | 6 ++ src/org/labkey/test/tests/FolderTest.java | 71 ++++++++++++++++++- src/org/labkey/test/tests/wiki/WikiTest.java | 6 +- src/org/labkey/test/util/WikiHelper.java | 11 +++ .../util/search/SearchAdminAPIHelper.java | 15 ++-- 6 files changed, 169 insertions(+), 10 deletions(-) create mode 100644 src/org/labkey/test/pages/admin/FolderAliasesPage.java diff --git a/src/org/labkey/test/pages/admin/FolderAliasesPage.java b/src/org/labkey/test/pages/admin/FolderAliasesPage.java new file mode 100644 index 0000000000..9ab9bb7380 --- /dev/null +++ b/src/org/labkey/test/pages/admin/FolderAliasesPage.java @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2017-2019 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.pages.admin; + +import org.apache.commons.lang3.StringUtils; +import org.labkey.test.Locator; +import org.labkey.test.pages.LabKeyPage; +import org.openqa.selenium.WebDriver; +import org.openqa.selenium.WebElement; + +import java.util.Arrays; +import java.util.List; + +public class FolderAliasesPage extends LabKeyPage +{ + public FolderAliasesPage(WebDriver driver) + { + super(driver); + } + + public List getAliases() + { + String aliases = getFormElement(elementCache().aliases); + return Arrays.asList(aliases.split("\\R")); + } + + public FolderAliasesPage setAliases(List aliases) + { + setFormElement(elementCache().aliases, StringUtils.join(aliases, "\n")); + return this; + } + + public FolderManagementPage clickSave() + { + elementCache().saveBtn.click(); + return new FolderManagementPage(getDriver()); + } + public FolderManagementPage clickCancel() + { + elementCache().cancelBtn.click(); + return new FolderManagementPage(getDriver()); + } + + @Override + protected ElementCache newElementCache() + { + return new ElementCache(); + } + + protected class ElementCache extends LabKeyPage.ElementCache + { + WebElement aliases = Locator.textarea("aliases").findWhenNeeded(this); + + WebElement saveBtn = Locator.lkButton("Save Aliases").refindWhenNeeded(this); + WebElement cancelBtn = Locator.button("Cancel").refindWhenNeeded(this); + } +} \ No newline at end of file diff --git a/src/org/labkey/test/pages/admin/FolderManagementPage.java b/src/org/labkey/test/pages/admin/FolderManagementPage.java index 3f588c36ba..d4a3844d96 100644 --- a/src/org/labkey/test/pages/admin/FolderManagementPage.java +++ b/src/org/labkey/test/pages/admin/FolderManagementPage.java @@ -166,6 +166,12 @@ protected ElementCache newElementCache() return new ElementCache(); } + public FolderAliasesPage goToAliases() + { + beginAt(WebTestHelper.buildRelativeUrl("admin", getCurrentContainerPath(), "folderAliases")); + return new FolderAliasesPage(getDriver()); + } + protected class ElementCache extends LabKeyPage.ElementCache { private final Map tabs = new HashMap<>(); diff --git a/src/org/labkey/test/tests/FolderTest.java b/src/org/labkey/test/tests/FolderTest.java index 2fac7a56bd..1267c66f52 100644 --- a/src/org/labkey/test/tests/FolderTest.java +++ b/src/org/labkey/test/tests/FolderTest.java @@ -34,6 +34,7 @@ import org.labkey.test.categories.Hosting; import org.labkey.test.components.ext4.Window; import org.labkey.test.pages.FolderManagementFolderTree; +import org.labkey.test.pages.admin.FolderAliasesPage; import org.labkey.test.pages.admin.FolderManagementPage; import org.labkey.test.pages.admin.ReorderFoldersPage; import org.labkey.test.pages.list.BeginPage; @@ -44,9 +45,11 @@ import org.labkey.test.util.LoggedParam; import org.labkey.test.util.PasswordUtil; import org.labkey.test.util.PortalHelper; +import org.labkey.test.util.WikiHelper; import org.labkey.test.util.WorkbookHelper; import org.openqa.selenium.WebElement; +import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.HashSet; @@ -95,8 +98,72 @@ public static void testSetup() init._containerHelper.createProject(init.getProjectName(), null); init._containerHelper.createProject(secondProject, null); init.goToProjectHome(); - init.importFolderFromZip(TestFileUtils.getSampleData("FolderTest/FolderTestProject.folder.zip")); - init.moveTestProjectToTop(); +// init.importFolderFromZip(TestFileUtils.getSampleData("FolderTest/FolderTestProject.folder.zip")); +// init.moveTestProjectToTop(); + } + + @Test + public void testAliases() + { + String firstContent = "This is the first folder"; + String secondContent = "This is the second folder"; + String originalName1 = "OriginalName1" + TRICKY_CHARACTERS_FOR_PROJECT_NAMES; + String originalName2 = "OriginalName2" + TRICKY_CHARACTERS_FOR_PROJECT_NAMES; + String newName = "NewName" + TRICKY_CHARACTERS_FOR_PROJECT_NAMES; + String additionalAlias = "AdditionalAlias" + TRICKY_CHARACTERS_FOR_PROJECT_NAMES; + + // Create folders and give them a wiki as content so we can be sure we land in the right spot when following an alias + _containerHelper.createSubfolder(getProjectName(), originalName1); + createWikiAndAddToPortal(firstContent, originalName1); + _containerHelper.createSubfolder(getProjectName(), originalName2); + createWikiAndAddToPortal(secondContent, originalName2); + + _containerHelper.renameFolder(getProjectName(), originalName1, newName, true); + navigateToFolder(getProjectName(), newName); + assertTextPresent(firstContent); + + // Ensure the alias was created and works + beginAt(WebTestHelper.buildURL("project", getProjectName() + "/" + originalName1 , "begin")); + assertTextPresent(firstContent); + FolderAliasesPage aliasesPage = goToFolderManagement().goToAliases(); + List aliases = new ArrayList<>(aliasesPage.getAliases()); + // Ensure it's being saved as lower case + assertEquals(Arrays.asList(("/" + getProjectName() + "/" + originalName1).toLowerCase()), aliases); + aliases.add("/" + getProjectName() + "/" + additionalAlias); + aliasesPage.setAliases(aliases); + aliasesPage.clickSave(); + + beginAt(WebTestHelper.buildURL("project", getProjectName() + "/" + originalName1 , "begin")); + assertTextPresent(firstContent); + beginAt(WebTestHelper.buildURL("project", getProjectName() + "/" + additionalAlias , "begin")); + assertTextPresent(firstContent); + + // Steal the alias in another folder + navigateToFolder(getProjectName(), originalName2); + assertTextPresent(secondContent); + aliasesPage = goToFolderManagement().goToAliases(); + aliasesPage.setAliases(Arrays.asList("/" + getProjectName() + "/" + additionalAlias)); + aliasesPage.clickSave(); + beginAt(WebTestHelper.buildURL("project", getProjectName() + "/" + additionalAlias , "begin")); + assertTextPresent(secondContent); + } + + private void createWikiAndAddToPortal(String body, String folderName) + { + navigateToFolder(getProjectName(), folderName); + WikiHelper wikiHelper = new WikiHelper(this); + wikiHelper.createNewWikiPage("HTML"); + String pageName = "ReferencePoint"; + wikiHelper.setWikiName(pageName); + wikiHelper.setWikiTitle(pageName); + wikiHelper.setWikiBody(body); + wikiHelper.saveWikiPage(); + + navigateToFolder(getProjectName(), folderName); + PortalHelper portalHelper = new PortalHelper(this); + portalHelper.addBodyWebPart("Wiki"); + wikiHelper.clickChooseAPage(); + wikiHelper.saveChosenPage(); } @LogMethod diff --git a/src/org/labkey/test/tests/wiki/WikiTest.java b/src/org/labkey/test/tests/wiki/WikiTest.java index c1260552de..e8f0261f86 100644 --- a/src/org/labkey/test/tests/wiki/WikiTest.java +++ b/src/org/labkey/test/tests/wiki/WikiTest.java @@ -313,7 +313,6 @@ public void testUpdateWikiWithHostileNameAndTitle() throws Exception var createResponse = createCmd.execute(cn, getProjectName()); var createResponseJson = new JSONObject(createResponse.getParsedData()); var wikiProps = createResponseJson.getJSONObject("wikiProps"); - SearchAdminAPIHelper.waitForIndexer(); // now, update the wiki with hostile inputs, expecting error/failure var updateJson = new JSONObject(); @@ -372,7 +371,6 @@ public void testRenameWebPartWiki() throws Exception createJson.put("pageVersionId", -1); createCmd.setJsonObject(createJson); createCmd.execute(cn, SUBFOLDER_PATH); - SearchAdminAPIHelper.waitForIndexer(); // give the folder a wikiWebPart goToProjectFolder(PROJECT_NAME, SUBFOLDER_NAME); @@ -383,13 +381,13 @@ public void testRenameWebPartWiki() throws Exception .descendant(Locator.tagWithText("p", "content for wiki webpart rename")); // configure the webPart to use the wiki created above - waitAndClickAndWait(Locator.linkWithText("Choose an existing page to display")); + wikiHelper.clickChooseAPage(); var selectedPageOption = getSelectedOptionText(Locator.name("name")); checker().withScreenshot("unexpected_selected_page") .wrapAssertion(()-> Assertions.assertThat(selectedPageOption) .as("expect our wiki to be selected") .startsWith(wikiName)); - waitAndClickAndWait(Locator.id("btnSubmit")); + wikiHelper.saveChosenPage(); // verify the webpart's content is our expected content checker().withScreenshot("unexpected_wiki_content") diff --git a/src/org/labkey/test/util/WikiHelper.java b/src/org/labkey/test/util/WikiHelper.java index f78c50e823..27bdda94f1 100644 --- a/src/org/labkey/test/util/WikiHelper.java +++ b/src/org/labkey/test/util/WikiHelper.java @@ -125,6 +125,17 @@ private void setWikiSourceTab(String srcFragment) _test.setFormElement(Locator.name("body"), srcFragment); } + public void clickChooseAPage() + { + _test.waitAndClickAndWait(Locator.linkWithText("Choose an existing page to display")); + } + + public void saveChosenPage() + { + _test.waitAndClickAndWait(Locator.id("btnSubmit")); + } + + public void saveWikiPage() { saveWikiPage(true); diff --git a/src/org/labkey/test/util/search/SearchAdminAPIHelper.java b/src/org/labkey/test/util/search/SearchAdminAPIHelper.java index 3a73eface6..28e8a52f5d 100644 --- a/src/org/labkey/test/util/search/SearchAdminAPIHelper.java +++ b/src/org/labkey/test/util/search/SearchAdminAPIHelper.java @@ -42,6 +42,13 @@ public abstract class SearchAdminAPIHelper { + @LogMethod(quiet = true) + public static void purgeForContainer(String containerPath) + { + var cmd = new SimplePostCommand("search", "cancelIndexing"); + executeCommand(cmd, containerPath); + } + public static void waitForIndexer() { waitForIndexer(WAIT_FOR_PAGE); @@ -57,7 +64,7 @@ public static void waitForIndexer(int timeout) var cmd = new SimplePostCommand("search", "waitForIndexer"); cmd.setTimeout(timeout); - executeWaitForIndexer(cmd); + executeCommand(cmd, null); } public static void waitForIndexerBackground() @@ -73,7 +80,7 @@ public static void waitForIndexerBackground(int timeout) cmd.setTimeout(timeout); cmd.setParameters(Map.of("priority", "background")); - executeWaitForIndexer(cmd); + executeCommand(cmd, null); } @LogMethod(quiet = true) @@ -106,11 +113,11 @@ public static void waitForSearchServiceBootstrap(Connection cn) while (!timer.isTimedOut()); } - private static void executeWaitForIndexer(PostCommand cmd) + private static void executeCommand(PostCommand cmd, String containerPath) { try { - var response = cmd.execute(WebTestHelper.getRemoteApiConnection(), null); + var response = cmd.execute(WebTestHelper.getRemoteApiConnection(), containerPath); assertEquals("WaitForIndexer action timed out", HttpStatus.SC_OK, response.getStatusCode()); } catch (Exception cmdException) { From 77b3d04fb72ba2ee086dac2171d4beee23922e36 Mon Sep 17 00:00:00 2001 From: labkey-jeckels Date: Fri, 18 Jul 2025 11:12:05 -0700 Subject: [PATCH 2/3] Reenable original test --- src/org/labkey/test/tests/FolderTest.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/org/labkey/test/tests/FolderTest.java b/src/org/labkey/test/tests/FolderTest.java index 1267c66f52..4b607f80dd 100644 --- a/src/org/labkey/test/tests/FolderTest.java +++ b/src/org/labkey/test/tests/FolderTest.java @@ -98,8 +98,8 @@ public static void testSetup() init._containerHelper.createProject(init.getProjectName(), null); init._containerHelper.createProject(secondProject, null); init.goToProjectHome(); -// init.importFolderFromZip(TestFileUtils.getSampleData("FolderTest/FolderTestProject.folder.zip")); -// init.moveTestProjectToTop(); + init.importFolderFromZip(TestFileUtils.getSampleData("FolderTest/FolderTestProject.folder.zip")); + init.moveTestProjectToTop(); } @Test From 36d97563aa61c4863380c64770f13adf68ace6b5 Mon Sep 17 00:00:00 2001 From: labkey-jeckels Date: Tue, 22 Jul 2025 09:54:19 -0700 Subject: [PATCH 3/3] Comment and revert change intended for another FB --- src/org/labkey/test/util/WikiHelper.java | 2 ++ .../test/util/search/SearchAdminAPIHelper.java | 15 ++++----------- 2 files changed, 6 insertions(+), 11 deletions(-) diff --git a/src/org/labkey/test/util/WikiHelper.java b/src/org/labkey/test/util/WikiHelper.java index 27bdda94f1..cdebf5dfaf 100644 --- a/src/org/labkey/test/util/WikiHelper.java +++ b/src/org/labkey/test/util/WikiHelper.java @@ -125,11 +125,13 @@ private void setWikiSourceTab(String srcFragment) _test.setFormElement(Locator.name("body"), srcFragment); } + /** For customizing wiki web parts */ public void clickChooseAPage() { _test.waitAndClickAndWait(Locator.linkWithText("Choose an existing page to display")); } + /** For customizing wiki web parts */ public void saveChosenPage() { _test.waitAndClickAndWait(Locator.id("btnSubmit")); diff --git a/src/org/labkey/test/util/search/SearchAdminAPIHelper.java b/src/org/labkey/test/util/search/SearchAdminAPIHelper.java index 28e8a52f5d..3a73eface6 100644 --- a/src/org/labkey/test/util/search/SearchAdminAPIHelper.java +++ b/src/org/labkey/test/util/search/SearchAdminAPIHelper.java @@ -42,13 +42,6 @@ public abstract class SearchAdminAPIHelper { - @LogMethod(quiet = true) - public static void purgeForContainer(String containerPath) - { - var cmd = new SimplePostCommand("search", "cancelIndexing"); - executeCommand(cmd, containerPath); - } - public static void waitForIndexer() { waitForIndexer(WAIT_FOR_PAGE); @@ -64,7 +57,7 @@ public static void waitForIndexer(int timeout) var cmd = new SimplePostCommand("search", "waitForIndexer"); cmd.setTimeout(timeout); - executeCommand(cmd, null); + executeWaitForIndexer(cmd); } public static void waitForIndexerBackground() @@ -80,7 +73,7 @@ public static void waitForIndexerBackground(int timeout) cmd.setTimeout(timeout); cmd.setParameters(Map.of("priority", "background")); - executeCommand(cmd, null); + executeWaitForIndexer(cmd); } @LogMethod(quiet = true) @@ -113,11 +106,11 @@ public static void waitForSearchServiceBootstrap(Connection cn) while (!timer.isTimedOut()); } - private static void executeCommand(PostCommand cmd, String containerPath) + private static void executeWaitForIndexer(PostCommand cmd) { try { - var response = cmd.execute(WebTestHelper.getRemoteApiConnection(), containerPath); + var response = cmd.execute(WebTestHelper.getRemoteApiConnection(), null); assertEquals("WaitForIndexer action timed out", HttpStatus.SC_OK, response.getStatusCode()); } catch (Exception cmdException) {