extremely cheezy

Main menu

Post navigation

Drag-and-Drop in Watir

A month ago I was working with a team that had a need to write acceptance tests for a feature that included drag-and-drop. My initial search turned up some code that implemented it well. I have since tried to find that code again with no success so I am sorry for not being able to give credit where it is due. Anyway, I enhanced the code I originally found and wish to present it here.

What is presented below is an Internet Explorer only solution because that is what the client needed. I would be happy to work with somebody to make this enhancement more robust and add Firefox support. Just let me know if you have the time and want to help.

The first piece of code is a new module that provides low level access to mouse events. Here it is:

The methods of interest here are drag_drop_on, drag_drop_distance, drag_drop_at, drag_drop_below, and drag_drop_above. These methods allow you to drag a Watir::Element to some destination designated by the method you call.

Using drag-and-drop

The team I was coaching used ExtJS for their javascript library. I wrote three simple Cucumber Scenarios for the team that demonstrated how to use the drag-and-drop features that ran against the ExtJS online samples. Here is the feature file:

Scenario: simple drag and drop
Given I am on the extjs free drag-drop example page
When I drag item 1 around the page
Then it should move
Scenario: drag and drop with a grid
Given I am on the extjs grid drag-drop example page
When I drag Joe from the first grid to the second grid
Then he should be in the second grid
Scenario: drag something below another object
Given I am on the extjs grid to tree example
When I add AT&T to the root of the tree
And I add Boeing to the root of the tree
And I drag Leaf1 below AT&T
And I drag Boeing above Leaf1
Then Leaf1 should be the last item in the list

And here are the step definitions:

Given /^I am on the extjs free drag\-drop example page$/ do
@browser.goto "http://examples.extjs.eu/freedrag.html"
@browser.wait
end
When /^I drag item 1 around the page$/ do
item_one = @browser.div(:id => 'item-1')
item_one.drag_drop_distance(0, 50)
item_one.drag_drop_distance(50, 0)
item_one.drag_drop_distance(0, -50)
item_one.drag_drop_distance(-50, 0)
end
Then /^it should move$/ do
# sleeping to allow person to observe the results
sleep 3
end
Given /^I am on the extjs grid drag\-drop example page$/ do
@browser.goto "http://examples.extjs.eu/ddgrids.html"
@browser.wait
end
When /^I drag Joe from the first grid to the second grid$/ do
joe = @browser.div(:class => 'x-grid3-row x-grid3-row-first')
target = @browser.div(:id => 'ext-gen124')
joe.drag_drop_on(target)
end
Then /^he should be in the second grid$/ do
# sleeping to allow person to observe the results
sleep 3
end
Given /^I am on the extjs grid to tree example$/ do
@browser.goto "http://examples.extjs.eu/grid2treedrag.html"
@browser.wait
end
When /^I add AT&T to the root of the tree$/ do
att = @browser.div(:text => 'AT&T Inc.')
root = @browser.link(:class => 'x-tree-node-anchor')
att.drag_drop_on(root)
end
When /^I add Boeing to the root of the tree$/ do
boing = @browser.div(:text => 'Boeing Co.')
root = @browser.link(:class => 'x-tree-node-anchor')
boing.drag_drop_on(root)
end
When /^I drag Leaf1 below AT&T$/ do
leaf1 = @browser.span(:text => 'Leaf 1')
att = @browser.span(:text => 'AT&T Inc.')
leaf1.drag_drop_below(att)
end
When /^I drag Boeing above Leaf1$/ do
boing = @browser.span(:text => 'Boeing Co.')
target = @browser.span(:text => 'Leaf 1')
boing.drag_drop_above(target)
end
Then /^Leaf1 should be the last item in the list$/ do
leaf1 = @browser.span(:text => 'Leaf 1')
att = @browser.span(:text => 'AT&T Inc.')
boing = @browser.span(:text => 'Boeing Co.')
att.top_edge.should be < boing.top_edge
boing.top_edge.should be < leaf1.top_edge
# sleeping to allow person to observe the results
sleep 3
end

15 thoughts on “Drag-and-Drop in Watir”

I’m not so familiar with Cucumber, but shouldn’t all “Then” steps perform some assertation about the situation? “sleep 3” is nice for people to observe, but that doesn’t ever tell anything if something is wrong. Even those observing people might not understand when something should or should not happen by just looking. Or even you.

I’d say that you should just have more “When” and “Then” steps there to actually have them useful.

If you’d change the usages of Win32API to ruby-ffi [1] (it should be quite easy) then it might end up in Watir’s repo. Of course i’d check out WebDriver’s and/or Watir-WebDriver’s API for drag & drop also.

Jarmo, thanks for the comments. You are right that Then steps should perform some verification. The example here was what I shared with the team I was coaching to give them some idea how to use the extension I wrote for them and as such was not really testing anything. I in turn helped them write real features against their application (not here).

ffi is a very good choice and I should have selected it when I did this work. What you see here was trying to solve a problem experienced by the team I was working with and I didn’t plan to move it beyond that group. Do you think there is the need for drag-and-drop in the community? If so, I could place this in github and make the necessary changes to make it viable.

I think the code could be cleaned up a little and be ready. Jarmo suggested changing to use ffi. I think that would be very easy to do. It would also be easy to write a few specs to add to watirspec.

The main problem I see here is that this solution does not work on Firefox. When I looked into it briefly the problem was with finding the beginning and ending coordinates. The *_absolute methods did not work properly on Firefox.

I think the link you are looking for is here: http://wiki.openqa.org/display/WTR/Right+Click+an+Element. I wrote this with some really great feedback from Bill Agee and Paul Rogers. I never posted the drag and drop variant that is suggested in the ExtJS forums but I did work with it at work and never had a chance to repost. Yours looks better :).

How was your client experience with Watir/ExtJS? Our company is looking at going to ExtJS and we aren’t sure if Watir or Selenium would be the best choice.

It’s weird but I need to sleep for 2 seconds after I move the mouse in order to load a a flex comboBox and then click and it seems the sleep is done after the click and not in the moment I wrote it:
move where combo is
click to open the combo
move where the option I want to click is
sleep 2 seconds to wait the options are displayed
click on desired option

Hi, really like this, its very simple i’m learning a lot with this, i’m new in testing also, i’m testing a webpage with selenium Webdriver, i need a little help, i’m trying to write a test that use a silverlight button to upload a file, anybody can help me with that?