diff --git a/scripts/device-test.ps1 b/scripts/device-test.ps1
index 6a20d133d5..4a3d29e6c7 100644
--- a/scripts/device-test.ps1
+++ b/scripts/device-test.ps1
@@ -11,6 +11,7 @@ param(
Set-StrictMode -Version latest
$ErrorActionPreference = 'Stop'
+. $PSScriptRoot/ios-simulator-utils.ps1
if (!$Build -and !$Run)
{
@@ -57,8 +58,15 @@ try
'--app', "$buildDir/Sentry.Maui.Device.TestApp.app",
'--target', 'ios-simulator-64',
'--launch-timeout', '00:10:00',
- '--set-env', 'CI=$envValue'
+ '--set-env', "CI=$envValue"
)
+
+ $udid = Get-IosSimulatorUdid -IosVersion '18.5' -Verbose
+ if ($udid) {
+ $arguments += @('--device', $udid)
+ } else {
+ Write-Host "No suitable simulator found; proceeding without a specific --device"
+ }
}
if ($Build)
@@ -76,7 +84,7 @@ try
if (!(Get-Command xharness -ErrorAction SilentlyContinue))
{
Push-Location ($CI ? $env:RUNNER_TEMP : $IsWindows ? $env:TMP : $IsMacos ? $env:TMPDIR : '/temp')
- dotnet tool install Microsoft.DotNet.XHarness.CLI --global --version '10.0.0-prerelease.25330.2' `
+ dotnet tool install Microsoft.DotNet.XHarness.CLI --global --version '10.0.0-prerelease.25412.1' `
--add-source https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-eng/nuget/v3/index.json
Pop-Location
}
diff --git a/scripts/ios-simulator-utils.ps1 b/scripts/ios-simulator-utils.ps1
new file mode 100644
index 0000000000..51f1b72fbd
--- /dev/null
+++ b/scripts/ios-simulator-utils.ps1
@@ -0,0 +1,95 @@
+function Get-IosSimulatorUdid {
+ [CmdletBinding()]
+ param(
+ [string]$IosVersion = '18.5',
+ [string[]]$PreferredDeviceTypes = @(
+ 'com.apple.CoreSimulator.SimDeviceType.iPhone-XS',
+ 'com.apple.CoreSimulator.SimDeviceType.iPhone-16',
+ 'com.apple.CoreSimulator.SimDeviceType.iPhone-15'
+ )
+ )
+
+ try {
+ $simDevices = & xcrun simctl list devices --json | ConvertFrom-Json
+ } catch {
+ Write-Verbose "Failed to query simctl: $($_.Exception.Message)"
+ return $null
+ }
+ if (-not $simDevices -or -not $simDevices.devices) {
+ Write-Verbose "No devices structure returned."
+ return $null
+ }
+
+ $devicesByRuntime = $simDevices.devices
+ $preferredIndex = @{}
+ for ($i = 0; $i -lt $PreferredDeviceTypes.Count; $i++) {
+ $preferredIndex[$PreferredDeviceTypes[$i]] = $i
+ }
+
+ $dashVer = $IosVersion -replace '\.','-'
+ $exactKey = "com.apple.CoreSimulator.SimRuntime.iOS-$dashVer"
+ $runtimeKey = $null
+
+ $allRuntimeNames = $devicesByRuntime.PSObject.Properties.Name
+ if ($allRuntimeNames -contains $exactKey) {
+ $runtimeKey = $exactKey
+ Write-Verbose "Found exact runtime: $runtimeKey"
+ } else {
+ $major = ($IosVersion.Split('.')[0])
+ $candidates = $allRuntimeNames | Where-Object { $_ -match "com\.apple\.CoreSimulator\.SimRuntime\.iOS-$major-" }
+ if ($candidates) {
+ $runtimeKey = $candidates |
+ Sort-Object {
+ $v = ($_ -replace '.*iOS-','') -replace '-','.'
+ try { [Version]$v } catch { [Version]'0.0' }
+ } -Descending |
+ Select-Object -First 1
+ Write-Verbose "Exact runtime $exactKey not found. Using fallback runtime $runtimeKey"
+ } else {
+ Write-Verbose "No simulator runtime found for iOS major $major"
+ return $null
+ }
+ }
+
+ $runtimeDevices = $devicesByRuntime.PSObject.Properties |
+ Where-Object { $_.Name -eq $runtimeKey } |
+ Select-Object -ExpandProperty Value
+
+ if (-not $runtimeDevices) {
+ Write-Verbose "Runtime key $runtimeKey present but no devices listed."
+ return $null
+ }
+
+ $usable = $runtimeDevices | Where-Object { $_.isAvailable -and $_.state -in @('Shutdown','Booted') }
+ if (-not $usable) {
+ Write-Verbose "No available devices in runtime $runtimeKey"
+ return $null
+ }
+
+ $ranked = $usable | ForEach-Object {
+ $dt = $_.deviceTypeIdentifier
+ $weightPref = if ($preferredIndex.ContainsKey($dt)) { $preferredIndex[$dt] } else { 9999 }
+ $weightFamily = if ($dt -match 'iPhone') { 0 } else { 1 } # prefer iPhone if not explicitly listed
+ [PSCustomObject]@{
+ Device = $_
+ WeightPref = $weightPref
+ WeightFamily = $weightFamily
+ WeightBoot = if ($_.state -eq 'Booted') { 0 } else { 1 }
+ SortName = $_.name
+ }
+ }
+
+ $sorted = $ranked | Sort-Object WeightPref, WeightFamily, WeightBoot, SortName
+ $sorted | Select-Object -First 5 | ForEach-Object {
+ Write-Verbose ("Candidate: {0} | {1} | pref={2} fam={3} bootW={4}" -f $_.Device.name, $_.Device.deviceTypeIdentifier, $_.WeightPref, $_.WeightFamily, $_.WeightBoot)
+ }
+
+ $selected = $sorted | Select-Object -First 1
+ if (-not $selected) {
+ Write-Verbose "Failed to select a simulator."
+ return $null
+ }
+
+ Write-Verbose ("Selected simulator: {0} ({1}) [{2}]" -f $selected.Device.name, $selected.Device.deviceTypeIdentifier, $selected.Device.udid)
+ return $selected.Device.udid
+}
diff --git a/test/Sentry.Maui.Device.TestApp/Sentry.Maui.Device.TestApp.csproj b/test/Sentry.Maui.Device.TestApp/Sentry.Maui.Device.TestApp.csproj
index 15beeb7e92..3ea49a432c 100644
--- a/test/Sentry.Maui.Device.TestApp/Sentry.Maui.Device.TestApp.csproj
+++ b/test/Sentry.Maui.Device.TestApp/Sentry.Maui.Device.TestApp.csproj
@@ -34,7 +34,7 @@
21.0
- 18
+ 18.0
true