我正在浏览selenium中的截图代码。以下是代码:
File src = ((TakesScreenshot)driver).getScreenshotAs(OutputType.File);
在上面一行中,TakesScreenshot是一个界面,getScreenshotAs是一种方法。所以我从中理解的是,我们将驱动程序类型转换为TakesScreenshot接口,这实际上意味着我们的驱动程序将从现在起像TakesScreenshot,之后将执行getScreenshotAs方法。
我的问题是接口只能有抽象方法。那么,如何通过TakesScreenshot接口执行getScreenshotAs方法,因为它没有此方法的任何定义。更准确地说,getScreenshotAs方法定义在哪里以及上述代码行如何工作?
添加更多细节:
TakesScreenshot - >界面
驱动程序 - > ChromeDriver类的实例(WebDriver驱动程序=新的ChromeDriver())
getScreenshotAs - > TakesScreenshot界面中的方法。
以上代码用于截取selenium中的网页截图。
答案 0 :(得分:2)
方法getScreenshotAs
在RemoteWebDriver类中实现。您无法在driver
实例中使用它,因为您使用了WebDriver
接口(不扩展TakesScreenshot
接口)来创建driver
实例。
投放到(或首先使用)RemoteWebDriver
或ChromeDriver
也可以使用该方法。
File src = ((RemoteWebDriver)driver).getScreenshotAs(OutputType.File);
答案 1 :(得分:1)
首先让我分解您的解释代码:
File src = ((TakesScreenshot)driver).getScreenshotAs(OutputType.File);
分为以下两行:
TakesScreenshot ts = (TakesScreenshot) driver;
File source = ts.getScreenshotAs(OutputType.FILE);
根据文档, TakesScreenshot 是org.openqa.selenium
包中 Selenium 中的一个界面。 public interface TakesScreenshot
表示可以捕获屏幕截图并以下面提到的不同方式存储它的驱动程序。 public interface TakesScreenshot
已知子接口为 WebElement 。已知的实现类是:
在第一行中,我们将 TakesScreenshot 的实例初始化为ts
,并将 WebDriver 实例(即driver
)转换为该实例。< / p>
在第二行中,我们尝试捕获屏幕截图并将其存储在指定位置。对于 WebDriver 扩展TakesScreenshot
,这会根据浏览器(已投放)做出最大努力,以按优先顺序返回以下对象:
getScreenshotAs()
方法返回Object,其中包含有关屏幕截图的信息。失败java.lang.UnsupportedOperationException
,这意味着底层实现不支持屏幕截图捕获机制。
您可以找到详细信息文档here。
答案 2 :(得分:0)
嗯,据我所知,这实际上并不是特定于硒的问题,而是基本的Java问题。
您提供的表达方式的含义:
((TakesScreenshot) driver).getScreenshotAs(OutputType.File)
如下:无论driver
变量的类型是什么,在这一行中我们都确定它实现了具有TakesScreenshot
方法的getScreenshotAs
接口。因此,我们将类型转换为TakesScreenshot
并在getScreenshotAs
对象上调用driver
方法。这个方法的实现是在真正的driver
类中,无论它是什么。
给你一个非常接近问题代码的例子(我使这个方法接受Object
所以我们真的需要将o
转换为目标接口。不要这样做在实际代码中):
public void log(Object o) {
((Printable) o).print();
}
其中Printable
是方法print
的某个界面:
public interface Printable {
void print();
}
所以如果我们有一些Printable
的实现,比如
public class Greeting implements Printable {
@Override
public void print() {
System.out.println("Hello, username");
}
}
我们可以致电
log(new Greeting())
导致行“Hello,username”
编辑:
正如我在JavaDoc中看到的那样,WebDriver
接口不会扩展TakesScreenshot
接口。因此,如果driver
变量的类型是WebDriver
接口,则必须将其强制转换。 WebDriver driver = new ChromeDriver()
- 编译器只有WebDriver
类型的引用。尽管真正的类是ChromeDriver
编译器不知道它。因此,在这种情况下,为了调用getScreenshotAs
方法,您必须将driver
投射到TakesScreenshot
(并且它是安全的,因为driver
是ChromeDriver
的实例,它实现了两者WebDriver
和TakesScreenshot
接口)。只有在此之后,您才能从getScreenshotAs
界面调用TakesScreenshot
方法。
嗯,据我所知,这实际上并不是特定于硒的问题,而是基本的Java问题。
您提供的表达方式的含义:
((TakesScreenshot) driver).getScreenshotAs(OutputType.File)
如下:无论driver
变量的类型是什么,在这一行中我们都确定它实现了具有TakesScreenshot
方法的getScreenshotAs
接口。因此,我们将类型转换为TakesScreenshot
并在getScreenshotAs
对象上调用driver
方法。这个方法的实现是在真正的driver
类中,无论它是什么。
给你一个非常接近问题代码的例子(我使这个方法接受Object
所以我们真的需要将o
转换为目标接口。不要这样做在实际代码中):
public void log(Object o) {
((Printable) o).print();
}
其中Printable
是方法print
的某个界面:
public interface Printable {
void print();
}
所以如果我们有一些Printable
的实现,比如
public class Greeting implements Printable {
@Override
public void print() {
System.out.println("Hello, username");
}
}
我们可以致电
log(new Greeting())
导致行“Hello,username”
编辑:
正如我在JavaDoc中看到的那样,WebDriver
接口不会扩展TakesScreenshot
接口。因此,如果driver
变量的类型是WebDriver
接口,则必须将其强制转换。 WebDriver driver = new ChromeDriver()
- 编译器只有WebDriver
类型的引用。尽管真正的类是ChromeDriver
编译器不知道它。因此,在这种情况下,为了调用getScreenshotAs
方法,您必须将driver
投射到TakesScreenshot
(并且它是安全的,因为driver
是ChromeDriver
的实例,它实现了两者WebDriver
和TakesScreenshot
接口)。只有在此之后,您才能从getScreenshotAs
界面调用TakesScreenshot
方法。
WebDriver driver = new ChromeDriver();
// driver.getScreenshotAs(OutputType.File); // compilation error as there is no method getScreenshotAs in WebDriver interface
((TakesScreenshot) driver).getScreenshotAs(OutputType.File); // ok after explicit casting