Getting set up with CodePlex

We recommend you install Visual Studio Service Pack 1 which includes a required WAP update.

As mentioned in the previous section, anyone can go and browse the CodePlex site. Create an account on CodePlex, then click the “Source Code” tab of the web site. There will be a heading there with instructions on how to set up your Visual Studio 2005 connection to Team Foundation Server. It is possible that the codeplex site may not have been updated to include you as a developer, hence you may not be able to see the heading under the source code tab. You should confirm that your login shows up under the people tab in that case. If you think you should be seeing it and you do not then you should contact a codeplex coordinator.

Note that you’ll need to install Visual Studio Team Explorer onto your machine to access via Visual Studio.

Once you’ve got VSTE installed, start up VS2005 (or just VSTE if you don’t have VS)
First, make sure that TFS is configured as your Source Control provider. Choose your Tools > Options menu, then select the “Source Control” node:


Choose Tools -> Connect to Team Foundation Server. Click the “Server…” button and add the information from the “Source Code” tab on the website.


Click OK and you’ll be prompted for your TFS credentials. The password is the same as your CodePlex login.

Note: The CodePlex guys have had do to some magic to mate the TFS credential system (domain/NTLM based) with the forms-based system on the CodePlex website – therefore, your TFS username is likely to be “<username>cp”, so if your login name is codeplexuser, you should type “codeplexusercp” into the dialog box. If that doesn’t work, try your normal user name, as I know the CodePlex team is working on finding a solution for this.

Click Close and you’ll see ASP.Net AJAX Control Toolkit in the list of projects. Selected it, and choose OK. You are now connected to the CodePlex project.


Installing prerequisites:

The Toolkit project takes advantage of the features available with the Visual Studio 2005 Web Application Project (WAP) update. To install this update so you can contribute to the project.
Install the Visual Studio 2005 WAP update, then install WAP itself. Wap installation on vista needs to be performed locally in quiet mode from a command prompt run as administrator because running the regular install results in an msi error (code 2869).

  • If you install Visual Studio Service Pack 1 then the wap update need not be installed separately.
  • ASP.Net AJAX(atlas) needs to be installed to be able to successfully load and build the toolkit project.

Synching and Building

Choose View -> “Team Explorer” and you’ll see the ASP.Net AJAXControlToolkit project in the list of items.


Double click “Source Control” and you’ll be taken to the Source Control Explorer. Highlight “ASP.Net AJAXControlToolkit” and click the “Get Latest Version (Recursive)” toolbar button.


This will bring up a folder-picker dialog for you to choose where you want the Toolkit code to be placed on your machine. Hit OK and the source code will be downloaded. Navigate to the folder, and open the ASP.Net AJAXControlToolkit.sln solution in Visual Studio. At this point you will be able to build and launch the SampleWebsite, navigate the code, etc. When you open the project for the first time, you may get a warning about the TemplateVSI project. This is because it’s a modified C# project that we use to do custom steps to build the VSI installer for the templates. If you see the following dialog, chose “Load project normally”. You should only see this the first time you load the solution:


The final step is binding your project to the source control system. Right click in the blank area between or next to Visual Studio’s toolbars. You should see a list of possible toolbars in a context menu. Choose “Source Control –Team Foundation”:


A Source Control Toolbar will appear. Click the “Change Source Control” Button:


Then for each of the projects listed, click the “Bind” button, and hit “OK”. If the project is already bound no further action is necessary.


You are now ready to begin using the Team Foundation Server source control system.

IMPORTANT: A note on using TFS source control. Please DO NOT check out files with locks unless absolutely necessary (which should be never). Checking out files with locks prevents other people from checking them out. We basically never use exclusive checkout systems here at Microsoft and it works out fine. There are occasionally merging issues but the vast majority of the time, it’s a small price to pay for the benefit in terms of productivity. In a project like this where contributors may be on opposite sides of the world, a locked file could be a real blocking problem.

Understanding the project layout

The Toolkit is organized into a very simple code tree. The project is organized into several sub-folders:
  1. AJAXControlToolkit – this is the main Toolkit codebase where components are authored. This project builds AJAXControlToolkit.dll
  2. SampleWebSite – this is the website that serves as a demonstration page as well as basic documentation for each of the components.
  3. TemplateVSI – This project builds the project and item templates for creating new Toolkit components.
  4. Prototype – This is a checkin place for components that have been approved for Toolkit submission but are not fully ready for check-in to the actual Toolkit. Note components should not languish in the Prototype project for long periods of time. This is meant to be a place to publish nearly-complete components for feedback or testing by the Toolkit community, so all components should be initially checked in to this project.
  5. ToolkitTests – this is a project that contains the simple Toolkit test framework plus the test harness for components in the Toolkit.

Creating your component
Components that are nearly ready to be added to the Toolkit should be first added to the Prototype project.
First, ensure that you’ve installed the Toolkit templates. The VSI to install the templates is built by the TemplateVSI project. Build the TemplateVSI project, then navigate to its “bin” directory, where you will find “AJAXControlExtenders.vsi”. To install the templates, simply launch this file. Note that since this VSI is not signed (you just built it!), you’ll get a warning from the VSI installer. Don’t worry: what you’re installing isn’t running any code. You can inspect the files and you’ll see that they’re just ZIP files of various templates.
In the Prototype project, right click on the “Components” folder, and chose “Add New Item…”. At the bottom, you should see “ASP.Net AJAX” Control Extender. Choose that and give it an appropriate name:


Hit OK. This will create four files in the Components folder:
  • MyControlBehavior.js – the main JavaScript file for your component
  • MyControlDesigner.cs – the designer file for your component. You probably won’t need to modify this.
  • MyControlExtender.cs – the extender control class for your component.

IMPORTANT: The new item template isn’t able to completely get things set up for you. You need to set the Build Action property of the MyControlBehavior.js file to “Embedded Resource” in order for your extender to work properly:


Go ahead and build. You’re now ready to place your extender on the page! The project already defines the namespace for your components, so you can add it to the default.aspx as follows:


Finally, please don’t check code into this project until it’s nearly at completion. We don’t want a dozen half-finished components running around in here. If code does sit untouched for significant periods of time, we may have do a cleanup and remove them from the project (after notifying the authors of course).

Testing your component
When submitting a new component for the “ASP.Net AJAX” Control Toolkit, we ask that you also provide several tests that exercise its functionality. These tests are used to ensure that your component is running smoothly in all the major browsers supported by “ASP.Net AJAX” before we build a new release. They are also invaluable to anyone maintaining your component, or the base classes used by your component, as a smoke test for their work. Whenever you checkin changes to your component, be sure these changes are reflected in your tests as well.

JavaScript presents several challenges when testing user interface components written using “ASP.Net AJAX.” With asynchronous operations like web service calls or animation, you have to start the operation and wait for it to complete without blocking before you can verify the result. Postbacks are just as difficult because you have to perform an action that causes a postback and then have the test resume processing where it left off when the page loads again. We have written a JavaScript testing framework, in the ToolkitTests web project, to eliminate these problems when writing tests for your components.

The following walkthrough describes the steps you need to take to get started using the “ASP.Net AJAX” Control Toolkit
Automated Test Harness.

Creating a Component Unit Test

The “ASP.Net AJAX” Control Toolkit Automated Test Harness allows you to easily write tests for user interface components written in JavaScript. The test harness is the web application that actually runs all of the selected test suites and displays their results. A test suite is an *.aspx page that contains instances of your component as well as the definition of several test cases. A test case is an individual unit test consisting of a series of test steps to evaluate a particular area of functionality. A test step is an action (possibly performed asynchronously or after a postback) that operates on your component.
There are four basic steps to creating a suite:
  1. Create an ASPX page with the UI that you’d like to test
  2. Declare a top-level Javascript variable called typeDependencies that lists the types that need to be loaded for your type to run.
  3. Declare a Javascript function called registerTests that defines the tests and the steps of those tests.
  4. Inside of registerTests, declare a set of tests and test steps.

As you’ll see below, the Test Harness takes a set of steps, queues them up, then executes them in order, either synchronously or asynchronously by waiting for their completion function to return true.

To create a new test suite, add a new Web Form to the ToolkitTests project and select the Default.master master page. Then add instances of your component to the Web Form that you will use in the tests. Next, you need to create a <script> block that contains definitions of your test cases and test harness entry points. If you were writing a test suite for CascadingDropDown, it would look something like this:

<%@ Page
Title="CascadingDropDown Tests"
EnableEventValidation="false" %>
<asp:Content ID="Content" ContentPlaceHolderID="ContentPlaceHolder1" Runat="Server">
<asp:DropDownList ID="DropDownList1" runat="server" Width="170"
<ajaxToolkit:CascadingDropDown ID="CascadingDropDown1" runat="server">
<ajaxToolkit:CascadingDropDownProperties TargetControlID="DropDownList1"
Category="Make" PromptText="Please select a make"
ServicePath="CarsService.asmx" ServiceMethod="GetDropDownContents" />

<asp:Label ID="Label1" runat="server" Text="Label"></asp:Label><br />
<asp:Button ID="Button1" runat="server" Text="Button" OnClick="Button1_Click" />

<script type="text/javascript">
// Define the test cases

Now, in the Javascript block, we declare an array of strings called typeDependencies that contains the fully qualified JavaScript names of the components used in your test suite. The test harness will wait for all of these objects to have been defined before running any of your tests. This is critical; without it the tests will intermittently fail based on how long it takes to load the behaviors.
For the CascadingDropDown test suite, we have:

// Script objects that should be loaded before we run
var typeDependencies = square bracket open: 'AJAXControlToolkit.CascadingDropDownBehavior' : square bracket close;

Next, declare a function registerTests that takes a parameter called harness. The test harness will pass this function a reference to itself when loading the test suite so the suite can add new test cases. You will often want to save the reference to the test harness in a global variable because it contains useful utility functions, like assertions, that you may want to use elsewhere.

Before we start writing test cases, let’s first get references to controls used in the test suite with testHarness.getElement(id) and testHarness.getObject(‘id’). These two methods wrap document.getElementByID and Sys.Application.findControl respectively, but also raise errors if controls aren’t found and prevent your test cases from running. Since we will use the references in other areas, we make them global variables. The script for the CascadingDropDown test suite should now look like this:

<script type="text/javascript">
// Script objects that should be loaded before we run
var typeDependencies = square bracket open : 'AjaxControlToolkit.CascadingDropDownBehavior' : square bracket close;

// Test Harness
var testHarness = null;

// Controls in the test page
var drop1 = null;
var btn = null;
var label = null;

// Run the tests
function registerTests(harness) {
testHarness = harness;

// Get the client ID’s from the controls on the page
drop1 = testHarness.getElement('ctl00_ContentPlaceHolder1_DropDownList1');
drop2 = testHarness.getElement('ctl00_ContentPlaceHolder1_DropDownList2');
drop3 = testHarness.getElement('ctl00_ContentPlaceHolder1_DropDownList3');
btn = testHarness.getElement('ctl00_ContentPlaceHolder1_Button1');
label = testHarness.getElement('ctl00_ContentPlaceHolder1_Label1');

For the full version of these functions, please see CascadingDropDown.aspx in the ToolkitTests project. Now that we have all the plumbing out of the way, we can define the test cases using var test = testHarness.addTest(‘test name’). This returns a test case object that we can add a sequence of steps to for the test harness to run. We will reload the page before running each test case, so you should expect the controls to be in their initial state for each test iteration. Be careful not to expect changes to persist from one test to another.

Once we have a test case, we can add steps to it with test.addStep and test.addPostBack. There are three main types of test steps:
  • simple steps that perform an action an return
  • steps that perform an asynchronous action and wait for it to finish
test.addStep(someFunction, isCompleteFunction, pollingInterval,
timeOutTime, verifyStateFunction)
  • steps that force post-backs
For an asynchronous step, here are the parameter descriptions:
  • someFunction, the function to execute
  • isCompleteFunction, a function to call to check if the action has completed (optional)
  • interval, the time to wait between calls to the check function (optional)
  • timeout , the total time to wait before failing the test (optional)
  • verifyStateFunction, a function to call to verify the state after the check function has completed (optional)

Note that the functions must take no parameters (if they need to take parameters, wrap them as mentioned below).
Here are example test cases from the registerTests function in the CascadingDropDown test suite, see below for function definitions):

// Test the initial values
var test = testHarness.addTest('Initial Values');
// Wait until the drop downs are loaded
test.addStep(function() {}, checkLoaded(drop1, drop4, drop5, drop6));

// Select from first level
var test = testHarness.addTest('Select from first level');
test.addStep(function() {}, checkLoaded(drop1, drop4, drop5, drop6));
test.addStep(setSelectedIndex(drop1, 3), checkLoaded(drop1, drop2),

To add a postback step, simply call test.addPostBack(element); where the element is a link, button, form, etc., that will cause a postback when clicked or submitted. When the test case is run and a postback occurs, the test harness will automatically resume processing the test on the next step after the postback when the page has reloaded. The following test case from the CascadingDropDown test suite shows an example of using a postback step:

// Values preserved on postback
var test = testHarness.addTest('Values preserved on PostBack');
test.addStep(function() {}, checkLoaded(drop1, drop4, drop5, drop6));
test.addStep(setSelectedIndex(drop1, 3), checkLoaded(drop1, drop2),
test.addStep(empty, checkLoaded(drop1, drop2, drop4, drop5, drop6));

To define the test cases, we will need to provide the test steps with functions that actually operate on the component. It is very important to note that the test steps can only take functions with no parameters, so if we have a function that needs parameters, wrap it in a parameterless function (for an example, see setSelectedIndex below). These functions can use the utility functions of the test harness to make them easier to write.

The utility functions will be familiar to those using TDD and include:
  • assertTrue(condition, ‘message’)
  • assertFalse(condition, ‘message’),
  • assertEqual(objA, objB, ‘message’)
  • assertNotEqual(objA, objB, ‘message’)
  • assertNull(obj, ‘message’)
  • assertNotNull(obj, ‘message’)
  • fireEvent(element, ‘eventName’).

For the CascadingDropDown test suite, we could add the following test functions:

// Check if the drop down elements passed as arguments are loaded
// by seeing if they have been enabled
function checkLoaded() {
// ...

// Ensure the dropdown is properly enabled
function checkEnabled(dropdown) {
"Drop down '" + + "' should be enabled");

// ...

// Set the selected index of a drop down and
// force the onChange event to be fired
function setSelectedIndex(dropdown, index) {
return function() {
dropdown.selectedIndex = index;
testHarness.fireEvent(dropdown, 'onchange');

// Test the initial state
function testInitialState() {
// ...


// Ensure the last dropdowns respond after a selection in the first
function testValuesAfterFirstSelected() {
// ...

// Ensure the last dropdown responds after a selection in the second
function testValuesAfterSecondSelected() {
// ...

We can now start the test harness by viewing Default.aspx of the ToolkitTests project and select our test suite to run. For the full CascadingDropDown.aspx test suite, along with many more tests, see the ToolkitTests project.

Checkin process and policies
It’s critical that quality remains high in the project. As such, here’s the practice and policies that we’re going to use to help ensure this. Of course, at the end of the day much of this is based on the honor system. However, getting bad code into the project is bad for everyone, so hopefully a little policy will go a long way.
  • Scenario tests – Ensure that you’ve added tests for your component and they pass reliably on IE 6 and 7, and the latest released version of Firefox. Please also test on Safari if you can.
  • Code Review – Unless your changes are extremely trivial (use judgment here), please get a code review from another developer on the project. Here’s the easiest way we’ve found for doing code review. Choose View > Other Windows > Pending Changes from the VS menu. Under pending changes, check the files that you’d like to have reviewed and press “Shelve Changes”:


Hit “Shelve”. The developer doing the code review can then go to the Pending Changes window and hit “Unshelve” and search for your shelve set, then hit “Details”. That developer can either apply the changes and diff them in the local enlistment or diff them directly from the “unshelve” dialog:


The reviewing developer should look at and understand all the changes, ask for explanations, etc. This could be best done over the phone or Instant Messenger. Any feedback from the code review should be addressed before checkin. For the first part of the project, Microsoft developers should be contacted for additional code reviews. As others come up to speed on the project, they can be used as code reviewers as well.
  • Code Analysis – run the static analysis tool on the project to make sure all the code complies with the guidelines. To run Code Analysis, right-click on the “AjaxControlTooklit” project, choose “Properties”, and then look for a “Code Analysis” tab. Just click the “Enable Code Analysis” checkbox and rebuild the project, fixing any errors or warnings. Please disable Code Anaylsis before you check in. It takes time and we don’t want it running with every build.

  • Sample Page – make sure your component has a working sample page in the SampleWebsite, complete with basic documentation, known issues, etc.
  • Checkin – do your checkin.
  • Buddy build (instructions below) – make sure your builds work by getting a new copy of the source tree after your check in and making sure it builds and runs properly. This helps catch things like files that didn’t get added or deleted, etc. After you check in, load your buddy project in Visual Studio, get the latest versions of everything and build, then run the suites.

The easiest way to do this is to maintain a second workspace that’s “clean” of changes. To do this, open Source Explorer, then in the “Workspaces” drop-down at the top, choose “Workspaces…”. On that dialog, choose “Add…”, and create a new workspace.


Hit OK, then select this workspace from the “Workspaces” drop down. Right-click on “AjaxControlToolkit” in the folders window, then “Get Latest Version”, and choose a new folder.

Bug\Work Item Guidelines
CodePlex provides a useful web-based interface to its bug tracking functionality. If you log into the Toolkit project you’ll see a tab marked “Issue Tracker”. Issues can be browsed without signing into the site but filing or modifying existing issues requires a CodePlex account.
  • Fixing bugs assigned to you:
    • Update the bug when you check-in with the
      • Release number you would like the change to be picked up in
      • Changelist number
      • Brief description of the fix
      • And mark the bug as “fixed”
  • Closing bugs assigned to you:
    • If you opened the bug and it is assigned to you as “fixed”
      • Verify that it has been fixed and mark the bug as “closed” with a small summary of the validation you ran
      • If you think the bug needs more information please mark the bug as “closed” with the relevant information it requires
    • If you think the fix is not required please mark the bug as “closed” with the correct reason, for example “by design”, “not enough resources”, “not a valid scenario” etc.
  • Reopening bugs assigned to you:
    • If you opened the bug and it is assigned to you as closed with more information or code requested, reopen the bug only when you have all the information necessary for the developer to reproduce the problem
    • If you have a bug that has been closed because it does not mandate a fix reopen it only if you have a compelling scenario that it needs to be fixed for.
  • Opening Bugs
    • Before filing a bug, please search to ensure that the issue has not already been filed
    • If opening an issue on a component authored, please assign the issue to yourself
    • If opening an issue on another author’s component, please simply leave it unassigned

You can also enter and manage bugs via the Team Explorer interface. It’s a good idea to create a query that searches for issues that are assigned to you or in areas that you “own”. In Team Explorer, right click on “My Queries” and select “Add Query”.


This allows you to easily track when you have work items to address.

Weekly triage: The toolkit team at Microsoft will triage active unassigned items and assign them to the appropriate owners ensuring that no issues go unaddressed.
Moving code to the production branch
Once your component is working properly, has good test coverage, and has received an appropriate amount of review and feedback, it’s time to move it to the production branch.
No magic here, simply create a new sub-folder in the production branch and move the code over. Please take this opportunity to re-factor, rename, comment, and otherwise clean up the code so what ends up in the Production branch is of the highest possible quality.

Status updates: At regular intervals the Toolkit team will post an update on the latest issues, upcoming releases, new controls, top work items, any policy changes etc. to the toolkit alias and also post the same on the wiki.

Last edited Jan 1, 2007 at 11:32 PM by kirtid, version 8