diff --git a/src/Plugin.Maui.UITestHelpers.Appium/Actions/AppiumLifecycleActions.cs b/src/Plugin.Maui.UITestHelpers.Appium/Actions/AppiumLifecycleActions.cs index b7defe2d..2700d4e9 100644 --- a/src/Plugin.Maui.UITestHelpers.Appium/Actions/AppiumLifecycleActions.cs +++ b/src/Plugin.Maui.UITestHelpers.Appium/Actions/AppiumLifecycleActions.cs @@ -53,7 +53,23 @@ CommandResponse LaunchApp(IDictionary parameters) if (_app?.Driver is null) return CommandResponse.FailedEmptyResponse; - _app.Driver.LaunchApp(); + if (_app.GetTestDevice() == TestDevice.Mac) + { + _app.Driver.ExecuteScript("macos: activateApp", new Dictionary + { + { "bundleId", _app.GetAppId() }, + }); + } + else if (_app.GetTestDevice() == TestDevice.Windows) + { +#pragma warning disable CS0618 // Type or member is obsolete + _app.Driver.LaunchApp(); +#pragma warning restore CS0618 // Type or member is obsolete + } + else + { + _app.Driver.ActivateApp(_app.GetAppId()); + } return CommandResponse.SuccessEmptyResponse; } @@ -85,25 +101,8 @@ CommandResponse ResetApp(IDictionary parameters) if (_app?.Driver is null) return CommandResponse.FailedEmptyResponse; - // Terminate App not supported on Mac - if (_app.GetTestDevice() == TestDevice.Mac) - { - _app.Driver.ResetApp(); - } - else if (_app.GetTestDevice() == TestDevice.Windows) - { - CloseApp(parameters); - _app.Driver.LaunchApp(); - } - else - { - _app.Driver.TerminateApp(_app.GetAppId()); - - if (_app.GetTestDevice() == TestDevice.iOS) - _app.Driver.ActivateApp(_app.GetAppId()); - else - _app.Driver.LaunchApp(); - } + CloseApp(parameters); + LaunchApp(parameters); return CommandResponse.SuccessEmptyResponse; } @@ -113,7 +112,24 @@ CommandResponse CloseApp(IDictionary parameters) if (_app?.Driver is null) return CommandResponse.FailedEmptyResponse; - _app.Driver.CloseApp(); + if (_app.AppState == ApplicationState.NotRunning) + return CommandResponse.SuccessEmptyResponse; + + if (_app.GetTestDevice() == TestDevice.Mac) + { + _app.Driver.ExecuteScript("macos: terminateApp", new Dictionary + { + { "bundleId", _app.GetAppId() }, + }); + } + else if (_app.GetTestDevice() == TestDevice.Windows) + { +#pragma warning disable CS0618 // Type or member is obsolete + _app.Driver.CloseApp(); +#pragma warning restore CS0618 // Type or member is obsolete + } + else + _app.Driver.TerminateApp(_app.GetAppId()); return CommandResponse.SuccessEmptyResponse; } diff --git a/src/Plugin.Maui.UITestHelpers.Appium/Actions/AppiumPointerActions.cs b/src/Plugin.Maui.UITestHelpers.Appium/Actions/AppiumPointerActions.cs index 537ed073..0b74de81 100644 --- a/src/Plugin.Maui.UITestHelpers.Appium/Actions/AppiumPointerActions.cs +++ b/src/Plugin.Maui.UITestHelpers.Appium/Actions/AppiumPointerActions.cs @@ -200,8 +200,13 @@ CommandResponse ScrollTo(IDictionary parameters) throw new TimeoutException($"Timed out scrolling to {toElementId}"); } - var scrollAction = new TouchAction(_appiumApp.Driver).Press(x, startY).MoveTo(x, endY).Release(); - scrollAction.Perform(); + var touchDevice = new OpenQA.Selenium.Appium.Interactions.PointerInputDevice(PointerKind.Touch); + var scrollSequence = new ActionSequence(touchDevice, 0); + scrollSequence.AddAction(touchDevice.CreatePointerMove(CoordinateOrigin.Viewport, x, (int)startY, TimeSpan.Zero)); + scrollSequence.AddAction(touchDevice.CreatePointerDown(PointerButton.TouchContact)); + scrollSequence.AddAction(touchDevice.CreatePointerMove(CoordinateOrigin.Viewport, x, (int)endY, TimeSpan.FromMilliseconds(500))); + scrollSequence.AddAction(touchDevice.CreatePointerUp(PointerButton.TouchContact)); + _appiumApp.Driver.PerformActions([scrollSequence]); } } @@ -265,11 +270,13 @@ static PointF ElementToClickablePoint(AppiumElement element) static void DragCoordinates(AppiumDriver driver, double fromX, double fromY, double toX, double toY) { - new TouchAction(driver) - .Press(fromX, fromY) - .MoveTo(toX, toY) - .Release() - .Perform(); + var touchDevice = new OpenQA.Selenium.Appium.Interactions.PointerInputDevice(PointerKind.Touch); + var dragSequence = new ActionSequence(touchDevice, 0); + dragSequence.AddAction(touchDevice.CreatePointerMove(CoordinateOrigin.Viewport, (int)fromX, (int)fromY, TimeSpan.Zero)); + dragSequence.AddAction(touchDevice.CreatePointerDown(PointerButton.TouchContact)); + dragSequence.AddAction(touchDevice.CreatePointerMove(CoordinateOrigin.Viewport, (int)toX, (int)toY, TimeSpan.FromMilliseconds(250))); + dragSequence.AddAction(touchDevice.CreatePointerUp(PointerButton.TouchContact)); + driver.PerformActions([dragSequence]); } } } \ No newline at end of file diff --git a/src/Plugin.Maui.UITestHelpers.Appium/Actions/AppiumScrollActions.cs b/src/Plugin.Maui.UITestHelpers.Appium/Actions/AppiumScrollActions.cs index 647c1184..6427a701 100644 --- a/src/Plugin.Maui.UITestHelpers.Appium/Actions/AppiumScrollActions.cs +++ b/src/Plugin.Maui.UITestHelpers.Appium/Actions/AppiumScrollActions.cs @@ -1,5 +1,7 @@ using OpenQA.Selenium.Appium; +using OpenQA.Selenium.Appium.Interactions; using OpenQA.Selenium.Appium.MultiTouch; +using OpenQA.Selenium.Interactions; using Plugin.Maui.UITestHelpers.Core; namespace Plugin.Maui.UITestHelpers.Appium @@ -13,6 +15,8 @@ public enum ScrollStrategy public class AppiumScrollActions : ICommandExecutionGroup { + const int ScrollTouchDownTime = 100; + const int ProgrammaticallyScrollTime = 0; const string ScrollLeftCommand = "scrollLeft"; const string ScrollDownCommand = "scrollDown"; const string ScrollRightCommand = "scrollRight"; @@ -138,8 +142,8 @@ CommandResponse ScrollUp(IDictionary parameters) static void ScrollToLeft(AppiumDriver driver, AppiumElement element, ScrollStrategy strategy, double swipePercentage, int swipeSpeed, bool withInertia = true) { - var position = element.Location; - var size = element.Size; + var position = element is not null ? element.Location : System.Drawing.Point.Empty; + var size = element is not null ? element.Size : driver.Manage().Window.Size; int startX = (int)(position.X + (size.Width * 0.05)); int startY = position.Y + size.Height / 2; @@ -147,18 +151,20 @@ static void ScrollToLeft(AppiumDriver driver, AppiumElement element, ScrollStrat int endX = (int)(position.X + (size.Width * swipePercentage)); int endY = startY; - new TouchAction(driver) - .Press(startX, startY) - .Wait(strategy != ScrollStrategy.Programmatically ? swipeSpeed : 0) - .MoveTo(endX, endY) - .Release() - .Perform(); + var touchDevice = new OpenQA.Selenium.Appium.Interactions.PointerInputDevice(PointerKind.Touch); + var scrollSequence = new ActionSequence(touchDevice, 0); + scrollSequence.AddAction(touchDevice.CreatePointerMove(CoordinateOrigin.Viewport, startX, startY, TimeSpan.Zero)); + scrollSequence.AddAction(touchDevice.CreatePointerDown(PointerButton.TouchContact)); + scrollSequence.AddAction(touchDevice.CreatePause(TimeSpan.FromMilliseconds(ScrollTouchDownTime))); + scrollSequence.AddAction(touchDevice.CreatePointerMove(CoordinateOrigin.Viewport, endX, endY, TimeSpan.FromMilliseconds(strategy != ScrollStrategy.Programmatically ? swipeSpeed : ProgrammaticallyScrollTime))); + scrollSequence.AddAction(touchDevice.CreatePointerUp(PointerButton.TouchContact)); + driver.PerformActions([scrollSequence]); } static void ScrollToDown(AppiumDriver driver, AppiumElement element, ScrollStrategy strategy, double swipePercentage, int swipeSpeed, bool withInertia = true) { - var position = element.Location; - var size = element.Size; + var position = element is not null ? element.Location : System.Drawing.Point.Empty; + var size = element is not null ? element.Size : driver.Manage().Window.Size; int startX = position.X + size.Width / 2; int startY = (int)(position.Y + (size.Height * swipePercentage)); @@ -166,18 +172,20 @@ static void ScrollToDown(AppiumDriver driver, AppiumElement element, ScrollStrat int endX = startX; int endY = (int)(position.Y + (size.Height * 0.05)); - new TouchAction(driver) - .Press(startX, startY) - .Wait(strategy != ScrollStrategy.Programmatically ? swipeSpeed : 0) - .MoveTo(endX, endY) - .Release() - .Perform(); + var touchDevice = new OpenQA.Selenium.Appium.Interactions.PointerInputDevice(PointerKind.Touch); + var scrollSequence = new ActionSequence(touchDevice, 0); + scrollSequence.AddAction(touchDevice.CreatePointerMove(CoordinateOrigin.Viewport, startX, startY, TimeSpan.Zero)); + scrollSequence.AddAction(touchDevice.CreatePointerDown(PointerButton.TouchContact)); + scrollSequence.AddAction(touchDevice.CreatePause(TimeSpan.FromMilliseconds(ScrollTouchDownTime))); + scrollSequence.AddAction(touchDevice.CreatePointerMove(CoordinateOrigin.Viewport, endX, endY, TimeSpan.FromMilliseconds(strategy != ScrollStrategy.Programmatically ? swipeSpeed : ProgrammaticallyScrollTime))); + scrollSequence.AddAction(touchDevice.CreatePointerUp(PointerButton.TouchContact)); + driver.PerformActions([scrollSequence]); } static void ScrollToRight(AppiumDriver driver, AppiumElement element, ScrollStrategy strategy, double swipePercentage, int swipeSpeed, bool withInertia = true) { - var position = element.Location; - var size = element.Size; + var position = element is not null ? element.Location : System.Drawing.Point.Empty; + var size = element is not null ? element.Size : driver.Manage().Window.Size; int startX = (int)(position.X + (size.Width * swipePercentage)); int startY = position.Y + size.Height / 2; @@ -185,18 +193,20 @@ static void ScrollToRight(AppiumDriver driver, AppiumElement element, ScrollStra int endX = (int)(position.X + (size.Width * 0.05)); int endY = startY; - new TouchAction(driver) - .Press(startX, startY) - .Wait(strategy != ScrollStrategy.Programmatically ? swipeSpeed : 0) - .MoveTo(endX, endY) - .Release() - .Perform(); + var touchDevice = new OpenQA.Selenium.Appium.Interactions.PointerInputDevice(PointerKind.Touch); + var scrollSequence = new ActionSequence(touchDevice, 0); + scrollSequence.AddAction(touchDevice.CreatePointerMove(CoordinateOrigin.Viewport, startX, startY, TimeSpan.Zero)); + scrollSequence.AddAction(touchDevice.CreatePointerDown(PointerButton.TouchContact)); + scrollSequence.AddAction(touchDevice.CreatePause(TimeSpan.FromMilliseconds(ScrollTouchDownTime))); + scrollSequence.AddAction(touchDevice.CreatePointerMove(CoordinateOrigin.Viewport, endX, endY, TimeSpan.FromMilliseconds(strategy != ScrollStrategy.Programmatically ? swipeSpeed : ProgrammaticallyScrollTime))); + scrollSequence.AddAction(touchDevice.CreatePointerUp(PointerButton.TouchContact)); + driver.PerformActions([scrollSequence]); } static void ScrollToUp(AppiumDriver driver, AppiumElement element, ScrollStrategy strategy, double swipePercentage, int swipeSpeed, bool withInertia = true) { - var position = element.Location; - var size = element.Size; + var position = element is not null ? element.Location : System.Drawing.Point.Empty; + var size = element is not null ? element.Size : driver.Manage().Window.Size; int startX = position.X + size.Width / 2; int startY = (int)(position.Y + (size.Height * 0.05)); @@ -204,12 +214,14 @@ static void ScrollToUp(AppiumDriver driver, AppiumElement element, ScrollStrateg int endX = startX; int endY = (int)(position.Y + (size.Height * swipePercentage)); - new TouchAction(driver) - .Press(startX, startY) - .Wait(strategy != ScrollStrategy.Programmatically ? swipeSpeed : 0) - .MoveTo(endX, endY) - .Release() - .Perform(); + var touchDevice = new OpenQA.Selenium.Appium.Interactions.PointerInputDevice(PointerKind.Touch); + var scrollSequence = new ActionSequence(touchDevice, 0); + scrollSequence.AddAction(touchDevice.CreatePointerMove(CoordinateOrigin.Viewport, startX, startY, TimeSpan.Zero)); + scrollSequence.AddAction(touchDevice.CreatePointerDown(PointerButton.TouchContact)); + scrollSequence.AddAction(touchDevice.CreatePause(TimeSpan.FromMilliseconds(ScrollTouchDownTime))); + scrollSequence.AddAction(touchDevice.CreatePointerMove(CoordinateOrigin.Viewport, endX, endY, TimeSpan.FromMilliseconds(strategy != ScrollStrategy.Programmatically ? swipeSpeed : ProgrammaticallyScrollTime))); + scrollSequence.AddAction(touchDevice.CreatePointerUp(PointerButton.TouchContact)); + driver.PerformActions([scrollSequence]); } } } diff --git a/src/Plugin.Maui.UITestHelpers.Appium/Actions/AppiumSliderActions.cs b/src/Plugin.Maui.UITestHelpers.Appium/Actions/AppiumSliderActions.cs index 2512dc33..d98820cc 100644 --- a/src/Plugin.Maui.UITestHelpers.Appium/Actions/AppiumSliderActions.cs +++ b/src/Plugin.Maui.UITestHelpers.Appium/Actions/AppiumSliderActions.cs @@ -1,5 +1,7 @@ using OpenQA.Selenium.Appium; +using OpenQA.Selenium.Appium.Interactions; using OpenQA.Selenium.Appium.MultiTouch; +using OpenQA.Selenium.Interactions; using Plugin.Maui.UITestHelpers.Core; namespace Plugin.Maui.UITestHelpers.Appium @@ -75,14 +77,15 @@ static void SetSliderValue(AppiumDriver driver, AppiumElement? element, double v int x = position.X; int y = position.Y; - double moveToX = (x + size.Width) * value / maximum; + int moveToX = (int)((x + size.Width) * value / maximum); - TouchAction touchAction = new TouchAction(driver); - touchAction - .Press(x, y) - .MoveTo(moveToX, y) - .Release() - .Perform(); + var touchDevice = new OpenQA.Selenium.Appium.Interactions.PointerInputDevice(PointerKind.Touch); + var touchSequence = new ActionSequence(touchDevice, 0); + touchSequence.AddAction(touchDevice.CreatePointerMove(CoordinateOrigin.Viewport, x, y, TimeSpan.Zero)); + touchSequence.AddAction(touchDevice.CreatePointerDown(PointerButton.TouchContact)); + touchSequence.AddAction(touchDevice.CreatePointerMove(CoordinateOrigin.Viewport, moveToX, y, TimeSpan.FromMicroseconds(250))); + touchSequence.AddAction(touchDevice.CreatePointerUp(PointerButton.TouchContact)); + driver.PerformActions([touchSequence]); } } } \ No newline at end of file diff --git a/src/Plugin.Maui.UITestHelpers.Appium/Actions/AppiumSwipeActions.cs b/src/Plugin.Maui.UITestHelpers.Appium/Actions/AppiumSwipeActions.cs index dd085003..608ccf33 100644 --- a/src/Plugin.Maui.UITestHelpers.Appium/Actions/AppiumSwipeActions.cs +++ b/src/Plugin.Maui.UITestHelpers.Appium/Actions/AppiumSwipeActions.cs @@ -1,5 +1,7 @@ using OpenQA.Selenium.Appium; +using OpenQA.Selenium.Appium.Interactions; using OpenQA.Selenium.Appium.MultiTouch; +using OpenQA.Selenium.Interactions; using Plugin.Maui.UITestHelpers.Core; namespace Plugin.Maui.UITestHelpers.Appium @@ -90,12 +92,13 @@ static void SwipeToRight(AppiumDriver driver, AppiumElement? element, double swi int endX = (int)(position.X + (size.Width * swipePercentage)); int endY = startY; - new TouchAction(driver) - .Press(startX, startY) - .Wait(swipeSpeed) - .MoveTo(endX, endY) - .Release() - .Perform(); + var touchDevice = new OpenQA.Selenium.Appium.Interactions.PointerInputDevice(PointerKind.Touch); + var swipeSequence = new ActionSequence(touchDevice, 0); + swipeSequence.AddAction(touchDevice.CreatePointerMove(CoordinateOrigin.Viewport, startX, startY, TimeSpan.Zero)); + swipeSequence.AddAction(touchDevice.CreatePointerDown(PointerButton.TouchContact)); + swipeSequence.AddAction(touchDevice.CreatePointerMove(CoordinateOrigin.Viewport, endX, endY, TimeSpan.FromMilliseconds(swipeSpeed))); + swipeSequence.AddAction(touchDevice.CreatePointerUp(PointerButton.TouchContact)); + driver.PerformActions([swipeSequence]); } static void SwipeToLeft(AppiumDriver driver, AppiumElement? element, double swipePercentage, int swipeSpeed, bool withInertia = true) @@ -109,12 +112,13 @@ static void SwipeToLeft(AppiumDriver driver, AppiumElement? element, double swip int endX = (int)(position.X + (size.Width * 0.05)); int endY = startY; - new TouchAction(driver) - .Press(startX, startY) - .Wait(swipeSpeed) - .MoveTo(endX, endY) - .Release() - .Perform(); + var touchDevice = new OpenQA.Selenium.Appium.Interactions.PointerInputDevice(PointerKind.Touch); + var swipeSequence = new ActionSequence(touchDevice, 0); + swipeSequence.AddAction(touchDevice.CreatePointerMove(CoordinateOrigin.Viewport, startX, startY, TimeSpan.Zero)); + swipeSequence.AddAction(touchDevice.CreatePointerDown(PointerButton.TouchContact)); + swipeSequence.AddAction(touchDevice.CreatePointerMove(CoordinateOrigin.Viewport, endX, endY, TimeSpan.FromMilliseconds(swipeSpeed))); + swipeSequence.AddAction(touchDevice.CreatePointerUp(PointerButton.TouchContact)); + driver.PerformActions([swipeSequence]); } } } \ No newline at end of file diff --git a/src/Plugin.Maui.UITestHelpers.Appium/AppiumApp.cs b/src/Plugin.Maui.UITestHelpers.Appium/AppiumApp.cs index d6462edc..119f4d6b 100644 --- a/src/Plugin.Maui.UITestHelpers.Appium/AppiumApp.cs +++ b/src/Plugin.Maui.UITestHelpers.Appium/AppiumApp.cs @@ -38,7 +38,7 @@ public AppiumApp(AppiumDriver driver, IConfig config) public FileInfo Screenshot(string fileName) { Screenshot screenshot = _driver.GetScreenshot(); - screenshot.SaveAsFile(fileName, ScreenshotImageFormat.Png); + screenshot.SaveAsFile(fileName); var file = new FileInfo(fileName); return file; } diff --git a/src/Plugin.Maui.UITestHelpers.Appium/Plugin.Maui.UITestHelpers.Appium.csproj b/src/Plugin.Maui.UITestHelpers.Appium/Plugin.Maui.UITestHelpers.Appium.csproj index 61935986..389b18b9 100644 --- a/src/Plugin.Maui.UITestHelpers.Appium/Plugin.Maui.UITestHelpers.Appium.csproj +++ b/src/Plugin.Maui.UITestHelpers.Appium/Plugin.Maui.UITestHelpers.Appium.csproj @@ -27,8 +27,8 @@ - - + +