Sometimes you need to do special stuff when a work item, build, etc changes in your Team Foundation Server. The best option that you have is to create a server event handler. To do that you need to follow this steps:

1.- Create a new Class Library project

[caption id="attachment_92" align="alignnone" width="955"]Create Class Library Create Class Library[/caption]

2.- Add reference to those libraries

[caption id="attachment_93" align="alignnone" width="447"]libraries libraries[/caption]

You could add the first three ones from Assemblies -> Extensions in the add reference window:

[caption id="attachment_94" align="alignnone" width="790"]add reference add reference[/caption]

You have to add the other two libraries from C:\Program Files\Microsoft Team Foundation Server 11.0\Application Tier\Web Services\bin

3.- Create a class that implements the ISubscriber interface

public class WorkItemChangedEventHandler : ISubscriber

4.- Implement the interface. To do that you have to implement the SubscribedTypes method:

public Type[] SubscribedTypes()
{
    return new Type[1] { typeof(WorkItemChangedEvent) };
}

The name property

public string Name
{
    get { return "WorkItemChangedEventHandler"; }
}

The priority property

public SubscriberPriority Priority
{
    get { return SubscriberPriority.Normal; }
}

And the ProcessEvent method

public EventNotificationStatus ProcessEvent(TeamFoundationRequestContext requestContext, NotificationType notificationType,
                                                    object notificationEventArgs, out int statusCode, out string statusMessage,
                                                    out ExceptionPropertyCollection properties)
{
    statusCode = 0;
    properties = null;
    statusMessage = String.Empty;
    try
    {
        if (notificationType == NotificationType.Notification && notificationEventArgs is WorkItemChangedEvent)
        {
            var ev = notificationEventArgs as WorkItemChangedEvent;
            // Do what you want
        }
    }
    catch (Exception exception)
    {
        TeamFoundationApplicationCore.LogException("Error processing event", exception);
    }
    return EventNotificationStatus.ActionPermitted;
}

In this example we are only subscribing to WorkItemChangedEvent. But you can subscribe to another events. To do that, just add more event types in SubscribedTypes method. You could find a list of available events here.

Can I debug the library?

Yes you can, and it's easy. First of all, change the output path in the project settings window and put C:\Program Files\Microsoft Team Foundation Server 11.0\Application Tier\Web Services\bin\Plugins\.

[caption id="attachment_95" align="alignnone" width="809"]project properties project properties[/caption]

And after that, attach your Visual Studio 2012 to the w3wp.exe process.

Conclusion

In this article we have seen how to develop a Team Foundation Server event handler and how to debug it. A very usefull technique in some scenarios.

See you soon!

In the previous tutorials ( 1 and 2 ) we have seen how to install CasperJS and make our first script. Today we are going to start writing tests with the API that CasperJS provide and doing some navigation between pages. To do that we will add a new model in our website:

public class InformationRequest
{
    public int InformationRequestId { get; set; }
    public string Name { get; set; }
    public string Surname { get; set; }
    public string Email { get; set; }
    public string Request { get; set; }
}

Now, using the capabilities of Visual Studio 2012 and ASP.NET MVC, we could make a new controller and views easily to create a form to request information. Add a new controller using the template which uses Entity Framework.

[caption id="attachment_73" align="alignnone" width="604"]add new controller add new controller[/caption]

Don't worry about the Data Context, we will not use it. Now we have a skeleton of controller methods and views to submit the form. Remove any reference to Entity Framework and the edit, delete, and list methods and views. Your project must look like the one in this screenshot

[caption id="attachment_75" align="alignnone" width="566"]solution explorer solution explorer[/caption]

The controller must have this code

public class InformationRequestController : Controller
{
    public ActionResult Index()
    {
        return RedirectToAction("Create");
    }

    public ActionResult Create()
    {
        return View();
    }

    [HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult Create(InformationRequest informationrequest)
    {
        return View("Thanks", informationrequest);
    }
}

And the Thanks.cshtml view is a very simple view with this markup

@model TestCasperJS.Models.InformationRequest

@{
    ViewBag.Title = "Thanks";
}

<h2>Thanks</h2>

Thanks @Model.Name @Model.Surname for contacting us. We will contact you as soon as possible.

<br/>

@Html.ActionLink("Return to index", "Index", "Home", null, new {id="returnToHomeLink"})

Finally, let's add the new option to main menu

<li>@Html.ActionLink("Information", "Index", "InformationRequest", null, new {id="informationRequestMenuLink"})</li>

Ok, now we can start writing our tests. Lets start with a simple assert. Go to the javascript file where your are writing the tests and put the following code

var url = 'http://localhost:8000/';
casper.start(url, function() {
    this.test.assert(this.getCurrentUrl() === url, 'url is the one expected');
});

casper.run(function () {
    this.test.done();
    this.echo("Done.").exit();
});

If you execute the file as usual

casperjs testCasperjs.js

The output should be

[caption id="attachment_80" align="alignnone" width="677"]test1 test 1[/caption]

Great! We have our first test passing.

Now, we will do the same same assertion than in the previous article, but using the test API.

casper.then(function() {
    this.test.assertResourceExists('error.js', 'error.js script was loaded');
});

And the output should be

[caption id="attachment_82" align="alignnone" width="677"]test 2 test 2[/caption]

Let's continue with our first interaction. We will click a link in the main menu and assert that we have navigated to the correct page.

casper.then(function() {
    this.click('#informationRequestMenuLink');
});

casper.then(function() {
    this.test.assertTitle('Information request', 'the page has the correct title');
});

The output should be:

[caption id="attachment_83" align="alignnone" width="677"]test 3 test 3[/caption]

Now we will fill a form, submit it and check that we are in the correct page.

casper.then(function() {
    this.fill('form', {
        'Name': 'John',
        'Surname': 'Smith',
        'Email': 'jsmith@example.com',
        'Request': 'Example request'
    }, true);
});

casper.then(function() {
    this.test.assertTextExists('Thanks John Smith', 'page body contains "John Smith"');
});

With the last parameter of the fill function we are telling CasperJs that we want to submit the form.

The ouput should be

[caption id="attachment_84" align="alignnone" width="677"]test 4 test 4[/caption]

That's great!

Finally we will return to the main page and assert than a particular selector exists to ensure that we are in the main page.

casper.then(function () {
    this.click('#returnToHomeLink');
});

casper.then(function() {
    this.test.assertSelectorExists('ol[class=round]', 'there is an ol with round class');
});

And the output should be.

[caption id="attachment_85" align="alignnone" width="677"]test 5 test 5[/caption]

We have seen how to use the test API from CasperJS and how to make a basic but useful interaction. I recommend you to take a look at the great documentation that CasperJS has. It's really good and has lots of information.

In the next tutorial we will see how to integrate this tests results into a Team Foundation Server build.

See you soon!

In our last post we have seen how to install CasperJS and how to make a very simple script. In this post we will make more interesting stuff.

In this tutorial we will see how to catch any error in our web page, whether it be the lack of an image or script or an error in javascript code.

So, lets start forcing these errors. Go to your _layout.cshtml page (or other page if you are not using ASP.NET MVC) and add this line to try to load a non existing script.

<script type="text/javascript" src="js/fake.js"></script>

In the same page, find where the logo link is created

<p class="site-title">@Html.ActionLink("your logo here", "Index", "Home")</p>

and change it for a non existing image, like this:

<a href="http://localhost:8000">
    <img src="~/Content/Images/logo.png"></img>
</a>

Now, go to the site.css file, and add this line to .body

background: url("../Images/noExists.png") no-repeat;

And finally, create a script in Scripts folder with this content and name it error.js

function throwError() {
    throw new Error();
}

throwError();

And add it at the end of your _layout.cshtml page

<script src="~/Scripts/error.js"></script>

If we load the page and take a look at the network tab of the developer tools we could see the errors on resource loading.

[caption id="attachment_51" align="alignnone" width="1239"]error loading resourcees error loading resourcees[/caption]

And taking a look at the errors tab, we could see more errors

[caption id="attachment_52" align="alignnone" width="669"]error loading resources error loading resources[/caption]

So, let's try to catch these errors.

Put this code between the casper.start call and the casper.run call.

casper.start('http://localhost:8000/', function () {
    if (this.resourceExists('fake.js')) {
        this.echo('fake.js is downloaded');
    } else {
        this.echo('fake.js is not downloaded');
    }

    if (this.resourceExists('error.js')) {
        this.echo('error.js is downloaded');
    } else {
        this.echo('error.js is not downloaded');
    }
});

With this code we are asking CasperJS whether fake.js and error.js are downloaded. As a result we should have this output:

[caption id="attachment_56" align="alignnone" width="675"]result result[/caption]

That's great! Error.js exists in our project but fake.js don't. So the result is the expected.

Could we do the same with the images? Yes, of course. Replace the previous code with this one:

casper.start('http://localhost:8000/', function () {
    if (this.resourceExists('logo.png')) {
        this.echo('logo.js is downloaded');
    } else {
        this.echo('logo.js is not downloaded');
    }
});

And we should have this output:

[caption id="attachment_57" align="alignnone" width="676"]result result[/caption]

Ok, that's great but it's not reasonable to have all the resources in our web hardcoded in the script. Let's try to generalize a little bit more. Let's start with the scripts:

var scriptsArray = [];

function getScripts() {
    var scripts = document.querySelectorAll('script[src]');
    return Array.prototype.map.call(scripts, function(e) {
        return e.getAttribute('src');
    });
};

casper.start('http://localhost:8000/', function () {
    scriptsArray = this.evaluate(getScripts);
    var self = this;
    scriptsArray.forEach(function(item) {
        if (self.resourceExists(item)) {
            self.echo(item + ' loaded');
        } else {
            self.echo(item + ' not loaded', 'ERROR');
        }
    });
});

In this script we are retrieving all the page's scripts using a css selector. To do this we have to use the evaluate function. With the array of scripts we could call the resourceExists function to know whether the resource is loaded or not.

Executing the script we should have this result:

[caption id="attachment_58" align="alignnone" width="675"]result result[/caption]

And yes, we could do the same for the images, changing the css selector a little bit:

var imagesArray = [];

function getImages() {
    var scripts = document.querySelectorAll('img[src]');
    return Array.prototype.map.call(scripts, function (e) {
        return e.getAttribute('src');
    });
};

casper.start('http://localhost:8000/', function () {
    imagesArray = this.evaluate(getImages);
    var self = this;
    imagesArray.forEach(function (item) {
        if (self.resourceExists(item)) {
            self.echo(item + ' loaded');
        } else {
            var message = item + ' not loaded';
            self.echo(message, 'ERROR');
        }
    });
});

And the output:

[caption id="attachment_59" align="alignnone" width="675"]result result[/caption]

Could be a good idea to take a snapshot if an image is not loaded. We could do this using the capture function:

casper.start('http://localhost:8000/', function () {
    imagesArray = this.evaluate(getImages);
    var self = this;
    var isThereAnError = false;
    imagesArray.forEach(function (item) {
        if (self.resourceExists(item)) {
            self.echo(item + ' loaded');
        } else {
            var message = item + ' not loaded';
            self.echo(message, 'ERROR');
            self.isThereAnError = true;
        }
    });

    if (this.isThereAnError == true) {
        casper.capture('noimages.png');
    }
});

The output will be the same as before, but if you take a look at the script folder you will see that now there is an image in it:

[caption id="attachment_61" align="alignnone" width="826"]no images no images[/caption]

And if you open the image, you will see the web page rendered.

[caption id="attachment_62" align="alignnone" width="1024"]page rendered page rendered[/caption]

But we have a problem. We don't have any notices about the image set in body's background that doesn't exist. We have to try another approach to catch this error. It would be great to catch any 404 error on resources loading, and CasperJS allows us to do.

Change the previous function by this one:

casper.on("resource.received", function(request) {
    if (request.status === 404) {
        this.echo('Resource Not Found:' + request.url);
    }
});

casper.start('http://localhost:8000/', function () {});

Now, we are subscribing to the resource.received event, and looking at the status code we could know whether the resource is loaded or not.

If we take a look at the output we could see that an error is shown for the image inside the css too.

[caption id="attachment_63" align="alignnone" width="675"]catching 404 errors catching 404 errors[/caption]

 

Ok, now we have a generic way to be aware of errors when loading resources. Now we need to know when a javascript error happens. To do that we are going to use the events too, but now we are going to subscribe to page.error event:

casper.on("page.error", function (msg, trace) {
    this.echo("Error:    " + msg, "ERROR");
    this.echo("file:     " + trace[0].file, "WARNING");
    this.echo("line:     " + trace[0].line, "WARNING");
    this.echo("function: " + trace[0]["function"], "WARNING");
});

And we obtain as a result

[caption id="attachment_64" align="alignnone" width="675"]on error on error[/caption]

So, we have a generic way to obtain the errors loading resources or executing javascript of our web page. In upcoming tutorials we will explore more capabilities of CasperJs.

See you soon!

Today we will start a serie of tutorials about testing websites using CasperJS. We will cover installation and basic error detection, integration with a Team Foundation Server build and executing tests.

What is CasperJS?

In words of its creators, CasperJS is an open source navigation scripting & testing utility written in Javascript and based on PhantomJS — the scriptable headless WebKit engine. It eases the process of defining a full navigation scenario and provides useful high-level functions, methods & syntactic sugar for doing common tasks.

Installation

First of all we have to download the latest version of PhantomJS and extract the contact where you want. After that it's recommended to add this path to your PATH environment variable.

Now you can download the tag 1.0.2 of CasperJS repository on GitHub. You can clone the repository and checkout this tag:

$ git clone git://github.com/n1k0/casperjs.git
$ cd casperjs
$ git checkout tags/1.0.2

or you can download directly from here.

As before, it's recommended to add the path where you have downloaded CasperJS to your PATH environment variable. But don't add the base path, add the batchbin folder.

First steps

To test CasperJS we will use the web site created by the MVC internet application template of Visual Studio 2012. If you are not a .Net developer, please create a simple website with your prefered technology, and skip this step.

For .Net developers, open your VS2012 in administrator mode and create a new project with the MVC4 application project type

[caption id="attachment_32" align="alignnone" width="300"]Project template Project template[/caption]

And now chose the internet application template

ProjectCreation2

 

In order to facilitate our job, we will create a new web site on IIS and link it to our brand-new project. So please, open IIS manager and create a new website

[caption id="attachment_35" align="alignnone" width="599"]Web site creation Web site creation[/caption]

And now open the properties window of the web site application project in VS2012 and associate the project to the new web site we've just created

[caption id="attachment_36" align="alignnone" width="1199"]project properties project properties[/caption]

Now, add a folder under the Scripts folder and create a new JavaScript file called testCasperJS.js.

Working with CasperJS

All the scripts start with a call to 'create' method. The simplest way to do it is this:

var casper = require('casper').create();

You can pass a javascript settings object to this method with several parameters. For example, we could set the viewport size:

var casper = require('casper').create({
    viewportSize: {width: 1024, height: 768}
});

The next function we need to call is 'start'. This call could be without parameters or we could pass an Url and the function that will be called after the page downloading.

casper.start('http://localhost:8000/', function () {
    this.echo('page downloaded: ' + this.getCurrentUrl());
});

Now, we only need one more code block to end our first CasperJS script

casper.run(function () {
    this.echo("Done.").exit();
});

With this code, we are indicating to CasperJS that we want to run our script and that, when it finishes we  want to write 'Done' in the console and exit CasperJS.

Right now, we could save our script, open a Command Prompt, go where the script is located and write

casperjs testCasperJs.js

And we will see the result of our script

[caption id="attachment_42" align="alignnone" width="677"]script result script result[/caption]

Conclusions

In this post we have seen how to install CasperJS and how to make a very simple script. In the next posts of this series, we will see more operations to use and how to integrate all these scripts in a build for our Team Foundation Server.

See you soon!