Skip to content
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

Add AppleTV support #2067

Open
wants to merge 29 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
457e1a9
create a new xcode target for tvOS
maxphillipsdev Sep 20, 2024
9002f77
enable maestro-driver-iosUITests to run against tvOS target
maxphillipsdev Sep 20, 2024
5896b72
update ScreenSizeHelper to compile on tvOS
maxphillipsdev Sep 20, 2024
0342d49
update EventRecord to compile on tvOS
maxphillipsdev Sep 20, 2024
fdd81b4
fix typo
maxphillipsdev Sep 20, 2024
eddeb59
update SystemPermissionHelper to compile on tvOS
maxphillipsdev Sep 20, 2024
563785e
update XCUIElement extension to compile on tvOS
maxphillipsdev Sep 20, 2024
33f8636
add tvOS bindings for Remote Dpad controls
maxphillipsdev Sep 20, 2024
c4dbed1
migrate maestro-driver to swiftui so tvOS and ios can share a target
maxphillipsdev Sep 20, 2024
de24aef
run build script for ios driver
maxphillipsdev Sep 22, 2024
d3bc0cb
update xcode build script, remove old targets, run new ios / tvos build
maxphillipsdev Sep 22, 2024
0d62edc
update bundle id
maxphillipsdev Sep 22, 2024
bdc809c
update springboard references for tvOS
maxphillipsdev Sep 25, 2024
bcb2041
add new ios and tvos drivers
maxphillipsdev Sep 25, 2024
8bc3dd5
update maestro-ios-driver to install separate drivers for tvOS and iOS
maxphillipsdev Sep 25, 2024
6a717a4
run apple build scripts
maxphillipsdev Jan 7, 2025
8a93210
remove duplicate bundleid
maxphillipsdev Jan 7, 2025
908aae9
update docs
maxphillipsdev Jan 7, 2025
2ad31ea
fix test run scripts to support the tvos changes
maxphillipsdev Jan 7, 2025
16b2353
update xctestrun
maxphillipsdev Jan 7, 2025
868d367
undo change of the object version
maxphillipsdev Jan 7, 2025
52c80d1
change maestro-driver from a folder to a group
maxphillipsdev Jan 11, 2025
c0e5edc
revert renames of ios specific files
maxphillipsdev Jan 11, 2025
0df112b
fix asset paths and remove unsupported swiftui feat
maxphillipsdev Jan 11, 2025
de2fbb4
update the xctest driver app
maxphillipsdev Jan 11, 2025
9eecc64
fix name
maxphillipsdev Jan 11, 2025
f0e93b1
fix test target name
maxphillipsdev Jan 11, 2025
48beba8
update the built resources in the ios-driver
maxphillipsdev Jan 11, 2025
76751bf
fix log
maxphillipsdev Jan 11, 2025
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
20 changes: 1 addition & 19 deletions maestro-client/src/main/java/maestro/drivers/IOSDriver.kt
Original file line number Diff line number Diff line change
Expand Up @@ -130,25 +130,7 @@ class IOSDriver(

override fun pressKey(code: KeyCode) {
metrics.measured("operation", mapOf("command" to "pressKey")) {
val keyCodeNameMap = mapOf(
KeyCode.BACKSPACE to "delete",
KeyCode.ENTER to "return",
)

val buttonNameMap = mapOf(
KeyCode.HOME to "home",
KeyCode.LOCK to "lock",
)

runDeviceCall("pressKey") {
keyCodeNameMap[code]?.let { name ->
iosDevice.pressKey(name)
}

buttonNameMap[code]?.let { name ->
iosDevice.pressButton(name)
}
}
iosDevice.pressButton(code.description)
}
}

Expand Down
1 change: 1 addition & 0 deletions maestro-ios-driver/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ dependencies {
implementation(project(":maestro-utils"))

api(libs.square.okhttp)
api(libs.google.gson)
api(libs.square.okhttp.logs)
api(libs.jackson.module.kotlin)
api(libs.jarchivelib)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import okio.source
import org.apache.commons.io.FileUtils
import org.rauschig.jarchivelib.ArchiverFactory
import org.slf4j.LoggerFactory
import util.LocalSimulatorUtils
import util.XCRunnerCLIUtils
import xcuitest.XCTestClient
import java.io.File
Expand Down Expand Up @@ -176,24 +177,42 @@ class LocalXCTestInstaller(
return checkSuccessful
}

private fun isTV(deviceId: String): Boolean {
val list = LocalSimulatorUtils.list()
for (entry in list.devices.entries) {
for (device in entry.value) {
if (device.udid != deviceId) continue
if (device.deviceTypeIdentifier == null) continue
if (device.deviceTypeIdentifier.contains("Apple-TV") == true) {
logger.trace("Device is an AppleTV")
return true
}
}
}

return false
}

private fun startXCTestRunner() {
if (isChannelAlive()) {
logger.info("UI Test runner already running, returning")
return
}

val isTV = isTV(deviceId)

logger.info("[Start] Writing xctest run file")
val tempDir = File(tempDir).apply { mkdir() }
val xctestRunFile = File("$tempDir/maestro-driver-ios-config.xctestrun")
writeFileToDestination(XCTEST_RUN_PATH, xctestRunFile)
val xctestRunFile = File("${tempDir}/maestro-driver-ios-config.xctestrun")
writeFileToDestination(XCTEST_RUN_PATH, xctestRunFile, isTV)
logger.info("[Done] Writing xctest run file")

logger.info("[Start] Writing maestro-driver-iosUITests-Runner app")
extractZipToApp("maestro-driver-iosUITests-Runner", UI_TEST_RUNNER_PATH)
extractZipToApp("maestro-driver-iosUITests-Runner", UI_TEST_RUNNER_PATH, isTV)
logger.info("[Done] Writing maestro-driver-iosUITests-Runner app")

logger.info("[Start] Writing maestro-driver-ios app")
extractZipToApp("maestro-driver-ios", UI_TEST_HOST_PATH)
extractZipToApp("maestro-driver-ios", UI_TEST_HOST_PATH, isTV)
logger.info("[Done] Writing maestro-driver-ios app")

logger.info("[Start] Running XcUITest with `xcodebuild test-without-building`")
Expand All @@ -218,30 +237,36 @@ class LocalXCTestInstaller(
logger.info("[Done] Cleaning up the ui test runner files")
}

private fun extractZipToApp(appFileName: String, srcAppPath: String) {
val appFile = File("$tempDir/Debug-iphonesimulator").apply { mkdir() }
private fun extractZipToApp(appFileName: String, srcAppPath: String, isTV: Boolean) {
val appFile = when(isTV) {
true -> File("$tempDir/Debug-appletvsimulator").apply { mkdir() }
false -> File("$tempDir/Debug-iphonesimulator").apply { mkdir() }
}
val appZip = File("$tempDir/$appFileName.zip")

writeFileToDestination(srcAppPath, appZip)
writeFileToDestination(srcAppPath, appZip, isTV)
ArchiverFactory.createArchiver(appZip).apply {
extract(appZip, appFile)
}
}

private fun writeFileToDestination(srcPath: String, destFile: File) {
LocalXCTestInstaller::class.java.getResourceAsStream(srcPath)?.let {
private fun writeFileToDestination(srcPath: String, destFile: File, isTV: Boolean) {
val prefix = when (isTV) {
true -> "/tvos/"
false -> "/ios/"
}
LocalXCTestInstaller::class.java.getResourceAsStream(prefix + srcPath)?.let {
val bufferedSink = destFile.sink().buffer()
bufferedSink.writeAll(it.source())
bufferedSink.flush()
}
}

companion object {
private const val UI_TEST_RUNNER_PATH = "/maestro-driver-iosUITests-Runner.zip"
private const val XCTEST_RUN_PATH = "/maestro-driver-ios-config.xctestrun"
private const val UI_TEST_HOST_PATH = "/maestro-driver-ios.zip"
private const val UI_TEST_RUNNER_APP_BUNDLE_ID =
"dev.mobile.maestro-driver-iosUITests.xctrunner"
private const val UI_TEST_RUNNER_PATH = "maestro-driver-iosUITests-Runner.zip"
private const val XCTEST_RUN_PATH = "maestro-driver-ios-config.xctestrun"
private const val UI_TEST_HOST_PATH = "maestro-driver-ios.zip"
private const val UI_TEST_RUNNER_APP_BUNDLE_ID = "dev.mobile.maestro-driver-iosUITests.xctrunner"

private const val SERVER_LAUNCH_TIMEOUT_MS = 120000L
private const val MAESTRO_DRIVER_STARTUP_TIMEOUT = "MAESTRO_DRIVER_STARTUP_TIMEOUT"
Expand Down
Loading
Loading