From 3d0a44071842b15141e43ba961447ac9a817a141 Mon Sep 17 00:00:00 2001 From: Andrei Solntsev Date: Tue, 11 Nov 2025 00:03:34 +0200 Subject: [PATCH] #16573 unwrap double-wrapped webdriver --- .../decorators/WebDriverDecorator.java | 18 +++++++++++++-- .../DecoratedRemoteWebDriverTest.java | 22 +++++++++++++++++++ 2 files changed, 38 insertions(+), 2 deletions(-) diff --git a/java/src/org/openqa/selenium/support/decorators/WebDriverDecorator.java b/java/src/org/openqa/selenium/support/decorators/WebDriverDecorator.java index f500774138277..6709ed290053a 100644 --- a/java/src/org/openqa/selenium/support/decorators/WebDriverDecorator.java +++ b/java/src/org/openqa/selenium/support/decorators/WebDriverDecorator.java @@ -195,7 +195,7 @@ protected static class Definition { public Definition(Decorated decorated) { this.decoratedClass = decorated.getClass(); - this.originalClass = decorated.getOriginal().getClass(); + this.originalClass = unwrapOriginal(decorated).getClass(); } @Override @@ -217,6 +217,17 @@ public int hashCode() { } } + private static Object unwrapOriginal(Decorated decorated) { + return unwrapWebdriver(decorated.getOriginal()); + } + + private static Object unwrapWebdriver(Object webDriver) { + if (webDriver instanceof WebDriver && webDriver instanceof WrapsDriver) { + return unwrapWebdriver(((WrapsDriver) webDriver).getWrappedDriver()); + } + return webDriver; + } + public interface HasTarget { Decorated getTarget(); @@ -480,12 +491,15 @@ private static void extractInterfaces(final Set> collector, final Class private Map, Function> deriveAdditionalInterfaces(Z sample) { Map, Function> handlers = new HashMap<>(); - if (sample instanceof WebDriver && !(sample instanceof WrapsDriver)) { + if (sample instanceof WebDriver) { handlers.put( WrapsDriver.class, (instance) -> (proxy, method, args) -> { if ("getWrappedDriver".equals(method.getName())) { + return unwrapWebdriver(instance); + } + if (sample instanceof WrapsDriver) { return instance; } throw new UnsupportedOperationException(method.getName()); diff --git a/java/test/org/openqa/selenium/support/decorators/DecoratedRemoteWebDriverTest.java b/java/test/org/openqa/selenium/support/decorators/DecoratedRemoteWebDriverTest.java index 0cfd9dc081d5b..d7459627d1956 100644 --- a/java/test/org/openqa/selenium/support/decorators/DecoratedRemoteWebDriverTest.java +++ b/java/test/org/openqa/selenium/support/decorators/DecoratedRemoteWebDriverTest.java @@ -55,6 +55,28 @@ void shouldImplementWrapsDriverToProvideAccessToUnderlyingDriver() { RemoteWebDriver underlying = (RemoteWebDriver) ((WrapsDriver) decoratedDriver).getWrappedDriver(); assertThat(underlying.getSessionId()).isEqualTo(sessionId); + assertThat(underlying).isSameAs(originalDriver); + } + + @Test + void canWrapDriverMultipleTimes() { + SessionId sessionId = new SessionId(UUID.randomUUID()); + RemoteWebDriver originalDriver = mock(RemoteWebDriver.class); + when(originalDriver.getSessionId()).thenReturn(sessionId); + + RemoteWebDriver decorated1 = + new WebDriverDecorator<>(RemoteWebDriver.class).decorate(originalDriver); + RemoteWebDriver decorated2 = + new WebDriverDecorator<>(RemoteWebDriver.class).decorate(decorated1); + RemoteWebDriver decoratedDriver = + new WebDriverDecorator<>(RemoteWebDriver.class).decorate(decorated2); + + assertThat(decoratedDriver.getSessionId()).isEqualTo(sessionId); + + RemoteWebDriver underlying = + (RemoteWebDriver) ((WrapsDriver) decoratedDriver).getWrappedDriver(); + assertThat(underlying.getSessionId()).isEqualTo(sessionId); + assertThat(underlying).isSameAs(originalDriver); } @Test