From 7df39a39504da9a3685b48c2a8b96829bdd98536 Mon Sep 17 00:00:00 2001 From: labkey-nicka Date: Tue, 21 Jul 2026 17:37:53 -0700 Subject: [PATCH 1/2] 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 7eeb7e3bf9dd37b8fc77f95ff4ba38cdae92f425 Mon Sep 17 00:00:00 2001 From: labkey-nicka Date: Wed, 22 Jul 2026 16:20:09 -0700 Subject: [PATCH 2/2] 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(); } }