Issue
I am using spring framework with selenium and testNG, then I decided to integrate with allure reports, the reports are working fine.
My issue is with attaching screenshots on failure. The @Autowired driver is returning null when getScreenshotAs is called.
I'll post some code, if more is needed let me know.
@Component
public class ScreenshotUtil {
@Autowired
private WebDriver driver;
@Attachment(value = "Screenshot", type = "image/png")
public byte[] saveScreenshotOnFailure() {
return ((TakesScreenshot) driver).getScreenshotAs(OutputType.BYTES); //this is where im getting error
}
}
Then I have the listener class..
public class AllureListener implements ITestListener {
@Autowired
private ScreenshotUtil screenshotUtil;
@Override
public void onTestFailure(ITestResult result) {
screenshotUtil.saveScreenshotOnFailure();
}
}
I have my test classes with @Test all working fine.. I'll add the WebDriverConfig component aswell (dont know if that will be useful).
@Configuration
public class WebDriverConfig {
@Bean
@Scope("browserscope") //This is for parallel run
public WebDriver driver() {
if(System.getProperty("browser").equals("firefox") {
.. return firefox driver //let me know if this code might be necessary
} else {
.. return chrome driver //let me know if this code might be necessary
}
}
@Bean
public WebDriverWait webDriverWait(WebDriver driver) {
return new WebDriverWait(driver, timeout);
}
}
Thanks in advance, any help is appreciated..
Solution
I want to answer my own question, because after a lot of help and some research I was able to solve this issue.
What happens is, spring context is different from testNG context. When we implement ITestListener class, the TestNG context does not have access to spring context. This class is necessary for taking screenshots on test failure.
So the solution is (I took it from here: https://dzone.com/articles/autowiring-spring-beans-into-classes-not-managed-by-spring)
First create this service to retrieve the beans from spring:
@Service
public class BeanUtil implements ApplicationContextAware {
private static ApplicationContext context;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
context = applicationContext;
}
public static <T> T getBean(Class<T> beanClass) {
return context.getBean(beanClass);
}
}
Then on my AllureListener class I'll retrieve the ScreenshotUtil bean like this:
public class AllureListener implements ITestListener {
@Override
public void onTestFailure(ITestResult result) {
ScreenshotUtil screenshotUtil = BeanUtil.getBean(ScreenshotUtil.class);
screenshotUtil.saveScreenshotOnFailure();
}
}
Hopefully this will help someone in the future using spring framework, spring and allure report.
Answered By - kivul
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.