Skip to content

Commit

Permalink
Mouse and Touch (#9)
Browse files Browse the repository at this point in the history
 touch and mouse
  • Loading branch information
licanhua committed Nov 16, 2020
1 parent 795beb5 commit 6d849f1
Show file tree
Hide file tree
Showing 15 changed files with 336 additions and 23 deletions.
20 changes: 10 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -165,19 +165,19 @@ Because YWinAppDriver is for desktop application other than browser, `no` below
|no|POST| /session/:sessionId/alert_text |Sends keystrokes to a JavaScript prompt() dialog.
|no|POST| /session/:sessionId/accept_alert |Accepts the currently displayed alert dialog.
|no|POST| /session/:sessionId/dismiss_alert |Dismisses the currently displayed alert dialog.
|in progress|POST| /session/:sessionId/moveto |Move the mouse by an offset of the specificed element.
|completed|POST| /session/:sessionId/moveto |Move the mouse by an offset of the specificed element.
|completed|POST| /session/:sessionId/click |Click any mouse button (at the coordinates set by the last moveto command).
|in progress|POST| /session/:sessionId/buttondown |Click and hold the left mouse button (at the coordinates set by the last moveto command).
|in progress|POST| /session/:sessionId/buttonup |Releases the mouse button previously held (where the mouse is currently at).
|in progress|POST| /session/:sessionId/doubleclick |Double-clicks at the current mouse coordinates (set by moveto).
|in progress|POST| /session/:sessionId/touch/click |Single tap on the touch enabled device.
|in progress|POST| /session/:sessionId/touch/down |Finger down on the screen.
|in progress|POST| /session/:sessionId/touch/up |Finger up on the screen.
|in progress|POST| session/:sessionId/touch/move |Finger move on the screen.
|completed|POST| /session/:sessionId/buttondown |Click and hold the left mouse button (at the coordinates set by the last moveto command).
|completed|POST| /session/:sessionId/buttonup |Releases the mouse button previously held (where the mouse is currently at).
|completed|POST| /session/:sessionId/doubleclick |Double-clicks at the current mouse coordinates (set by moveto).
|not tested|POST| /session/:sessionId/touch/click |Single tap on the touch enabled device.
|not tested|POST| /session/:sessionId/touch/down |Finger down on the screen.
|not tested|POST| /session/:sessionId/touch/up |Finger up on the screen.
|not tested|POST| session/:sessionId/touch/move |Finger move on the screen.
|in progress|POST| session/:sessionId/touch/scroll |Scroll on the touch screen using finger based motion events.
|in progress|POST| session/:sessionId/touch/scroll |Scroll on the touch screen using finger based motion events.
|in progress|POST| session/:sessionId/touch/doubleclick |Double tap on the touch screen using finger motion events.
|in progress|POST| session/:sessionId/touch/longclick |Long press on the touch screen using finger motion events.
|not testeds|POST| session/:sessionId/touch/doubleclick |Double tap on the touch screen using finger motion events.
|not tested|POST| session/:sessionId/touch/longclick |Long press on the touch screen using finger motion events.
|in progress|POST| session/:sessionId/touch/flick |Flick on the touch screen using finger motion events.
|in progress|POST| session/:sessionId/touch/flick |Flick on the touch screen using finger motion events.
|no|GET |/session/:sessionId/location |Get the current geo location.
Expand Down
4 changes: 4 additions & 0 deletions src/Infra/CommandHandler/CommandHandlers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@ public class CommandHandlers: ICommandHandlers
{ Command.AppiumLaunchApp, new AppiumLaunchAppHandler() },
{ Command.SessionSendKeys, new SessionSendKeysHandler() },
{ Command.GetCapabilities, new GetCapabilitesHandler() },
{ Command.SessionMoveTo, new SessionMoveToHandler() },
{ Command.SessionMouseAction, new SessionMouseActionHandler() },
{ Command.SessionTouchActionOnElement, new SessionTouchActionOnElementHandler() },
{ Command.SessionTouchUpDownMove, new SessionTouchUpDownMoveHandler() },
};

public object ExecuteCommand(Command command, ISessionManager sessionManager, string sessionId, object req, string elementId)
Expand Down
4 changes: 4 additions & 0 deletions src/Infra/CommandHandler/ICommandHandlers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@ public enum Command
AppiumCloseApp,
AppiumLaunchApp,
GetCapabilities,
SessionMoveTo,
SessionTouchActionOnElement,
SessionTouchUpDownMove,
SessionMouseAction,
}

public interface ICommandHandlers
Expand Down
50 changes: 50 additions & 0 deletions src/Infra/CommandHandler/SessionHandlers.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
// Copyright (c) https://github.com/licanhua/YWinAppDriver. All rights reserved.
// Licensed under the MIT License.

using Microsoft.Windows.Apps.Test.Foundation;
using WinAppDriver.Infra.Communication;

namespace WinAppDriver.Infra.CommandHandler
{
class SetImplicitTimeoutHandler : SessionCommandHandlerBase<SetImplicitTimeoutReq, object>
Expand Down Expand Up @@ -126,4 +129,51 @@ protected override object ExecuteSessionCommand(ISessionManager sessionManager,
return session.GetApplicationRoot().GetFocusedElement().GetId();
}
}

class SessionMoveToHandler : SessionCommandHandlerBase<MoveToReq, object>
{
protected override object ExecuteSessionCommand(ISessionManager sessionManager, ISession session, MoveToReq req, string elementId)
{
if ((req.xoffset == null || req.yoffset == null) && req.element == null)
{
throw new InvalidArgumentException("element and xoffset/yoffset can't all be null");
}

IElement element = null;
if (req.element != null)
{
element = session.FindElement(req.element);
}

element.MouseMoveTo(req.xoffset, req.yoffset);
return null;
}
}

class SessionMouseActionHandler : SessionCommandHandlerBase<MouseActionReq, object>
{
protected override object ExecuteSessionCommand(ISessionManager sessionManager, ISession session, MouseActionReq req, string action)
{
req.button.MouseAction(action);
return null;
}
}
class SessionTouchActionOnElementHandler : SessionCommandHandlerBase<ElementReq, object>
{
protected override object ExecuteSessionCommand(ISessionManager sessionManager, ISession session, ElementReq req, string action)
{
session.FindElement(req.element).TouchActionOnElement(action);
return null;
}
}

class SessionTouchUpDownMoveHandler : SessionCommandHandlerBase<XYReq, object>
{
protected override object ExecuteSessionCommand(ISessionManager sessionManager, ISession session, XYReq req, string action)
{
req.TouchUpDownMove(action);
return null;
}
}

}
151 changes: 150 additions & 1 deletion src/Infra/Extension.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,30 @@
using System;
using Microsoft.Windows.Apps.Test.Foundation;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Text;
using WinAppDriver.Infra.Communication;

namespace WinAppDriver.Infra
{
public enum TouchAction
{
Click,
DoubleClick,
PressAndHold,
Down,
Up,
Move,
}

public enum MouseAction
{
Up,
Down,
Click,
DoubleClick,
}

static class Extension
{
// Convert the string to camel case.
Expand Down Expand Up @@ -37,5 +58,133 @@ public static string ToProperCase(this string the_string)
if (string.IsNullOrEmpty(camelCase)) return camelCase;
return char.ToUpper(camelCase[0]) + camelCase.Substring(1);
}

static Point ToPoint(object x, object y)
{
if (x == null || y == null)
{
throw new InvalidArgumentException("x or y is null");
}
return new Point() { X = (int)Double.Parse(x.ToString()), Y = (int)Double.Parse(y.ToString()) };
}

static Point ToPoint(double x, double y)
{
return new Point() { X = (int)x, Y = (int)y };
}

public static void MouseMoveTo(this IElement element, object x, object y)
{
if (element == null)
{
PointerInput.Move(ToPoint(x, y));
}
else
{
UIObject uiObject = (UIObject)element.GetUIObject();
if (x == null || y == null)
{
PointerInput.Move(uiObject);
}
else
{
PointerInput.Move(uiObject, Double.Parse(x.ToString()), Double.Parse(y.ToString()));
}

}
}

private static PointerButtons ToPointerButton(this MouseButton button)
{
if (button == MouseButton.LEFT)
{
return PointerButtons.Primary;
}
else if (button == MouseButton.RIGHT)
{
return PointerButtons.Secondary;
}
else return PointerButtons.Middle;
}

public static void MouseAction(this MouseButton button, string action)
{
MouseAction mouseAction = (MouseAction)Enum.Parse(typeof(MouseAction), action);
if (mouseAction == Infra.MouseAction.Down)
{
PointerInput.Press(ToPointerButton(button));
}
else if (mouseAction == Infra.MouseAction.Up)
{
PointerInput.Release(ToPointerButton(button));
}
else if (mouseAction == Infra.MouseAction.Click)
{
PointerInput.Click(button.ToPointerButton(), 1);
}
else if (mouseAction == Infra.MouseAction.DoubleClick)
{
PointerInput.Click(button.ToPointerButton(), 2);
}
else
{
throw new InvalidArgumentException();
}
}


public static void TouchActionOnElement(this IElement element, string action)
{
UIObject uiObject = (UIObject)element.GetUIObject();

TouchAction touchAction = (TouchAction)Enum.Parse(typeof(TouchAction), action);
if (touchAction == TouchAction.Click)
{
uiObject.Tap();
}
else if (touchAction == TouchAction.DoubleClick)
{
uiObject.DoubleTap();
}
else if (touchAction == TouchAction.PressAndHold)
{
uiObject.TapAndHold();
}
else
{
throw new InvalidArgumentException();
}
}

public static void TouchUpDownMove(this XYReq req, string action)
{
TouchAction touchAction = (TouchAction)Enum.Parse(typeof(TouchAction), action);
if (touchAction == TouchAction.Up)
{
using (InputController.Activate(PointerInputType.MultiTouch))
{
PointerInput.Move(ToPoint(req.x, req.y));
PointerInput.Release(PointerButtons.Primary);
}

}
else if (touchAction == TouchAction.Move)
{
using (InputController.Activate(PointerInputType.MultiTouch))
{
PointerInput.Move(ToPoint(req.x, req.y));
}
}
else if (touchAction == TouchAction.Down)
{
using (InputController.Activate(PointerInputType.MultiTouch))
{
PointerInput.Move(ToPoint(req.x, req.y));
PointerInput.Press(PointerButtons.Primary);
}

}
else throw new InvalidArgumentException();
}
}
}
File renamed without changes.
File renamed without changes.
11 changes: 11 additions & 0 deletions src/Infra/Helper/PointerInputHelpers.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
using System;
using System.Collections.Generic;
using System.Text;

namespace WinAppDriver.Infra.Helper
{
class PointerInputHelpers
{

}
}
31 changes: 31 additions & 0 deletions src/Infra/Request/SessionReqs.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,4 +30,35 @@ public class ActivateWindowReq
public string name;
}

public class MoveToReq
{
public string element;

public object xoffset;
public object yoffset;
}

[Flags]
public enum MouseButton
{
LEFT = 0,
MIDDLE = 1,
RIGHT = 2
}
public class MouseActionReq
{
public MouseButton button;
}

public class ElementReq
{
[JsonProperty(Required = Required.DisallowNull)]
public string element;
}

public class XYReq
{
public double x;
public double y;
}
}

0 comments on commit 6d849f1

Please sign in to comment.