简体   繁体   中英

Fail to take screenshots with Selenium WebDriver using Java when a JUnit test fails

I am using Java with Webdriver, and I am having problem with taking screenshots with failed test.

My jUnit test:

....
public class TestGoogleHomePage extends Browser {

....
@Test
public void testLoadGoogle() {
//this test will fail
}
}

My Browser class:

public class Browser {
protected static WebDriver driver;

public Browser() {
    driver = new FirefoxDriver();
}

.....
@Rule
public TestWatcher watchman = new TestWatcher() {

    @Override
    protected void failed(Throwable e, Description description) {
        File scrFile = ((TakesScreenshot) driver)
                .getScreenshotAs(OutputType.FILE);
        try {
            FileUtils.copyFile(scrFile, new File(
                    "C:\\screenshot.png"));
        } catch (IOException e1) {
            System.out.println("Fail to take screen shot");
        }
        // this won't work
        // driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);

    }

    @Override
    protected void succeeded(Description description) {
     ....
    }
};

@After
public void closeBrowser() {
    driver.quit();
}

}

The execution of the test will result in the following error message (part of the error message):

org.openqa.selenium.remote.SessionNotFoundException: The FirefoxDriver cannot be used after quit() was called.

Looks like it is complaining about my @After method.

I have tried to change the Browser class to be:

public class Browser {
protected static WebDriver driver;

public Browser() {
    driver = new FirefoxDriver();
}

.....
@Rule
public TestWatcher watchman = new TestWatcher() {

    @Override
    protected void failed(Throwable e, Description description) {
        File scrFile = ((TakesScreenshot) driver)
                .getScreenshotAs(OutputType.FILE);
        try {
            FileUtils.copyFile(scrFile, new File(
                    "C:\\screenshot.png"));
        } catch (IOException e1) {
            System.out.println("Fail to take screen shot");
        }
        driver.quit();
    }

    @Override
    protected void succeeded(Description description) {
     ....
     driver.quit();
    }
};

}

And the above codes work fine. But I don't want to quit the driver there because there might be something else I want to clean up after each test run, and I want to close the browser in the @After method.

Is there a way I can do that?

The problem is because of the following code:

@After
public void closeBrowser() {
    driver.quit();
}

The driver.quit() is attempting to close the browser after EVERY test; and it is getting executed before the call-back methods of your TestWatcher . This is preventing TestWatcher from getting a handle of the driver . Try using a more restrictive life-cycle annotation like @AfterClass or @AfterSuite .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM