From 52e15475ac248bf233fc6bc946cf172284418158 Mon Sep 17 00:00:00 2001 From: Shane Neuville Date: Sat, 17 Feb 2024 19:21:46 -0600 Subject: [PATCH] Setup Android App With More Accurate settings --- .../Platforms/Android/MainActivity.cs | 2 ++ .../UITests/Tests/CoreGalleryBasePageTest.cs | 3 +- .../UITests/Tests/Issues/_IssuesUITest.cs | 2 +- .../Actions/AppiumLifecycleActions.cs | 19 ++++++++++-- .../src/UITest.Appium/AppiumAndroidApp.cs | 7 +++-- src/TestUtils/src/UITest.Appium/AppiumApp.cs | 3 ++ .../src/UITest.Appium/HelperExtensions.cs | 31 ++++++++++++++++++- 7 files changed, 60 insertions(+), 7 deletions(-) diff --git a/src/Controls/samples/Controls.Sample.UITests/Platforms/Android/MainActivity.cs b/src/Controls/samples/Controls.Sample.UITests/Platforms/Android/MainActivity.cs index be015c14658d..a0eb1ce025ec 100644 --- a/src/Controls/samples/Controls.Sample.UITests/Platforms/Android/MainActivity.cs +++ b/src/Controls/samples/Controls.Sample.UITests/Platforms/Android/MainActivity.cs @@ -1,5 +1,6 @@ using Android.App; using Android.Content.PM; +using Android.Runtime; using Microsoft.Maui; namespace Maui.Controls.Sample.Platform @@ -11,6 +12,7 @@ namespace Maui.Controls.Sample.Platform [IntentFilter( new[] { Microsoft.Maui.ApplicationModel.Platform.Intent.ActionAppAction }, Categories = new[] { Android.Content.Intent.CategoryDefault })] + [Register("com.microsoft.maui.uitests.MainActivity")] public class MainActivity : MauiAppCompatActivity { } diff --git a/src/Controls/tests/UITests/Tests/CoreGalleryBasePageTest.cs b/src/Controls/tests/UITests/Tests/CoreGalleryBasePageTest.cs index 1c3c248795cc..8b9bef5d3cc8 100644 --- a/src/Controls/tests/UITests/Tests/CoreGalleryBasePageTest.cs +++ b/src/Controls/tests/UITests/Tests/CoreGalleryBasePageTest.cs @@ -1,4 +1,5 @@ using NUnit.Framework; +using UITest.Appium; using UITest.Core; namespace Microsoft.Maui.AppiumTests @@ -23,7 +24,7 @@ protected override void FixtureSetup() TestContext.Error.WriteLine($">>>>> {DateTime.Now} The FixtureSetup threw an exception. Attempt {retries}/{SetupMaxRetries}.{Environment.NewLine}Exception details: {e}"); if (retries++ < SetupMaxRetries) { - Reset(); + App.ResetApp(); } else { diff --git a/src/Controls/tests/UITests/Tests/Issues/_IssuesUITest.cs b/src/Controls/tests/UITests/Tests/Issues/_IssuesUITest.cs index 390782ceb052..d8fac4211fa5 100644 --- a/src/Controls/tests/UITests/Tests/Issues/_IssuesUITest.cs +++ b/src/Controls/tests/UITests/Tests/Issues/_IssuesUITest.cs @@ -24,7 +24,7 @@ protected override void FixtureSetup() TestContext.Error.WriteLine($">>>>> {DateTime.Now} The FixtureSetup threw an exception. Attempt {retries}/{SetupMaxRetries}.{Environment.NewLine}Exception details: {e}"); if (retries++ < SetupMaxRetries) { - Reset(); + App.ResetApp(); } else { diff --git a/src/TestUtils/src/UITest.Appium/Actions/AppiumLifecycleActions.cs b/src/TestUtils/src/UITest.Appium/Actions/AppiumLifecycleActions.cs index ec0dd0f03593..53a480d7f5c5 100644 --- a/src/TestUtils/src/UITest.Appium/Actions/AppiumLifecycleActions.cs +++ b/src/TestUtils/src/UITest.Appium/Actions/AppiumLifecycleActions.cs @@ -1,4 +1,5 @@ -using UITest.Core; +using OpenQA.Selenium.Appium.Android; +using UITest.Core; namespace UITest.Appium { @@ -6,6 +7,7 @@ public class AppiumLifecycleActions : ICommandExecutionGroup { const string LaunchAppCommand = "launchApp"; const string BackgroundAppCommand = "backgroundApp"; + const string ForegroundAppCommand = "foregroundApp"; const string ResetAppCommand = "resetApp"; const string CloseAppCommand = "closeApp"; const string BackCommand = "back"; @@ -15,6 +17,7 @@ public class AppiumLifecycleActions : ICommandExecutionGroup readonly List _commands = new() { LaunchAppCommand, + ForegroundAppCommand, BackgroundAppCommand, ResetAppCommand, CloseAppCommand, @@ -36,6 +39,7 @@ public CommandResponse Execute(string commandName, IDictionary p return commandName switch { LaunchAppCommand => LaunchApp(parameters), + ForegroundAppCommand => ForegroundApp(parameters), BackgroundAppCommand => BackgroundApp(parameters), ResetAppCommand => ResetApp(parameters), CloseAppCommand => CloseApp(parameters), @@ -54,6 +58,16 @@ CommandResponse LaunchApp(IDictionary parameters) return CommandResponse.SuccessEmptyResponse; } + CommandResponse ForegroundApp(IDictionary parameters) + { + if (_app?.Driver is null) + return CommandResponse.FailedEmptyResponse; + + _app.Driver.ActivateApp(_app.GetAppId()); + + return CommandResponse.SuccessEmptyResponse; + } + CommandResponse BackgroundApp(IDictionary parameters) { if (_app?.Driver is null) @@ -69,7 +83,8 @@ CommandResponse ResetApp(IDictionary parameters) if (_app?.Driver is null) return CommandResponse.FailedEmptyResponse; - _app.Driver.ResetApp(); + _app.Driver.TerminateApp(_app.GetAppId()); + _app.Driver.LaunchApp(); return CommandResponse.SuccessEmptyResponse; } diff --git a/src/TestUtils/src/UITest.Appium/AppiumAndroidApp.cs b/src/TestUtils/src/UITest.Appium/AppiumAndroidApp.cs index 0ecfa53ae558..acaae78fb79c 100644 --- a/src/TestUtils/src/UITest.Appium/AppiumAndroidApp.cs +++ b/src/TestUtils/src/UITest.Appium/AppiumAndroidApp.cs @@ -71,14 +71,17 @@ private static AppiumOptions GetOptions(IConfig config) { config.SetProperty("PlatformName", "Android"); config.SetProperty("AutomationName", "UIAutomator2"); + var appId = config.GetProperty("AppId"); var options = new AppiumOptions(); + SetGeneralAppiumOptions(config, options); - var appId = config.GetProperty("AppId"); if (!string.IsNullOrWhiteSpace(appId)) { - options.AddAdditionalAppiumOption(IOSMobileCapabilityType.BundleId, appId); + options.AddAdditionalAppiumOption(MobileCapabilityType.NoReset, "true"); + options.AddAdditionalAppiumOption(AndroidMobileCapabilityType.AppPackage, appId); + options.AddAdditionalAppiumOption(AndroidMobileCapabilityType.AppActivity, $"{appId}.MainActivity"); } return options; diff --git a/src/TestUtils/src/UITest.Appium/AppiumApp.cs b/src/TestUtils/src/UITest.Appium/AppiumApp.cs index 950cae363e8c..ad7c8c6bdcde 100644 --- a/src/TestUtils/src/UITest.Appium/AppiumApp.cs +++ b/src/TestUtils/src/UITest.Appium/AppiumApp.cs @@ -113,6 +113,9 @@ protected static void SetGeneralAppiumOptions(IConfig config, AppiumOptions appi if (config.GetProperty("FullReset")) appiumOptions.AddAdditionalAppiumOption(MobileCapabilityType.FullReset, "true"); + if (config.GetProperty("NoReset")) + appiumOptions.AddAdditionalAppiumOption(MobileCapabilityType.NoReset, "true"); + var appPath = config.GetProperty("AppPath"); if (!string.IsNullOrEmpty(appPath)) appiumOptions.App = appPath; diff --git a/src/TestUtils/src/UITest.Appium/HelperExtensions.cs b/src/TestUtils/src/UITest.Appium/HelperExtensions.cs index a274bfadcdc8..6a12c4205d64 100644 --- a/src/TestUtils/src/UITest.Appium/HelperExtensions.cs +++ b/src/TestUtils/src/UITest.Appium/HelperExtensions.cs @@ -95,7 +95,7 @@ public static void SendKeys(this IApp app, int keyCode, int metastate = 0) ske.PressKeyCode(keyCode, metastate); return; } - + throw new InvalidOperationException($"SendKeys is not supported on {aaa.Driver}"); } @@ -452,6 +452,15 @@ public static void BackgroundApp(this IApp app) app.CommandExecutor.Execute("backgroundApp", ImmutableDictionary.Empty); } + /// + /// If the application is already running then it will be brought to the foreground. + /// + /// Represents the main gateway to interact with an app. + public static void ForegroundApp(this IApp app) + { + app.CommandExecutor.Execute("foregroundApp", ImmutableDictionary.Empty); + } + /// /// Reset the currently running app for this session. /// @@ -541,6 +550,26 @@ public static void Back(this IApp app) app.CommandExecutor.Execute("back", ImmutableDictionary.Empty); } + /// + /// Return the AppId of the running app. This is used inside any appium command that want the app id + /// + /// Represents the main gateway to interact with an app. + public static string GetAppId(this IApp app) + { + if (app is not AppiumApp aaa) + { + throw new InvalidOperationException($"GetAppId is only supported on AppiumApp"); + } + + var appId = aaa.Config.GetProperty("AppId"); + if (appId is not null) + { + return appId; + } + + throw new InvalidOperationException("AppId not found"); + } + static IUIElement Wait(Func query, Func satisfactory, string? timeoutMessage = null,