I want to use @RegisterExtension in Junit5 to make screenshot on test failure. The driver quits after every test, and a new driver instance is created, but @RegisterExtension still uses the first driver instance, which is null. Is there a way to pass parameter, which changes with @RegisterExtension?
This is the test class:
import Test.OpenPageFactory;
import Test.TakeScreenshotOnFailure;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestInstance;
import org.junit.jupiter.api.extension.RegisterExtension;
import org.openqa.selenium.WebDriver;
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
public class Tests2 extends BaseTest {
WebDriver driver = initializeBrowser("chrome");
OpenPageFactory openPageFactory = new OpenPageFactory(driver);
@RegisterExtension
public TakeScreenshotOnFailure takeScreenshotOnFailure = new TakeScreenshotOnFailure(driver);
@BeforeEach
public void setUp() {
if (driver.toString().contains("null")) {
driver = initializeBrowser("chrome");
openPageFactory = new OpenPageFactory(driver);
}
}
@Test
public void verifyAllLinksWithNotLoggedInUser() throws InterruptedException {
openPageFactory.goToHomePage();
}
@Test
public void negativeTestSignInWithInvalidData() throws Exception {
openPageFactory.goToSignInPage();
}
And this is the class, which is passed with @RegisterExtension:
import Test.BaseTest;
import org.junit.jupiter.api.extension.ExtensionContext;
import org.junit.jupiter.api.extension.TestWatcher;
import org.openqa.selenium.WebDriver;
import ru.yandex.qatools.ashot.AShot;
import ru.yandex.qatools.ashot.Screenshot;
import javax.imageio.ImageIO;
import java.io.File;
import java.io.IOException;
public class TakeScreenshotOnFailure2 extends BaseTest implements TestWatcher {
public WebDriver driver;
public TakeScreenshotOnFailure2(WebDriver driver) {
this.driver = driver;
}
@Override
public void testFailed(ExtensionContext context, Throwable cause) {
String screenShotName = context.getDisplayName();
String screenShotPath = "\\screenshotPath.png";
Screenshot screenshot = new AShot()
.takeScreenshot(driver);
try {
ImageIO.write(screenshot.getImage(), "PNG", new File(screenShotPath));
} catch (IOException e) {
throw new RuntimeException(e);
} finally {
driver.quit();
}
}
@Override
public void testSuccessful(ExtensionContext context) {
driver.quit();
}
}
I cannot understand why TakeScreenshotOnFailure2 class doesn't use the new instance of driver parameter.
Your problem is @TestInstance(TestInstance.Lifecycle.PER_CLASS)
. Since all tests run on the same instance of your test class, the extension is only registered once.
If you go back to the standard PER_INSTANCE
lifecycle, the extension should be instantiated for each test and thus the driver
variable contain the appropriate web driver.