Drag and drop in cucumber with selenium
I needed to show a bug using a cucumber script which includes drag and drop. Turned out to be difficult for several reasons
- drag and drop is not supported by webrat for selenium
- ‘within’ for scoping is not supported by webrat for selenium
this made the feature difficult to quickly specifiy. The feature contains:
[...] And I drag "Todo 3" to "Todo 2" [...] When I expand the dependencies of "Todo 1" Then I should see "Todo 2" within the dependencies of "Todo 1" [...]
drag_id = Todo.find_by_description(dragged).id
drop_id = Todo.find_by_description(target).id
drag_name = "xpath=//div[@id='line_todo_#{drag_id}']//img[@class='grip']"
drop_name = "xpath=//div[@id='line_todo_#{drop_id}']//div[@class='description']"
selenium.drag_and_drop_to_object(drag_name, drop_name)
arrow = "xpath=//div[@id='line_todo_#{drop_id}']/div/a[@class='show_successors']/img"
selenium.wait_for_element(arrow)
xpath = "//div[@id='line_todo_#{todo.id}'"
Then "I should see \"#{successor_description}\" within \"xpath=#{xpath}\""
xpath = "xpath=//div[@id='line_todo_#{todo.id}']//div[@id='successor_line_todo_#{successor.id}']//span"
selenium.wait_for_element(xpath)
UPDATE: In Tracks Eric added a change to show an image where to drop a todo. Problem is that the image only appears when dragging starts. Selenium does not have semantics for this, i.e. the drop target cannot be found when it is hidden before calling drag_and_drop_to_object.
I needed to ‘fix’ this by showing the image before I started the drag and drop. Somehow I also needed to use the id of the img. An xpath with the class did not seem to work:
drag_name = "xpath=//div[@id='line_todo_#{drag_id}']//img[@class='grip']"
drop_name = "xpath=//div[@id='line_todo_#{drop_id}']//img[@id='successor_target_#{drop_id}']"
# the target img is hidden until drag starts. We need to show the img or the
# xpath will not find it
js="$('img#successor_target_#{drop_id}').show();"
selenium.get_eval "(function() {with(this) {#{js}}}).call(selenium.browserbot.getCurrentWindow());"
selenium.drag_and_drop_to_object(drag_name, drop_name)
Resulting patch here.
Explore posts in the same categories: Tracks