Skip to content

Commit 9f1d9ed

Browse files
Copilot CICopilot
andcommitted
Register the catalyst app with LaunchServices in the path that builds it
The Appium mac2 driver resolves the app through LaunchServices by bundleId, and a freshly built Catalyst .app is not registered there, so OneTimeSetUp fails for every test with "The app representing com.microsoft.maui.uitests could not be found". BuildAndRunHostApp.ps1 documents this and calls lsregister -f, but the replication verification path never runs that script - across the 22 cached logs carrying this error, lsregister appears zero times. All 22 are catalyst and all 22 blocked with nothing published: 14% of the 160 cached catalyst runs. It is intermittent only because agents are reused and a warm agent keeps the earlier registration. Registers the bundle in Build-AndDeploy.ps1's catalyst branch, probing both known lsregister paths, exporting MAC_APP_PATH, and checking the exit code rather than claiming success unconditionally. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 735ac9a2-7bec-4baa-ad19-c298e5bc795a
1 parent 7475ede commit 9f1d9ed

2 files changed

Lines changed: 117 additions & 2 deletions

File tree

.github/scripts/Replication-Pipeline.Tests.ps1

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1377,3 +1377,50 @@ Describe 'An already-covered issue may be re-run deliberately' {
13771377
$splat | Should -BeGreaterThan 0
13781378
}
13791379
}
1380+
1381+
Describe 'The catalyst build registers its app where the mac2 driver looks' {
1382+
# Every one of the 22 cached runs that failed with "The app representing
1383+
# com.microsoft.maui.uitests could not be found" was catalyst, and every one
1384+
# was blocked with nothing published - 14% of all cached catalyst runs.
1385+
# BuildAndRunHostApp.ps1 documents the cause and registers the bundle, but
1386+
# the replication verification path never calls it: `lsregister` appeared
1387+
# zero times in all 22 logs. Build-AndDeploy.ps1 is the script that path
1388+
# does run, and it believed "no install step needed".
1389+
BeforeAll {
1390+
$script:DeploySource = Get-Content -Raw -LiteralPath (Join-Path $PSScriptRoot 'shared/Build-AndDeploy.ps1')
1391+
$catalystStart = $script:DeploySource.IndexOf('$Platform -eq "catalyst"')
1392+
$windowsStart = $script:DeploySource.IndexOf('$Platform -eq "windows"')
1393+
$script:CatalystBranch = $script:DeploySource.Substring($catalystStart, $windowsStart - $catalystStart)
1394+
}
1395+
1396+
It 'registers the built bundle with LaunchServices' {
1397+
$script:CatalystBranch | Should -Match 'lsregister'
1398+
}
1399+
1400+
It 'probes both known lsregister locations' {
1401+
# A single hard-coded path silently skips registration on an agent whose
1402+
# framework symlink layout differs, which looks exactly like the bug.
1403+
([regex]::Matches($script:CatalystBranch, 'LaunchServices\.framework')).Count |
1404+
Should -BeGreaterThan 1
1405+
}
1406+
1407+
It 'reports a failed registration instead of claiming success' {
1408+
# Claiming success unconditionally is how a failed registration becomes
1409+
# an unexplained Appium error several attempts later.
1410+
$success = $script:CatalystBranch.IndexOf('Registered MacCatalyst app with LaunchServices')
1411+
$check = $script:CatalystBranch.IndexOf('$LASTEXITCODE -eq 0')
1412+
$check | Should -BeGreaterThan 0
1413+
$check | Should -BeLessThan $success
1414+
}
1415+
1416+
It 'exposes the bundle path for the mac2 driver as well' {
1417+
# bundleId resolution is primary, but options.App still needs the path.
1418+
$script:CatalystBranch | Should -Match 'MAC_APP_PATH'
1419+
}
1420+
1421+
It 'does not fail the build when registration is unavailable' {
1422+
# On an agent where the bundle is already registered the run still
1423+
# works; hard-failing would break runs that pass today.
1424+
$script:CatalystBranch | Should -Not -Match 'lsregister not found[^\r\n]*\r?\n\s*exit 1'
1425+
}
1426+
}

.github/scripts/shared/Build-AndDeploy.ps1

Lines changed: 70 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -414,8 +414,76 @@ if ($Platform -eq "android") {
414414

415415
Write-Success "Build completed in $($buildDuration.TotalSeconds) seconds"
416416

417-
# MacCatalyst apps run directly on the Mac - no install step needed
418-
# The test framework (Appium) will launch the app directly
417+
# MacCatalyst apps run directly on the Mac, so there is no install step -
418+
# but "no install" is not the same as "nothing to do". The Appium mac2
419+
# driver (WebDriverAgentMac) resolves the app through LaunchServices via
420+
# the bundleId capability, and a freshly built Catalyst .app has never been
421+
# registered there. When the lookup fails, OneTimeSetUp fails for EVERY
422+
# test in the run with "The app representing com.microsoft.maui.uitests
423+
# could not be found", which reads like a harness outage rather than a
424+
# missing registration. Setting MAC_APP_PATH / options.App alone is NOT
425+
# sufficient, because the driver still resolves by bundleId first.
426+
#
427+
# BuildAndRunHostApp.ps1 already documents this and registers the bundle,
428+
# but the replication verification path never calls it: across the 22
429+
# cached runs that hit this error - every one of them catalyst, and every
430+
# one blocked with nothing published - `lsregister` appears zero times.
431+
# That is 14% of all cached catalyst runs lost to a missing one-line step.
432+
# It is intermittent rather than universal because agents are reused, so a
433+
# warm agent can still carry the registration from an earlier run.
434+
#
435+
# Registration failure is deliberately a warning and not a build failure:
436+
# on an agent where the bundle is already registered the run still works,
437+
# and turning that into a hard failure would break runs that pass today.
438+
$catalystAppPath = $null
439+
$searchPath = Split-Path -Parent $ProjectPath
440+
$artifactsDir = $null
441+
while ($searchPath -and -not $artifactsDir) {
442+
$testPath = Join-Path $searchPath "artifacts"
443+
if (Test-Path $testPath) { $artifactsDir = $testPath; break }
444+
$parent = Split-Path -Parent $searchPath
445+
if ($parent -eq $searchPath) { break }
446+
$searchPath = $parent
447+
}
448+
449+
if ($artifactsDir) {
450+
$catalystAppPath = Get-ChildItem -Path $artifactsDir -Filter "*.app" -Recurse -ErrorAction SilentlyContinue |
451+
Where-Object {
452+
$_.FullName -match "$Configuration.*$macRid.*$projectName" -and
453+
$_.FullName -notmatch "[\\/]obj[\\/]"
454+
} |
455+
Select-Object -First 1
456+
}
457+
458+
if ($catalystAppPath) {
459+
$env:MAC_APP_PATH = $catalystAppPath.FullName
460+
Write-Info "MacCatalyst app bundle: $($catalystAppPath.FullName)"
461+
462+
# Probe both known lsregister locations so a differing framework
463+
# symlink layout on any agent macOS version cannot silently skip
464+
# registration.
465+
$lsregisterCandidates = @(
466+
"/System/Library/Frameworks/CoreServices.framework/Frameworks/LaunchServices.framework/Support/lsregister",
467+
"/System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/LaunchServices.framework/Versions/A/Support/lsregister"
468+
)
469+
$lsregister = $lsregisterCandidates | Where-Object { Test-Path $_ } | Select-Object -First 1
470+
if ($lsregister) {
471+
& $lsregister -f $catalystAppPath.FullName 2>&1 | Out-Null
472+
# Report the actual result. Claiming success unconditionally is how
473+
# a failed registration turns into an unexplained Appium error four
474+
# attempts later.
475+
if ($LASTEXITCODE -eq 0) {
476+
Write-Success "Registered MacCatalyst app with LaunchServices"
477+
} else {
478+
Write-Warn "lsregister exited $LASTEXITCODE; the mac2 driver may not resolve the bundle by id"
479+
}
480+
} else {
481+
Write-Warn "lsregister not found at any known path; skipping LaunchServices registration"
482+
}
483+
} else {
484+
Write-Warn "Could not locate the built MacCatalyst .app under $artifactsDir; skipping LaunchServices registration"
485+
}
486+
419487
Write-Success "MacCatalyst app ready (runs on host Mac)"
420488

421489
#endregion

0 commit comments

Comments
 (0)