-
-
Notifications
You must be signed in to change notification settings - Fork 0
Sauce: Implement CopyDeviceItem, log file parameter for RunApplication & fix issues #32
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
- Add optional LogFilePath parameter to Invoke-DeviceApp and RunApplication - Implement log file retrieval with fallback to system logs in SauceLabsProvider - Add method overloads to AdbProvider and XboxProvider for compatibility - Reduce code footprint by consolidating log retrieval logic - Maintain backward compatibility with existing provider implementations Co-authored-by: Claude Sonnet <claude@anthropic.com>
- Replace method overloads with single method using optional LogFilePath parameter - Update base DeviceProvider class to include optional parameter - Simplify all provider implementations (SauceLabs, Adb, Xbox) - Remove conditional logic from Invoke-DeviceApp - single method call - Clean up code by eliminating method overload complexity Co-authored-by: Claude Sonnet <claude@anthropic.com>
- Add optional LogFilePath parameter to match other providers - Ensures consistent method signature across all provider implementations - Completes the refactoring to use optional parameters instead of overloads Co-authored-by: Claude Sonnet <claude@anthropic.com>
|
|
On it! We are reviewing the PR and will provide feedback shortly. |
|
|
||
| # Split the arguments string by spaces, but handle quoted strings (both single and double quotes) | ||
| $argTokens = [regex]::Matches($Arguments, '(\"[^\"]*\"|''[^'']*''|\S+)') | ForEach-Object { $_.Value.Trim('"', "'") } | ||
|
|
||
| foreach ($token in $argTokens) { | ||
| $argumentsArray += $token | ||
| } | ||
|
|
||
| $launchBody['arguments'] = $argumentsArray |
This comment was marked as outdated.
This comment was marked as outdated.
Sorry, something went wrong.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Even better, how about we change $arguments param to [object] and let users pass string or array?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually, [string[]] actually accepts both a string and an array of strings
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We have multiple places where we represent arguments as a single string. I suppose I can refactor all of that in this PR.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you shouldn't really need to change that. a single string works the same as an array of a a single string
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I mean that we accept a string as arguments in various API calls. Now if we change policy to accept arguments as an array, we still need arguments as a single string in some places. Converting from array of strings to a single string is not straightforward - requires proper escaping. One way or the other we'll have to deal with conversion.
| if ($Error.Exception.Message -match "500|Internal Server Error") { | ||
| $errorMsg += "`n`nTroubleshooting $($this.MobilePlatform) file access:" | ||
| $errorMsg += "`n- App Package/Bundle ID: '$($this.CurrentPackageName)'" | ||
| $errorMsg += "`n- Requested path: '$DevicePath'" | ||
|
|
||
| if ($this.MobilePlatform -eq 'iOS') { | ||
| try { | ||
| $appInfo = $this.CheckAppFileSharingCapability() | ||
| if ($appInfo.AllApps -and $appInfo.AllApps.Count -gt 0) { | ||
| $errorMsg += "`n- Available apps: $($appInfo.AllApps -join ', ')" | ||
| if ($appInfo.Found -and -not $appInfo.FileSharingEnabled) { | ||
| $errorMsg += "`n- App found but UIFileSharingEnabled=false" | ||
| } | ||
| } | ||
| } catch { | ||
| $errorMsg += "`n- Could not check app capabilities: $($_.Exception.Message)" | ||
| } | ||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In the HandleCopyDeviceItemError method, the error handling tries to call CheckAppFileSharingCapability() to provide diagnostic information. However, if this method itself throws an exception (which it can on line 629 with 'No active SauceLabs session'), the exception is caught but the session existence should have been verified before attempting the CopyDeviceItem operation. Consider moving the session check to the beginning of CopyDeviceItem instead of relying on nested error handling.
Severity: MEDIUM
🤖 Prompt for AI Agent
Review the code at the location below. A potential bug has been identified by an AI
agent.
Verify if this is a real issue. If it is, propose a fix; if not, explain why it's not
valid.
Location: app-runner/Private/DeviceProviders/SauceLabsProvider.ps1#L738-L755
Potential issue: In the `HandleCopyDeviceItemError` method, the error handling tries to
call `CheckAppFileSharingCapability()` to provide diagnostic information. However, if
this method itself throws an exception (which it can on line 629 with 'No active
SauceLabs session'), the exception is caught but the session existence should have been
verified before attempting the CopyDeviceItem operation. Consider moving the session
check to the beginning of `CopyDeviceItem` instead of relying on nested error handling.
Did we get this right? 👍 / 👎 to inform future reviews.
Reference ID: 1
| .PARAMETER LogFilePath | ||
| Optional path to a log file on the device to retrieve instead of using system logs (syslog/logcat). | ||
| Path format is platform-specific: | ||
| - iOS: Use bundle format like "@com.example.app:documents/logs/app.log" | ||
| - Android: Use absolute path like "/data/data/com.example.app/files/logs/app.log" | ||
| .EXAMPLE | ||
| Invoke-DeviceApp -ExecutablePath "MyGame.exe" -Arguments "--debug --level=1" | ||
| .EXAMPLE |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The new LogFilePath parameter documentation provides good examples for iOS and Android, but doesn't mention platform limitations. Since only SauceLabsProvider currently implements log file retrieval, calling Invoke-DeviceApp with LogFilePath on other platforms will silently ignore the parameter (due to the default null value). Consider adding a note in the documentation that this parameter is platform-specific, or consider warning the user if the parameter is provided but not supported by the current provider.
Severity: MEDIUM
🤖 Prompt for AI Agent
Review the code at the location below. A potential bug has been identified by an AI
agent.
Verify if this is a real issue. If it is, propose a fix; if not, explain why it's not
valid.
Location: app-runner/Public/Invoke-DeviceApp.ps1#L15-L25
Potential issue: The new `LogFilePath` parameter documentation provides good examples
for iOS and Android, but doesn't mention platform limitations. Since only
SauceLabsProvider currently implements log file retrieval, calling `Invoke-DeviceApp`
with `LogFilePath` on other platforms will silently ignore the parameter (due to the
default null value). Consider adding a note in the documentation that this parameter is
platform-specific, or consider warning the user if the parameter is provided but not
supported by the current provider.
Did we get this right? 👍 / 👎 to inform future reviews.
Reference ID: 1
| Found = $true | ||
| BundleId = $this.CurrentPackageName | ||
| FileSharingEnabled = [bool]$targetApp.UIFileSharingEnabled | ||
| Name = $targetApp.CFBundleDisplayName -or $targetApp.CFBundleName -or "Unknown" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Or doesn't work like a null-coallescing operator in Powershell so the current code returns $true instead of a name. Instead, you can do this:
| Name = $targetApp.CFBundleDisplayName -or $targetApp.CFBundleName -or "Unknown" | |
| Name = $targetApp.CFBundleDisplayName ?? $targetApp.CFBundleName ?? "Unknown" |
but that could still return an empty string - "??" only works with nulls.
If it's possible these would be empty strings, you need to expand to if-else loop, for example like this:
| Name = $targetApp.CFBundleDisplayName -or $targetApp.CFBundleName -or "Unknown" | |
| Name = $( | |
| if ($targetApp.CFBundleDisplayName) { $targetApp.CFBundleDisplayName } | |
| elseif ($targetApp.CFBundleName) { $targetApp.CFBundleName } | |
| else { "Unknown" } | |
| ) |
| Write-Error $errorMsg | ||
| throw |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Write-error doesn't just log. with our ErrorActionPreference, it's functionally equivalent to throwing. so the next line is never reached. You can use Write-Warning instead
vaind
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've found a couple of bugs and a few improvement ideas
Updated device provider APIs to consistently accept arguments as string arrays rather than pre-formatted strings, improving type safety and eliminating argument parsing ambiguities. Added ConvertArgumentsToString method to DeviceProvider base class for consistent string conversion when needed by underlying tools. Co-authored-by: Claude <claude@anthropic.com>
| if ($Arguments) { | ||
| # Appium 'mobile: launchApp' supports arguments? | ||
| # Or use 'appium:processArguments' capability during session creation? | ||
| # For now, we'll try to pass them if supported by the endpoint or warn. | ||
| $launchBody['arguments'] = $Arguments -split ' ' # Simple split, might need better parsing | ||
| # Parse arguments string into array, handling quoted strings and standalone "--" separator | ||
| $argumentsArray = @() | ||
|
|
||
| # Split the arguments string by spaces, but handle quoted strings (both single and double quotes) | ||
| $argTokens = [regex]::Matches($Arguments, '(\"[^\"]*\"|''[^'']*''|\S+)') | ForEach-Object { $_.Value.Trim('"', "'") } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Bug: The iOS implementation in RunApplication passes the $Arguments array directly to [regex]::Matches without first converting it to a string, unlike the Android path. This will cause incorrect argument parsing.
Severity: CRITICAL | Confidence: High
🔍 Detailed Analysis
In the RunApplication function, the iOS implementation incorrectly handles the $Arguments parameter, which is an array ([string[]]). Unlike the Android implementation which correctly converts the array to a string, the iOS code passes the array directly to [regex]::Matches on line 379. This function expects a string, and relying on PowerShell's implicit array-to-string conversion is fragile and will likely lead to incorrect argument parsing. This will cause iOS apps launched via SauceLabs to receive malformed arguments, potentially leading to launch failures or incorrect application behavior. Additionally, logging on line 363 will be improperly formatted.
💡 Suggested Fix
Before the iOS implementation logic (line 362), convert the $Arguments array to a string using $argumentsString = $this.ConvertArgumentsToString($Arguments). Subsequently, use this new $argumentsString variable for logging (line 363) and in the regex parsing logic (line 379) to ensure arguments are handled correctly.
🤖 Prompt for AI Agent
Review the code at the location below. A potential bug has been identified by an AI
agent.
Verify if this is a real issue. If it is, propose a fix; if not, explain why it's not
valid.
Location: app-runner/Private/DeviceProviders/SauceLabsProvider.ps1#L374-L379
Potential issue: In the `RunApplication` function, the iOS implementation incorrectly
handles the `$Arguments` parameter, which is an array (`[string[]]`). Unlike the Android
implementation which correctly converts the array to a string, the iOS code passes the
array directly to `[regex]::Matches` on line 379. This function expects a string, and
relying on PowerShell's implicit array-to-string conversion is fragile and will likely
lead to incorrect argument parsing. This will cause iOS apps launched via SauceLabs to
receive malformed arguments, potentially leading to launch failures or incorrect
application behavior. Additionally, logging on line 363 will be improperly formatted.
Did we get this right? 👍 / 👎 to inform future reviews.
Reference ID: 7483056
I tested it on iOS in Sauce Labs, and it should work on Android too. This PR also fixes some issues specific to iOS in Sauce Labs runner: splitting CLI arguments correctly and using correct Appium parameter for iOS.
These changes are sufficient to get E2E tests green on iOS in the Godot SDK.