feat: add 6 tvOS button values for mobile: pressButton#1116
feat: add 6 tvOS button values for mobile: pressButton#1116eglitise merged 5 commits intoappium:masterfrom
mobile: pressButton#1116Conversation
There was a problem hiding this comment.
Pull request overview
Adds additional tvOS remote button name mappings to mobile: pressButton (via XCUIDevice helper) so Appium/WDA can trigger more Apple TV remote buttons through XCTest/WDA.
Changes:
- Map
pageUp,pageDown, andguideto the correspondingXCUIRemoteButton*enums. - Add tvOS 18.1+ button mappings (
fourColors,oneTwoThree,tvProvider) behind compile-time and runtime availability checks.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
|
||
| // since tvOS 14.3 | ||
| if ([buttonName.lowercaseString isEqualToString:@"pageup"]) { | ||
| remoteButton = XCUIRemoteButtonPageUp; |
There was a problem hiding this comment.
I have confirmed on my XCTest header note, the blow ones were added in Xcode 15.3
- XCUIRemoteButtonPageUp
- XCUIRemoteButtonPageDown
- XCUIRemoteButtonGuide
This is since Xcode 15.3:
AppleTVOS/Frameworks/XCTest.framework/Headers/Headers/XCUIRemote.h: * @enum XCUIRemoteButton
AppleTVOS/Frameworks/XCTest.framework/Headers/Headers/XCUIRemote.h:typedef NS_ENUM(NSUInteger, XCUIRemoteButton) {
AppleTVOS/Frameworks/XCTest.framework/Headers/Headers/XCUIRemote.h: XCUIRemoteButtonUp = 0,
AppleTVOS/Frameworks/XCTest.framework/Headers/Headers/XCUIRemote.h: XCUIRemoteButtonDown = 1,
AppleTVOS/Frameworks/XCTest.framework/Headers/Headers/XCUIRemote.h: XCUIRemoteButtonLeft = 2,
AppleTVOS/Frameworks/XCTest.framework/Headers/Headers/XCUIRemote.h: XCUIRemoteButtonRight = 3,
AppleTVOS/Frameworks/XCTest.framework/Headers/Headers/XCUIRemote.h: XCUIRemoteButtonSelect = 4,
AppleTVOS/Frameworks/XCTest.framework/Headers/Headers/XCUIRemote.h: XCUIRemoteButtonMenu = 5,
AppleTVOS/Frameworks/XCTest.framework/Headers/Headers/XCUIRemote.h: XCUIRemoteButtonPlayPause = 6,
AppleTVOS/Frameworks/XCTest.framework/Headers/Headers/XCUIRemote.h: XCUIRemoteButtonHome = 7,
AppleTVOS/Frameworks/XCTest.framework/Headers/Headers/XCUIRemote.h: XCUIRemoteButtonPageUp API_AVAILABLE(tvos(14.3)) = 9,
AppleTVOS/Frameworks/XCTest.framework/Headers/Headers/XCUIRemote.h: XCUIRemoteButtonPageDown API_AVAILABLE(tvos(14.3)) = 10,
AppleTVOS/Frameworks/XCTest.framework/Headers/Headers/XCUIRemote.h: XCUIRemoteButtonGuide API_AVAILABLE(tvos(14.3)) = 11
AppleTVOS/Frameworks/XCTest.framework/Headers/Headers/XCUIRemote.h:- (void)pressButton:(XCUIRemoteButton)remoteButton;
KazuCocoa
left a comment
There was a problem hiding this comment.
I'm fine to add the Xcode version check for the page up/down and guide since our supported Xcode version is the latest two major versions - 26 and 16 for now.
| } | ||
| [supportedButtonNames addObject:@"select"]; | ||
|
|
||
| // since tvOS 14.3 |
There was a problem hiding this comment.
the method is now big and is hard to read. Consider splitting it to smaller ones
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 1 out of 1 changed files in this pull request and generated 3 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
You can also share your feedback on Copilot code review. Take the survey.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 1 out of 1 changed files in this pull request and generated 5 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
You can also share your feedback on Copilot code review. Take the survey.
| #if TARGET_OS_TV | ||
| NSDictionary<NSString *, NSNumber *> *availableButtonNames(void) { | ||
| static dispatch_once_t onceToken; | ||
| static NSDictionary *result; | ||
| dispatch_once(&onceToken, ^{ |
There was a problem hiding this comment.
availableButtonNames is declared as a global C function in this .m file. Since it’s only used internally, consider marking it static (or giving it an FB-prefixed name) to avoid exporting a generic symbol that could collide at link time.
There was a problem hiding this comment.
I assume it's not exported as it's not included in the headers file
There was a problem hiding this comment.
this comment still makes sense, lets add FB prefix
| NSDictionary<NSString *, NSNumber *> *availableButtons = availableButtonNames(); | ||
| NSNumber *buttonValue = availableButtons[buttonName.lowercaseString]; | ||
|
|
||
| if (!buttonValue) { | ||
| return [[[FBErrorBuilder builder] | ||
| withDescriptionFormat:@"The button '%@' is not supported. The device under test only supports the following buttons: %@", buttonName, supportedButtonNames] | ||
| withDescriptionFormat:@"The button '%@' is not supported. The device under test only supports the following buttons: %@", buttonName, availableButtons.allKeys] | ||
| buildError:error]; |
There was a problem hiding this comment.
The unsupported-button error now prints availableButtons.allKeys, which is not ordered and can lead to noisy/non-deterministic messages. Consider sorting the keys (e.g. case-insensitive compare) before including them in the error description to keep output stable and easier to read.
There was a problem hiding this comment.
I could add this, but I'm not sure it's really an issue
There was a problem hiding this comment.
lets add sorting, it's a simple change
| #if __clang_major__ >= 15 // Xcode 15+ | ||
| buttons[@"pageup"] = @(XCUIRemoteButtonPageUp); // 9 | ||
| buttons[@"pagedown"] = @(XCUIRemoteButtonPageDown); // 10 | ||
| buttons[@"guide"] = @(XCUIRemoteButtonGuide); // 11 | ||
| #endif |
There was a problem hiding this comment.
The tvOS button availability is gated using __clang_major__ (Xcode/clang version), but the PR description says the guard should be based on whether the SDK headers include the enum values. Using clang version is an indirect proxy and can unnecessarily disable support when building with an SDK that already contains these enum cases. Prefer guarding with the SDK availability macros (e.g. __TV_OS_VERSION_MAX_ALLOWED) so the checks reflect the actual headers being compiled against.
There was a problem hiding this comment.
We don't use the _VERSION_MAX_ALLOWED macros anywhere, and in this case the clang version actually has a stricter requirement than the tvOS version
| #if __clang_major__ >= 17 // likely Xcode 16.3+ | ||
| if (@available(tvOS 18.1, *)) { | ||
| buttons[@"fourcolors"] = @(XCUIRemoteButtonFourColors); // 12 | ||
| buttons[@"onetwothree"] = @(XCUIRemoteButtonOneTwoThree); // 13 | ||
| buttons[@"tvprovider"] = @(XCUIRemoteButtonTVProvider); // 14 | ||
| } | ||
| #endif |
There was a problem hiding this comment.
Same issue for the tvOS 18.1+ remote buttons: __clang_major__ is a brittle proxy for SDK support. Guard these enum references with the corresponding tvOS SDK max-allowed macro (and keep the @available(tvOS 18.1, *) runtime gate) to ensure compilation is tied to header availability rather than compiler version.
| if (@available(iOS 16.0, *)) { | ||
| #if defined(XCUIDeviceButtonAction) | ||
| #if __clang_major__ >= 15 // likely Xcode 15+ | ||
| if ([XCUIDevice.sharedDevice hasHardwareButton:XCUIDeviceButtonAction]) { | ||
| buttons[@"action"] = @(XCUIDeviceButtonAction); | ||
| buttons[@"action"] = @(XCUIDeviceButtonAction); // 4 | ||
| } | ||
| #endif | ||
| #if defined(XCUIDeviceButtonCamera) | ||
| #if !TARGET_OS_SIMULATOR | ||
| #if (!TARGET_OS_SIMULATOR && __clang_major__ >= 16) // likely Xcode 16+ | ||
| if ([XCUIDevice.sharedDevice hasHardwareButton:XCUIDeviceButtonCamera]) { | ||
| buttons[@"camera"] = @(XCUIDeviceButtonCamera); | ||
| } |
There was a problem hiding this comment.
On iOS, gating XCUIDeviceButtonAction/XCUIDeviceButtonCamera behind __clang_major__ ties the feature to compiler version rather than SDK header availability. To match the intent (“guard behind whether the used Xcode SDK includes its enum”), use the relevant __IPHONE_OS_VERSION_MAX_ALLOWED checks (plus the existing @available(iOS 16.0, *) runtime guard) so the code compiles/behaves correctly across different toolchains.
## [11.3.0](v11.2.0...v11.3.0) (2026-03-05) ### Features * add 6 tvOS button values for `mobile: pressButton` ([#1116](#1116)) ([efd64ed](efd64ed))
|
🎉 This PR is included in version 11.3.0 🎉 The release is available on: Your semantic-release bot 📦🚀 |
|
@eglitise Please don't forget to update docs for the appropriate execute extension in the xcuitest driver |
Similarly to #1115, this adds support for 6 tvOS buttons to
mobile: pressButton:pageUp(tvOS 14.3+)pageDown(tvOS 14.3+)guide(tvOS 14.3+)fourColors(tvOS 18.1+)oneTwoThree(tvOS 18.1+)tvProvider(tvOS 18.1+)Each button is guarded behind whether the used Xcode SDK includes its enum, and the latter three also behind tvOS 18.1+ (the former three aren't guarded, as we only support tvOS 15+)
Reference: https://developer.apple.com/documentation/xcuiautomation/xcuiremotebutton/home?language=objc