Skip to content

Commit 6f951b2

Browse files
authored
[java] Decorator should honour implementation checks (#11438)
Fixes #11432 The current web driver decorator looks for Class name compatibility against a bunch of interfaces. So this works with we use WebDriver but does not Work when we use RemoteWebDriver. Altered the logic to use assignability checks between classes instead of doing a equals check.
1 parent 5e3b2d2 commit 6f951b2

File tree

2 files changed

+33
-2
lines changed

2 files changed

+33
-2
lines changed

java/src/org/openqa/selenium/support/decorators/WebDriverDecorator.java

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -304,13 +304,25 @@ protected final <Z> Z createProxy(final Decorated<Z> decorated, Class<Z> clazz)
304304
|| decoratedInterfaces.contains(method.getDeclaringClass())) {
305305
return method.invoke(decorated, args);
306306
}
307-
if (originalInterfaces.contains(method.getDeclaringClass())) {
307+
// Check if the class in which the method resides, implements any one of the
308+
// interfaces that we extracted from the decorated class.
309+
boolean isCompatible = originalInterfaces.stream()
310+
.anyMatch(eachInterface -> eachInterface.isAssignableFrom(method.getDeclaringClass()));
311+
312+
if (isCompatible) {
308313
decorated.beforeCall(method, args);
309314
Object result = decorated.call(method, args);
310315
decorated.afterCall(method, result, args);
311316
return result;
312317
}
313-
if (derivedInterfaces.containsKey(method.getDeclaringClass())) {
318+
319+
// Check if the class in which the current method resides, implements any of the
320+
// additional interfaces that we extracted from the decorated class.
321+
// E.g., of additional interfaces include WrapsDriver,WrapsElement,JsonSerializer
322+
isCompatible = derivedInterfaces.keySet().stream()
323+
.anyMatch(eachInterface -> eachInterface.isAssignableFrom(method.getDeclaringClass()));
324+
325+
if (isCompatible) {
314326
return derivedInterfaces.get(method.getDeclaringClass()).invoke(proxy, method, args);
315327
}
316328

java/test/org/openqa/selenium/support/events/EventFiringDecoratorTest.java

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,12 @@
2121
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
2222
import static org.assertj.core.api.Assertions.assertThatNoException;
2323
import static org.mockito.ArgumentMatchers.any;
24+
import static org.mockito.Mockito.doNothing;
2425
import static org.mockito.Mockito.mock;
2526
import static org.mockito.Mockito.when;
2627
import static org.mockito.Mockito.withSettings;
2728

29+
import java.util.concurrent.atomic.AtomicInteger;
2830
import org.junit.jupiter.api.Test;
2931
import org.junit.jupiter.api.Tag;
3032
import org.openqa.selenium.Alert;
@@ -436,4 +438,21 @@ public void onError(Object target, Method method, Object[] args, InvocationTarge
436438
assertThatExceptionOfType(WebDriverException.class)
437439
.isThrownBy(decorated::getWindowHandle);
438440
}
441+
442+
@Test
443+
public void ensureListenersAreInvokedWhenUsingDecoratedSubClasses() {
444+
RemoteWebDriver originalDriver = mock(RemoteWebDriver.class);
445+
doNothing().when(originalDriver).get(any());
446+
AtomicInteger invocationCount = new AtomicInteger(0);
447+
WebDriverListener listener = new WebDriverListener() {
448+
@Override
449+
public void beforeAnyCall(Object target, Method method, Object[] args) {
450+
invocationCount.incrementAndGet();
451+
}
452+
};
453+
RemoteWebDriver rem = new EventFiringDecorator<>(RemoteWebDriver.class, listener)
454+
.decorate(originalDriver);
455+
rem.get("http://localhost:4444");
456+
assertThat(invocationCount.get()).isEqualTo(1);
457+
}
439458
}

0 commit comments

Comments
 (0)