Add AppleTV support
Proposed changes
This is a draft for adding AppleTV support to the iOS driver, looking for feedback on the approach. Also the PR is pretty big so happy to split it into some smaller ones if that's preferred.
Feature additions
- When running tests against a tvOS device, the Maestro iOS driver will now install a tvOS compatible driver
- A subset of the DPAD commands that are available on AndroidTV through
pressKeyare now available on AppleTV as well. I only included the ones that had a clear mapping to something fromXCUIRemote - Maestro studio also works (see screenshot)
Implementation
- Migrated
maestro-ios-xctest-runnerfrom Storyboard to SwiftUI so iOS and tvOS could share the same XCode target. - Updated XCode build settings to support tvOS as a compilation and testing target.
- Added platform check compiler directives in several Swift files to provide tvOS support.
- Added bindings for Remote Dpad commands in
PressButtonRequest.swiftand passed them through from the iOS driver. - Updated the
maestro-ios-xctest-runnerbuild script to build separate versions for iOS and tvOS and copy them into the resources folder under anios/ortvos/prefix. - Updated the iOS driver to detect when a device is using tvOS and install the correct driver.
Limitations
- Certain commands and features of Studio are not available on tvOS since there are no
XCUIRemotemappings (tapOn, swipe for example) - Since tvOS is a different compile target than iOS, I had to include binaries for both as part of the iOS driver resources. I haven't measured the size difference of the CLI build yet but I expect it to be larger.
- When launching in Studio on tvOS the driver app goes to the foreground and you have to close it manually or launch another app with
launchApp. Not sure why this is happening, any ideas are appreciated - Still need to test the normal Maestro commands more fully to see which need modification for tvOS
- Studio fails when uninstalling the driver app on tvOS, still investigating
Screenshots
Testing
- Tested locally with tvOS and iOS simulators.
- Ran and tested Studio locally.
- Ran e2e tests on iOS, investigating adding separate tests for tvOS.
Issues fixed
#1515 – Add support for testing tvOS apps
Ooh! Very nice would be very helpful for our situation
@maxphillipsdev I really appreciate your work on this -- it would be game-changing for testing the React Native TV repo. I will look through this, and try it out!
@maxphillipsdev I created a branch in my fork where I cherry-picked all your commits against current main, and resolved conflicts. Testing this out today... https://github.com/douglowder/maestro/tree/tvos-with-main-merge
PR is rebased and CLI correctly installs / uninstalls the test runner when using studio / test commands. You can try it out locally by gradle syncing, launching a tvOS simulator and running ./maestro --verbose test some-test.yml or ./maestro --verbose studio. Here's an example yml I've been working with:
appId: com.apple.TVSettings
---
- launchApp
- assertVisible: 'General'
- pressKey: Remote Dpad Down
- pressKey: Remote Dpad Down
- pressKey: Remote Dpad Down
To do
- [ ] Fix runner app not dismissing when launching studio on tvOS
- [x] ~~Fix CI (the xcode proj buildstep seems to be failing silently due to an xcode version mismatch with the github agent)~~ Had to convert a folder to a group in xcode due to a weird backwards compatibility issue with CI agent.
- [x] ~~Investigate adding support for the
focusedselector of theassertVisiblecommand, which would allow for making assertions about the TV's focus state.~~ Done, thanks Doug!
To do
- [ ] Fix CI (the xcode proj buildstep seems to be failing silently due to an xcode version mismatch with the github agent)
- [ ] Fix runner app not dismissing when launching studio on tvOS
- [x] Investigate adding support for the
focusedselector of theassertVisiblecommand, which would allow for making assertions about the TV's focus state.
@maxphillipsdev it appears that focused support is already working, at least for RNTester in the latest RNTV build (0.77.0-0rc5 prerelease). Example:
appId: com.meta.RNTester.localDevelopment
---
- launchApp #RNTester app launch
- assertVisible: 'Components'
- pressKey: Remote Dpad Down
- pressKey: Remote Dpad Down
- pressKey: Remote Dpad Down
- pressKey: Remote Dpad Down
- pressKey: Remote Dpad Center # Arrow key down to Button example and launch
- pressKey: Remote Dpad Down
- pressKey: Remote Dpad Down
- pressKey: Remote Dpad Down # First example button should be focused
- assertVisible:
id: 'button_default_styling'
focused: true
- assertVisible:
id: 'cancel_button'
focused: false
- pressKey: Remote Dpad Down # Down arrow to the cancel button, which should now be focused
- assertVisible:
id: 'button_default_styling'
focused: false
- assertVisible:
id: 'cancel_button'
focused: true
I decided to try the same test on RNTester for Android TV, and it works, but requires some changes because the focus engine is a little different, so a different series of down and right arrow presses are needed to navigate to the expected buttons for the test.
appId: com.facebook.react.uiapp
---
- launchApp #RNTester app launch
- assertVisible: 'Components'
- pressKey: Remote Dpad Down
- pressKey: Remote Dpad Right
- pressKey: Remote Dpad Down
- pressKey: Remote Dpad Down
- pressKey: Remote Dpad Down
- pressKey: Remote Dpad Down
- pressKey: Remote Dpad Center #Arrow key down to Button example and launch
- pressKey: Remote Dpad Down
- pressKey: Remote Dpad Right
- pressKey: Remote Dpad Down #First example button should be focused
- assertVisible:
id: 'button_default_styling'
focused: true
- assertVisible:
id: 'cancel_button'
focused: false
- pressKey: Remote Dpad Down #Down arrow to the cancel button, which should now be focused
- assertVisible:
id: 'button_default_styling'
focused: false
- assertVisible:
id: 'cancel_button'
focused: true
Hi @maxphillipsdev would you be able to fix conflicts on this PR and see if it is passing checks now? I could really use this 😄
@douglowder sorry for delay, conflicts are fixed. There was a refactor to the driver installation part of the CLI, so working on updating the PR to work with those changes.
On a side note, I think the "warn build xctest runner" github action has the wrong permissions... it seems to be failing CI since it can't comment on the PR 😅
Should all work now, there is one test that's passing locally but failing in CI though that I'm still debugging. Will bump maestro team for a review