Skip to content

Commit 98cb43d

Browse files
committed
chore(dotnet-maui): add integration tests
1 parent 578403c commit 98cb43d

File tree

11 files changed

+1356
-0
lines changed

11 files changed

+1356
-0
lines changed

.github/workflows/dotnet-maui-browserstack.yml

Lines changed: 411 additions & 0 deletions
Large diffs are not rendered by default.
Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
using System;
2+
using OpenQA.Selenium;
3+
using OpenQA.Selenium.Appium;
4+
using OpenQA.Selenium.Appium.Android;
5+
using OpenQA.Selenium.Appium.iOS;
6+
7+
namespace DittoMauiTasksApp.UITests
8+
{
9+
// BrowserStack-specific test fixture for managing Appium driver lifecycle
10+
public class BrowserStackTestFixture : IDisposable
11+
{
12+
public AppiumDriver? Driver { get; private set; }
13+
14+
public BrowserStackTestFixture()
15+
{
16+
InitializeBrowserStackDriver();
17+
}
18+
19+
private void InitializeBrowserStackDriver()
20+
{
21+
var username = Environment.GetEnvironmentVariable("BROWSERSTACK_USERNAME");
22+
var accessKey = Environment.GetEnvironmentVariable("BROWSERSTACK_ACCESS_KEY");
23+
var appId = Environment.GetEnvironmentVariable("BROWSERSTACK_APP_ID");
24+
var platform = Environment.GetEnvironmentVariable("BROWSERSTACK_PLATFORM") ?? "iOS";
25+
var device = Environment.GetEnvironmentVariable("BROWSERSTACK_DEVICE") ?? "iPhone 15";
26+
var osVersion = Environment.GetEnvironmentVariable("BROWSERSTACK_OS_VERSION") ?? "17";
27+
28+
if (string.IsNullOrEmpty(username) || string.IsNullOrEmpty(accessKey) || string.IsNullOrEmpty(appId))
29+
{
30+
Console.WriteLine("⚠️ BrowserStack credentials not found - using null driver");
31+
Driver = null;
32+
return;
33+
}
34+
35+
try
36+
{
37+
var capabilities = new AppiumOptions();
38+
39+
// BrowserStack specific capabilities
40+
capabilities.AddAdditionalCapability("browserstack.user", username);
41+
capabilities.AddAdditionalCapability("browserstack.key", accessKey);
42+
capabilities.AddAdditionalCapability("app", appId);
43+
44+
// Project information
45+
capabilities.AddAdditionalCapability("project", "Ditto MAUI Quickstart");
46+
capabilities.AddAdditionalCapability("build", $"Build #{Environment.GetEnvironmentVariable("GITHUB_RUN_NUMBER") ?? "local"}");
47+
capabilities.AddAdditionalCapability("name", $"Ditto {platform} Sync Test");
48+
49+
// Debug capabilities
50+
capabilities.AddAdditionalCapability("browserstack.debug", true);
51+
capabilities.AddAdditionalCapability("browserstack.video", true);
52+
capabilities.AddAdditionalCapability("browserstack.networkLogs", true);
53+
capabilities.AddAdditionalCapability("browserstack.appiumLogs", true);
54+
55+
if (platform.Equals("iOS", StringComparison.OrdinalIgnoreCase))
56+
{
57+
// iOS capabilities
58+
capabilities.AddAdditionalCapability("platformName", "iOS");
59+
capabilities.AddAdditionalCapability("platformVersion", osVersion);
60+
capabilities.AddAdditionalCapability("deviceName", device);
61+
capabilities.AddAdditionalCapability("automationName", "XCUITest");
62+
capabilities.AddAdditionalCapability("browserstack.resignApp", true);
63+
capabilities.AddAdditionalCapability("autoGrantPermissions", true);
64+
65+
var hubUrl = new Uri("https://hub-cloud.browserstack.com/wd/hub");
66+
Driver = new IOSDriver(hubUrl, capabilities, TimeSpan.FromMinutes(10));
67+
}
68+
else if (platform.Equals("Android", StringComparison.OrdinalIgnoreCase))
69+
{
70+
// Android capabilities
71+
capabilities.AddAdditionalCapability("platformName", "Android");
72+
capabilities.AddAdditionalCapability("platformVersion", osVersion);
73+
capabilities.AddAdditionalCapability("deviceName", device);
74+
capabilities.AddAdditionalCapability("automationName", "UiAutomator2");
75+
capabilities.AddAdditionalCapability("autoGrantPermissions", true);
76+
77+
var hubUrl = new Uri("https://hub-cloud.browserstack.com/wd/hub");
78+
Driver = new AndroidDriver(hubUrl, capabilities, TimeSpan.FromMinutes(10));
79+
}
80+
else
81+
{
82+
throw new ArgumentException($"Unsupported platform: {platform}");
83+
}
84+
85+
Console.WriteLine($"✅ BrowserStack {platform} driver initialized successfully");
86+
Console.WriteLine($"Device: {device} ({osVersion})");
87+
Console.WriteLine($"App ID: {appId}");
88+
}
89+
catch (Exception ex)
90+
{
91+
Console.WriteLine($"❌ Failed to initialize BrowserStack driver: {ex.Message}");
92+
Driver = null;
93+
}
94+
}
95+
96+
public void Dispose()
97+
{
98+
try
99+
{
100+
Driver?.Quit();
101+
Console.WriteLine("BrowserStack driver disposed");
102+
}
103+
catch (Exception ex)
104+
{
105+
Console.WriteLine($"Error disposing BrowserStack driver: {ex.Message}");
106+
}
107+
}
108+
}
109+
}
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<TargetFramework>net9.0</TargetFramework>
5+
<ImplicitUsings>enable</ImplicitUsings>
6+
<Nullable>enable</Nullable>
7+
<IsPackable>false</IsPackable>
8+
<IsTestProject>true</IsTestProject>
9+
<RootNamespace>DittoMauiTasksApp.UITests</RootNamespace>
10+
</PropertyGroup>
11+
12+
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
13+
<DefineConstants>$(DefineConstants);DEBUG</DefineConstants>
14+
</PropertyGroup>
15+
16+
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
17+
<DefineConstants>$(DefineConstants);RELEASE</DefineConstants>
18+
</PropertyGroup>
19+
20+
<ItemGroup>
21+
<!-- Core testing packages -->
22+
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.11.1" />
23+
<PackageReference Include="xunit" Version="2.9.2" />
24+
<PackageReference Include="xunit.runner.visualstudio" Version="2.8.2">
25+
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
26+
<PrivateAssets>all</PrivateAssets>
27+
</PackageReference>
28+
<PackageReference Include="coverlet.collector" Version="6.0.2">
29+
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
30+
<PrivateAssets>all</PrivateAssets>
31+
</PackageReference>
32+
33+
<!-- MAUI Testing packages - with explicit version -->
34+
<PackageReference Include="Microsoft.Maui.Controls" Version="9.0.0" />
35+
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="9.0.1" />
36+
37+
<!-- Microsoft.Maui.TestFramework is not available - using Appium directly -->
38+
<!-- <PackageReference Include="Microsoft.Maui.TestFramework" Version="9.0.0" /> -->
39+
<!-- <PackageReference Include="Microsoft.Maui.Testing" Version="9.0.0" /> -->
40+
<!-- <PackageReference Include="Microsoft.Maui.Appium" Version="9.0.0" /> -->
41+
42+
<!-- Appium WebDriver for cross-platform UI testing -->
43+
<PackageReference Include="Appium.WebDriver" Version="4.4.5" />
44+
<PackageReference Include="Selenium.WebDriver" Version="4.15.0" />
45+
<PackageReference Include="Selenium.Support" Version="4.15.0" />
46+
47+
<!-- BrowserStack specific packages -->
48+
<PackageReference Include="BrowserStack.Appium" Version="1.0.0" Condition="Exists('BrowserStack.Appium')" />
49+
</ItemGroup>
50+
51+
<ItemGroup>
52+
<!-- Test configuration files -->
53+
<None Include="appsettings.json" CopyToOutputDirectory="PreserveNewest" />
54+
<None Include="browserstack.conf.json" CopyToOutputDirectory="PreserveNewest" />
55+
</ItemGroup>
56+
57+
<!-- BrowserStack specific build targets -->
58+
<Target Name="PrepareForBrowserStack" BeforeTargets="Build">
59+
<Message Text="Preparing UI tests for BrowserStack execution" Importance="high" />
60+
</Target>
61+
62+
<!-- Test output settings -->
63+
<PropertyGroup>
64+
<TestResults>TestResults</TestResults>
65+
<VSTestResultsDirectory>$(TestResults)</VSTestResultsDirectory>
66+
</PropertyGroup>
67+
68+
</Project>

0 commit comments

Comments
 (0)