@@ -0,0 +1,2619 @@
+package nl.hsac.fitnesse.junit;%0A%0Aimport org.junit.runner.Description;%0Aimport org.junit.runner.Result;%0Aimport org.junit.runner.notification.Failure;%0Aimport org.junit.runner.notification.RunListener;%0A%0Aimport java.io.PrintStream;%0A%0A/**%0A * JUnit RunListener so that TeamCity is updated with progress info while tests run.%0A */%0Apublic class JUnitTeamcityReporter extends RunListener %7B%0A    private final PrintStream out;%0A    private String currentTestClassName = null;%0A%0A    public JUnitTeamcityReporter() %7B%0A        this(System.out);%0A    %7D%0A%0A    public JUnitTeamcityReporter(final PrintStream out) %7B%0A        this.out = out;%0A        this.currentTestClassName = null;%0A    %7D%0A%0A    @Override%0A    public void testStarted(Description description) %7B%0A        final String testClassName = getTestClassName(description);%0A        final String testName = getTestName(description);%0A%0A        if (currentTestClassName == null %7C%7C !currentTestClassName.equals(testClassName)) %7B%0A            testRunFinished(null);%0A            this.out.println(String.format(%22##teamcity%5BtestSuiteStarted name='%25s'%5D%22, testClassName));%0A            currentTestClassName = testClassName;%0A        %7D%0A%0A        out.println(String.format(%22##teamcity%5BtestStarted name='%25s' captureStandardOutput='true'%5D%22, testName));%0A    %7D%0A%0A    @Override%0A    public void testFinished(Description description) %7B%0A        final String testName = getTestName(description);%0A%0A        out.println(String.format(%22##teamcity%5BtestFinished name='%25s'%5D%22, testName));%0A    %7D%0A%0A    @Override%0A    public void testFailure(Failure failure) %7B%0A        if (failure.getTrace() != null && !failure.getTrace().isEmpty())%0A            out.print(failure.getTrace());%0A        out.println(String.format(%22##teamcity%5BtestFailed name='%25s' message='%25s' details='%25s'%5D%22,%0A                getTestName(failure.getDescription()),%0A                %22failed%22,%0A                %22%22));%0A        testFinished(failure.getDescription());%0A    %7D%0A%0A    @Override%0A    public void testIgnored(Description description) %7B%0A        out.println(String.format(%22##teamcity%5BtestIgnored name='%25s' message='%25s'%5D%22,%0A                getTestName(description),%0A                %22%22));%0A    %7D%0A%0A    @Override%0A    public void testRunFinished(Result result) %7B%0A        if (currentTestClassName != null) %7B%0A            out.println(String.format(%22##teamcity%5BtestSuiteFinished name='%25s'%5D%22, currentTestClassName));%0A        %7D%0A    %7D%0A%0A    protected String getTestClassName(final Description description) %7B%0A        return description.getTestClass().getName();%0A    %7D%0A%0A    protected String getTestName(final Description description) %7B%0A        return description.getMethodName();%0A    %7D%0A%7D

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.)