This Question is Answered

1 "correct" answer available (4 pts) 1 "helpful" answer available (2 pts)
4 Replies Last post: Oct 29, 2009 3:01 PM by Jim Chaney  
Jim Chaney Newbie 5 posts since
Oct 23, 2009
Currently Being Moderated

Oct 23, 2009 9:36 PM

Image Artifact viewing tab

One of the artifacts of our current build is a collection of .png images (the 'build' is actually running a complex unit test of some image manipulation functionality).  Although I am uploading the images as single artifacts, it is a laborious process to click each link in turn and briefly the images to see if it went 'wrong'.

 

I looked through the online docs and found two possible avenues:

 

http://www.jetbrains.net/confluence/display/TCD4/Including+Third-Party+Reports+in+the+Build+Results

Using this, I could generate an html page along with the images, zip them all up and add one entry to the main-config.xml.  How does this know what build configuration to attach to?

 

http://www.jetbrains.net/confluence/display/TCD4/Web+UI+Extensions

The 'full on' approach, creating an extension that creates the tab dynamically by examining the artifacts and creating the webpage on demand.  I'd love to have this (it would be pretty reusable by others) but I am not a web developer and wouldn't really know where to start.

 

Does anyone have an opinion on whether 1) will work, or even better, opt to write 2) for me and publish it to the JetBrains respoitory?

 

Thanks in advance,

Jim

stefan_b Newbie 13 posts since
May 27, 2009
Currently Being Moderated
Oct 24, 2009 1:43 PM in response to: Jim Chaney
Re: Image Artifact viewing tab

Hi Jim,

 

we use approach 1) which works quite well for us:

 

The tab-location is relative to the build's artifact dir.

We have something like

  <report-tab title="Acceptance Tests" basePath="test/acceptance/" />

in the main-config.xml and publish an index.html using

 

##teamcity[publishArtifacts 'tmp/acceptancetest/index.html => test/acceptance']

 

This index.html etc. are generated with a ruby script (running on the agent)

and all subtests html-pages and PNGs are pushed to the server via service message, like

 

##teamcity[publishArtifacts 'tmp/acceptancetest/subtest1.html => test/acceptance']

##teamcity[publishArtifacts 'tmp/acceptancetest/subtest1.png=> test/acceptance']

 

To have a direct link to the test html you could then try to write a plugin using

  http://javadoc.jetbrains.net/teamcity/openapi/current/jetbrains/buildServer/serverSide/FailedTestOutputFormatter.html

We currently hacked the jsp-page to include our test results, but this not really recommended. The code is below and

is simply added to teamcity/WEBAPPS/root/web-inf/tags/tests/testStacktracePart.tag. This is realy a quick hack we did

to migrate from our old system to TC. The java part reads the artifact html, and uses everything inside the body-tags.

The jsp-part simply displays the three standard png-images our regression-tests generate (gold image, generated image, diff image).

Works with 4.5.x version of TC.

 

Stefan

 

<!-- begin dart tweak -->
 
  <style type="text/css">
    table.dart_summary {
      visibility: collapse ;
    }
    table.dart {
    color : #ffffff;
    font-family: trebuchet ms, verdana, tahoma, arial, sans-serif;
    font-size:12px;
    border-collapse: collapse;
    padding: 4px;
    }
    .dart td.td-key { border: 1px solid #D6DCE4; padding: 2px; background: #E3E9EF; color: #0254D0;}
    .dart td.td-value { border: 1px solid #D6DCE4; padding: 2px; background: #FFFFFF; color: #000040;}
    .dart th.th-key { border: 1px solid #D6DCE4; padding: 2px; background: #E3E9EF; color: #0254D0;}
    .dart th.th-value { border: 1px solid #D6DCE4; padding: 2px; background: #FFFFFF; color: #000040;}
    .dart tr.ruled { background: #cccc00; }
  </style>

 

  <br/>
 
   <%
    java.lang.String testType = new java.lang.String();
   
    if (test.getPackage().endsWith("module"))
    {
        testType = "module";
    }
    if (test.getPackage().endsWith("acceptance"))
    {
        testType = "acceptance";
    }
   
    if (testType.length() > 0)
    {
        java.io.File myFile = new java.io.File(buildData.getArtifactsDirectory(),"test/" + testType + "/" + test.getPackage() + "/" + test.getShortName()
        + ".results.xml.test.html");
       
        try {
          java.io.BufferedReader input =  new java.io.BufferedReader(new java.io.FileReader(myFile));
         
          Boolean insideBody = false;
         
          try {
            String line = null;
            while (( line = input.readLine()) != null)
            {
             if (line.contains("</body>"))
             {
                insideBody = false;
             }
             if (insideBody)
             {
                out.println(line);
             }
             if (line.contains("<body>"))
             {
                insideBody = true;
             }
            }
          }
          finally {
            input.close();
          }
        }
        catch (java.io.IOException ex){
            out.println(ex.getMessage());
       }
   }
  %>
    
  <c:if test="${fn:endsWith(fn:toLowerCase(test.package),'acceptance')}">
  <br>
    <a href="repository/download/${buildType.buildTypeId}/${buildData.buildId}:id/test/acceptance/${test.package}/${test.shortName}.diff.png">
    <img title="Diff Image" width="25%" alt="" src="repository/download/${buildType.buildTypeId}/${buildData.buildId}:id/test/acceptance/${test.package}/${test.shortName}.diff.png"/>
    </a>
    <a href="repository/download/${buildType.buildTypeId}/${buildData.buildId}:id/test/acceptance/${test.package}/${test.shortName}.gold.png">
    <img title="Gold Image" width="25%" alt="" src="repository/download/${buildType.buildTypeId}/${buildData.buildId}:id/test/acceptance/${test.package}/${test.shortName}.gold.png"/>
    </a>
    <a href="repository/download/${buildType.buildTypeId}/${buildData.buildId}:id/test/acceptance/${test.package}/${test.shortName}.image.png">
    <img title="Generated Image" width="25%" alt="" src="repository/download/${buildType.buildTypeId}/${buildData.buildId}:id/test/acceptance/${test.package}/${test.shortName}.image.png"/>
    </a>
    <br>
  </c:if>
  <c:if test="${fn:endsWith(fn:toLowerCase(test.package),'module')}">
  <br>
    <a href="repository/download/${buildType.buildTypeId}/${buildData.buildId}:id/test/module/${test.package}/${test.shortName}.diff.png">
    <img title="Diff Image" width="25%" alt="" src="repository/download/${buildType.buildTypeId}/${buildData.buildId}:id/test/module/${test.package}/${test.shortName}.diff.png"/>
    </a>
    <a href="repository/download/${buildType.buildTypeId}/${buildData.buildId}:id/test/module/${test.package}/${test.shortName}.gold.png">
    <img title="Gold Image" width="25%" alt="" src="repository/download/${buildType.buildTypeId}/${buildData.buildId}:id/test/module/${test.package}/${test.shortName}.gold.png"/>
    </a>
    <a href="repository/download/${buildType.buildTypeId}/${buildData.buildId}:id/test/module/${test.package}/${test.shortName}.image.png">
    <img title="Generated Image" width="25%" alt="" src="repository/download/${buildType.buildTypeId}/${buildData.buildId}:id/test/module/${test.package}/${test.shortName}.image.png"/>
    </a>
    <br>
  </c:if>
 
  <!-- end  dart tweak -->

Yegor Yarko JetBrains 1,429 posts since
May 5, 2004
Currently Being Moderated
Oct 26, 2009 3:43 PM in response to: Jim Chaney
Re: Image Artifact viewing tab

Jim,

 

Feel free to post a feature request into our tracker. We can then see how many people find this useful by the number of votes and comments.

 

I am not sure, however, that displaying images as thumbnails in artifacts list is a good approach... For any non-tiny images thumbnail will still needs clicking to see it's content and mixing thumbnails and usual files does not seem usable.

 

It seems that generating a HTML and displaying it as a report tab is an appropriate approach. For this approach I would consider packing the images into archive.

 

> How does this know what build configuration to attach to?

 

The report tab is displayed for every build that has an artifact that matches basePath in artifact tab definition.

More Like This

  • Retrieving data ...