【问题标题】:Selenium screenshot listener captures the wrong browserSelenium 屏幕截图监听器捕获错误的浏览器
【发布时间】:2017-02-01 15:31:29
【问题描述】:

我有一个 selenium 项目,它通过 testng 运行并行测试。当测试失败时,我有一个捕获屏幕截图的侦听器类。类如下

public class ScreenshotOnFailure extends TestListenerAdapter {

@Override
public void onTestFailure(ITestResult tr) {
    WebDriver driver = SeleniumSetup.driverrunning;
    boolean hasQuit = driver.toString().contains("(null)");
    if(!hasQuit){
        System.out.println(driver);
        File scrFile = ((TakesScreenshot)driver).getScreenshotAs(OutputType.FILE);
        DateFormat dateFormat = new SimpleDateFormat("dd_MMM_yyyy__hh_mm_ssaa");
        Date date = new Date();
        String NewFileNamePath = null;
        File directory = new File(".");
        String methodName = tr.getMethod().getMethodName();
        try {
            NewFileNamePath =directory.getCanonicalPath() + "\\target\\surefire-reports\\html\\Screenshots\\"+methodName+"_"+ dateFormat.format(date) +"Listener.png";
        } catch (IOException e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        }


        try {
            FileUtils.copyFile(scrFile, new File(NewFileNamePath));
        } catch (IOException e) {
            e.printStackTrace();
        }
        String reportFilePath = ".\\Screenshots\\"+methodName+"_"+ dateFormat.format(date) +".png";
        System.setProperty("org.uncommons.reportng.escape-output", "false");    
        Reporter.log("<a href=" + reportFilePath + ">Click to open screenshot</a><img src=" + reportFilePath +  " height='350' width='700'>");      
    }
}}

在我的测试中,我有一个 AfterMethod 可以清理测试

    @AfterMethod(alwaysRun = true)
public void tearDown() throws Exception
{
    driver.quit();
}

如果测试是逐个运行的,那么会捕获正确的浏览器屏幕截图,但是如果我运行并行测试,则会捕获错误的测试浏览器。 我认为问题可能是以下之一

  • after方法已经退出浏览器(这是一个案例 有时这就是为什么我必须添加 hasQuit 布尔值)
  • 听者引用了错误的驱动程序对象。我相信这是问题所在,但我不确定如何确保它引用正确的驱动程序。

我有一个解决方法,它几乎涉及创建一个静态屏幕捕获对象,然后将其添加到 AfterMethod,但是这不太理想,因为我想使用一个侦听器。

【问题讨论】:

  • 你确定 selenium 关注的是正确的窗口吗?如果您打开一个新选项卡(例如),selenium 将继续使用旧选项卡,除非您明确切换到新选项卡。当您拉动驱动程序运行时,您可能正在拉动第一个或最后一个启动的驱动程序。
  • @Brydenr 是的,我相信它可能会拉动最后一个启动的驱动程序。我不知道如何让它拉出正确的驱动程序。有什么想法吗?
  • 切换标签,使用窗口句柄stackoverflow.com/questions/19112209/…

标签: java selenium selenium-webdriver testng


【解决方案1】:

从您的代码WebDriver driver = SeleniumSetup.driverrunning 看来,driverrunning 似乎是 SeleniumSetup 类中的静态驱动程序实例。因此,在并行执行中,它可能会引用错误的驱动程序对象。

ThreadLocal 可以帮助你创建一个线程安全的驱动对象,下面是一个例子。

public class DriverFactory
{

   private DriverFactory()
   {
      //Do-nothing..Do not allow to initialize this class from outside
   }
   private static DriverFactory instance = new DriverFactory();

   public static DriverFactory getInstance()
   {
      return instance;
   }

   ThreadLocal<WebDriver> driver = new ThreadLocal<WebDriver>() // thread local driver object for webdriver
   {
      @Override
      protected WebDriver initialValue()
      {
         return new FirefoxDriver(); // can be replaced with other browser drivers
      }
   };

   public WebDriver getDriver() // call this method to get the driver object and launch the browser
   {
      return driver.get();
   }

   public void removeDriver() // Quits the driver and closes the browser
   {
      driver.get().quit();
      driver.remove();
   }
}

使用DriverFactory获取驱动实例。

WebDriver driver = DriverFactory.getInstance().getDriver();

【讨论】:

  • 您必须在 testng 配置文件中将驱动程序名称作为参数传递,这可能会对您有所帮助。 stackoverflow.com/questions/26604745/…
  • 感谢您的建议。我实施了这门课,它很有魅力。我还添加了一个 setter 方法,以便可以根据浏览器类型等构建驱动程序。
猜你喜欢
  • 2018-06-20
  • 2021-11-09
  • 2013-05-27
  • 2015-06-14
  • 1970-01-01
  • 1970-01-01
  • 2011-10-13
  • 1970-01-01
  • 2016-12-11
相关资源
最近更新 更多