Skip to content

Commit 15f6904

Browse files
authored
[java] Add hooks around getScreenshotAs in WebDriverListener #16232 (#16233)
* [java] Add hooks around getScreenshotAs in WebDriverListener #16232 WebDriverListener has now default methods for both WebDriver and WebElement for clients to be notified before and after a screenshot is being taken. Fixes #16232 * fixup! [java] Add hooks around getScreenshotAs in WebDriverListener #16232 * fixup! [java] Add hooks around getScreenshotAs in WebDriverListener #16232 * fixup! [java] Add hooks around getScreenshotAs in WebDriverListener #16232
1 parent 6a8f6c6 commit 15f6904

File tree

2 files changed

+104
-1
lines changed

2 files changed

+104
-1
lines changed

java/src/org/openqa/selenium/support/events/WebDriverListener.java

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,10 @@
3030
import org.openqa.selenium.Cookie;
3131
import org.openqa.selenium.Dimension;
3232
import org.openqa.selenium.JavascriptExecutor;
33+
import org.openqa.selenium.OutputType;
3334
import org.openqa.selenium.Point;
3435
import org.openqa.selenium.ScriptKey;
36+
import org.openqa.selenium.TakesScreenshot;
3537
import org.openqa.selenium.WebDriver;
3638
import org.openqa.selenium.WebElement;
3739
import org.openqa.selenium.WindowType;
@@ -330,6 +332,26 @@ default void beforeResetInputState(WebDriver driver) {}
330332
*/
331333
default void afterResetInputState(WebDriver driver) {}
332334

335+
/**
336+
* This method will be called before {@link TakesScreenshot#getScreenshotAs(OutputType)} is
337+
* called.
338+
*
339+
* @param driver decorated WebDriver instance
340+
* @param target target type, see {@link OutputType}
341+
* @param <X> return type for getScreenshotAs
342+
*/
343+
default <X> void beforeGetScreenshotAs(WebDriver driver, OutputType<X> target) {}
344+
345+
/**
346+
* This method will be called after {@link TakesScreenshot#getScreenshotAs(OutputType)} is called.
347+
*
348+
* @param driver decorated WebDriver instance
349+
* @param target target type, see {@link OutputType}
350+
* @param result object that stores the screenshot information
351+
* @param <X> return type for getScreenshotAs
352+
*/
353+
default <X> void afterGetScreenshotAs(WebDriver driver, OutputType<X> target, X result) {}
354+
333355
// WebElement
334356

335357
/**
@@ -581,6 +603,26 @@ default void beforeGetCssValue(WebElement element, String propertyName) {}
581603
*/
582604
default void afterGetCssValue(WebElement element, String propertyName, String result) {}
583605

606+
/**
607+
* This method will be called before {@link TakesScreenshot#getScreenshotAs(OutputType)} is
608+
* called.
609+
*
610+
* @param element decorated WebElement instance
611+
* @param target target type, see {@link OutputType}
612+
* @param <X> return type for getScreenshotAs
613+
*/
614+
default <X> void beforeGetScreenshotAs(WebElement element, OutputType<X> target) {}
615+
616+
/**
617+
* This method will be called after {@link TakesScreenshot#getScreenshotAs(OutputType)} is called.
618+
*
619+
* @param element decorated WebElement instance
620+
* @param target target type, see {@link OutputType}
621+
* @param result result object that stores the screenshot information
622+
* @param <X> return type for getScreenshotAs
623+
*/
624+
default <X> void afterGetScreenshotAs(WebElement element, OutputType<X> target, X result) {}
625+
584626
// Navigation (WebDriver.Navigation)
585627

586628
/**

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

Lines changed: 62 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,9 @@
4444
import org.openqa.selenium.Dimension;
4545
import org.openqa.selenium.ImmutableCapabilities;
4646
import org.openqa.selenium.JavascriptExecutor;
47+
import org.openqa.selenium.OutputType;
4748
import org.openqa.selenium.Point;
49+
import org.openqa.selenium.TakesScreenshot;
4850
import org.openqa.selenium.WebDriver;
4951
import org.openqa.selenium.WebDriverException;
5052
import org.openqa.selenium.WebElement;
@@ -285,9 +287,11 @@ public void afterPerform(WebDriver driver, Collection<Sequence> actions) {
285287

286288
@Test
287289
void shouldFireWebElementEvents() {
290+
String result = "result";
288291
WebDriver driver = mock(WebDriver.class);
289292
WebElement element = mock(WebElement.class);
290293
when(driver.findElement(any())).thenReturn(element);
294+
when(element.getScreenshotAs(OutputType.BASE64)).thenReturn(result);
291295

292296
CollectorListener listener =
293297
new CollectorListener() {
@@ -467,6 +471,20 @@ public void beforeGetCssValue(WebElement element, String propertyName) {
467471
public void afterGetCssValue(WebElement element, String propertyName, String result) {
468472
acc.append("afterGetCssValue").append("\n");
469473
}
474+
475+
@Override
476+
public <X> void beforeGetScreenshotAs(WebElement element, OutputType<X> target) {
477+
acc.append("beforeGetScreenshotAs ").append(target).append("\n");
478+
}
479+
480+
@Override
481+
public <X> void afterGetScreenshotAs(WebElement element, OutputType<X> target, X result) {
482+
acc.append("afterGetScreenshotAs ")
483+
.append(target)
484+
.append(" ")
485+
.append(result)
486+
.append("\n");
487+
}
470488
};
471489

472490
WebDriver decorated = new EventFiringDecorator<>(listener).decorate(driver);
@@ -485,6 +503,7 @@ public void afterGetCssValue(WebElement element, String propertyName, String res
485503
element1.getSize();
486504
element1.getCssValue("test");
487505
element1.clear();
506+
element1.getScreenshotAs(OutputType.BASE64);
488507

489508
assertThat(listener.acc.toString().trim())
490509
.isEqualTo(
@@ -545,7 +564,11 @@ public void afterGetCssValue(WebElement element, String propertyName, String res
545564
"beforeAnyWebElementCall clear",
546565
"beforeClear",
547566
"afterClear",
548-
"afterAnyWebElementCall clear"));
567+
"afterAnyWebElementCall clear",
568+
"beforeAnyWebElementCall getScreenshotAs",
569+
"beforeGetScreenshotAs OutputType.BASE64",
570+
"afterGetScreenshotAs OutputType.BASE64 " + result,
571+
"afterAnyWebElementCall getScreenshotAs"));
549572
}
550573

551574
@Test
@@ -973,6 +996,44 @@ public void afterAlert(WebDriver.TargetLocator targetLocator, Alert alert) {
973996
"afterAnyCall alert"));
974997
}
975998

999+
@Test
1000+
void shouldFireWebDriverTakesScreenshotEvents() {
1001+
String result = "result";
1002+
WebDriver driver = mock(WebDriver.class, withSettings().extraInterfaces(TakesScreenshot.class));
1003+
when(((TakesScreenshot) driver).getScreenshotAs(OutputType.BASE64)).thenReturn(result);
1004+
1005+
CollectorListener listener =
1006+
new CollectorListener() {
1007+
@Override
1008+
public <X> void beforeGetScreenshotAs(WebDriver driver, OutputType<X> target) {
1009+
acc.append("beforeGetScreenshotAs ").append(target).append("\n");
1010+
}
1011+
1012+
@Override
1013+
public <X> void afterGetScreenshotAs(WebDriver driver, OutputType<X> target, X result) {
1014+
acc.append("afterGetScreenshotAs ")
1015+
.append(target)
1016+
.append(" ")
1017+
.append(result)
1018+
.append("\n");
1019+
}
1020+
};
1021+
WebDriver decorated = new EventFiringDecorator<>(listener).decorate(driver);
1022+
1023+
((TakesScreenshot) decorated).getScreenshotAs(OutputType.BASE64);
1024+
1025+
assertThat(listener.acc.toString().trim())
1026+
.isEqualTo(
1027+
String.join(
1028+
"\n",
1029+
"beforeAnyCall getScreenshotAs",
1030+
"beforeAnyWebDriverCall getScreenshotAs",
1031+
"beforeGetScreenshotAs OutputType.BASE64",
1032+
"afterGetScreenshotAs OutputType.BASE64 " + result,
1033+
"afterAnyWebDriverCall getScreenshotAs",
1034+
"afterAnyCall getScreenshotAs"));
1035+
}
1036+
9761037
@Test
9771038
void shouldSuppressExceptionInBeforeAnyCall() {
9781039
WebDriver driver = mock(WebDriver.class);

0 commit comments

Comments
 (0)