From 90e5ad7a87b5fc8b9960f6e9ed7b20bbd2dbce95 Mon Sep 17 00:00:00 2001 From: rconner46 Date: Fri, 6 Feb 2026 10:29:23 -0600 Subject: [PATCH] Fix LazyWebElement exists() throwing error when element is not present --- .../pageobjectmodel/base/BaseComponent.java | 7 +------ .../pageobjectmodel/base/BaseElement.java | 7 +------ .../factory/LazyWebElement.java | 16 +++++++++++++--- .../factory/LazyWebElementTest.java | 19 +++++++++++++++++++ 4 files changed, 34 insertions(+), 15 deletions(-) diff --git a/auto-sdk-java-page-object/src/main/java/com/applause/auto/pageobjectmodel/base/BaseComponent.java b/auto-sdk-java-page-object/src/main/java/com/applause/auto/pageobjectmodel/base/BaseComponent.java index 512e094..4e82f10 100644 --- a/auto-sdk-java-page-object/src/main/java/com/applause/auto/pageobjectmodel/base/BaseComponent.java +++ b/auto-sdk-java-page-object/src/main/java/com/applause/auto/pageobjectmodel/base/BaseComponent.java @@ -288,12 +288,7 @@ public boolean exists() { "Cannot check existence of component [%s] with no underlying element" .formatted(this.getClass().getSimpleName())); } - boolean exists = true; - try { - this.underlying.isEnabled(); - } catch (NoSuchElementException | TimeoutException | StaleElementReferenceException e) { - exists = false; - } + boolean exists = this.underlying.exists(); logger.debug("{} {}.", this.getClass().getSimpleName(), exists ? "exists" : "does not exist"); return exists; diff --git a/auto-sdk-java-page-object/src/main/java/com/applause/auto/pageobjectmodel/base/BaseElement.java b/auto-sdk-java-page-object/src/main/java/com/applause/auto/pageobjectmodel/base/BaseElement.java index 29520e6..e9a3220 100644 --- a/auto-sdk-java-page-object/src/main/java/com/applause/auto/pageobjectmodel/base/BaseElement.java +++ b/auto-sdk-java-page-object/src/main/java/com/applause/auto/pageobjectmodel/base/BaseElement.java @@ -275,12 +275,7 @@ public Point getLocation() { @Override public boolean exists() { - boolean exists = true; - try { - this.underlying.isEnabled(); - } catch (NoSuchElementException | TimeoutException | StaleElementReferenceException e) { - exists = false; - } + boolean exists = this.underlying.exists(); logger.debug("{} {}.", this.getClass().getSimpleName(), exists ? "exists" : "does not exist"); return exists; diff --git a/auto-sdk-java-page-object/src/main/java/com/applause/auto/pageobjectmodel/factory/LazyWebElement.java b/auto-sdk-java-page-object/src/main/java/com/applause/auto/pageobjectmodel/factory/LazyWebElement.java index 234c4b8..0da0594 100644 --- a/auto-sdk-java-page-object/src/main/java/com/applause/auto/pageobjectmodel/factory/LazyWebElement.java +++ b/auto-sdk-java-page-object/src/main/java/com/applause/auto/pageobjectmodel/factory/LazyWebElement.java @@ -556,11 +556,21 @@ public Duration getWaitPollingInterval() { return this.pollingInterval; } + /** + * Checks if the element exists in the DOM. This is done by calling isEnabled() and catching any + * exceptions that indicate the element isn't present. + */ @Override - @SuppressWarnings( - "PMD.LambdaCanBeMethodReference") // Lambda required to defer null check for lazy-loading public boolean exists() { - return runLazily(() -> this.underlying.isEnabled()); + boolean exists = true; + try { + this.isEnabled(); + } catch (NoSuchElementException | TimeoutException | StaleElementReferenceException e) { + exists = false; + } + + logger.debug("{} {}.", this.getClass().getSimpleName(), exists ? "exists" : "does not exist"); + return exists; } @Override diff --git a/auto-sdk-java-page-object/src/test/java/com/applause/auto/pageobjectmodel/factory/LazyWebElementTest.java b/auto-sdk-java-page-object/src/test/java/com/applause/auto/pageobjectmodel/factory/LazyWebElementTest.java index 5159d6d..3182dd8 100644 --- a/auto-sdk-java-page-object/src/test/java/com/applause/auto/pageobjectmodel/factory/LazyWebElementTest.java +++ b/auto-sdk-java-page-object/src/test/java/com/applause/auto/pageobjectmodel/factory/LazyWebElementTest.java @@ -92,6 +92,8 @@ private PageObjectContext getMockDriver() { when(mockDriver.findElements(By.id("top-grand-child"))).thenReturn(List.of(grandChildMock)); when(mockDriver.findElement(By.id("%s"))).thenThrow(new NoSuchElementException("")); when(mockDriver.findElements(By.id("%s"))).thenThrow(new NoSuchElementException("")); + when(mockDriver.findElement(By.id("no-such-element"))) + .thenThrow(new NoSuchElementException("")); final var jQueryMock = mock(WebElement.class); when(jQueryMock.getAttribute("id")).thenReturn("fake-id"); @@ -464,4 +466,21 @@ public void testElementWithJavaScript() { logger.info("STEP 3: Get an attribute from the element, finding it on the page."); assertEquals(element.getAttribute("id"), "fake-id"); } + + /** + * Validate that the exists() function does not throw a no such element exception when the element + * is not found, and instead returns false. + */ + @Test + public void testExistsNoSuchElement() { + logger.info("STEP 1: Create a Locator for a non-existent element."); + Locator locator = new Locator(LocatedBy.id("no-such-element"), this.context.getPlatform()); + + logger.info("STEP 2: Create a LazyWebElement with the Locator."); + LazyWebElement lazy = new LazyWebElement(locator, this.context); + + logger.info( + "STEP 3: Call exists() on the LazyWebElement, which should return false without throwing an exception."); + assertFalse(lazy.exists()); + } }