diff --git a/.vscode/launch.json b/.vscode/launch.json
index 76dc08d5..efdaa6ea 100644
--- a/.vscode/launch.json
+++ b/.vscode/launch.json
@@ -28,6 +28,19 @@
"request": "launch",
"projectPath": "${workspaceFolder}/src/PostIt/PostIt.Desktop/PostIt.Desktop.csproj",
+ },
+ {
+ "name": "Test PostIt.Android launch (Xamarin.UITest)",
+ "type": "coreclr",
+ "request": "launch",
+ "program": "${workspaceFolder}/src/PostIt.Tests/bin/Debug/net10.0/PostIt.Tests.dll",
+ "args": [
+ "--filter-method",
+ "PostIt.Tests.AndroidAppLaunchTests.PostIt_starts_and_draws_a_first_frame_on_the_emulator"
+ ],
+ "cwd": "${workspaceFolder}/src/PostIt.Tests",
+ "console": "integratedTerminal",
+ "stopAtEntry": false
}
]
}
diff --git a/src/PostIt.Tests/AndroidAppLaunchTests.cs b/src/PostIt.Tests/AndroidAppLaunchTests.cs
new file mode 100644
index 00000000..2198bb78
--- /dev/null
+++ b/src/PostIt.Tests/AndroidAppLaunchTests.cs
@@ -0,0 +1,76 @@
+using System;
+using System.Diagnostics;
+using System.IO;
+using System.Linq;
+using Xamarin.UITest;
+using Xamarin.UITest.Android;
+using Xunit;
+
+namespace PostIt.Tests;
+
+///
+/// Smoke test: launches the installed PostIt.Android app on the running
+/// emulator and waits for the first Avalonia frame to render. Reveals the
+/// "démarrage KO" bug — the test fails if Avalonia never draws a frame
+/// within the timeout.
+///
+/// Skip conditions: the package is not installed on the connected device,
+/// or no device is connected via adb.
+///
+public class AndroidAppLaunchTests
+{
+ private const string PackageName = "com.CompanyName.PostIt";
+
+ private readonly ITestOutputHelper _output;
+
+ public AndroidAppLaunchTests(ITestOutputHelper output)
+ {
+ _output = output;
+ }
+
+ [Fact]
+ public void PostIt_starts_and_draws_a_first_frame_on_the_emulator()
+ {
+ if (!IsPackageInstalledOnAnyDevice())
+ {
+ _output.WriteLine($"[skip] {PackageName} not installed on any device");
+ return;
+ }
+
+ _output.WriteLine($"[step] configuring app via InstalledApp({PackageName})");
+ var app = ConfigureApp.Android
+ .InstalledApp(PackageName)
+ .StartApp(Xamarin.UITest.Configuration.AppDataMode.DoNotClear);
+ _output.WriteLine("[step] app.StartApp returned, waiting for first frame");
+
+ app.WaitForElement(
+ e => e.Class("android.view.View"),
+ timeout: TimeSpan.FromSeconds(30));
+ _output.WriteLine("[step] first frame observed");
+ }
+
+ private static bool IsPackageInstalledOnAnyDevice()
+ {
+ try
+ {
+ var startInfo = new ProcessStartInfo("adb", "shell pm list packages")
+ {
+ RedirectStandardOutput = true,
+ RedirectStandardError = true,
+ UseShellExecute = false,
+ CreateNoWindow = true,
+ };
+ using var proc = Process.Start(startInfo);
+ if (proc is null) return false;
+ var stdout = proc.StandardOutput.ReadToEnd();
+ proc.WaitForExit(5000);
+ return stdout
+ .Split('\n', StringSplitOptions.RemoveEmptyEntries)
+ .Any(line => line.Trim().Equals($"package:{PackageName}", StringComparison.Ordinal));
+ }
+ catch
+ {
+ return false;
+ }
+ }
+}
diff --git a/src/PostIt.Tests/Directory.Packages.props b/src/PostIt.Tests/Directory.Packages.props
index 15c4e24b..4731d4f0 100644
--- a/src/PostIt.Tests/Directory.Packages.props
+++ b/src/PostIt.Tests/Directory.Packages.props
@@ -1,10 +1,10 @@
-
+
\ No newline at end of file
diff --git a/src/PostIt.Tests/PostIt.Tests.csproj b/src/PostIt.Tests/PostIt.Tests.csproj
index 54c40e8c..249e3d92 100644
--- a/src/PostIt.Tests/PostIt.Tests.csproj
+++ b/src/PostIt.Tests/PostIt.Tests.csproj
@@ -13,6 +13,7 @@
+