StudioCommand.kt•4.39 kB
package maestro.cli.command
import maestro.cli.App
import maestro.cli.DisableAnsiMixin
import maestro.cli.ShowHelpMixin
import maestro.cli.report.TestDebugReporter
import maestro.cli.session.MaestroSessionManager
import maestro.cli.view.blue
import maestro.cli.view.bold
import maestro.cli.view.box
import maestro.cli.view.faint
import maestro.studio.MaestroStudio
import picocli.CommandLine
import java.awt.Desktop
import java.net.URI
import java.util.concurrent.Callable
import maestro.cli.util.getFreePort
import picocli.CommandLine.Option
@CommandLine.Command(
name = "studio",
hidden = true,
description = ["Launch Maestro Studio"],
)
class StudioCommand : Callable<Int> {
@CommandLine.Mixin
var disableANSIMixin: DisableAnsiMixin? = null
@CommandLine.Mixin
var showHelpMixin: ShowHelpMixin? = null
@CommandLine.ParentCommand
private val parent: App? = null
@Option(
names = ["--debug-output"],
description = ["Configures the debug output in this path, instead of default"]
)
private var debugOutput: String? = null
@Option(
names = ["--no-window"],
description = ["When set, a browser window will not be automatically opened"]
)
private var noWindow: Boolean? = null
@Option(
names = ["--android-webview-hierarchy"],
description = ["Set to \"devtools\" to use Chrome dev tools for Android WebView hierarchy"],
hidden = true,
)
private var androidWebViewHierarchy: String? = null
@Option(
names = ["--apple-team-id"],
description = ["The Team ID is a unique 10-character string generated by Apple that is assigned to your team's apple account."]
)
private var appleTeamId: String? = null
override fun call(): Int {
println()
println("""
╭────────────────────────────────────────────────────────────────────────────────╮
│ │
│ Download the new and improved Maestro Studio app today! │
│ │
│ https://maestro.dev?utm_source=cli&utm_campaign=download_studio#maestro-studio │
│ │
╰────────────────────────────────────────────────────────────────────────────────╯""".trimIndent().bold())
println()
TestDebugReporter.install(debugOutputPathAsString = debugOutput, printToConsole = parent?.verbose == true)
MaestroSessionManager.newSession(
host = parent?.host,
port = parent?.port,
driverHostPort = null,
teamId = appleTeamId,
deviceId = parent?.deviceId,
platform = parent?.platform,
isStudio = true,
) { session ->
session.maestro.setAndroidChromeDevToolsEnabled(androidWebViewHierarchy == "devtools")
val port = getFreePort()
MaestroStudio.start(port, session.maestro)
val studioUrl = "http://localhost:${port}"
val message = ("Maestro Studio".bold() + " is running at " + studioUrl.blue()).box()
println()
println(message)
tryOpenUrl(studioUrl)
println()
println("Tip: Maestro Studio can now run simultaneously alongside other Maestro CLI commands!")
println()
println("Navigate to $studioUrl in your browser to open Maestro Studio. Ctrl-C to exit.".faint())
Thread.currentThread().join()
}
TestDebugReporter.deleteOldFiles()
return 0
}
private fun tryOpenUrl(studioUrl: String) {
try {
if (Desktop.isDesktopSupported() && noWindow != true) {
Desktop.getDesktop().browse(URI(studioUrl))
}
} catch (ignore: Exception) {
// Do nothing
}
}
}