From 966d3000cf976cef6a7edfbb893542feddb558d9 Mon Sep 17 00:00:00 2001 From: labkey-nicka Date: Tue, 21 Jul 2026 17:37:53 -0700 Subject: [PATCH 1/3] BaseReactSelect: support for "Add New" --- .../components/react/BaseReactSelect.java | 34 +++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/src/org/labkey/test/components/react/BaseReactSelect.java b/src/org/labkey/test/components/react/BaseReactSelect.java index c9037b2747..faa00615fd 100644 --- a/src/org/labkey/test/components/react/BaseReactSelect.java +++ b/src/org/labkey/test/components/react/BaseReactSelect.java @@ -422,6 +422,39 @@ public String getName() return elementCache().input.getAttribute("name"); } + /** + * Determines whether the "Add New" menu footer is present at the bottom of the select's menu area. This item is + * rendered only when the underlying schema/query is registered and configured to support adding new values. + * + * @return true if the "Add New" menu item is visible, otherwise false + */ + public boolean isAddNewVisible() + { + open(); + WebElement addNew = Locators.addEntitiesFooter.findElementOrNull(getComponentElement()); + return addNew != null && addNew.isDisplayed(); + } + + /** + * Clicks the "Add New" menu item at the bottom of the select's menu area. The menu is opened first if it is not + * already expanded. This intentionally returns void: the resulting UI varies by schema/query, so the caller is + * responsible for constructing and interacting with whatever the click produces. + */ + public void clickAddNew() + { + open(); + WebElement addNew = Locators.addEntitiesFooter.waitForElement(getComponentElement(), WAIT_FOR_JAVASCRIPT); + try + { + addNew.click(); + } + catch (WebDriverException wde) // handle the "another element would receive the click" situation + { + getWrapper().scrollIntoView(addNew); + getWrapper().fireEvent(addNew, WebDriverWrapper.SeleniumEvent.click); + } + } + protected T scrollIntoView() { try @@ -515,6 +548,7 @@ private Locators() } public static final Locator.XPathLocator option = Locator.tagWithClass("div", "select-input__option"); + public static final Locator.XPathLocator addEntitiesFooter = Locator.tagWithClass("div", "add-entities-footer"); public static final Locator placeholder = Locator.tagWithClass("div", "select-input__placeholder"); public static final Locator clear = Locator.tagWithClass("div","select-input__clear-indicator"); public static final Locator arrow = Locator.tagWithClass("div","select-input__dropdown-indicator"); From 96bb8cb8aedc3e10cb8b026f406c632e1948813c Mon Sep 17 00:00:00 2001 From: labkey-nicka Date: Wed, 22 Jul 2026 16:20:09 -0700 Subject: [PATCH 2/3] Review feedback --- .../test/components/react/BaseReactSelect.java | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/org/labkey/test/components/react/BaseReactSelect.java b/src/org/labkey/test/components/react/BaseReactSelect.java index faa00615fd..915d2b17c1 100644 --- a/src/org/labkey/test/components/react/BaseReactSelect.java +++ b/src/org/labkey/test/components/react/BaseReactSelect.java @@ -431,8 +431,7 @@ public String getName() public boolean isAddNewVisible() { open(); - WebElement addNew = Locators.addEntitiesFooter.findElementOrNull(getComponentElement()); - return addNew != null && addNew.isDisplayed(); + return Locators.addEntitiesFooter.isDisplayed(this); } /** @@ -443,15 +442,18 @@ public boolean isAddNewVisible() public void clickAddNew() { open(); - WebElement addNew = Locators.addEntitiesFooter.waitForElement(getComponentElement(), WAIT_FOR_JAVASCRIPT); + try { - addNew.click(); + Locators.addEntitiesFooter.findElement(this).click(); } - catch (WebDriverException wde) // handle the "another element would receive the click" situation + catch (WebDriverException e) { - getWrapper().scrollIntoView(addNew); - getWrapper().fireEvent(addNew, WebDriverWrapper.SeleniumEvent.click); + // ReactSelect is notoriously bad at positioning the menu so that it does not render off the screen. + // That said, it can behave better if you close and reopen the menu. + close(); + open(); + Locators.addEntitiesFooter.findElement(this).click(); } } From 91430c8fe4162dd453fc8f165293eb7b4c66ea54 Mon Sep 17 00:00:00 2001 From: labkey-nicka Date: Thu, 23 Jul 2026 09:58:19 -0700 Subject: [PATCH 3/3] Test updates --- .../ui/entities/EntityBulkUpdateDialog.java | 6 ++---- .../components/ui/files/FileAttachmentContainer.java | 11 ----------- src/org/labkey/test/util/AuditLogHelper.java | 2 +- 3 files changed, 3 insertions(+), 16 deletions(-) diff --git a/src/org/labkey/test/components/ui/entities/EntityBulkUpdateDialog.java b/src/org/labkey/test/components/ui/entities/EntityBulkUpdateDialog.java index 3bf4ae3880..2e2a242f9c 100644 --- a/src/org/labkey/test/components/ui/entities/EntityBulkUpdateDialog.java +++ b/src/org/labkey/test/components/ui/entities/EntityBulkUpdateDialog.java @@ -264,8 +264,7 @@ public String getDateField(CharSequence fieldIdentifier) */ private FileAttachmentContainer getFileField(CharSequence fieldIdentifier) { - FieldKey identifier = FileAttachmentContainer.fileUploadFieldKey(fieldIdentifier); - return enableAndWait(identifier, elementCache().fileUploadField(identifier)); + return enableAndWait(fieldIdentifier, elementCache().fileUploadField(fieldIdentifier)); } /** @@ -307,8 +306,7 @@ public EntityBulkUpdateDialog removeExistingAttachment(CharSequence fieldIdentif public FileUploadField getExistingFileCard(CharSequence fieldIdentifier) { - FieldKey identifier = FileAttachmentContainer.fileUploadFieldKey(fieldIdentifier); - return enableAndWait(identifier, elementCache().fileField(identifier)); + return enableAndWait(fieldIdentifier, elementCache().fileField(fieldIdentifier)); } /** diff --git a/src/org/labkey/test/components/ui/files/FileAttachmentContainer.java b/src/org/labkey/test/components/ui/files/FileAttachmentContainer.java index 575da2774f..a2c088a534 100644 --- a/src/org/labkey/test/components/ui/files/FileAttachmentContainer.java +++ b/src/org/labkey/test/components/ui/files/FileAttachmentContainer.java @@ -21,7 +21,6 @@ import org.labkey.test.components.WebDriverComponent; import org.labkey.test.components.html.FileInput; import org.labkey.test.components.html.Input; -import org.labkey.test.params.FieldKey; import org.openqa.selenium.ElementNotInteractableException; import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebElement; @@ -211,16 +210,6 @@ protected class ElementCache extends Component.ElementCache public Locator fileUploadScrollFooterLoc = Locator.tagWithClass("div", "file-upload__scroll-footer"); } - /** - * File upload fields append "-fileUpload" to the field's fieldKey - * @param fieldIdentifier Identifier for the field; name ({@link String}) or fieldKey ({@link FieldKey}) - * @return FieldKey with expected suffix - */ - public static FieldKey fileUploadFieldKey(CharSequence fieldIdentifier) - { - return FieldKey.fromFieldKey(FieldKey.fromName(fieldIdentifier) + "-fileUpload"); // Issue 53394 - } - public static class FileAttachmentContainerFinder extends WebDriverComponentFinder { private final Locator.XPathLocator _baseLocator = Locator.tagWithClass("div", "file-upload__container").parent("div"); diff --git a/src/org/labkey/test/util/AuditLogHelper.java b/src/org/labkey/test/util/AuditLogHelper.java index d84d230f21..7e25761b5d 100644 --- a/src/org/labkey/test/util/AuditLogHelper.java +++ b/src/org/labkey/test/util/AuditLogHelper.java @@ -349,7 +349,7 @@ public void checkTransactionAuditLogDetails(Integer transactionAuditId, Map