Skip to content

Instantly share code, notes, and snippets.

@lefthandedgoat
Last active September 4, 2019 13:20
Show Gist options
  • Save lefthandedgoat/9126142 to your computer and use it in GitHub Desktop.
Save lefthandedgoat/9126142 to your computer and use it in GitHub Desktop.
How to embed images for failed tests in Team City (using canopy)
//first read about how to do something similar here:
http://atombrenner.blogspot.com/2012/09/embed-url-links-in-teamcity-build-logs.html
//plugin location
http://confluence.jetbrains.com/display/TW/StaticUIExtensions
//download at:
http://teamcity.jetbrains.com/repository/download/TeamCityPluginsByJetBrains_StaticUiExtensionsAgainstTeamCity8/latest.lastSuccessful/static-ui-extensions.zip
//after downloading you can go to you team city administrator, go to plugins, and upload the one you just downloaded
//restart TC web server so that it registers the plugin, once you go back you should have 1 more
//configure the plugin
//found at C:\ProgramData\JetBrains\TeamCity\config\_static_ui_extensions
//edit static-ui-extensions.xml and remove existing rule and add below rule
---------------------------
<rule place-id="BUILD_RESULTS_FRAGMENT " html-file="show-image.html">
<url equals=""/>
<url starts="viewLog.html"/>
</rule>
//in C:\ProgramData\JetBrains\TeamCity\config\_static_ui_extensions
//add new file called show-image.html with below conents:
-------------
<script>
(function ($) {
var regex = /canopy-image\((.*)\)/g
function createImagesFromCanopyImages() {
$("div .fullStacktrace, div .msg").each(function () {
var div = $(this);
var oldHtml = div.html();
var newHtml = oldHtml.replace(regex, '<td><img alt="" src="data:image/jpeg;base64,$1" /></td>');
if (oldHtml !== newHtml) div.html(newHtml);
});
}
$(document).ready(createImagesFromCanopyImages);
$(document).click(function () {
window.setTimeout(createImagesFromCanopyImages, 50);
window.setTimeout(createImagesFromCanopyImages, 100);
window.setTimeout(createImagesFromCanopyImages, 500);
});
})(window.jQuery);
</script>
//then in your canopyExtensions (or wherever you put your helper methods)
// add this, you may need to add open reporters at the top and maybe open types
//this is an improved TC reporter I am working on
-----------------------
type TeamCityReporter() =
let consoleReporter : IReporter = new ConsoleReporter() :> IReporter
let tcFriendlyMessage (message : string) =
let message = message.Replace("|", "||")
let message = message.Replace("'", "|'")
let message = message.Replace(@"\n", "|n")
let message = message.Replace(@"\r", "|r")
let message = message.Replace(System.Environment.NewLine, "|r|n")
let message = message.Replace(@"\u", "|u")
let message = message.Replace("[", "|[")
let message = message.Replace("]", "|]")
message
interface IReporter with
member this.pass () = consoleReporter.pass ()
member this.fail ex id ss =
let mutable image = ""
if not (Array.isEmpty ss) then
image <- String.Format("canopy-image({0})", Convert.ToBase64String(ss))
consoleReporter.describe (String.Format("##teamcity[testFailed name='{0}' message='{1}' details='{3}']",
(tcFriendlyMessage id),
(tcFriendlyMessage ex.Message),
(tcFriendlyMessage ex.StackTrace),
(tcFriendlyMessage image)))
consoleReporter.fail ex id ss
member this.describe d =
consoleReporter.describe (String.Format("##teamcity[message text='{0}' status='NORMAL']", (tcFriendlyMessage d)))
consoleReporter.describe d
member this.contextStart c =
consoleReporter.describe (String.Format("##teamcity[testSuiteStarted name='{0}']", (tcFriendlyMessage c)))
consoleReporter.contextStart c
member this.contextEnd c =
consoleReporter.describe (String.Format("##teamcity[testSuiteFinished name='{0}']", (tcFriendlyMessage c)))
consoleReporter.contextEnd c
member this.summary minutes seconds passed failed = consoleReporter.summary minutes seconds passed failed
member this.write w = consoleReporter.write w
member this.suggestSelectors selector suggestions = consoleReporter.suggestSelectors selector suggestions
member this.testStart id = consoleReporter.describe (String.Format("##teamcity[testStarted name='{0}']", (tcFriendlyMessage id)))
member this.testEnd id = consoleReporter.describe (String.Format("##teamcity[testFinished name='{0}']", (tcFriendlyMessage id)))
member this.quit () = ()
member this.suiteBegin () = ()
member this.suiteEnd () = ()
member this.coverage url ss = ()
member this.todo () = ()
member this.skip () = ()
//in your program fs add this
//reporter <- new TeamCityReporter() :> IReporter
//you will have to make sure that you open reporter before your extensions file
//it works by base64 encoding the image, and putting it in canopy-image(alksdjflskjf)
//then the show-image.html is picked up by the static ui plugin, and it will find any canopy-image
//and put it in an img tag and render correctly!
//enough hacks for 10 developers!
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment