diff --git a/Ginger/Ginger/Actions/ActionEditPages/ActMobileDeviceEditPage.xaml b/Ginger/Ginger/Actions/ActionEditPages/ActMobileDeviceEditPage.xaml index ec4e98cbe4..3425a426e2 100644 --- a/Ginger/Ginger/Actions/ActionEditPages/ActMobileDeviceEditPage.xaml +++ b/Ginger/Ginger/Actions/ActionEditPages/ActMobileDeviceEditPage.xaml @@ -12,7 +12,7 @@ @@ -55,5 +55,32 @@ + + + + + + + + + + + + + + + + + diff --git a/Ginger/Ginger/Actions/ActionEditPages/ActMobileDeviceEditPage.xaml.cs b/Ginger/Ginger/Actions/ActionEditPages/ActMobileDeviceEditPage.xaml.cs index f3be6e8f7c..9f94c6296a 100644 --- a/Ginger/Ginger/Actions/ActionEditPages/ActMobileDeviceEditPage.xaml.cs +++ b/Ginger/Ginger/Actions/ActionEditPages/ActMobileDeviceEditPage.xaml.cs @@ -66,6 +66,13 @@ private void BindControls() xPhotoSumilationTxtBox.Init(Context.GetAsContext(mAct.Context), mAct.GetOrCreateInputParam(nameof(ActMobileDevice.SimulatedPhotoPath)), true, true, UCValueExpression.eBrowserType.File, "*", ValueTextBox_ClickBrowse); + xAppPackageVE.Init(Context.GetAsContext(mAct.Context), mAct.ActionAppPackage, nameof(ActInputValue.Value)); + + xPressDurationTxtBox.Init(Context.GetAsContext(mAct.Context), mAct.PressDuration, nameof(ActInputValue.Value)); + xDragDurationTxtBox.Init(Context.GetAsContext(mAct.Context), mAct.DragDuration, nameof(ActInputValue.Value)); + xSwipeScaleTxtBox.Init(Context.GetAsContext(mAct.Context), mAct.SwipeScale, nameof(ActInputValue.Value)); + xSwipeDurationTxtBox.Init(Context.GetAsContext(mAct.Context), mAct.SwipeDuration, nameof(ActInputValue.Value)); + UpdateBaseLineImage(true); @@ -196,6 +203,10 @@ private void SetControlsView() xXY2Pnl.Visibility = Visibility.Collapsed; xPhotoSimulationPnl.Visibility = Visibility.Collapsed; xAuthSimulationPnl.Visibility = Visibility.Collapsed; + xAppPnl.Visibility = Visibility.Collapsed; + xPressPnl.Visibility = Visibility.Collapsed; + xDragPnl.Visibility = Visibility.Collapsed; + xSwipePnl.Visibility = Visibility.Collapsed; switch (mAct.MobileDeviceAction) { @@ -204,24 +215,52 @@ private void SetControlsView() xKeyPressPnl.Visibility = Visibility.Visible; break; - case ActMobileDevice.eMobileDeviceAction.PressXY: - case ActMobileDevice.eMobileDeviceAction.LongPressXY: case ActMobileDevice.eMobileDeviceAction.TapXY: + case ActMobileDevice.eMobileDeviceAction.DoubleTapXY: + case ActMobileDevice.eMobileDeviceAction.LongPressXY: xXY1Pnl.Visibility = Visibility.Visible; break; + case ActMobileDevice.eMobileDeviceAction.PressXY: + xXY1Pnl.Visibility = Visibility.Visible; + xPressPnl.Visibility = Visibility.Visible; + break; + case ActMobileDevice.eMobileDeviceAction.DragXYXY: + xXY1Pnl.Visibility = Visibility.Visible; + xXY2Pnl.Visibility = Visibility.Visible; + xPressPnl.Visibility = Visibility.Visible; + xDragPnl.Visibility = Visibility.Visible; + break; + case ActMobileDevice.eMobileDeviceAction.SwipeByCoordinates: xXY1Pnl.Visibility = Visibility.Visible; xXY2Pnl.Visibility = Visibility.Visible; + xSwipePnl.Visibility = Visibility.Visible; + xSwipeScalePnl.Visibility = Visibility.Collapsed; + break; + + case ActMobileDevice.eMobileDeviceAction.SwipeDown: + case ActMobileDevice.eMobileDeviceAction.SwipeUp: + case ActMobileDevice.eMobileDeviceAction.SwipeLeft: + case ActMobileDevice.eMobileDeviceAction.SwipeRight: + xSwipePnl.Visibility = Visibility.Visible; + xSwipeScalePnl.Visibility = Visibility.Visible; break; + case ActMobileDevice.eMobileDeviceAction.SimulatePhoto: case ActMobileDevice.eMobileDeviceAction.SimulateBarcode: xPhotoSimulationPnl.Visibility = Visibility.Visible; break; + case ActMobileDevice.eMobileDeviceAction.SimulateBiometrics: xAuthSimulationPnl.Visibility = Visibility.Visible; break; + + case ActMobileDevice.eMobileDeviceAction.CloseApp: + case ActMobileDevice.eMobileDeviceAction.OpenApp: + xAppPnl.Visibility = Visibility.Visible; + break; } } diff --git a/Ginger/Ginger/Drivers/DriversWindows/MobileDriverWindow.xaml b/Ginger/Ginger/Drivers/DriversWindows/MobileDriverWindow.xaml index bd1056db19..cccd98e3b4 100644 --- a/Ginger/Ginger/Drivers/DriversWindows/MobileDriverWindow.xaml +++ b/Ginger/Ginger/Drivers/DriversWindows/MobileDriverWindow.xaml @@ -4,11 +4,11 @@ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:UserControls="clr-namespace:Amdocs.Ginger.UserControls" xmlns:Ginger="clr-namespace:Ginger" xmlns:GingerCore="clr-namespace:GingerCore;assembly=GingerCore" mc:Ignorable="d" - Title="Loading Device..." Height="685" Width="323" - MinHeight="600" MinWidth="300" WindowStyle="SingleBorderWindow" + Title="Loading Device..." Height="685" Width="323" + MinHeight="600" MinWidth="300" WindowStyle="ToolWindow" ResizeMode="CanMinimize" WindowStartupLocation="CenterScreen" Closing="Window_Closing" SizeChanged="Window_SizeChanged" Loaded="Window_Loaded" Topmost="False" KeyDown="Window_KeyDown"> - + @@ -24,16 +24,16 @@ - - - - - - - - - - + + + + + + + + + + @@ -46,20 +46,18 @@ - - - - - - - - - - - + + + + + + + + + @@ -74,12 +72,11 @@ - - + + - @@ -97,10 +94,10 @@ - - - - + + + + @@ -110,6 +107,7 @@ + @@ -211,6 +209,10 @@ + + + + diff --git a/Ginger/Ginger/Drivers/DriversWindows/MobileDriverWindow.xaml.cs b/Ginger/Ginger/Drivers/DriversWindows/MobileDriverWindow.xaml.cs index 207dd21ca6..299a2d0754 100644 --- a/Ginger/Ginger/Drivers/DriversWindows/MobileDriverWindow.xaml.cs +++ b/Ginger/Ginger/Drivers/DriversWindows/MobileDriverWindow.xaml.cs @@ -232,6 +232,10 @@ await this.Dispatcher.InvokeAsync(async () => SetOrientationButton(); xSwipeBtn.Visibility = Visibility.Visible; xCordBtn.Visibility = Visibility.Visible; + if (mDriver.IsUftLabDevice) + { + xExternalViewBtn.Visibility = Visibility.Visible; + } DoContinualDeviceScreenshotRefresh(); Dictionary mDeviceGeneralInfo; @@ -658,6 +662,7 @@ private void Window_SizeChanged(object sender, SizeChangedEventArgs e) } DateTime mClickStartTime; + DateTime mMoveStartTime; private void xDeviceScreenshotImage_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) { mClickStartTime = DateTime.Now; @@ -677,6 +682,7 @@ private void xDeviceScreenshotImage_MouseLeftButtonDown(object sender, MouseButt private void xDeviceScreenshotImage_MouseMove(object sender, MouseEventArgs e) { + mMoveStartTime = DateTime.Now; if (mIsMousePressed == true) { //it's a drag @@ -720,19 +726,23 @@ private void xDeviceScreenshotImage_MouseLeftButtonUp(object sender, MouseButton } mIsMousePressed = false; + TimeSpan pressDuration; + if (mIsItDragAction == true) { //do drag mIsItDragAction = false; - DeviceScreenshotImageMouseDragAsync(mMouseStartPoint, mMouseEndPoint); + pressDuration = mMoveStartTime - mClickStartTime; + TimeSpan dragDuration = clickEndTime - mMoveStartTime; + DeviceScreenshotImageMouseDragAsync(mMouseStartPoint, mMouseEndPoint, pressDuration, dragDuration); } else { - TimeSpan clickDuration = clickEndTime - mClickStartTime; - if (clickDuration.TotalSeconds > 1) + pressDuration = clickEndTime - mClickStartTime; + if (pressDuration.TotalSeconds > 1) { //do long press - DeviceScreenshotImageMouseClickAsync(mMouseEndPoint, true); + DeviceScreenshotImageMouseClickAsync(mMouseEndPoint, true, pressDuration); } else { @@ -744,15 +754,13 @@ private void xDeviceScreenshotImage_MouseLeftButtonUp(object sender, MouseButton private void xDeviceScreenshotImage_MouseWheel(object sender, MouseWheelEventArgs e) { - //System.Windows.Point mMousePoint = e.GetPosition((System.Windows.Controls.Image)sender); - //DeviceScreenshotImageMouseDragAsync(mMousePoint, new System.Windows.Point(mMousePoint.X, mMousePoint.Y + e.Delta)); if (e.Delta > 0) { - PerformScreenSwipe(eSwipeSide.Up, 0.25); + PerformScreenSwipe(eSwipeSide.Up, 0.25, TimeSpan.FromMilliseconds(200)); } else { - PerformScreenSwipe(eSwipeSide.Down, 0.25); + PerformScreenSwipe(eSwipeSide.Down, 0.25, TimeSpan.FromMilliseconds(200)); } } @@ -1040,25 +1048,20 @@ private void xLockPnl_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e) { - //if (((Window)sender).IsKeyboardFocused) - //{ - mUserClosing = true; + mUserClosing = true; - if (!mSelfClosing) + if (!mSelfClosing) + { + try { - if (Reporter.ToUser(eUserMsgKey.StaticQuestionsMessage, "Close Mobile Agent?") == eUserMsgSelection.Yes) - { - try - { - mAgent.AgentOperations.Close(); - } - catch (Exception ex) - { - Reporter.ToUser(eUserMsgKey.StaticErrorMessage, "Failed to close Agent, Error: " + ex.Message); - } - } + mAgent.AgentOperations.Close(); } - //} + catch (Exception ex) + { + Reporter.ToUser(eUserMsgKey.StaticErrorMessage, "Failed to close Agent, Error: " + ex.Message); + } + } + mWindowIsOpen = false; } @@ -1144,32 +1147,32 @@ private void Window_KeyDown(object sender, KeyEventArgs e) private void xSwipeLeft_Click(object sender, RoutedEventArgs e) { - PerformScreenSwipe(eSwipeSide.Left); + PerformScreenSwipe(eSwipeSide.Left, 1, TimeSpan.FromMilliseconds(200)); } private void xSwipeRight_Click(object sender, RoutedEventArgs e) { - PerformScreenSwipe(eSwipeSide.Right); + PerformScreenSwipe(eSwipeSide.Right, 1, TimeSpan.FromMilliseconds(200)); } private void xSwipeUp_Click(object sender, RoutedEventArgs e) { - PerformScreenSwipe(eSwipeSide.Up, 0.25); + PerformScreenSwipe(eSwipeSide.Up, 1, TimeSpan.FromMilliseconds(200)); } private void xSwipeUp_MouseDoubleClick(object sender, MouseButtonEventArgs e) { - PerformScreenSwipe(eSwipeSide.Up, 0.5); + PerformScreenSwipe(eSwipeSide.Up, 1.5, TimeSpan.FromMilliseconds(200)); } private void xSwipeDown_MouseDoubleClick(object sender, MouseButtonEventArgs e) { - PerformScreenSwipe(eSwipeSide.Down, 0.5); + PerformScreenSwipe(eSwipeSide.Down, 1.5, TimeSpan.FromMilliseconds(200)); } private void xSwipeDown_Click(object sender, RoutedEventArgs e) { - PerformScreenSwipe(eSwipeSide.Down, 0.25); + PerformScreenSwipe(eSwipeSide.Down, 1, TimeSpan.FromMilliseconds(200)); } private void xDeviceSettingsBtn_Click(object sender, RoutedEventArgs e) @@ -1208,7 +1211,7 @@ public void InitWindowLook() } this.Width = 320; - this.Height = 650; + this.Height = 650; xMessageLbl.Content = "Connecting to Device..."; //Configurations @@ -1245,6 +1248,7 @@ public void InitWindowLook() xPortraiteBtn.ButtonStyle = FindResource("$ImageButtonStyle_WhiteSmoke") as Style; xLandscapeBtn.ButtonStyle = FindResource("$ImageButtonStyle_WhiteSmoke") as Style; xMetricsBtn.ButtonStyle = FindResource("$ImageButtonStyle_WhiteSmoke") as Style; + xExternalViewBtn.ButtonStyle = FindResource("$ImageButtonStyle_WhiteSmoke") as Style; xPinBtn_Click(null, null); //Loading Pnl @@ -1500,7 +1504,7 @@ private System.Windows.Point GetPointOnMobile(System.Windows.Point pointOnImage) } } - private async void DeviceScreenshotImageMouseClickAsync(System.Windows.Point clickedPoint, bool performLongPress = false) + private async void DeviceScreenshotImageMouseClickAsync(System.Windows.Point clickedPoint, bool performLongPress = false, TimeSpan? clickDuration=null) { try { @@ -1516,7 +1520,7 @@ await Task.Run(() => { try { - mDriver.PerformLongPress(pointOnMobile_X, pointOnMobile_Y); + mDriver.PerformLongPress(pointOnMobile_X, pointOnMobile_Y, clickDuration); } catch (Exception ex) { @@ -1552,7 +1556,7 @@ await Task.Run(() => } } - private async void DeviceScreenshotImageMouseDragAsync(System.Windows.Point startPoint, System.Windows.Point endPoint) + private async void DeviceScreenshotImageMouseDragAsync(System.Windows.Point startPoint, System.Windows.Point endPoint, TimeSpan pressDuration, TimeSpan dragDuration) { try { @@ -1564,7 +1568,7 @@ await Task.Run(() => { try { - mDriver.PerformDrag(new System.Drawing.Point((int)startPoint.X, (int)startPoint.Y), new System.Drawing.Point((int)endPoint.X, (int)endPoint.Y)); + mDriver.PerformDrag(new System.Drawing.Point((int)startPoint.X, (int)startPoint.Y), new System.Drawing.Point((int)endPoint.X, (int)endPoint.Y), pressDuration, dragDuration); } catch (Exception ex) { @@ -1637,11 +1641,11 @@ private void DoSelfClose() } } - private void PerformScreenSwipe(eSwipeSide swipeSide, double impact = 1) + private void PerformScreenSwipe(eSwipeSide swipeSide, double swipeScale, TimeSpan swipeDuration) { try { - mDriver.PerformScreenSwipe(swipeSide, impact); + mDriver.PerformScreenSwipe(swipeSide, swipeScale, swipeDuration); if (mDeviceAutoScreenshotRefreshMode == eAutoScreenshotRefreshMode.PostOperation) { @@ -1727,5 +1731,42 @@ private void xCordsStack_MouseEnter(object sender, MouseEventArgs e) } Canvas.SetLeft(xCordsStack, mCordsStackZIndex); } + + private void xExternalViewBtn_Click(object sender, RoutedEventArgs e) + { + mDriver.OpenDeviceExternalView(); + } + + double imageSourceWidthPrecentage = 0.2; + private void xZoomInBtn_Click(object sender, RoutedEventArgs e) + { + imageSourceWidthPrecentage += 0.05; + AdjustWindowSize(imageSourceWidthPrecentage); + } + + private void xZoomOutBtn_Click(object sender, RoutedEventArgs e) + { + imageSourceWidthPrecentage -= 0.05; + AdjustWindowSize(imageSourceWidthPrecentage); + } + + private void AdjustWindowSize(double widthPrecentage) + { + + if (xDeviceScreenshotImage.Source != null && widthPrecentage > 0.2 && widthPrecentage < 0.5) + { + double imageSourceHightWidthRatio = xDeviceScreenshotImage.Source.Height / xDeviceScreenshotImage.Source.Width; + double previousCanasWidth = xDeviceScreenshotCanvas.ActualWidth; + double previousCanasHeight = xDeviceScreenshotCanvas.ActualHeight; + + //Update canvas size + xDeviceScreenshotCanvas.Width = (xDeviceScreenshotImage.Source.Width * widthPrecentage); + xDeviceScreenshotCanvas.Height = xDeviceScreenshotCanvas.Width * imageSourceHightWidthRatio; + + //Update window size + this.Width = this.Width + (xDeviceScreenshotCanvas.Width - previousCanasWidth); + this.Height = this.Height + (xDeviceScreenshotCanvas.Height - previousCanasHeight); + } + } } } diff --git a/Ginger/GingerCoreNET/ActionsLib/UI/Legacy/ActGenElement.cs b/Ginger/GingerCoreNET/ActionsLib/UI/Legacy/ActGenElement.cs index 3e09456e68..1d11760a03 100644 --- a/Ginger/GingerCoreNET/ActionsLib/UI/Legacy/ActGenElement.cs +++ b/Ginger/GingerCoreNET/ActionsLib/UI/Legacy/ActGenElement.cs @@ -615,6 +615,10 @@ public enum eGenElementAction Enabled = 52, [EnumValueDescription("Tap Element")] TapElement = 53, + [EnumValueDescription("Double Tap Element")] + DoubleTapElement=68, + [EnumValueDescription("Press Element")] + PressElement = 69, [EnumValueDescription("Select From Drop Down (By Index)")] SelectFromDropDownByIndex = 54, XYClick = 55, diff --git a/Ginger/GingerCoreNET/ActionsLib/UI/Mobile/ActMobileDevice.cs b/Ginger/GingerCoreNET/ActionsLib/UI/Mobile/ActMobileDevice.cs index 1d25e4f084..85ee59c93a 100644 --- a/Ginger/GingerCoreNET/ActionsLib/UI/Mobile/ActMobileDevice.cs +++ b/Ginger/GingerCoreNET/ActionsLib/UI/Mobile/ActMobileDevice.cs @@ -180,6 +180,58 @@ public ActInputValue ActionAppPackage } } + public ActInputValue PressDuration + { + get + { + return GetOrCreateInputParam(nameof(PressDuration), "200"); + } + set + { + AddOrUpdateInputParamValue(nameof(PressDuration), value.ToString()); + OnPropertyChanged(nameof(PressDuration)); + } + } + + public ActInputValue DragDuration + { + get + { + return GetOrCreateInputParam(nameof(DragDuration), "200"); + } + set + { + AddOrUpdateInputParamValue(nameof(DragDuration), value.ToString()); + OnPropertyChanged(nameof(DragDuration)); + } + } + + public ActInputValue SwipeScale + { + get + { + return GetOrCreateInputParam(nameof(SwipeScale), "1"); + } + set + { + AddOrUpdateInputParamValue(nameof(SwipeScale), value.ToString()); + OnPropertyChanged(nameof(SwipeScale)); + } + } + + public ActInputValue SwipeDuration + { + get + { + return GetOrCreateInputParam(nameof(SwipeDuration), "200"); + } + set + { + AddOrUpdateInputParamValue(nameof(SwipeDuration), value.ToString()); + OnPropertyChanged(nameof(SwipeDuration)); + } + } + public string mSimulatedPhotoPath; public ActInputValue SimulatedPhotoPath { @@ -250,7 +302,9 @@ public enum eMobileDeviceAction [EnumValueDescription("Long Press XY")] LongPressXY, [EnumValueDescription("Tap XY")] - TapXY, + TapXY, + [EnumValueDescription("Double Tap XY")] + DoubleTapXY, [EnumValueDescription("Drag XY to XY")] DragXYXY, [EnumValueDescription("Get Current Application Identifiers")] diff --git a/Ginger/GingerCoreNET/Drivers/CoreDrivers/Mobile/Appium/GenericAppiumDriver.cs b/Ginger/GingerCoreNET/Drivers/CoreDrivers/Mobile/Appium/GenericAppiumDriver.cs index a033aa31ef..7a8e42c1da 100644 --- a/Ginger/GingerCoreNET/Drivers/CoreDrivers/Mobile/Appium/GenericAppiumDriver.cs +++ b/Ginger/GingerCoreNET/Drivers/CoreDrivers/Mobile/Appium/GenericAppiumDriver.cs @@ -53,13 +53,14 @@ limitations under the License. using OpenQA.Selenium; using OpenQA.Selenium.Appium; using OpenQA.Selenium.Appium.Android; -using OpenQA.Selenium.Appium.Interfaces; +using OpenQA.Selenium.Appium.Interactions; using OpenQA.Selenium.Appium.iOS; -using OpenQA.Selenium.Appium.MultiTouch; +using OpenQA.Selenium.Interactions; using OpenQA.Selenium.Remote; using RestSharp; using System; using System.Collections.Generic; +using System.Diagnostics; using System.Drawing; using System.Drawing.Imaging; using System.IO; @@ -68,6 +69,9 @@ limitations under the License. using System.Text; using System.Threading.Tasks; using System.Xml; +using AppiumInteractions = OpenQA.Selenium.Appium.Interactions; + + namespace Amdocs.Ginger.CoreNET { @@ -169,6 +173,21 @@ public bool IsDeviceConnected set => mIsDeviceConnected = value; } + public bool IsUftLabDevice + { + get + { + if (DeviceSource == eDeviceSource.MicroFoucsUFTMLab) + { + return true; + } + else + { + return false; + } + } + } + RestClient restClient; public bool ShowWindow @@ -176,19 +195,19 @@ public bool ShowWindow get => LoadDeviceWindow; } - public override ePomElementCategory? PomCategory + public override ePomElementCategory? PomCategory { get { if (AppType == eAppType.NativeHybride) { - switch(DevicePlatformType) + switch (DevicePlatformType) { case eDevicePlatformType.iOS: - return ePomElementCategory.iOS; + return ePomElementCategory.iOS; case eDevicePlatformType.Android: default: - return ePomElementCategory.Android; + return ePomElementCategory.Android; } } else @@ -235,7 +254,7 @@ public GenericAppiumDriver(BusinessFlow BF) public override void StartDriver() { - mIsDeviceConnected = ConnectToAppium(); + mIsDeviceConnected = ConnectToAppium(); OnDriverMessage(eDriverMessageType.DriverStatusChanged); } @@ -291,7 +310,7 @@ public bool ConnectToAppium() ErrorMessageFromDriver = error; return false; } - + if (Driver.Capabilities.HasCapability("message") && Driver.Capabilities.GetCapability("message").ToString() == "Could not find available device") { string error = string.Format("Failed to start Appium session.{0}Error: Mobile device is already in use. Please close all other sessions and try again.", System.Environment.NewLine); @@ -326,34 +345,10 @@ public bool ConnectToAppium() string error = string.Format("Failed to start Appium session.{0}Error: '{1}'", System.Environment.NewLine, ex.Message); Reporter.ToLog(eLogLevel.ERROR, error, ex); ErrorMessageFromDriver = error; - - //if (!WorkSpace.Instance.RunningInExecutionMode) - //{ - // Reporter.ToUser(eUserMsgKey.MobileConnectionFailed, ex.Message); - //} return false; } } - //private static ICommandExecutor CreateRealExecutor(Uri remoteAddress, TimeSpan commandTimeout, IWebProxy proxy) - //{ - // var seleniumAssembly = Assembly.Load("WebDriver"); - // var commandType = seleniumAssembly.GetType("OpenQA.Selenium.Remote.HttpCommandExecutor"); - // ICommandExecutor commandExecutor = null; - - // if (null != commandType) - // { - // commandExecutor = - // Activator.CreateInstance(commandType, new object[] { remoteAddress, commandTimeout }) as - // ICommandExecutor; - // } - - // commandExecutor = new HttpCommandExecutor(remoteAddress, commandTimeout); - // ((HttpCommandExecutor)commandExecutor).Proxy = proxy; - - // return commandExecutor; - //} - private DriverOptions GetCapabilities() { //see http://appium.io/slate/en/master/?csharp#appium-server-capabilities for full list of capabilities values @@ -413,7 +408,7 @@ private DriverOptions GetCapabilities() else if (UserCapability.Parameter.Trim().ToLower() == "platformVersion".ToLower() || UserCapability.Parameter.Trim().ToLower() == "appium:platformVersion".ToLower()) { driverOptions.PlatformVersion = UserCapability.Value; - } + } else if (UserCapability.Parameter.Trim().ToLower() == "deviceName".ToLower() || UserCapability.Parameter.Trim().ToLower() == "appium:deviceName".ToLower()) { driverOptions.DeviceName = UserCapability.Value; @@ -436,7 +431,7 @@ private DriverOptions GetCapabilities() } } } - catch(Exception ex) + catch (Exception ex) { Reporter.ToLog(eLogLevel.ERROR, string.Format("Failed to set Appium capability '{0}'='{1}'", UserCapability.Parameter, UserCapability.Value), ex); } @@ -466,26 +461,6 @@ public override void CloseDriver() OnDriverMessage(eDriverMessageType.DriverStatusChanged); } - //public List LocateElements(eLocateBy LocatorType, string LocValue) - //{ - // if (AppType == eAppType.Web) - // return mSeleniumDriver.LocateElements(LocatorType, LocValue); - - // IReadOnlyCollection elem = null; - - // switch (LocatorType) - // { - // //need to override regular selenium driver locator if needed, - // //if not then to run the regular selenium driver locator for it to avoid duplication - - // default: - // elem = mSeleniumDriver.LocateElements(LocatorType, LocValue); - // break; - // } - - // return elem.ToList(); - //} - public IWebElement LocateElement(Act act) { //need to override regular selenium driver locator if needed, @@ -598,7 +573,7 @@ private void UIElementActionHandler(ActUIElement act) { case ActUIElement.eElementAction.JavaScriptClick: case ActUIElement.eElementAction.Submit: - e = LocateElement(act); + e = LocateElement(act); if (e != null) { e.Click(); @@ -611,7 +586,7 @@ private void UIElementActionHandler(ActUIElement act) case ActUIElement.eElementAction.SetValue: case ActUIElement.eElementAction.SetText: - e = LocateElement(act); + e = LocateElement(act); if (e != null) { e.SendKeys(act.GetInputParamCalculatedValue("Value")); @@ -624,7 +599,7 @@ private void UIElementActionHandler(ActUIElement act) case ActUIElement.eElementAction.GetText: case ActUIElement.eElementAction.GetFont: - e = LocateElement(act); + e = LocateElement(act); if (e != null) { /// As text attribute does not exist on iOS devices @@ -644,7 +619,7 @@ private void UIElementActionHandler(ActUIElement act) break; case ActUIElement.eElementAction.GetTextLength: - e = LocateElement(act); + e = LocateElement(act); if (e != null) { /// As text attribute does not exist on iOS devices @@ -670,7 +645,7 @@ private void UIElementActionHandler(ActUIElement act) break; case ActUIElement.eElementAction.IsValuePopulated: - e = LocateElement(act); + e = LocateElement(act); if (e != null) { switch (act.ElementType) @@ -691,7 +666,7 @@ private void UIElementActionHandler(ActUIElement act) break; case ActUIElement.eElementAction.GetSize: - e = LocateElement(act); + e = LocateElement(act); if (e != null) { act.AddOrUpdateReturnParamActual("Actual", e.GetAttribute("contentSize").ToString()); @@ -711,7 +686,8 @@ private void UIElementActionHandler(ActUIElement act) int numberOfMaxLoops = (element_Y - 500) / 200; while (!e.Displayed && numberOfMaxLoops > 0) { - (BuildTouchAction(Driver, element_X, 500, element_X, 300, 200)).Perform(); + //(BuildTouchAction(Driver, element_X, 500, element_X, 300, 200)).Perform(); + SwipeByXY(element_X, 500, element_X, 300, TimeSpan.FromMilliseconds(200)); numberOfMaxLoops--; } } @@ -720,7 +696,8 @@ private void UIElementActionHandler(ActUIElement act) int numberOfMaxLoops = 12; while (numberOfMaxLoops > 0) { - (BuildTouchAction(Driver, 500, 500, 500, 300, 200)).Perform(); + //(BuildTouchAction(Driver, 500, 500, 500, 300, 200)).Perform(); + SwipeByXY(500, 500, 500, 300, TimeSpan.FromMilliseconds(200)); e = LocateElement(act); if (e != null && e.Displayed) { @@ -745,9 +722,7 @@ private void UIElementActionHandler(ActUIElement act) break; case ActUIElement.eElementAction.ClickXY: - ITouchAction tc; - tc = new TouchAction(Driver); - tc.Press(Convert.ToInt32(act.GetInputParamCalculatedValue(ActUIElement.Fields.XCoordinate)), Convert.ToInt32(act.GetInputParamCalculatedValue(ActUIElement.Fields.YCoordinate))).Perform(); + TapXY(Convert.ToInt32(act.GetInputParamCalculatedValue(ActUIElement.Fields.XCoordinate)), Convert.ToInt32(act.GetInputParamCalculatedValue(ActUIElement.Fields.YCoordinate))); break; default: @@ -791,7 +766,7 @@ private void GenElementHandler(ActGenElement act) y = Convert.ToInt64(act.LocateValueCalculated.Split(',')[1]); } catch { x = 0; y = 0; } - TapXY(x, y); + TapXY((int)x, (int)y); } else { @@ -803,9 +778,32 @@ private void GenElementHandler(ActGenElement act) try { e = LocateElement(act); - TouchAction t = new TouchAction(Driver); - t.Tap(e, 1, 1); - Driver.PerformTouchAction(t); + TapElement(e, 1, 1); + } + catch (Exception ex) + { + act.Error = "Error: Action failed to be performed, Details: " + ex.Message; + } + break; + + + case ActGenElement.eGenElementAction.DoubleTapElement: + try + { + e = LocateElement(act); + DoubleTapElement(e, 1, 1); + } + catch (Exception ex) + { + act.Error = "Error: Action failed to be performed, Details: " + ex.Message; + } + break; + + case ActGenElement.eGenElementAction.PressElement: + try + { + e = LocateElement(act); + PressElement(e, 1, 1, TimeSpan.FromSeconds(1)); } catch (Exception ex) { @@ -821,7 +819,7 @@ private void GenElementHandler(ActGenElement act) //make sure value was cleared- trying to handle clear issue in WebViews try { - //TODO: Need to add a flag in the action for this case, as sometimes the value is clear but show text under like 'Searc, or say "OK Google". + //TODO: Need to add a flag in the action for this case, as sometimes the value is clear but show text under like 'Search, or say "OK Google". //Wasting time when not needed string elemntContent = e.Text; //.GetAttribute("name"); if (string.IsNullOrEmpty(elemntContent) == false) @@ -842,16 +840,12 @@ private void GenElementHandler(ActGenElement act) switch (DevicePlatformType) { case eDevicePlatformType.Android: - //e.Clear(); e.SendKeys(act.GetInputParamCalculatedValue("Value")); break; case eDevicePlatformType.iOS: - //e.Clear(); e.SendKeys(act.GetInputParamCalculatedValue("Value")); - //((IOSElement)e).SetImmediateValue(act.GetInputParamCalculatedValue("Value")); break; } - //if (DriverWindow != null) DriverWindow.ShowActionEfect(true, 100); } else { @@ -960,25 +954,79 @@ private void GenElementHandler(ActGenElement act) } } + private string GetAppPackage(ActMobileDevice act) + { + string appPackage = null; + if (string.IsNullOrEmpty(act.ActionAppPackage.ValueForDriver) || act.ActionAppPackage.ValueForDriver.ToLower().Trim() == "default") + { + if (DevicePlatformType == eDevicePlatformType.Android) + { + appPackage = AppiumCapabilities.FirstOrDefault(x => x.Parameter == "appPackage" || x.Parameter == "appium:appPackage").Value; + } + else + { + appPackage = AppiumCapabilities.FirstOrDefault(x => x.Parameter == "bundleId" || x.Parameter == "appium:bundleId").Value; + } + + return appPackage; + } + else + { + return act.ActionAppPackage.Value; + } + } + private void MobileDeviceActionHandler(ActMobileDevice act) { - ITouchAction tc; + //ITouchAction tc; try { switch (act.MobileDeviceAction) { + case ActMobileDevice.eMobileDeviceAction.TapXY: + TapXY(Convert.ToInt32(act.X1.ValueForDriver), Convert.ToInt32(act.Y1.ValueForDriver)); + break; + + case ActMobileDevice.eMobileDeviceAction.DoubleTapXY: + DoubleTapXY(Convert.ToInt32(act.X1.ValueForDriver), Convert.ToInt32(act.Y1.ValueForDriver)); + break; + case ActMobileDevice.eMobileDeviceAction.PressXY: - tc = new TouchAction(Driver); - tc.Press(Convert.ToInt32(act.X1.ValueForDriver), Convert.ToInt32(act.Y1.ValueForDriver)).Perform(); + PressXY(Convert.ToInt32(act.X1.ValueForDriver), Convert.ToInt32(act.Y1.ValueForDriver), + TimeSpan.FromMilliseconds(Convert.ToInt32(act.PressDuration.ValueForDriver))); break; case ActMobileDevice.eMobileDeviceAction.LongPressXY: - tc = new TouchAction(Driver); - tc.LongPress(Convert.ToInt32(act.X1.ValueForDriver), Convert.ToInt32(act.Y1.ValueForDriver)).Perform(); + PressXY(Convert.ToInt32(act.X1.ValueForDriver), Convert.ToInt32(act.Y1.ValueForDriver), TimeSpan.FromSeconds(3)); break; - case ActMobileDevice.eMobileDeviceAction.TapXY: - TapXY(Convert.ToInt32(act.X1.ValueForDriver), Convert.ToInt32(act.Y1.ValueForDriver)); + case ActMobileDevice.eMobileDeviceAction.DragXYXY: + DragAndDropByXY(Convert.ToInt32(act.X1.ValueForDriver), Convert.ToInt32(act.Y1.ValueForDriver), + Convert.ToInt32(act.X2.ValueForDriver), Convert.ToInt32(act.Y2.ValueForDriver), + TimeSpan.FromMilliseconds(Convert.ToInt32(act.PressDuration.ValueForDriver)), + TimeSpan.FromMilliseconds(Convert.ToInt32(act.DragDuration.ValueForDriver))); + break; + + case ActMobileDevice.eMobileDeviceAction.SwipeByCoordinates: + SwipeByXY(Convert.ToInt32(act.X1.ValueForDriver), Convert.ToInt32(act.Y1.ValueForDriver), + Convert.ToInt32(act.X2.ValueForDriver), Convert.ToInt32(act.Y2.ValueForDriver), + TimeSpan.FromMilliseconds(Convert.ToInt32(act.SwipeDuration.ValueForDriver))); + break; + + case ActMobileDevice.eMobileDeviceAction.SwipeDown: + SwipeScreen(eSwipeSide.Down, Convert.ToDouble(act.SwipeScale.ValueForDriver), TimeSpan.FromMilliseconds(Convert.ToInt32(act.SwipeDuration.ValueForDriver))); + break; + + case ActMobileDevice.eMobileDeviceAction.SwipeUp: + SwipeScreen(eSwipeSide.Up, Convert.ToDouble(act.SwipeScale.ValueForDriver), TimeSpan.FromMilliseconds(Convert.ToInt32(act.SwipeDuration.ValueForDriver))); + break; + + case ActMobileDevice.eMobileDeviceAction.SwipeLeft: + SwipeScreen(eSwipeSide.Left, Convert.ToDouble(act.SwipeScale.ValueForDriver), TimeSpan.FromMilliseconds(Convert.ToInt32(act.SwipeDuration.ValueForDriver))); + break; + + case ActMobileDevice.eMobileDeviceAction.SwipeRight: + SwipeScreen(eSwipeSide.Right, Convert.ToDouble(act.SwipeScale.ValueForDriver), TimeSpan.FromMilliseconds(Convert.ToInt32(act.SwipeDuration.ValueForDriver))); break; case ActMobileDevice.eMobileDeviceAction.PressBackButton: @@ -1048,30 +1096,10 @@ private void MobileDeviceActionHandler(ActMobileDevice act) } break; - case ActMobileDevice.eMobileDeviceAction.SwipeDown: - SwipeScreen(eSwipeSide.Down, 1); - break; - - case ActMobileDevice.eMobileDeviceAction.SwipeUp: - SwipeScreen(eSwipeSide.Up, 1); - break; - case ActMobileDevice.eMobileDeviceAction.SwipeLeft: - SwipeScreen(eSwipeSide.Left); - break; - - case ActMobileDevice.eMobileDeviceAction.SwipeRight: - SwipeScreen(eSwipeSide.Right); - break; - case ActMobileDevice.eMobileDeviceAction.TakeScreenShot: ActScreenShotHandler(act); break; - case ActMobileDevice.eMobileDeviceAction.DragXYXY: - DoDrag(Convert.ToInt32(act.X1.ValueForDriver), Convert.ToInt32(act.Y1.ValueForDriver), - Convert.ToInt32(act.X2.ValueForDriver), Convert.ToInt32(act.Y2.ValueForDriver)); - break; - case ActMobileDevice.eMobileDeviceAction.GetCurrentApplicationInfo: act.AddOrUpdateReturnParamActual("Current Application Identifiers", GetURL()); break; @@ -1079,18 +1107,14 @@ private void MobileDeviceActionHandler(ActMobileDevice act) case ActMobileDevice.eMobileDeviceAction.OpenApp: if (AppType == eAppType.NativeHybride) { - Driver.ActivateApp((GetAppPackage(act))); - } - else - { - act.Error = "Operation not supported for this mobile OS or application type."; + Driver.ActivateApp(GetAppPackage(act)); } break; case ActMobileDevice.eMobileDeviceAction.CloseApp: if (AppType == eAppType.NativeHybride) { - Driver.TerminateApp((GetAppPackage(act))); + Driver.TerminateApp(GetAppPackage(act)); } else { @@ -1098,48 +1122,45 @@ private void MobileDeviceActionHandler(ActMobileDevice act) } break; - case ActMobileDevice.eMobileDeviceAction.SwipeByCoordinates: - ITouchAction swipe; - swipe = BuildTouchAction(Driver, - Convert.ToInt32(act.X1.ValueForDriver), - Convert.ToInt32(act.Y1.ValueForDriver), - Convert.ToInt32(act.X2.ValueForDriver), - Convert.ToInt32(act.Y2.ValueForDriver), 1000); - swipe.Perform(); - break; - case ActMobileDevice.eMobileDeviceAction.GetPageSource: act.AddOrUpdateReturnParamActual("Page Source", Driver.PageSource); break; case ActMobileDevice.eMobileDeviceAction.LockDevice: - PerformLockButtonPress(eLockOperation.Lock); + PerformLockButtonPress(eLockOperation.Lock); break; + case ActMobileDevice.eMobileDeviceAction.UnlockDevice: - PerformLockButtonPress(eLockOperation.UnLock); + PerformLockButtonPress(eLockOperation.UnLock); break; + case ActMobileDevice.eMobileDeviceAction.GetDeviceBattery: AddReturnParamFromDict(GetDeviceBatteryInfo(), act); act.RawResponseValues = GetDeviceMetricsString("batteryinfo").Result; break; + case ActMobileDevice.eMobileDeviceAction.GetDeviceCPUUsage: AddReturnParamFromDict(GetDeviceCPUInfo(), act); act.RawResponseValues = GetDeviceMetricsString("cpuinfo").Result; break; + case ActMobileDevice.eMobileDeviceAction.GetDeviceNetwork: act.AddOrUpdateReturnParamActual("Device's network information", GetDeviceNetworkInfo()?.Result); act.RawResponseValues = GetDeviceMetricsString("networkinfo").Result; break; + case ActMobileDevice.eMobileDeviceAction.GetDeviceRAMUsage: AddReturnParamFromDict(GetDeviceMemoryInfo(), act); act.RawResponseValues = GetDeviceMetricsString("memoryinfo").Result; break; + case ActMobileDevice.eMobileDeviceAction.GetDeviceGeneralInfo: foreach (KeyValuePair entry in GetDeviceGeneralInfo()) { act.AddOrUpdateReturnParamActual(entry.Key, entry.Value.ToString()); } break; + case ActMobileDevice.eMobileDeviceAction.SimulatePhoto: string photoString = WorkSpace.Instance.Solution.SolutionOperations.ConvertSolutionRelativePath(act.GetOrCreateInputParam(nameof(act.SimulatedPhotoPath)).ValueForDriver); string photoSimulationResponse = SimulatePhotoOrBarcode(photoString, "camera"); @@ -1148,6 +1169,7 @@ private void MobileDeviceActionHandler(ActMobileDevice act) act.Error = photoSimulationResponse; } break; + case ActMobileDevice.eMobileDeviceAction.SimulateBarcode: string barcodeString = WorkSpace.Instance.Solution.SolutionOperations.ConvertSolutionRelativePath(act.GetOrCreateInputParam(nameof(act.SimulatedPhotoPath)).ValueForDriver); string barcodeSimulationResponse = SimulatePhotoOrBarcode(barcodeString, "barcode"); @@ -1156,6 +1178,7 @@ private void MobileDeviceActionHandler(ActMobileDevice act) act.Error = barcodeSimulationResponse; } break; + case ActMobileDevice.eMobileDeviceAction.SimulateBiometrics: { string biometricsAnswer = string.Empty; @@ -1183,9 +1206,11 @@ private void MobileDeviceActionHandler(ActMobileDevice act) } break; } + case ActMobileDevice.eMobileDeviceAction.StopSimulatePhotoOrVideo: CameraAndBarcodeSimulationRequest(null, ImageFormat.Png, contentType: "image", fileName: "image.png", action: "camera"); break; + default: throw new Exception("Action unknown/not implemented for the Driver: '" + this.GetType().ToString() + "'"); } @@ -1196,28 +1221,6 @@ private void MobileDeviceActionHandler(ActMobileDevice act) } } - private string GetAppPackage(ActMobileDevice act) - { - string appPackage = null; - if (string.IsNullOrEmpty(act.ActionAppPackage.ValueForDriver) || act.ActionAppPackage.ValueForDriver.ToLower().Trim() == "default") - { - if (DevicePlatformType == eDevicePlatformType.Android) - { - appPackage = AppiumCapabilities.Where(x => x.Parameter == "appPackage" || x.Parameter == "appium:appPackage").FirstOrDefault().Value; - } - else - { - appPackage = AppiumCapabilities.Where(x => x.Parameter == "bundleId" || x.Parameter == "appium:bundleId").FirstOrDefault().Value; - } - - return appPackage; - } - else - { - return act.ActionAppPackage.Value; - } - } - public string SimulatePhotoOrBarcode(string photoString, string action) { Bitmap picture = null; @@ -1278,7 +1281,7 @@ public string CameraAndBarcodeSimulationRequest(Bitmap picture, ImageFormat form Array.Clear(bytes); } } - + Dictionary sensorSimulationMap = new Dictionary { { "uploadMedia", encodeString }, @@ -1324,7 +1327,6 @@ private void AddReturnParamFromDict(Dictionary dict, ActMobileDe { act.AddOrUpdateReturnParamActual(entry.Key, entry.Value); } - } public override void HighlightActElement(Act act) @@ -1344,44 +1346,121 @@ private void ActScreenShotHandler(Act act) } } - //private void CreateScreenShot(Act act) - //{ - // Screenshot ss = ((ITakesScreenshot)Driver).GetScreenshot(); - // string filename = Path.GetTempFileName(); - // ss.SaveAsFile(filename, ScreenshotImageFormat.Png); - // Bitmap tmp = new System.Drawing.Bitmap(filename); - // act.AddScreenShot(tmp); - //} - - //public Screenshot GetScreenShot() - //{ - // Screenshot ss=null; - // try - // { - // ss = Driver.GetScreenshot (); - - // } - // catch - // { - // Bitmap bmp = new Bitmap (1024, 768); - // var ms = new MemoryStream (); - // bmp.Save (ms, System.Drawing.Imaging.ImageFormat.Png); - // var byteImage = ms.ToArray (); - // ss = new Screenshot (Convert.ToBase64String (byteImage)); - // } - // return ss; - //} - public ICollection GetAllElements() { return (ICollection)Driver.FindElements(By.XPath(".//*")); } - public void TapXY(long x, long y) + public void TapXY(int pageX, int pageY) + { + AppiumInteractions.PointerInputDevice finger = new AppiumInteractions.PointerInputDevice(PointerKind.Touch); + ActionBuilder actionBuilder = new ActionBuilder(); + actionBuilder.AddAction(finger.CreatePointerMove(CoordinateOrigin.Viewport, pageX, pageY, TimeSpan.Zero)); + actionBuilder.AddAction(finger.CreatePointerDown(PointerButton.TouchContact)); + actionBuilder.AddAction(finger.CreatePointerUp(PointerButton.TouchContact)); + Driver.PerformActions(actionBuilder.ToActionSequenceList()); + } + + public void TapElement(IWebElement element, int elementX, int elementY) + { + AppiumInteractions.PointerInputDevice finger = new AppiumInteractions.PointerInputDevice(PointerKind.Touch); + ActionBuilder actionBuilder = new ActionBuilder(); + actionBuilder.AddAction(finger.CreatePointerMove(element, elementX, elementY, TimeSpan.Zero)); + actionBuilder.AddAction(finger.CreatePointerDown(PointerButton.TouchContact)); + actionBuilder.AddAction(finger.CreatePointerUp(PointerButton.TouchContact)); + Driver.PerformActions(actionBuilder.ToActionSequenceList()); + } + + public void DoubleTapXY(int pageX, int pageY) { - TouchAction t = new TouchAction(Driver); - t.Tap(x, y); - Driver.PerformTouchAction(t); + AppiumInteractions.PointerInputDevice finger = new AppiumInteractions.PointerInputDevice(PointerKind.Touch); + ActionBuilder actionBuilder = new ActionBuilder(); + actionBuilder.AddAction(finger.CreatePointerMove(CoordinateOrigin.Viewport, pageX, pageY, TimeSpan.Zero)); + actionBuilder.AddAction(finger.CreatePointerDown(PointerButton.TouchContact)); + actionBuilder.AddAction(finger.CreatePointerUp(PointerButton.TouchContact)); + actionBuilder.AddAction(finger.CreatePause(TimeSpan.FromMilliseconds(100)));// small wait before second tap + actionBuilder.AddAction(finger.CreatePointerDown(PointerButton.TouchContact)); + actionBuilder.AddAction(finger.CreatePointerUp(PointerButton.TouchContact)); + Driver.PerformActions(actionBuilder.ToActionSequenceList()); + } + + public void DoubleTapElement(IWebElement element, int elementX, int elementY) + { + AppiumInteractions.PointerInputDevice finger = new AppiumInteractions.PointerInputDevice(PointerKind.Touch); + ActionBuilder actionBuilder = new ActionBuilder(); + actionBuilder.AddAction(finger.CreatePointerMove(element, elementX, elementY, TimeSpan.Zero)); + actionBuilder.AddAction(finger.CreatePointerDown(PointerButton.TouchContact)); + actionBuilder.AddAction(finger.CreatePointerUp(PointerButton.TouchContact)); + actionBuilder.AddAction(finger.CreatePause(TimeSpan.FromMilliseconds(100)));// small wait before second tap + actionBuilder.AddAction(finger.CreatePointerDown(PointerButton.TouchContact)); + actionBuilder.AddAction(finger.CreatePointerUp(PointerButton.TouchContact)); + Driver.PerformActions(actionBuilder.ToActionSequenceList()); + } + + + public void PressXY(int pageX, int pageY, TimeSpan pressDuration) + { + AppiumInteractions.PointerInputDevice finger = new AppiumInteractions.PointerInputDevice(PointerKind.Touch); + ActionBuilder actionBuilder = new ActionBuilder(); + actionBuilder.AddAction(finger.CreatePointerMove(CoordinateOrigin.Viewport, pageX, pageY, TimeSpan.Zero)); + actionBuilder.AddAction(finger.CreatePointerDown(PointerButton.TouchContact)); + actionBuilder.AddAction(finger.CreatePause(pressDuration));// Hold for specified duration + actionBuilder.AddAction(finger.CreatePointerUp(PointerButton.TouchContact)); + Driver.PerformActions(actionBuilder.ToActionSequenceList()); + } + + public void PerformLongPress(long x, long y, TimeSpan? clickDuration = null) + { + if (clickDuration == null) + { + clickDuration = TimeSpan.FromSeconds(3); + } + + PressXY((int)x, (int)y, (TimeSpan)clickDuration); + + if (IsRecording) + { + var mobDevAction = GetMobileActionforRecording(ActMobileDevice.eMobileDeviceAction.LongPressXY); + mobDevAction.X1.Value = x.ToString(); + mobDevAction.Y1.Value = y.ToString(); + mobDevAction.PressDuration.Value = ((TimeSpan)clickDuration).TotalMilliseconds.ToString(); + RecordingOperations(mobDevAction); + } + } + + public void PressElement(IWebElement element, int elementX, int elementY, TimeSpan pressDuration) + { + AppiumInteractions.PointerInputDevice finger = new AppiumInteractions.PointerInputDevice(PointerKind.Touch); + ActionBuilder actionBuilder = new ActionBuilder(); + actionBuilder.AddAction(finger.CreatePointerMove(element, elementX, elementY, TimeSpan.Zero)); + actionBuilder.AddAction(finger.CreatePointerDown(PointerButton.TouchContact)); + actionBuilder.AddAction(finger.CreatePause(pressDuration));// Hold for specified duration + actionBuilder.AddAction(finger.CreatePointerUp(PointerButton.TouchContact)); + Driver.PerformActions(actionBuilder.ToActionSequenceList()); + } + + public void DragAndDropByXY(int pageDragX, int pageDragY, int pageDropX, int pageDropY, TimeSpan pressDuration, TimeSpan dragDuration) + { + AppiumInteractions.PointerInputDevice finger = new AppiumInteractions.PointerInputDevice(PointerKind.Touch); + ActionBuilder actionBuilder = new ActionBuilder(); + actionBuilder.AddAction(finger.CreatePointerMove(CoordinateOrigin.Viewport, pageDragX, pageDragY, TimeSpan.Zero)); + actionBuilder.AddAction(finger.CreatePointerDown(PointerButton.TouchContact)); + actionBuilder.AddAction(finger.CreatePause(pressDuration)); + actionBuilder.AddAction(finger.CreatePointerMove(CoordinateOrigin.Viewport, pageDropX, pageDropY, dragDuration)); + actionBuilder.AddAction(finger.CreatePause(TimeSpan.FromMilliseconds(200))); + actionBuilder.AddAction(finger.CreatePointerUp(PointerButton.TouchContact)); + Driver.PerformActions(actionBuilder.ToActionSequenceList()); + } + + public void SwipeByXY(int pageStartX, int pageStartY, int pageEndX, int pageEndY, TimeSpan swipeDuration) + { + AppiumInteractions.PointerInputDevice finger = new AppiumInteractions.PointerInputDevice(PointerKind.Touch); + ActionBuilder actionBuilder = new ActionBuilder(); + actionBuilder.AddAction(finger.CreatePointerMove(CoordinateOrigin.Viewport, pageStartX, pageStartY, TimeSpan.Zero)); + actionBuilder.AddAction(finger.CreatePointerDown(PointerButton.TouchContact)); + actionBuilder.AddAction(finger.CreatePointerMove(CoordinateOrigin.Viewport, pageEndX, pageEndY, swipeDuration)); + actionBuilder.AddAction(finger.CreatePointerUp(PointerButton.TouchContact)); + Driver.PerformActions(actionBuilder.ToActionSequenceList()); } public void PerformBackButtonPress() @@ -1513,7 +1592,7 @@ public void PerformLockButtonPress(eLockOperation LockOperation) case eLockOperation.UnLock: ((AndroidDriver)Driver).Unlock(); System.Threading.Thread.Sleep(200); - SwipeScreen(eSwipeSide.Up); + SwipeScreen(eSwipeSide.Up, 1, TimeSpan.FromMilliseconds(200)); break; } break; @@ -1558,11 +1637,6 @@ public void PerformLongKeyPress(string key) case eDevicePlatformType.Android: ((AndroidDriver)Driver).LongPressKeyCode(Convert.ToInt32(Enum.Parse(typeof(ActMobileDevice.ePressKey), key))); break; - //case eDevicePlatformType.iOS: - // Dictionary commandArgs = new Dictionary(); - // commandArgs.Add("name", key); - // Driver.ExecuteScript("mobile: pressButton", commandArgs); - // break; } } @@ -1584,7 +1658,7 @@ await Task.Run(() => return Pagesource; } - public void SwipeScreen(eSwipeSide side, double impact = 1) + public void SwipeScreen(eSwipeSide side, double swipeScale, TimeSpan swipeDuration) { System.Drawing.Size sz = Driver.Manage().Window.Size; double startX; @@ -1597,49 +1671,33 @@ public void SwipeScreen(eSwipeSide side, double impact = 1) startX = sz.Width * 0.5; startY = sz.Height * 0.3; endX = sz.Width * 0.5; - endY = startY + (sz.Height * 0.4 * impact); + endY = startY + (sz.Height * 0.4 * swipeScale); break; case eSwipeSide.Up: // center of header startX = sz.Width * 0.5; startY = sz.Height * 0.7; endX = sz.Width * 0.5; - endY = startY - (sz.Height * 0.4 * impact); + endY = startY - (sz.Height * 0.4 * swipeScale); break; case eSwipeSide.Right: // center of left side startX = sz.Width * 0.3; startY = sz.Height * 0.5; - endX = startX + (sz.Width * 0.4 * impact); + endX = startX + (sz.Width * 0.4 * swipeScale); endY = sz.Height * 0.5; break; case eSwipeSide.Left: // center of right side startX = sz.Width * 0.7; startY = sz.Height * 0.5; - endX = startX - (sz.Width * 0.4 * impact); + endX = startX - (sz.Width * 0.4 * swipeScale); endY = sz.Height * 0.5; break; default: throw new ArgumentException("swipeScreen(): dir: '" + side + "' NOT supported"); } - (BuildTouchAction(Driver, startX, startY, endX, endY, 200)).Perform(); - } - - public ITouchAction BuildTouchAction(AppiumDriver driver, double startX, double startY, double endX, double endY, int waitDuration = 200) - { - ITouchAction touchAction; - touchAction = new TouchAction(driver) - .Press(startX, startY) - .Wait(waitDuration) - .MoveTo(endX, endY) - .Release(); - - return touchAction; + SwipeByXY((int)startX, (int)startY, (int)endX, (int)endY, swipeDuration); } - public void DoDrag(int startX, int startY, int endX, int endY) - { - (BuildTouchAction(Driver, startX, startY, endX, endY, 200)).Perform(); - } private string GetCurrentPackage() { @@ -1676,7 +1734,7 @@ public string GetCurrentActivityDetails() } else if (DevicePlatformType == eDevicePlatformType.iOS) { - var detail= ((IOSDriver)Driver).GetSessionDetail("CFBundleIdentifier"); + var detail = ((IOSDriver)Driver).GetSessionDetail("CFBundleIdentifier"); if (detail != null) { return string.Format("{0}", ((IOSDriver)Driver).GetSessionDetail("CFBundleIdentifier").ToString()); @@ -1905,7 +1963,7 @@ async Task> IWindowExplorer.GetVisibleControls(PomSetting pomS } ElementInfo EI = await GetElementInfoforXmlNode(nodes[i]); - EI.IsAutoLearned = true; + EI.IsAutoLearned = true; if (pomSetting.relativeXpathTemplateList != null && pomSetting.relativeXpathTemplateList.Count > 0) { @@ -1933,10 +1991,10 @@ async Task> IWindowExplorer.GetVisibleControls(PomSetting pomS if (pomSetting.filteredElementType == null || (pomSetting.filteredElementType != null && pomSetting.filteredElementType.Contains(EI.ElementTypeEnum))) - { + { foundElementsList.Add(EI); } - } + } return foundElementsList.ToList(); } @@ -2676,7 +2734,7 @@ public object LocateElementByLocator(ElementLocator EL) break; default: - elem = mSeleniumDriver.LocateElementByLocator(EL, Driver); + elem = mSeleniumDriver.LocateElementByLocator(EL, Driver); break; } } @@ -2780,7 +2838,7 @@ public eAppType GetAppType() } int checkSessionCounter = 0; - public Byte[] GetScreenshotImage() + public Byte[] GetScreenshotImage() { checkSessionCounter++; //check session is still valid @@ -2790,7 +2848,7 @@ public Byte[] GetScreenshotImage() { return Driver.GetScreenshot().AsByteArray; } - } + } else { return Driver.GetScreenshot().AsByteArray; @@ -2832,7 +2890,7 @@ public void PerformTap(long x, long y) RecordingEvent?.Invoke(this, args); } } - TapXY(x, y); + TapXY((int)x, (int)y); } public bool TestLocatorOutput(ElementInfo Elem, ElementLocator LocatorToTest) @@ -2847,23 +2905,11 @@ public bool TestLocatorOutput(ElementInfo Elem, ElementLocator LocatorToTest) return false; } - public void PerformLongPress(long x, long y) - { - TouchAction tc = new TouchAction(Driver); - tc.LongPress(x, y).Perform(); - if (IsRecording) - { - var mobDevAction = GetMobileActionforRecording(ActMobileDevice.eMobileDeviceAction.LongPressXY); - mobDevAction.X1.Value = x.ToString(); - mobDevAction.Y1.Value = y.ToString(); - RecordingOperations(mobDevAction); - } - } - public void PerformDrag(Point start, Point end) + public void PerformDrag(Point start, Point end, TimeSpan pressDuration, TimeSpan dragDuration) { - DoDrag(start.X, start.Y, end.X, end.Y); + DragAndDropByXY(start.X, start.Y, end.X, end.Y, pressDuration, dragDuration); if (IsRecording) { @@ -2874,6 +2920,9 @@ public void PerformDrag(Point start, Point end) mobDevAction.X2.Value = end.X.ToString(); mobDevAction.Y2.Value = end.Y.ToString(); + + mobDevAction.PressDuration.Value = pressDuration.TotalMilliseconds.ToString(); + mobDevAction.DragDuration.Value = dragDuration.TotalMilliseconds.ToString(); RecordingOperations(mobDevAction); } } @@ -3098,7 +3147,7 @@ public void CalculateSourceMobileImageConvertFactors(eImagePointUsage factorUsag { mScreenScaleFactorCorrectionX = 1; mScreenScaleFactorCorrectionY = 1; - + //override with user configuration double userScreenScaleFactorCorrectionX; @@ -3111,10 +3160,10 @@ public void CalculateSourceMobileImageConvertFactors(eImagePointUsage factorUsag { mScreenScaleFactorCorrectionY = userScreenScaleFactorCorrectionY; } - } + } public override Point GetPointOnAppWindow(Point clickedPoint, double SrcWidth, double SrcHeight, double ActWidth, double ActHeight) - { + { double scale_factor_x = 1, scale_factor_y = 1; CalculateSourceMobileImageConvertFactors(eImagePointUsage.Explore); scale_factor_x = (SrcWidth / mScreenScaleFactorCorrectionX) / ActWidth; @@ -3243,13 +3292,15 @@ public string SelectionWindowText() } } - public void PerformScreenSwipe(eSwipeSide swipeSide, double impact = 1) + public void PerformScreenSwipe(eSwipeSide swipeSide, double swipeScale, TimeSpan swipeDuration) { - SwipeScreen(swipeSide, impact); + SwipeScreen(swipeSide, swipeScale, swipeDuration); if (IsRecording) { ActMobileDevice mobAct = new ActMobileDevice(); + mobAct.SwipeScale.Value = swipeScale.ToString(); + mobAct.SwipeDuration.Value = ((TimeSpan)swipeDuration).TotalMilliseconds.ToString(); switch (swipeSide) { case eSwipeSide.Up: @@ -3324,6 +3375,36 @@ public void OpenDeviceSettings() } } + public void OpenDeviceExternalView() + { + //open URL in browser + try + { + //build the URL to use + Uri serverUri = new Uri(this.AppiumServer); + var uribuilder = new UriBuilder + { + Scheme = serverUri.Scheme, + Port = serverUri.Port, + Host = serverUri.Host, + //Path = string.Format(@"/integration8/en/#/remote?deviceId={0}", GetDeviceUDID()) + }; + string deviceViewUrl = string.Format(@"{0}integration8/en/#/remote?deviceId={1}", uribuilder.Uri.ToString(), GetDeviceUDID().ToString()); + + // Launch the browser with the URL + System.Diagnostics.Process.Start(new ProcessStartInfo + { + FileName = deviceViewUrl, + UseShellExecute = true + }); + } + catch (Exception ex) + { + Reporter.ToLog(eLogLevel.ERROR, "Failed to open the external device URL in browser", ex); + Reporter.ToUser(eUserMsgKey.StaticErrorMessage, "Failed to open the external device URL in browser, Error: " + ex.Message); + } + } + public string GetApplitoolServerURL() { return WorkSpace.Instance.Solution.ApplitoolsConfiguration.ApiUrl; diff --git a/Ginger/GingerCoreNET/Drivers/DriversWindow/IMobileDriverWindow.cs b/Ginger/GingerCoreNET/Drivers/DriversWindow/IMobileDriverWindow.cs index 99242d16c5..f6f12665c4 100644 --- a/Ginger/GingerCoreNET/Drivers/DriversWindow/IMobileDriverWindow.cs +++ b/Ginger/GingerCoreNET/Drivers/DriversWindow/IMobileDriverWindow.cs @@ -27,6 +27,8 @@ public interface IMobileDriverWindow { bool IsDeviceConnected { get; set; } + bool IsUftLabDevice { get;} + eAutoScreenshotRefreshMode DeviceAutoScreenshotRefreshMode { get; set; } eDevicePlatformType GetDevicePlatformType(); @@ -47,11 +49,11 @@ public interface IMobileDriverWindow void PerformTap(long x, long y); - void PerformLongPress(long x, long y); + void PerformLongPress(long x, long y, TimeSpan? pressDuration = null); - void PerformDrag(System.Drawing.Point start, System.Drawing.Point end); + void PerformDrag(System.Drawing.Point start, System.Drawing.Point end, TimeSpan pressDuration, TimeSpan dragDuration); - void PerformScreenSwipe(eSwipeSide swipeSide, double impact = 1); + void PerformScreenSwipe(eSwipeSide swipeSide, double swipeScale, TimeSpan swipeDuration); void SwitchToLandscape(); @@ -63,6 +65,8 @@ public interface IMobileDriverWindow void OpenDeviceSettings(); + void OpenDeviceExternalView(); + Dictionary GetDeviceCPUInfo(); Dictionary GetDeviceMemoryInfo();