-
-
Notifications
You must be signed in to change notification settings - Fork 231
Expand file tree
/
Copy pathdevice-test-utils.ps1
More file actions
163 lines (142 loc) · 5.78 KB
/
device-test-utils.ps1
File metadata and controls
163 lines (142 loc) · 5.78 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
function Reset-IosSimulator {
[CmdletBinding()]
param(
[Parameter(Mandatory)]
[PSCustomObject]$SimInfo
)
$udid = $SimInfo.Udid
Write-Host "Hard-resetting simulator $($SimInfo.Name) [$udid]..."
# Shut down & delete the old device
xcrun simctl shutdown $udid 2>&1 | Out-Null
xcrun simctl delete $udid 2>&1 | Out-Null
# Restart the CoreSimulator service to clear any daemon-level state left
# over from a simulator crash (this is what makes a fresh runner "work").
Write-Host "Restarting CoreSimulator service..."
sudo launchctl kickstart -kp system/com.apple.CoreSimulator.CoreSimulatorService 2>&1 | Out-Null
Start-Sleep -Seconds 5 # give the daemon time to re-initialise
# Create a brand-new simulator with the same device type & runtime
$newUdid = (& xcrun simctl create $SimInfo.Name $SimInfo.DeviceType $SimInfo.Runtime).Trim()
Write-Host "Created new simulator $($SimInfo.Name) [$newUdid]"
# Boot and wait
xcrun simctl boot $newUdid 2>&1 | Out-Null
xcrun simctl bootstatus $newUdid -b
# Return updated info
$SimInfo.Udid = $newUdid
return $newUdid
}
function Install-XHarness
{
if (!(Get-Command xharness -ErrorAction SilentlyContinue))
{
$CI = Test-Path env:CI
Push-Location ($CI ? $env:RUNNER_TEMP : $IsWindows ? $env:TMP : $IsMacos ? $env:TMPDIR : '/tmp')
dotnet tool install Microsoft.DotNet.XHarness.CLI --global --version '11.0.0-prerelease.26117.1' `
--add-source https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-eng/nuget/v3/index.json
Pop-Location
}
}
function Get-AndroidEmulatorId
{
if ((Test-Path env:CI) -or (Test-Path env:ANDROID_SERIAL))
{
return $env:ANDROID_SERIAL
}
try
{
return & xharness android adb -- devices | Select-String "device$" | ForEach-Object { ($_ -split "`t")[0] } | Select-Object -First 1
}
catch
{
return $null
}
}
function Get-IosSimulatorUdid {
[CmdletBinding()]
param(
[string]$IosVersion = '26.0',
[string[]]$PreferredDeviceTypes = @(
'com.apple.CoreSimulator.SimDeviceType.iPhone-XS',
'com.apple.CoreSimulator.SimDeviceType.iPhone-17',
'com.apple.CoreSimulator.SimDeviceType.iPhone-16'
),
[string[]]$PreferredStates = @('Shutdown','Booted')
)
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 $PreferredStates }
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 [PSCustomObject]@{
Udid = $selected.Device.udid
Name = $selected.Device.name
DeviceType = $selected.Device.deviceTypeIdentifier
Runtime = $runtimeKey
}
}