package nl.hsac.fitnesse.junit;

import org.junit.runner.Description;
import org.junit.runner.Result;
import org.junit.runner.notification.Failure;
import org.junit.runner.notification.RunListener;

import java.io.PrintStream;

/**
 * JUnit RunListener so that TeamCity is updated with progress info while tests run.
 */
public class JUnitTeamcityReporter extends RunListener {
    private final PrintStream out;
    private String currentTestClassName = null;

    public JUnitTeamcityReporter() {
        this(System.out);
    }

    public JUnitTeamcityReporter(final PrintStream out) {
        this.out = out;
        this.currentTestClassName = null;
    }

    @Override
    public void testStarted(Description description) {
        final String testClassName = getTestClassName(description);
        final String testName = getTestName(description);

        if (currentTestClassName == null || !currentTestClassName.equals(testClassName)) {
            testRunFinished(null);
            this.out.println(String.format("##teamcity[testSuiteStarted name='%s']", testClassName));
            currentTestClassName = testClassName;
        }

        out.println(String.format("##teamcity[testStarted name='%s' captureStandardOutput='true']", testName));
    }

    @Override
    public void testFinished(Description description) {
        final String testName = getTestName(description);

        out.println(String.format("##teamcity[testFinished name='%s']", testName));
    }

    @Override
    public void testFailure(Failure failure) {
        if (failure.getTrace() != null && !failure.getTrace().isEmpty())
            out.print(failure.getTrace());
        out.println(String.format("##teamcity[testFailed name='%s' message='%s' details='%s']",
                getTestName(failure.getDescription()),
                "failed",
                ""));
        testFinished(failure.getDescription());
    }

    @Override
    public void testIgnored(Description description) {
        out.println(String.format("##teamcity[testIgnored name='%s' message='%s']",
                getTestName(description),
                ""));
    }

    @Override
    public void testRunFinished(Result result) {
        if (currentTestClassName != null) {
            out.println(String.format("##teamcity[testSuiteFinished name='%s']", currentTestClassName));
        }
    }

    protected String getTestClassName(final Description description) {
        return description.getTestClass().getName();
    }

    protected String getTestName(final Description description) {
        return description.getMethodName();
    }
}
Add RunListener to be used in combination with TeamCity so that start and end time of each page is recorded in the build log in a format that TeamCity can interpret. (Can be used as listener instead of JUnitXMLPerPageListener.)
Add RunListener to be used in combination with TeamCity so that start and end time of each page is recorded in the build log in a format that TeamCity can interpret. (Can be used as listener instead of JUnitXMLPerPageListener.)
