Skip to content

Commit 4555973

Browse files
committed
Make the RemoteWebDriver implement TakesScreenshot.
There's only one driver that doesn't implement the interface (the HtmUnitDriver) and this is the most common cause for using the Augmenter, which isn't very discoverable.
1 parent 7e259cf commit 4555973

File tree

2 files changed

+61
-27
lines changed

2 files changed

+61
-27
lines changed

java/client/src/org/openqa/selenium/remote/RemoteWebDriver.java

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,11 @@
3131
import org.openqa.selenium.Dimension;
3232
import org.openqa.selenium.HasCapabilities;
3333
import org.openqa.selenium.JavascriptExecutor;
34+
import org.openqa.selenium.OutputType;
3435
import org.openqa.selenium.Platform;
3536
import org.openqa.selenium.Point;
3637
import org.openqa.selenium.SearchContext;
38+
import org.openqa.selenium.TakesScreenshot;
3739
import org.openqa.selenium.UnsupportedCommandException;
3840
import org.openqa.selenium.WebDriver;
3941
import org.openqa.selenium.WebDriverException;
@@ -72,7 +74,7 @@
7274
public class RemoteWebDriver implements WebDriver, JavascriptExecutor,
7375
FindsById, FindsByClassName, FindsByLinkText, FindsByName,
7476
FindsByCssSelector, FindsByTagName, FindsByXPath,
75-
HasInputDevices, HasCapabilities {
77+
HasInputDevices, HasCapabilities, TakesScreenshot {
7678

7779
// TODO(dawagner): This static logger should be unified with the per-instance localLogs
7880
private static final Logger logger = Logger.getLogger(RemoteWebDriver.class.getName());
@@ -291,6 +293,23 @@ public String getCurrentUrl() {
291293
return execute(DriverCommand.GET_CURRENT_URL).getValue().toString();
292294
}
293295

296+
@Override
297+
public <X> X getScreenshotAs(OutputType<X> outputType) throws WebDriverException {
298+
Response response = execute(DriverCommand.SCREENSHOT);
299+
Object result = response.getValue();
300+
if (result instanceof String) {
301+
String base64EncodedPng = (String) result;
302+
return outputType.convertFromBase64Png(base64EncodedPng);
303+
} else if (result instanceof byte[]) {
304+
String base64EncodedPng = new String((byte[]) result);
305+
return outputType.convertFromBase64Png(base64EncodedPng);
306+
} else {
307+
throw new RuntimeException(String.format("Unexpected result for %s command: %s",
308+
DriverCommand.SCREENSHOT,
309+
result == null ? "null" : result.getClass().getName() + " instance"));
310+
}
311+
}
312+
294313
public List<WebElement> findElements(By by) {
295314
return by.findElements(this);
296315
}

java/client/test/org/openqa/selenium/remote/BaseAugmenterTest.java

Lines changed: 41 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -56,38 +56,31 @@ public void shouldReturnANormalWebDriverUntouched() {
5656
}
5757

5858
@Test
59-
public void shouldLeaveARemoteWebDriverWhichCannotTakeSnapshotsAlone() throws Exception {
59+
public void shouldAddInterfaceFromCapabilityIfNecessary() {
6060
DesiredCapabilities caps = new DesiredCapabilities();
61+
caps.setCapability("magic.numbers", true);
6162
WebDriver driver = new RemoteWebDriver(new StubExecutor(caps), caps);
6263

63-
WebDriver returned = getAugmenter().augment(driver);
64-
System.out.println("This is the returned webdriver " + returned);
65-
assertSame(driver, returned);
66-
assertFalse(returned instanceof TakesScreenshot);
67-
}
68-
69-
@Test
70-
public void shouldAddTheTakesSnapshotInterfaceIfNecessary() {
71-
DesiredCapabilities caps = new DesiredCapabilities();
72-
caps.setCapability(CapabilityType.TAKES_SCREENSHOT, true);
73-
WebDriver driver = new RemoteWebDriver(new StubExecutor(caps), caps);
74-
75-
WebDriver returned = getAugmenter().augment(driver);
64+
BaseAugmenter augmenter = getAugmenter();
65+
augmenter.addDriverAugmentation("magic.numbers", new AddsMagicNumberHolder());
66+
WebDriver returned = augmenter.augment(driver);
7667

7768
assertNotSame(driver, returned);
7869
assertTrue(returned instanceof TakesScreenshot);
7970
}
8071

8172
@Test
82-
public void shouldNotAddTheTakesSnapshotInterfaceWhenBooleanValueIsFalse() {
73+
public void shouldNotAddInterfaceWhenBooleanValueForItIsFalse() {
8374
DesiredCapabilities caps = new DesiredCapabilities();
84-
caps.setCapability(CapabilityType.TAKES_SCREENSHOT, false);
75+
caps.setCapability("magic.numbers", false);
8576
WebDriver driver = new RemoteWebDriver(new StubExecutor(caps), caps);
8677

87-
WebDriver returned = getAugmenter().augment(driver);
78+
BaseAugmenter augmenter = getAugmenter();
79+
augmenter.addDriverAugmentation("magic.numbers", new AddsMagicNumberHolder());
80+
WebDriver returned = augmenter.augment(driver);
8881

8982
assertSame(driver, returned);
90-
assertFalse(returned instanceof TakesScreenshot);
83+
assertFalse(returned instanceof MagicNumberHolder);
9184
}
9285

9386
@Test
@@ -121,12 +114,14 @@ public Object invoke(ExecuteMethod executeMethod, Object self, Method method,
121114
@Test
122115
public void shouldDelegateUnmatchedMethodCallsToDriverImplementation() {
123116
DesiredCapabilities caps = new DesiredCapabilities();
124-
caps.setCapability(CapabilityType.TAKES_SCREENSHOT, true);
117+
caps.setCapability("magic.numbers", true);
125118
StubExecutor stubExecutor = new StubExecutor(caps);
126119
stubExecutor.expect(DriverCommand.GET_TITLE, new HashMap<String, Object>(), "Title");
127120
WebDriver driver = new RemoteWebDriver(stubExecutor, caps);
128121

129-
WebDriver returned = getAugmenter().augment(driver);
122+
BaseAugmenter augmenter = getAugmenter();
123+
augmenter.addDriverAugmentation("magic.numbers", new AddsMagicNumberHolder());
124+
WebDriver returned = augmenter.augment(driver);
130125

131126
assertEquals("Title", returned.getTitle());
132127
}
@@ -135,12 +130,14 @@ public void shouldDelegateUnmatchedMethodCallsToDriverImplementation() {
135130
public void proxyShouldNotAppearInStackTraces() {
136131
final DesiredCapabilities caps = new DesiredCapabilities();
137132
// This will force the class to be enhanced
138-
caps.setCapability(CapabilityType.TAKES_SCREENSHOT, true);
133+
caps.setCapability("magic.numbers", true);
139134

140135
DetonatingDriver driver = new DetonatingDriver();
141136
driver.setCapabilities(caps);
142137

143-
WebDriver returned = getAugmenter().augment(driver);
138+
BaseAugmenter augmenter = getAugmenter();
139+
augmenter.addDriverAugmentation("magic.numbers", new AddsMagicNumberHolder());
140+
WebDriver returned = augmenter.augment(driver);
144141

145142
returned.findElement(By.id("ignored"));
146143
}
@@ -222,7 +219,7 @@ public void shouldNotChokeOnFinalFields() {
222219
public void shouldBeAbleToAugmentMultipleTimes() {
223220
DesiredCapabilities caps = new DesiredCapabilities();
224221
caps.setCapability("canRotate", true);
225-
caps.setCapability("reallyTakesScreenshot", true);
222+
caps.setCapability("magic.numbers", true);
226223

227224
StubExecutor stubExecutor = new StubExecutor(caps);
228225
stubExecutor.expect(DriverCommand.GET_SCREEN_ORIENTATION,
@@ -236,15 +233,15 @@ public void shouldBeAbleToAugmentMultipleTimes() {
236233
WebDriver augmented = augmenter.augment(driver);
237234
assertNotSame(augmented, driver);
238235
assertTrue(augmented instanceof Rotatable);
239-
assertFalse(augmented instanceof TakesScreenshot);
236+
assertFalse(augmented instanceof MagicNumberHolder);
240237

241238
augmenter = getAugmenter();
242-
augmenter.addDriverAugmentation("reallyTakesScreenshot", new AddTakesScreenshot());
239+
augmenter.addDriverAugmentation("magic.numbers", new AddsMagicNumberHolder());
243240

244241
WebDriver augmentedAgain = augmenter.augment(augmented);
245242
assertNotSame(augmentedAgain, augmented);
246243
assertTrue(augmentedAgain instanceof Rotatable);
247-
assertTrue(augmentedAgain instanceof TakesScreenshot);
244+
assertTrue(augmentedAgain instanceof MagicNumberHolder);
248245

249246
((Rotatable) augmentedAgain).getOrientation(); // Should not throw.
250247

@@ -355,4 +352,22 @@ public Capabilities getCapabilities() {
355352
}
356353

357354
public abstract BaseAugmenter getAugmenter();
355+
356+
private static class AddsMagicNumberHolder implements AugmenterProvider {
357+
@Override
358+
public Class<?> getDescribedInterface() {
359+
return MagicNumberHolder.class;
360+
}
361+
362+
@Override
363+
public InterfaceImplementation getImplementation(Object value) {
364+
return new InterfaceImplementation() {
365+
@Override
366+
public Object invoke(ExecuteMethod executeMethod, Object self, Method method,
367+
Object... args) {
368+
return null;
369+
}
370+
};
371+
}
372+
}
358373
}

0 commit comments

Comments
 (0)