1
votes

I try to automate tests of a drag and drop behavior in a WPF application. One custom control is dragged on another:

manual drag and drop

Drag and drop behavior implemented in the usual WPF way:

<UserControl ...
             MouseMove="ToolboxModule_OnMouseMove">
private void ToolboxModule_OnMouseMove(object sender, MouseEventArgs e)
{
    base.OnMouseMove(e);

    var data = new DataObject();
    data.SetData("ModuleDescription", DataContext);

    if (e.LeftButton == MouseButtonState.Pressed)
        DragDrop.DoDragDrop(this, data, DragDropEffects.Copy);
}
<UserControl ...
             Drop="WorkspaceView_OnDrop" AllowDrop="True">
private void WorkspaceView_OnDrop(object sender, DragEventArgs e)
{
    var dropped = e.Data.GetData("ModuleDescription");
    var viewModel = (WorkspaceViewModel)DataContext;
    if (viewModel.ChainVm.AddModuleCommand.CanExecute(dropped))
        viewModel.ChainVm.AddModuleCommand.Execute(dropped);
}

But when I try to automate this with WinAppDriver, the drag and drop does not work. Cursor shape is not changed and nothing happens.

WinAppDriver drag and drop

I've tried several approaches:

Actions Drag and Drop

var moduleControl = mainWindow.GetToolboxModuleControl(moduleName);
var actions = new Actions(_session);
actions.DragAndDrop(moduleControl, mainWindow.WorkspaceControl).Perform();

Actions click and hold

var moduleControl = mainWindow.GetToolboxModuleControl(moduleName);
var actions = new Actions(_session);
actions.ClickAndHold(moduleControl).MoveByOffset(200, 0).Release().Perform();

Driver mouse operations (from example)

_session.Mouse.MouseMove(moduleControl.Coordinates, 50, 50);
_session.Mouse.MouseDown(null);
_session.Mouse.MouseMove(mainWindow.WorkspaceControl.Coordinates, 100, 100);
_session.Mouse.MouseUp(null);

Driver mouse operations with delays

_session.Mouse.MouseMove(moduleControl.Coordinates, 50, 50);
Thread.Sleep(1000);
_session.Mouse.MouseDown(null);
Thread.Sleep(1000);
_session.Mouse.MouseMove(mainWindow.WorkspaceControl.Coordinates, 100, 100);
Thread.Sleep(1000);
_session.Mouse.MouseUp(null);

Nothing works. Any ideas what could be wrong and how to fix it?

When I try to move the app window by dragging it's title bar via WinAppDriver, it successfully moves the window. So the dragging operations technically work, but not in the case of dragging a control within the window.

1

1 Answers

2
votes

Found the answer.

WinAppDriver doesn't move the mouse, but "teleport" it. It means mouse cursor is not dragged all the way to the target with finite speed, it is being jumped from start to end position without any intermediate positions.

In this particular case it causes the problem. What actually happens:

  1. Cursor teleported to the center of first element. MouseMove and other mouse movement events are firing on first element. DragDrop.DoDragDrop method is not executed, because left mouse button is not pressed.
  2. Left mouse button is pressed. MouseDown, Click and other related event are firing on first element. DragDrop.DoDragDrop method is not executed, because there is no mouse movement.
  3. Cursor jumped to second element without touching the first. MouseMove and other mouse movement events are firing on second element only. Since no MouseMove event is firing on first element with left mouse button pressed, the drag and drop process never starts.

Solutions are simple: move the cursor within first element boundaries before jump to the second or change the event, where drag and drop process starts (MouseDown instead of MouseMove, for example). I chose the latter:

<UserControl ...
             MouseDown="ToolboxModule_OnMouseDown">
private void ToolboxModule_OnMouseDown(object sender, MouseButtonEventArgs e)
{
    base.OnMouseDown(e);

    var data = new DataObject();
    data.SetData("ModuleDescription", DataContext);
    DragDrop.DoDragDrop(this, data, DragDropEffects.Copy);
}