Closed eymasar closed 5 years ago
From the looks of this much of code, it seems that your code is not thread-safe. This is something you need to handle in your code. Can you share the ReportFactory and WebDriver generation logic of your code?
ReportFactory: PS: I have used concurrent hashmap, collections.synchronizedMap and hashmap before.
package ExtentFactory;
import java.io.File;
import java.net.UnknownHostException;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import com.aventstack.extentreports.ExtentReports;
import com.aventstack.extentreports.ExtentTest;
import com.aventstack.extentreports.reporter.ExtentHtmlReporter;
import com.aventstack.extentreports.reporter.configuration.Theme;
import base.TestBase;
public class ReportFactory extends TestBase {
public static ExtentReports reporter;
public static String Path = null;
public static ExtentHtmlReporter htmlReporter;
protected static ThreadLocal<ExtentTest> test = new ThreadLocal<ExtentTest>();
public synchronized static ExtentReports getExtentReport() throws UnknownHostException {
if (reporter == null) {
Path = System.getProperty("user.dir") + "\\Reports" + "\\extentReportsWeb3";
File folder = new File(Path);
if (!folder.exists()) {
folder.mkdir();
}
Path = Path+"\\"+reportFolder;
new File(Path).mkdir();
Path = Path +"\\"+"Report_"+reportFolder+".html";
htmlReporter = new ExtentHtmlReporter(Path);
htmlReporter.config().setTheme(Theme.STANDARD);
reporter = new ExtentReports();
reporter.attachReporter(htmlReporter);
}
return reporter;
}
public synchronized static void getTest(String testName, String testCategory, String browser,String priority_, String coverage_)
throws UnknownHostException {
ExtentTest parent = getExtentReport().createTest(testName).assignCategory(testCategory.toUpperCase()).
assignCategory(browser.toUpperCase()).assignCategory(priority_.toUpperCase()).assignCategory(coverage_.toUpperCase());
test.set(parent);
}
public synchronized static ExtentTest getTest() {
return test.get();
}
public synchronized static void closeTest(ExtentTest test) throws UnknownHostException {
if (test != null) {
reporter.flush();
}
}
public synchronized static void removeTest(ExtentTest test) throws UnknownHostException {
if (test != null) {
reporter.removeTest(test);
}
}
public synchronized static void closeTest() throws UnknownHostException {
closeTest(test.get());
}
}
And BeforeMethod :
protected static ThreadLocal<RemoteWebDriver> dr = new ThreadLocal<>();
@BeforeMethod(alwaysRun = true)
@Parameters(value = { "browser", "testName", "testCategory", "Priority","Coverage" })
public synchronized void beforeMethod(String browser, String testName, String testCategory, String Priority,String Coverage)
throws InterruptedException, IOException {
try {
RemoteWebDriver driverDocker = null;
testNameFromXml.set(testName);
testSuiteName = testCategory;
browserName = browser;
priority = Priority;
coverage = Coverage;
isBrowserDead=false;
ReportFactory.getTest(testNameFromXml.get(), testSuiteName, browserName,priority,coverage);
logger.info("Log4j appender configuration is successful !!");
DesiredCapabilities capabilities = new DesiredCapabilities();
ChromeOptions chromeOptions = new ChromeOptions();
Map<String, Object> prefs = new HashMap<String, Object>();
if (runOption.equalsIgnoreCase("GRID")) {
switch (browser) {
case "firefox":
...
case "chrome":
...
case "ie":
...
case "opera":
...
case "yandex":
...
}
driverDocker = new RemoteWebDriver(new URL("....:4444/wd/hub"), capabilities);
driverDocker.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
setWebDriver(driverDocker);
getDriver().navigate().to(CONFIG.getProperty("baseUrl"));
String implicitlyWait = CONFIG.getProperty("default_implicitWait");
getDriver().manage().timeouts().implicitlyWait(Long.parseLong(implicitlyWait), TimeUnit.SECONDS);
getDriver().manage().timeouts().pageLoadTimeout(Long.parseLong(CONFIG.getProperty("default_pageLoadWait")),
TimeUnit.SECONDS);}
public synchronized static WebDriver getDriver() {
return dr.get();
}
public void setWebDriver(RemoteWebDriver driver) {
dr.set(driver);
}
@eymasar everything seems fine here. Code looks to be thread safe too. Is it possible to create a small project to reproduce this problem. It is hard for me to understand the issue with so much of code clutter. Most of the code is specific to your project.
Hi again, So I have figured it out where we having trouble. When I create a report, I create it at shared folder on another server, so the application hold all the data in cache (probably) and transfer them to that server at the same time, and this approach causes data loss over network or i/o problems. Right now I create screenshots with base64 feature and attach the report which is on local machine then I transfer whole report to another server. But my point is, why extentreport get confused everytime it has problems with screenshots? So the driver is not null, testReporter logs fail message then tries to attach screenshot, but fails at some point and couldn't do it and Catch messages logs in another test case.
if(driver!=null) {
testReporter.log(Status.FAIL,"I am at "+ testName+" ," +methodName);
imagePath=takeScreenShotOfFailure( driver,testReporter,testName) ;
}
else {
testReporter.log( Status.FAIL , "Driver return null !! ");
}
} catch ( Throwable e) {
try {
testReporter.log( Status.FAIL , "Got an error !! ");
testReporter.log( Status.FAIL , e.getMessage());
} catch (Throwable e1) {
System.out.println("GOT AN ERROR !!! ");
}
}
@eymasar : The problem that you have described is a classical symptoms of multithreading issues. Looking at your production code can give me only this much information because I am looking at code snippets only. For example testReporter.log, what exactly does it do inside. Similary I cant see the usage of imagePath. It will be really nice if I can get structured information and also if you can provide me with the version of Extentreports you are using.
This issue has been automatically marked as stale because it has not had recent activity. It will be closed in a week if no further activity occurs.
This issue has been automatically closed because of inactivity.
We have been using ExtentReport with Testng Listeners and Selenium grid with 45 sessions total. I create report on BeforeMethod for each test and log through page object system. Then onListeners, I remove tests onSkip and I take screenshot onfailure and attach to the report. On execution, I flush it. But even though I tried everything I could, like, flush every onFinish, or flush it afterMethod, Scaling screenshot to minimum, using hashmap or threadlocal in extent report setting. But couldn't find any solutions. It is still getting mixed when I take screenshot at onFailure method.
Using: Extent reports - 4.0.9 TestNG - 6.14.3 Selenium - 3.14.0