如何关闭由Selenium打开的所有空闲Web浏览器?

时间:2019-01-31 16:24:51

标签: java selenium selenium-webdriver selenium-chromedriver google-chrome-headless

我正在使用“ selenium-java.jar”文件打开chrome无头驱动程序。 现在,我们正在使用线程打开无头铬。现在,如果发生任何错误,然后线程在不关闭浏览器的情况下退出,将会发生什么情况。

因此,我想实施一个解决方案,如果最近20分钟内没有任何无头镀铬是理想的,则关闭/退出它。

我在Google上进行了搜索,发现可能存在像https://github.com/seleniumhq/selenium/issues/1106这样的硒服务器独立解决方案

我的问题是我现在无法切换到独立服务器,因此我必须找出当前库的解决方案。

那么有什么方法可以关闭所有过去20分钟空闲的无头chrome浏览器吗?

请指导。

3 个答案:

答案 0 :(得分:1)

我将selenium-java.jar与TestNg一起使用,虽然我没有运行无头浏览器,但是我在TestNg之后的方法中进行了测试,但我确实进行了清理,这与您等待20分钟的时间并不完全相同,但是可能帮助。

在Windows操作系统上运行测试时,我检查以查看进程是否按名称运行并终止它:

public final class OsUtils
{
    private static final String TASKLIST = "tasklist";
    private static final String KILL = "taskkill /F /IM ";
    public static final String  IE_EXE = "iexplore.exe";
    public static final String  CHROME_EXE = "chrome.exe";
    public static final String  EDGE_EXE = "MicrosoftEdge.exe";
    public static final String  FIREFOX_EXE = "firefox.exe";


public static boolean isProcessRunning(String processName)
{
    Process process;
    try
    {
        process = Runtime.getRuntime().exec(TASKLIST);
    }
    catch (IOException ex)
    {
        Logger.error("Error on get runtime" + ex.getMessage());
        return false;
    }

    String line;
    try ( BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream())); )
    {
        while ((line = reader.readLine()) != null) {
            if (line.contains(processName)) {
                Logger.log("Process found");
                return true;
            }
        }
    }
    catch (IOException ex)
    {
        Logger.error("Error on check for process " + processName + ": " + ex.getMessage());
    }
    return false;
}

public static void killProcessIfRunning(String processName)
{
    Logger.log("Trying to kill process: " + processName);
    try
    {
        if (isProcessRunning(processName))
        {
            Runtime.getRuntime().exec(KILL + processName);
        }
    }
    catch (IOException ex)
    {
        Logger.error("Error on kill process " + processName+ ": " +  ex.getMessage());
    }
}
...
}

在Macmini上运行Safari时,我有一个类似的kill命令(它既适用于Safari,也适用于技术预览):

public static void killSafariProcess()
{
    Logger.log("Trying to kill Safari processes if running.");

    try
    {
        Process p = Runtime.getRuntime().exec(new String[]{"bash","-c","ps ux | grep -i app/Contents/MacOs/Safari | grep -v grep | awk '{print $2}' | xargs kill -9"});
    }
    catch (IOException ex)
    {
        Logger.error("Error on kill Safari processes: " +  ex.getMessage());
    }
}

自定义Logger类仅使用System.out.println(message)

答案 1 :(得分:0)

您可以将ChromeDriver子类化,并使用计时器实现自己的代理类,以在20分钟的空闲时间后退出:

public class TimedChromeDriver extends ChromeDriver {

  Timer timeOut;

  private void initTimer() {
    timeOut = new Timer();
  }

  private void startTimer() {
    timeOut.cancel();
    timeOut.schedule(
        new TimerTask() {
          @Override
          public void run() {
            quit();
          }
        },
        20 * 60 * 1000);
  }

  public TimedChromeDriver() {
    initTimer();
  }

  @Override
  public void get(String url) {
    super.get(url);
    startTimer();
  }

  // override every method of WebDriver and ChromeDriver in the same way
}

这仅在触发计时器之前未终止Java VM的情况下有效。垃圾收集器也可能会干扰。不建议覆盖finalize方法。

我将对您的线程进行一些分析工作,使其异常退出。这样可以从源头上解决您的问题。

答案 2 :(得分:-1)

您可能可以根据驱动程序条件对不同过程的开始时间进行一些分析。我认为它不会告诉您它空闲了多长时间,但是您可以假设它已经运行了20分钟(假设您的测试应该在几分钟之内成功完成),那么它可能已经孤立了。

我发现this answer展示了如何使用Java获取进程列表并查看其开始时间。从那里应该可以找到所有旧的驱动程序并将其杀死。

一种替代方法是使用Powershell来获取进程,启动时间并进行处理。这仅取决于您要查找的内容。 Here's an answer让您开始走这条路。