maestro icon indicating copy to clipboard operation
maestro copied to clipboard

Add AppleTV support

Open maxphillipsdev opened this issue 1 year ago • 1 comments

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 pressKey are now available on AppleTV as well. I only included the ones that had a clear mapping to something from XCUIRemote
  • Maestro studio also works (see screenshot)

Implementation

  • Migrated maestro-ios-xctest-runner from 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.swift and passed them through from the iOS driver.
  • Updated the maestro-ios-xctest-runner build script to build separate versions for iOS and tvOS and copy them into the resources folder under an ios/ or tvos/ 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 XCUIRemote mappings (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

image

image image

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

maxphillipsdev avatar Sep 26 '24 02:09 maxphillipsdev

Ooh! Very nice would be very helpful for our situation

timrijckaert avatar Oct 30 '24 12:10 timrijckaert

@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!

douglowder avatar Jan 05 '25 20:01 douglowder

@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

douglowder avatar Jan 05 '25 21:01 douglowder

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 focused selector of the assertVisible command, which would allow for making assertions about the TV's focus state.~~ Done, thanks Doug!

maxphillipsdev avatar Jan 07 '25 13:01 maxphillipsdev

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 focused selector of the assertVisible command, 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

douglowder avatar Jan 08 '25 17:01 douglowder

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 avatar Jul 31 '25 21:07 douglowder

@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 😅

maxphillipsdev avatar Aug 12 '25 08:08 maxphillipsdev

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

maxphillipsdev avatar Aug 18 '25 13:08 maxphillipsdev