I had to setup up client side tests to run for my team on Teamcity. I initially thought I should use rake to do this, but then I had to leverage the fact that my team is comfortable with the .Net stack and not so much with Ruby. At this point I just thought i should use a unit test to run my screw unit test via Watin in a browser. This idea is available in a lot of other blogs for QUnit tests. The unit test opens the suite.html , parses the file and reports if the test failed or passed.This works fine. But then when a test failed I had to either look at the logs of the build or had to navigate to the Url, this feedback was ok but not great
I tried to write a teamcity test runner for screw unit which will send messages to TeamCity , but this was hard work and the effort involved was simply too much
If not real time feedback from a test runner, at least seeing the suite.html as a tab on my build would be good.. so I just pushed the artifacts for the build to include the Screw Unit test pack and set up a new tab in TeamCity server config file (main.config file) called Screw Unit Report. This tab would open the html file for the tests from the artifacts. So now I have TeamCity showing the Screw Unit suite as a tab, that's better, the only thing is when you click on the tab it runs the tests every time, but that's not such a big deal really  . The effort involved in setting this up was 30 minutes. (I already knew how to setup tabs in TeamCity )
. The effort involved in setting this up was 30 minutes. (I already knew how to setup tabs in TeamCity )
So to summarize
1. Write a unit test runner which will use Watin to open the Screw Unit test suite.html file.
1: using System;
2: using System.Collections.Generic;
3: using System.Diagnostics;
4: using System.IO;
5: using System.Linq;
6: using System.Threading;
7: using MbUnit.Framework;
8: using NHamcrest.Core;
9: using WatiN.Core;
  10:  11: namespace Tests
  12: {  13:     [TestFixture]  14:     [Timeout(600)]15: public class TestRunner
  16:     {17: private FireFox browser;
  18:    19:         [SetUp]20: public void SetupBrowser()
  21:         {22: browser = new FireFox();
  23:         }24: /// <summary>
25: /// Tests that ScrewUnit tests pass
26: /// </summary>
  27:         [Test]28: [Category("ScrewUnitTests")]
29: public void RunAllTestsFromSuite()
  30:         {31: var screwUnitTestFile = Path.Combine(Environment.CurrentDirectory, @"Javascript\ScrewUnit\tests\spec\suite.html");
32: browser.GoTo(@"file:///" + screwUnitTestFile);
  33:             browser.WaitForComplete(5000);  34:  35: var resultsDiv = browser.ElementWithTag("h3", Find.ByClass("status"));
36: resultsDiv.WaitUntil(() => resultsDiv.Exists && !resultsDiv.Text.ToLower().Contains("Running"), 30000);
  37:    38:             AssertThatTestsHavePassed(resultsDiv);  39:         }  40:  41: private static void AssertThatTestsHavePassed(Element resultsDiv)
  42:         {43: var resultsArray = resultsDiv.Text.Split(new[] { ' ' });
  44:    45:             var numberOfFailures = Int32.Parse(resultsArray.ElementAt(2));  46:  47: Assert.That(numberOfFailures, Is.EqualTo(0), string.Format("{0}. Click on the Screw Unit Report Tab to see the details", resultsDiv.Text));
  48:         }  49:    50:         [TearDown]51: public void TearDownTestRunner()
  52:         {  53:             browser.Dispose();  54:             Thread.Sleep(2000);  55:             var browserProcesses = Process.GetProcesses()56: .Where(process => process.ProcessName.ToLower().Contains("firefox") && process.StartInfo.UserName.ToLower().Contains("build"));
  57:                     browserProcesses.Each(p => p.Kill());  58:         }  59:          60:    61:     }62: public static class Extensions
  63:     {64: public static void Each<T>(this IEnumerable<T> collection, Action<T> action)
  65:         {66: foreach (var item in collection)
  67:             {  68:                 action(item);  69:             }  70:         }  71:       72: public static void WaitUntil(this Element element, Func<bool> predicate, int timeout)
  73:         {  74:             var startTime = DateTime.Now;  75:  76: while (!predicate())
  77:             {  78:                 Thread.Sleep(1000);  79:                 var now = DateTime.Now;  80:  81: if ((now - startTime).TotalMilliseconds > timeout) throw new TimeoutException("Timed out waiting for condition to become true");
  82:             }  83:         }  84:     }  85: }2. Push the Screw Unit test suite into the artifacts of your build in the team city configuration of your build
3. Configure the main.config file located at <TeamCity Install Folder>\.BuildServer\configuration\confg to create a new tab.
Run your build and you should be able to see the screwunit report on the build server now
   1: <server>   2:  3: <report-tab title="Screw Unit Report" basePath="ScrewUnit.zip" startPage="tests/spec/suite.html" />
   4:     5: </server>   6:  You could use the screwunit test sample i took from git hub to test this Screw Unit Tests sample
 
