在 Java 中,检查 Selenium WebDriver 是不是已退出的最佳方法

Posted

技术标签:

【中文标题】在 Java 中,检查 Selenium WebDriver 是不是已退出的最佳方法【英文标题】:In Java, best way to check if Selenium WebDriver has quit在 Java 中,检查 Selenium WebDriver 是否已退出的最佳方法 【发布时间】:2013-09-08 06:32:05 【问题描述】:

我需要检查页面对象的集合,以查看每个页面对象是否已在其 WebDriver 上调用了 quit()。

我编写了以下方法来检查 WebDriver 的状态:

public static boolean hasQuit(WebDriver driver) 
        try 
            driver.getTitle();
            return false;
         catch (SessionNotFoundException e) 
            return true;
        

问题是:我不喜欢通过抛出和捕获异常来发现布尔值的真相,但似乎我别无选择,因为 WebDriver API 没有提供检查驱动程序是否退出的方法。

所以我的问题是,有没有更好的方法来检查 WebDriver 是否已退出?

我发现了一个类似(并且更一般)的问题 here,但该问题没有任何代码已尝试过,唯一的答案是始终将 WebDriver 设置为空退出(我不一定能控制)。

【问题讨论】:

您可以尝试查看firefox/chrome/IE进程是否正在运行。然后您可以决定浏览器是打开还是关闭。非常果断的决定。 @ran 在某些情况下,在退出后将驱动程序设置为 null 可能会起作用,但在很多情况下,您仍然可以拥有对驱动程序对象的其他引用,因此驱动程序不会被垃圾收集。所以大多数时候在退出后设置 null 并不是一个万无一失的解决方案。 【参考方案1】:

如果quit()被调用,driver.toString()返回null:

>>> FirefoxDriver: firefox on XP (null))

否则返回对象的哈希码:

>>> FirefoxDriver: firefox on XP (9f897f52-3a13-40d4-800b-7dec26a0c84d)

因此您可以在分配布尔值时检查 null:

boolean hasQuit = driver.toString().contains("(null)");

【讨论】:

-1:您不应该依赖toString() 进行编程行为。如果您费心研究这个函数,您会注意到null 来自sessionId,所以您真正需要的只是检查getSessionId() 是否返回null。然而,最终,Sajan's answer 更可靠,因为不能保证所有实现都会将 sessionId 设置为 null,但您可以保证会调用 stopClient() @Gili 你有一点关于检查getSessionId() == null是否有道理。但是,Sajan 的回答最终并不可靠,因为它仅在 WebDriver 的实例已按照他的建议进行子类化时才有效,并且不能保证 WebDriver 实际上会以这种方式进行子类化。 @TJamesBoone,没有什么能阻止您自己继承 WebDriver。我已经做到了,而且效果很好。 如果驱动程序可执行文件仍在运行但浏览器由于某些原因关闭,则此方法不起作用。在这种情况下,“driver.toString().contains("(null)")”部分返回 false,但如果我尝试通过驱动程序访问浏览器,它将引发异常。 “?真:假”部分也过多。你应该只写 "boolean hasQuit = driver.toString().contains("(null)");" @dnk.nitro:记录了过多的布尔赋值。我编辑了它。我相信 Pat Meeker 不会介意的。【参考方案2】:

根据您的具体情况,您基本上可以采用两种方法。

情况 1:扩展 WebDriver 不是一个现实的选择。

这是最常见的情况。 大多数在实际工作环境中使用 Selenium 的开发人员想要一种方便的方式来判断 WebDriver 是否已退出,他们正在一个已经建立的测试框架中工作,并尝试重构框架以确保只使用 WebDrivers 的自定义扩展可能比它的价值更麻烦。

在这种情况下,Sajan 的回答和 Gili 对他的回答的推荐将没有用,因为覆盖 RemoteWebDriver#stopClient() 不是一种选择。 (此外,即使是,大多数人都在寻找一个简单的答案。)

只要您只使用 Selenium 附带的 WebDriver 的标准实现(FirefoxDriver、ChromeDriver、InternetExplorerDriver、SafariDriver 等),您就可以将 WebDriver 转换为 RemoteWebDriver,然后检查 sessionId 是否为 null(Pat 是在正确的轨道上,但直接调用 sessionId 比使用 toString() 更好)。

public static boolean hasQuit(WebDriver driver) 
    return ((RemoteWebDriver)driver).getSessionId() == null;

这个答案应该适用于所有情况的 95%,因为您打算多久使用一次不实现 RemoteWebDriver 的 WebDriver? (不经常。)

情况 2:您可以实际扩展您的 WebDriver。

这种情况不太常见,但也许你是:     (a)  使用精心设计和抽象的框架,或     (b)  从头开始一个 selenium 测试框架。

在这种情况下,您可以创建自己的扩展 WebDriver 的接口:

public interface CustomDriver extends WebDriver 

    boolean hasQuit();


然后您可以像这样扩展标准 WebDriver(在本例中为 ChromeDriver):

public class CustomChromeDriver extends ChromeDriver implements CustomDriver 

    boolean hasQuit = false;

    @Override
    public boolean hasQuit() 
        return hasQuit;
    

    @Override
    public void stopClient() 
        super.stopClient();
        hasQuit = true;
    

【讨论】:

这是正确的做法,但是是否考虑了驱动程序崩溃的情况(例如BROWSER_TIMEOUT)?【参考方案3】:

StopClient 方法将在quit (RemoteWebDriver Source) 被调用后被调用,可能你可以继承RemoteWebDriver 的实例并覆盖stopClient 方法,设置一些标志并检查标志以确定如果 webdriver 已关闭 (quit)。

【讨论】:

总的来说我喜欢你的想法,但是:(1)我不一定能控制正在使用的 WebDriver 实例的实现; (2) 我可能想避免从驱动程序中调用我自己的方法,因为它没有在 WebDriver 接口中声明。但除此之外,这是一个巧妙的想法,并且显示出对 RemoteWebDriver 内部工作原理的良好了解,所以 +1。 不幸的是,我们必须像你之前展示的那样做一些事情,或者将 webdriver 设置为 null 并检查。

以上是关于在 Java 中,检查 Selenium WebDriver 是不是已退出的最佳方法的主要内容,如果未能解决你的问题,请参考以下文章

Selenium eclipse 配置与 Webdriver 2 和 Selenium Java 客户端驱动程序

如何让 Selenium firefox 驱动只截取浏览过的页面

如何在 selenium python 中按 Enter 键?

selenium 常用api

在 Java 中,检查 Selenium WebDriver 是不是已退出的最佳方法

Angular Material - 如何检查 selenium java 中是不是选中了复选框?