Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 33 additions & 0 deletions app-runner/Private/AndroidHelpers.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -140,3 +140,36 @@ function Format-LogcatOutput {
}
} | Where-Object { -not [string]::IsNullOrWhiteSpace($_) })
}

<#
.SYNOPSIS
Parses a logcat filter string into an array of filterspec tokens.

.DESCRIPTION
Splits a whitespace-separated logcat filter string into individual "tag[:priority]"
filterspec tokens, as accepted by `adb logcat` and by Appium's logcatFilterSpecs
capability. A tag on its own means "tag:V" (verbose); "*:S" silences everything else.
Empty tokens are removed.

.PARAMETER FilterString
The raw logcat filter string. May be null or empty, in which case an empty array is returned.

.EXAMPLE
ConvertTo-LogcatFilterSpec -FilterString "godot:V sentry-native:V *:S"
Returns: @('godot:V', 'sentry-native:V', '*:S')
#>
function ConvertTo-LogcatFilterSpec {
[CmdletBinding()]
param(
[Parameter(Mandatory = $false)]
[AllowNull()]
[AllowEmptyString()]
[string]$FilterString
)

if ([string]::IsNullOrWhiteSpace($FilterString)) {
return @()
}

return @($FilterString -split '\s+' | Where-Object { $_ -ne '' })
}
19 changes: 19 additions & 0 deletions app-runner/Private/DeviceProviders/SauceLabsProvider.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,10 @@ Requirements:
- SAUCE_REGION - SauceLabs region (e.g., us-west-1, eu-central-1)
- SAUCE_DEVICE_NAME - Device name (optional if using -Target parameter)
- SAUCE_SESSION_NAME - Session name for SauceLabs dashboard (optional, defaults to "App Runner Test")
- SAUCE_LOGCAT_FILTER - Android only, optional. Whitespace-separated logcat filterspecs
("tag[:priority]", e.g. "godot:V sentry-native:V *:S") applied to the Appium session via
the logcatFilterSpecs capability, trimming the otherwise very noisy system-wide logcat to
the given tags at capture time. Unset means the full, unfiltered logcat is returned.

Note: Device name must match a device available in the specified region.

Expand All @@ -51,6 +55,7 @@ class SauceLabsProvider : DeviceProvider {
[string]$SessionName = $null
[string]$CurrentPackageName = $null
[string]$MobilePlatform = $null # 'Android' or 'iOS'
[string[]]$LogcatFilterSpecs = @() # Android only: optional logcat filterspecs to trim noisy system logs

SauceLabsProvider([string]$MobilePlatform) {
if ($MobilePlatform -notin @('Android', 'iOS')) {
Expand All @@ -73,6 +78,12 @@ class SauceLabsProvider : DeviceProvider {
"App Runner $MobilePlatform Test"
}

# Read optional logcat filter (Android only). Applied at capture time via the
# logcatFilterSpecs session capability to trim the noisy system-wide logcat.
if ($MobilePlatform -eq 'Android') {
$this.LogcatFilterSpecs = ConvertTo-LogcatFilterSpec -FilterString $env:SAUCE_LOGCAT_FILTER
}

# Validate required credentials
if (-not $this.Username -or -not $this.AccessKey) {
throw "SAUCE_USERNAME and SAUCE_ACCESS_KEY environment variables must be set"
Expand Down Expand Up @@ -282,6 +293,14 @@ class SauceLabsProvider : DeviceProvider {
}
}

# Apply logcat filtering at capture time so the driver's logcat buffer only holds the
# requested tags. This keeps app markers from being evicted by the flood of system-wide
# log lines on noisy devices (a full logcat buffer can span only a few seconds).
if ($this.MobilePlatform -eq 'Android' -and $this.LogcatFilterSpecs.Count -gt 0) {
$capabilities.capabilities.alwaysMatch['appium:logcatFilterSpecs'] = $this.LogcatFilterSpecs
Write-Host "Applying logcat filter: $($this.LogcatFilterSpecs -join ' ')" -ForegroundColor Cyan
}

$sessionResponse = $this.InvokeSauceLabsApi('POST', $sessionUri, $capabilities, $false, $null)

# Extract session ID (response format varies)
Expand Down
4 changes: 4 additions & 0 deletions app-runner/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,10 @@ Connect-Device -Platform "Xbox" -TimeoutSeconds 300 # 5 minutes
- SauceLabs account with Real Device Cloud access
- Environment variables: `SAUCE_USERNAME`, `SAUCE_ACCESS_KEY`, `SAUCE_REGION`
- Valid SauceLabs device ID or capabilities for device selection
- Optional `SAUCE_LOGCAT_FILTER` (Android only): whitespace-separated logcat filterspecs
(`tag[:priority]`, e.g. `godot:V sentry-native:V *:S`) applied via the `logcatFilterSpecs`
session capability to trim the noisy system-wide logcat down to the given tags at capture
time. Unset returns the full logcat.

### Desktop Platform Requirements

Expand Down
29 changes: 29 additions & 0 deletions app-runner/Tests/AndroidHelpers.Tests.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -168,4 +168,33 @@ Describe 'AndroidHelpers' -Tag 'Unit', 'Android' {
$result[1] | Should -Be '01-01 12:00:01.000 1234 5678 E Tag: Error with special chars: @#$%^&*()'
}
}

Context 'ConvertTo-LogcatFilterSpec' {
It 'Splits a whitespace-separated filter string into filterspecs' {
$result = ConvertTo-LogcatFilterSpec -FilterString 'godot:V sentry-native:V *:S'

$result.Count | Should -Be 3
$result[0] | Should -Be 'godot:V'
$result[1] | Should -Be 'sentry-native:V'
$result[2] | Should -Be '*:S'
}

It 'Collapses runs of whitespace and ignores leading/trailing spaces' {
$result = ConvertTo-LogcatFilterSpec -FilterString " godot:V *:S "

$result.Count | Should -Be 2
$result[0] | Should -Be 'godot:V'
$result[1] | Should -Be '*:S'
}

It 'Returns an empty array for null input' {
$result = @(ConvertTo-LogcatFilterSpec -FilterString $null)
$result.Count | Should -Be 0
}

It 'Returns an empty array for whitespace-only input' {
$result = @(ConvertTo-LogcatFilterSpec -FilterString ' ')
$result.Count | Should -Be 0
}
}
}
Loading