Wednesday, March 28, 2007

Testing drag'n'drop with WatiN

Many of the recent Web 2.0 applications require drag and drop functionality. Sometimes it is useful, sometimes it is just marketing, but if you have to do it and at the same time you want to write all your code test first (TDD), a new problem arises: how to write a functional test to test the drag drop?


Starting from a wonderful article on the 'Z Bar Zone' blog, I modified it to work with WatiN in C#. The code tests the wonderful scripta.aculo.us based drag'n'shop:




using System.Threading;
using mshtml;
using NUnit.Framework;
using WatiN.Core;

namespace TestDragDropWatiN
{

[TestFixture]
public class DragDropScriptaculousTests
{
IE ie = null;

[Test]
public void TestDragDrop()
{
ie = new IE("http://demo.script.aculo.us/shop");
ie.ShowWindow(NativeMethods.WindowShowStyle.Maximize);

//add some items to the cart
int[] ids = new int[] { 1, 1, 2, 1, 2 };
foreach (int id in ids)
{
string product = "product_" + id;
RunScript("document.blah = document.createEventObject(); document.blah.button = 1");//create event object
RunScript("document.getElementById('" + product + "').fireEvent('onmousedown', document.blah)");//click on product-fire mouse down on product_id div
RunScript("document.blah = document.createEventObject(); document.blah.clientX = document.getElementById('cart').offsetLeft; document.blah.clientY = document.getElementById('cart').offsetTop");//obtain position of the cart
RunScript("document.getElementById('" + product + "').fireEvent('onmousemove', document.blah)");//move the product div to te cart-fire onmousemove
RunScript("document.getElementById('" + product + "').fireEvent('onmouseup', document.blah)");//drop-fire onmouseup


Thread.Sleep(1000);
}

//remove some items from cart
string[] items = {"item_1_1","item_2_0"};
foreach(string item in items)
{
RunScript("document.blah = document.createEventObject(); document.blah.button = 1");//event object
RunScript("document.getElementById('"+item+"').fireEvent('onmousedown', document.blah)");//click on item in the shopping cart
RunScript("document.blah = document.createEventObject(); document.blah.clientX = document.getElementById('wastebin').offsetLeft; document.blah.clientY = document.getElementById('wastebin').offsetTop");//obrain position of the wastebin
RunScript("document.getElementById('"+item+"').fireEvent('onmousemove', document.blah)");//move item to the wastebin
RunScript("document.getElementById('"+item+"').fireEvent('onmouseup', document.blah)");//drop-fire onmouse up
Thread.Sleep(1000);
}

ie.Close();
}

private void RunScript(string js)
{
IHTMLWindow2 window = ((HTMLDocument)ie.HtmlDocument).parentWindow;
window.execScript(js, "javascript");
}

}

}




Enjoy :)

1 comment:

ftorres said...

Dan, what you proved is that you can execute javascript from Watin.
This is not the most simple code.
Obviously I am bias, because I am the creator of InCisif.net another web testing tool for the .NET platform. What makes our tool different among other things with Watir/Watin is the API. This is how you program a drag and drop :

Page.Control("product_1").DragAndDrop(Page.Control("cart"));

I will post the full source code on my blog : blog.incisif.net.

This is still beautifull JavaScript :).