Attaching Selenium screen shots to MSTest results

This is more for my own reference but has proved rather useful. The problem it solves for me is that when automated Selenium tests run and fail its usually quite a task to figure out what went wrong. The best way around this is to take a screen shot of the issue. However taking a screen shot can end up with a folder on a tester server full of images you have to look through to find your test result image. The best option is to attach a screen shot your test takes when it fails to the results of the currently running test.

Below is how to do this with MSTest running in VSTS. All of our Selenium tests run as part of a timed VSTS Release Hub release twice a day.

1 [TestMethod] 2 public void BurnUp_86_CheckIterationPathsLoad() 3 { 4 bool isLoaded = false; 5 6 try 7 { 8 _selenium.ShowSelectedData(); 9 10 _selenium.ClickIterationPath(); 11 isLoaded = _selenium.CheckIterationPathsLoad(); 12 } 13 catch (Exception) 14 { 15 16 var testFilePath = _selenium.ScreenGrab("BurnUp_86_CheckIterationPathsLoadERROR"); 17 18 AttachScreenShotFileToTestResult(testFilePath); 19 20 throw; 21 } 22 23 Assert.IsTrue(isLoaded); 24 } 25 26 public TestContext TestContext { get; set; } 27 28 public void AttachScreenShotFileToTestResult(string screenShotPath) 29 { 30 try 31 { 32 if (!string.IsNullOrEmpty(screenShotPath)) 33 { 34 TestContext.AddResultFile(screenShotPath); 35 } 36 } 37 catch (Exception) 38 { 39 40 //We don't want to stop the tests because we can't attach a file so we let it go....let it go.. let it go... 41 } 42 43 }

Lets take a moment to step through the test method above called BurnUp_86_CheckIterationPathsLoad(). The test is contained in a try catch. All of my selenium functionality I keep inside a separate class so it abstracted and encapsulated from the actual unit tests, this helps greatly with maintaining my test as I only need to focus on the Selenium classes if the page layout for example changes. As part of this class it has a base class where I keep functionality common to all tests such as the ScreenGrab function found inside _selenium (more on this later).

If my test fails my try catch will catch the exception this is where I will take a screen grab of the issue and then allow the original exception to bubble up. But after I have taken a screen grab I attach this to the the current running tests results using the AttachScreenShotFileToTestResult function. You can see inside this function, I don’t care if it fails to attach the screen shot to the test results, I’d rather the rests of the tests continue to run. (I can almost sense the shock from my fellow developers Smile). The key piece of functionality to take away here is TestContext.AddResultFile. This is given the path to where we saved our screen grab in the previous step.

So what about that screen grab functionality?

Selenium has had the ability to take screen shots for a while. Below is the function in my _selenium class that takes the screen shot using the current version of the IWebDriver.

1 public class SeleniumBase 2 { 3 protected IWebDriver driver; 4 5 public string ScreenGrab(string test) 6 { 7 string baseDirectory = "C:\\UITests"; 8 string screenGrabs = Path.Combine(baseDirectory, $"{DateTime.Now:yyyy-MM-dd}"); 9 10 if (!Directory.Exists(baseDirectory)) 11 { 12 Directory.CreateDirectory(baseDirectory); 13 } 14 15 if (!Directory.Exists(screenGrabs)) 16 { 17 Directory.CreateDirectory(screenGrabs); 18 } 19 20 21 //Create these folders if not present 22 string filename = Path.Combine(screenGrabs, $"{test}-{DateTime.Now:yyyy-MM-dd_hh-mm-ss-tt}.png"); 23 24 try 25 { 26 Screenshot ss = ((ITakesScreenshot)driver).GetScreenshot(); 27 ss.SaveAsFile(filename, System.Drawing.Imaging.ImageFormat.Png); 28 29 30 } 31 catch (Exception) 32 { 33 34 //We swallow the exception because we want the tests to coninue anyway. Taking a screen shot was just a nice to have. 35 return string.Empty; 36 } 37 38 39 return filename; 40 } 41 }

So what does the result look like?

Below are the results from one of our automatic test runs that are run for us by Visual Studio Team Services Release Hub. If I click on the test that has failed you can see in the results section an attachment has been added which is the screen grab we took when the test failed.


Got a better way of doing the above? Or would like to recommend some changes? Don’t be shy leave a comment, I’d love to hear from you Smile

Is LeanKit talking to TFS a good idea?

LeanKit if you haven’t heard of it is a popular Kanban board available as a service over the Internet. I’ve used it myself and seen it used on several client sites in the past. However the one question I seem to be hearing lately is “can’t we use LeanKit for our tasks and TFS for code?”.

Its a reasonable question, Team Foundation Server depending on what version you are using gives you quite a lot of functionality out of the box. You could argue that if you have TFS 2012 you wouldn’t need to use a separate KanBan board. However just because you have a KanBan board doesn’t necessarily mean you’re writing code and an organisation may have been set on LeanKit way before TFS was introduced.

So can we have both?
You certainly can, and one sleepy afternoon I decided to see if I could get the two to talk to each other. The initial  integration between the two was a lot easier than I thought it would be, anyone who is familiar with REST and the TFS API would find it a breeze! And yes it answered the question of could it be done but it also raised several more questions!

  • Why?
  • What about conflicts?
  • Does this add value?

Now the “why” is probably self explanatory from the paragraphs above. However conflicts and “Does this type of integration actually add value” weren’t that straight forward. My conundrum wasn’t getting them to work together but more what to do about someone changing something in TFS and another changing something in LeanKit?

My Solution
So I came up with the following scenario.

“If you are storing tasks and editing them in LeanKit in the first place you’re probably not that likely to want to edit them in TFS? However when you check in your code you will probably want to associate your check in with a task you have been working on.”

While I appreciate the above probably doesn’t apply to everyone, this is one way with the least amount of effort I came up with for integrating the two that could add value. There are several more that I will go into in more detail on later.

Firstly I created a program that polled LeanKit for updates (I would have preferred an event service but couldn’t find one in the LeanKit API). I’ve called my simple polling app “LeanKit Kanban Caller” it basically goes over the tasks in LeanKit and ensure they exist in TFS.


If a task doesn’t exist in TFS the program creates one otherwise it just updates any existing tasks if they are different.


The program knows which task to associate with LeanKit because I altered the default Product Backlog Item WIT from the Scrum 2.0 template in TFS 2012 to store the LeanKit ID (note this type of integration should also work with TFS 2010 on a different template).


For the purposes of my experiment I only mapped the title, description and size fields across but mapping others is easy. I didn’t bother with the State of the item in TFS, partly because the state in LeanKit can be changed so easily by adding more columns while in TFS its a question of editing the workflow on the WIT. While it is possible to map these to each other it would end up making your board inflexible and for the purposes of this scenario we’re not actually using that field.

I have assumed that in TFS everything is a PBI and child tasks are redundant for the purpose of this scenario.

Pros and Cons of my approach


  • The polling app can sit on any machine that has the Team Explorer client installed and has an Internet connection
  • You can associate code check-ins with tasks from your LeanKit board as they now exist in TFS
  • Using LeanKit is business as usual as no changes are made to your LeanKit board


  • Changing a task in TFS will not update the task in LeanKit
  • The states in TFS are not mapped to those in LeanKit
  • Analysis tools in TFS for the backlog have no use with this scenario.

How else could we have worked?
There are several other ways in which I could have made this solution work.

  • Treat TFS as the master and overwrite anything in LeanKit (no real value)
  • Allow updates to go both ways and make use of the datetime stamp to determine if TFS updates LeanKit or if LeanKit updates TFS (could lead to conflicts).
  • Make TFS and LeanKit responsible for different fields. This way both can update each other sound in the knowledge that no data will be overwritten.

Are there any other scenarios? If you have any suggestions I’d love to hear them.

TFS Events Subscriptions Viewer (and editor)

A while ago I had to do a bit of work with the TFS Subscription service. The annoying problem was I needed to find a particular subscription and the tools that came out of the box weren’t very helpful.  I also wanted to keep the original subscription details but just add to it. So I created this little app


This little app will enable you to

  • View TFS Event Subscriptions from a machine that has the TFS 2010 or TFS 2012 client installed
  • Create a new event subscription from an existing one.
  • Unsubscribe from an event


  • Type in your TFS URL in most cases this would be http://tfs:8080/tfs if you have several instances ensure you place the correct instance onto the URL the above will usually give you the default instance. If you have an instance called “test” the url would be http://tfs:8080/tfs/test .
  • Type in your TFS username and password and hit the “List Subscriptions” button.
  • Select the subscription you’d like to look at and this will be shown in more detail in the bottom right hand section of the app called “Selected Event”
  • You can now unsubscribe or create a new event from the event you just selected. Ensure you change the event first or you may get an error having duplicate events.

In the sample picture you can see I am using the app to make a change to the Scrum For Team System event service by adding more WITs to it.

Most of the credit for the example code for this app should go to Rene van Osnabrugge’s article found here all I have done is throw a GUI on the front and added a few more functions that enable me to copy events.

Before using this app I would like to point out the following (pretty standard stuff)

  • Use of this app is completely at your own risk I or my employer accept no responsibility what so ever for any unintended effects as a result of its usage. If you are worried I would recommend downloading the code and stepping through it.
  • The code is rough and ready (I created it in a hurry) and is provided as is, by all means please look at the code before running the executable.
  • Please let me know if it was at all helpful

Download the Code

Download the TFS 2010 Executable Only 

Download the TFS 2012 Executable Only