4

I am having some difficulty tweaking ExtentReports to provide the desired output.

I have a simple test framework with TestNG, using a TestBase class to do the heavy lifting to keep tests simple. I wish to implement ExtentReports in a simple fashion, using the TestNG ITestResult interface to report Pass, Fail and Unknown.

Here are example tests, 1 pass and 1 deliberate fail:

public class BBCTest extends TestBase{

@Test
public void bbcHomepagePass() throws MalformedURLException {

    assertThat(driver.getTitle(), (equalTo("BBC - Home")));
}

@Test
public void bbcHomePageFail() throws MalformedURLException {

    assertThat(driver.getTitle(), (equalTo("BBC - Fail")));
}

And here is the relevant section in TestBase: public class TestBase implements Config {

protected WebDriver driver = null;
private Logger APPLICATION_LOGS = LoggerFactory.getLogger(getClass());
private static ExtentReports extent;
private static ExtentTest test;
private static ITestContext context;
private static String webSessionId;

@BeforeSuite
@Parameters({"env", "browser"})
public void beforeSuite(String env, String browser) {
    String f = System.getProperty("user.dir") + "\\test-output\\FabrixExtentReport.html";
    ExtentHtmlReporter h = new ExtentHtmlReporter(f);
    extent = new ExtentReports();
    extent.attachReporter(h);
    extent.setSystemInfo("browser: ", browser);
    extent.setSystemInfo("env: ", env);
}

@BeforeClass
@Parameters({"env", "browser", "login", "mode"})
public void initialiseTests(String env, String browser, String login, String mode) throws MalformedURLException {
    EnvironmentConfiguration.populate(env);
    WebDriverConfigBean webDriverConfig = aWebDriverConfig()
            .withBrowser(browser)
            .withDeploymentEnvironment(env)
            .withSeleniumMode(mode);

    driver = WebDriverManager.openBrowser(webDriverConfig, getClass());
    String baseURL = EnvironmentConfiguration.getBaseURL();
    String loginURL = EnvironmentConfiguration.getLoginURL();
    APPLICATION_LOGS.debug("Will use baseURL " + baseURL);

    switch (login) {
        case "true":
            visit(baseURL + loginURL);
            break;
        default:
            visit(baseURL);
            break;
    }
    driver.manage().deleteAllCookies();
}

@BeforeMethod
public final void beforeTests(Method method) throws InterruptedException {
    test = extent.createTest(method.getName());
    try {
        waitForPageToLoad();
        webSessionId = getWebSessionId();
    } catch (NullPointerException e) {
        APPLICATION_LOGS.error("could not get SessionID");
    }
}


@AfterMethod
public void runAfterTest(ITestResult result) throws IOException {
    switch (result.getStatus()) {
        case ITestResult.FAILURE:
            test.fail(result.getThrowable());
            test.fail("Screenshot below: " + test.addScreenCaptureFromPath(takeScreenShot(result.getMethod().getMethodName())));
            test.fail("WebSessionId: " + webSessionId);
            break;
        case ITestResult.SKIP:
            test.skip(result.getThrowable());
            break;
        case ITestResult.SUCCESS:
            test.pass("Passed");
            break;
        default:
            break;
    }
}

private String takeScreenShot(String methodName) {
    String path = System.getProperty("user.dir") + "\\test-output\\" + methodName + ".jpg";
    try {
        File screenshotFile = ((TakesScreenshot) driver).getScreenshotAs(OutputType.FILE);
        FileUtils.copyFile(screenshotFile, new File(path));
    } catch (Exception e) {
        APPLICATION_LOGS.error("Could not write screenshot" + e);
    }
    return path;
}

@AfterClass
public void tearDown() {
    driver.quit();
}

@AfterSuite()
public void afterSuite() {
    extent.flush();
}

Here is the report:

enter image description here

The issues are:

  1. The name of the failed test is not recorded at left hand menu
  2. The screenshot is not displayed despite correctly being taken
  3. It is reporting both a Pass and Unexpected for the passed test
Craig
  • 7,471
  • 4
  • 29
  • 46
Steerpike
  • 1,712
  • 6
  • 38
  • 71
  • Since u are starting off would you mind using version 3 which is the latest one? I can help you setup.... Can u also share complete code with variables of ur base cls? – Karthik Oct 30 '16 at 13:13
  • Thanks @Karthik I've upgraded to 3.0.0. The 2 variables are simply Strings passed as TestNG parameters to tell which environment and browser are being called. Now I have provided full code – Steerpike Oct 30 '16 at 13:24

2 Answers2

1

You need several changes to make. Instantiate the ExtentReport & add configuration information in any of the configuration methods except BeforeClass.

@BeforeTest
@Parameters({"env", "browser"})
public void initialiseTests(String env, String browser, String emulatorMode, String mode) {
    EnvironmentConfiguration.populate(env);
    WebDriverConfigBean webDriverConfig = aWebDriverConfig()
            .withBrowser(browser)
            .withDeploymentEnvironment(env)
            .withSeleniumMode(mode);

    driver = WebDriverManager.openBrowser(webDriverConfig, getClass());
    APPLICATION_LOGS.debug("Will use baseURL " + EnvironmentConfiguration.getBaseURL());
    try {
        visit(EnvironmentConfiguration.getBaseURL());
    } catch (MalformedURLException e) {
        e.printStackTrace();
    }
    driver.manage().deleteAllCookies();
}

Initailize test = extent.startTest(testName); in the @BeforeMethod section.

@BeforeMethod
public void beforeM(Method m) {
        test = extent.startTest(m.getName());
}

And, you may call extent.endTest(test); in the @AfterTest method.

    @AfterTest
    public void afterTests() {
        extent.endTest(test);

        extent.close();
    }

}

And, to log your step info call test.log(LogStatus, "your info to show"); with appropirate status.

optimistic_creeper
  • 2,739
  • 3
  • 23
  • 37
1

Version 3.0

Most of code is provided by person created this library, i just modified to your needs.

public class TestBase {

    private static ExtentReports extent;
    private static ExtentTest test;

    @BeforeSuite
    public void runBeforeEverything() {
        String f = System.getProperty("user.dir")+ "/test-output/MyExtentReport.html";
        ExtentHtmlReporter h = new ExtentHtmlReporter(f);
        extent = new ExtentReports();
        extent.attachReporter(h);
    }

    @BeforeMethod
    public void runBeforeTest(Method method) {
        test = extent.createTest(method.getName());
    }

    @AfterMethod
    public void runAfterTest(ITestResult result) {
        switch (result.getStatus()) {
        case ITestResult.FAILURE:
            test.fail(result.getThrowable());
            test.fail("Screenshot below: " + test.addScreenCaptureFromPath(takeScreenShot(result.getMethod().getMethodName())));
            break;
        case ITestResult.SKIP:
            test.skip(result.getThrowable());
            break;
        case ITestResult.SUCCESS:
            test.pass("Passed");
            break;
        default:
            break;
        }
        extent.flush();
    }

    protected String takeScreenShot(String methodName) {
        String path = "./screenshots/" + methodName + ".png";
        try {
            File screenshotFile = ((TakesScreenshot)driver).getScreenshotAs(OutputType.FILE);
            FileUtils.copyFile(screenshotFile, new File(path));
        } catch (Exception e) {
            APPLICATION_LOGS.error("Could not write screenshot" + e);
        }
        return path;
    }
}
Karthik
  • 477
  • 7
  • 18
  • 1
    Thanks Karthik that's brilliant. I'm still getting a broken link for the image - I want the filepath to be root/test-output. is this wrong:- String path = System.getProperty("user.dir") + "/test-output/" + methodName + ".png"; – Steerpike Oct 30 '16 at 14:04
  • 1
    Can you use "test-output/" + methodName + ".png" – Karthik Oct 30 '16 at 14:57
  • would you be able to show me how to build the report so that: the Class name is a node and all the methods within the report are underneath the relevant class name? Also, how can I inject custom html so that i can pre-pend a hyperlink with a base url in the report? – Steerpike Nov 03 '16 at 11:03
  • The above code you can add before and after class. In that you can create a test which is the same name as class name. I will share example soon. – Karthik Nov 03 '16 at 11:16
  • Thanks Karthik - I have updated code as I have it now. Where I want to inject custom HTML is where I get the web session id from a cookie (webSessionId) - this is a uuid which I want to print in the report but I need to prepend the UUID with a URL so it forms a hyperlink in the report – Steerpike Nov 03 '16 at 11:23
  • started a new question ;) http://stackoverflow.com/questions/40420679/configuring-extentreports-to-inject-custom-html – Steerpike Nov 04 '16 at 12:27