Skip to content

Commit

Permalink
Configure path for debugging flows output (mobile-dev-inc#1298)
Browse files Browse the repository at this point in the history
  • Loading branch information
amanjeetsingh150 authored Aug 3, 2023
1 parent b9c327a commit 13d8096
Show file tree
Hide file tree
Showing 6 changed files with 85 additions and 28 deletions.
5 changes: 0 additions & 5 deletions maestro-cli/src/main/java/maestro/cli/App.kt
Original file line number Diff line number Diff line change
Expand Up @@ -95,12 +95,7 @@ fun main(args: Array<String>) {
System.setProperty("apple.awt.UIElement", "true")

// logs & debug output
val debugOutputPath = TestDebugReporter.path
LogConfig.configure(debugOutputPath.absolutePathString() + "/maestro.log")

val logger = LoggerFactory.getLogger(App::class.java)
TestDebugReporter.logSystemInfo()
DebugLogStore.logSystemInfo()

Dependencies.install()
Updates.fetchUpdatesAsync()
Expand Down
16 changes: 15 additions & 1 deletion maestro-cli/src/main/java/maestro/cli/command/RecordCommand.kt
Original file line number Diff line number Diff line change
Expand Up @@ -23,16 +23,20 @@ import maestro.cli.App
import maestro.cli.CliError
import maestro.cli.DisableAnsiMixin
import maestro.cli.api.ApiClient
import maestro.cli.report.TestDebugReporter
import maestro.cli.runner.TestRunner
import maestro.cli.runner.resultview.AnsiResultView
import maestro.cli.session.MaestroSessionManager
import maestro.cli.view.ProgressBar
import maestro.debuglog.DebugLogStore
import maestro.debuglog.LogConfig
import okio.sink
import org.fusesource.jansi.Ansi
import picocli.CommandLine
import picocli.CommandLine.Option
import java.io.File
import java.util.concurrent.Callable
import kotlin.io.path.absolutePathString

@CommandLine.Command(
name = "record",
Expand All @@ -57,6 +61,12 @@ class RecordCommand : Callable<Int> {
@CommandLine.Spec
lateinit var commandSpec: CommandLine.Model.CommandSpec

@Option(
names = ["--debug-output"],
description = ["Configures the debug output in this path, instead of default"]
)
private var debugOutput: String? = null

override fun call(): Int {
if (!flowFile.exists()) {
throw CommandLine.ParameterException(
Expand All @@ -69,6 +79,10 @@ class RecordCommand : Callable<Int> {
throw CliError("--platform option was deprecated. You can remove it to run your test.")
}


TestDebugReporter.install(debugOutputPathAsString = debugOutput)
val path = TestDebugReporter.getDebugOutputPath()

return MaestroSessionManager.newSession(parent?.host, parent?.port, parent?.deviceId) { session ->
val maestro = session.maestro
val device = session.device
Expand All @@ -84,7 +98,7 @@ class RecordCommand : Callable<Int> {
val screenRecording = kotlin.io.path.createTempFile(suffix = ".mp4").toFile()
val exitCode = screenRecording.sink().use { out ->
maestro.startScreenRecording(out).use {
TestRunner.runSingle(maestro, device, flowFile, env, resultView)
TestRunner.runSingle(maestro, device, flowFile, env, resultView, path)
}
}

Expand Down
18 changes: 15 additions & 3 deletions maestro-cli/src/main/java/maestro/cli/command/TestCommand.kt
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ import maestro.cli.runner.resultview.AnsiResultView
import maestro.cli.runner.resultview.PlainTextResultView
import maestro.cli.session.MaestroSessionManager
import maestro.cli.util.PrintUtils
import maestro.debuglog.DebugLogStore
import maestro.debuglog.LogConfig
import maestro.orchestra.util.Env.withInjectedShellEnvVars
import maestro.orchestra.yaml.YamlCommandReader
import okio.buffer
Expand Down Expand Up @@ -79,6 +81,12 @@ class TestCommand : Callable<Int> {
@Option(names = ["--output"])
private var output: File? = null

@Option(
names = ["--debug-output"],
description = ["Configures the debug output in this path, instead of default"]
)
private var debugOutput: String? = null

@Option(
names = ["--include-tags"],
description = ["List of tags that will remove the Flows that does not have the provided tags"],
Expand Down Expand Up @@ -122,6 +130,9 @@ class TestCommand : Callable<Int> {
else parent?.deviceId

env = env.withInjectedShellEnvVars()

TestDebugReporter.install(debugOutputPathAsString = debugOutput)
val path = TestDebugReporter.getDebugOutputPath()

return MaestroSessionManager.newSession(parent?.host, parent?.port, deviceId) { session ->
val maestro = session.maestro
Expand Down Expand Up @@ -149,7 +160,8 @@ class TestCommand : Callable<Int> {
(output ?: File("report$extension"))
.sink()
.buffer()
}
},
debugOutput = debugOutput
)

if (suiteResult.passed) {
Expand All @@ -163,7 +175,7 @@ class TestCommand : Callable<Int> {
TestRunner.runContinuous(maestro, device, flowFile, env)
} else {
val resultView = if (DisableAnsiMixin.ansiEnabled) AnsiResultView() else PlainTextResultView()
val resultSingle = TestRunner.runSingle(maestro, device, flowFile, env, resultView)
val resultSingle = TestRunner.runSingle(maestro, device, flowFile, env, resultView, path)
if (resultSingle == 1) {
printExitDebugMessage()
}
Expand All @@ -176,6 +188,6 @@ class TestCommand : Callable<Int> {
private fun printExitDebugMessage() {
println()
println("==== Debug output (logs & screenshots) ====")
PrintUtils.message(TestDebugReporter.path.absolutePathString())
PrintUtils.message(TestDebugReporter.getDebugOutputPath().absolutePathString())
}
}
44 changes: 30 additions & 14 deletions maestro-cli/src/main/java/maestro/cli/report/TestDebugReporter.kt
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import maestro.Driver
import maestro.MaestroException
import maestro.TreeNode
import maestro.cli.runner.CommandStatus
import maestro.debuglog.DebugLogStore
import maestro.debuglog.LogConfig
import maestro.orchestra.MaestroCommand
import org.slf4j.LoggerFactory
import java.io.File
Expand All @@ -21,34 +23,25 @@ import java.time.temporal.ChronoUnit
import java.util.IdentityHashMap
import java.util.Properties
import kotlin.io.path.absolutePathString
import kotlin.math.log
import kotlin.io.path.exists

object TestDebugReporter {

private val logger = LoggerFactory.getLogger(TestDebugReporter::class.java)

private val dateFormat = "yyyy-MM-dd_HHmmss"
private val mapper = ObjectMapper()

private val parentPath = Paths.get(System.getProperty("user.home"), ".maestro", "tests")
val path: Path

init {
private var debugOutputPath: Path? = null
private var debugOutputPathAsString: String? = null

// folder
val dateFormatter = DateTimeFormatter.ofPattern(dateFormat)
val folderName = dateFormatter.format(LocalDateTime.now())

path = Paths.get(System.getProperty("user.home"), ".maestro", "tests", folderName)

Files.createDirectories(path)
init {

// json
mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL)
mapper.setSerializationInclusion(JsonInclude.Include.NON_EMPTY)
}

fun saveFlow(flowName: String, data: FlowDebugMetadata) {
fun saveFlow(flowName: String, data: FlowDebugMetadata, path: Path) {

// commands
val commandMetadata = data.commands
Expand Down Expand Up @@ -115,6 +108,29 @@ object TestDebugReporter {
logger.info("Architecture: $architecture")
logger.info("---------------------")
}

fun install(debugOutputPathAsString: String?) {
this.debugOutputPathAsString = debugOutputPathAsString
val path = getDebugOutputPath()
LogConfig.configure(path.absolutePathString() + "/maestro.log")
logSystemInfo()
DebugLogStore.logSystemInfo()
}

fun getDebugOutputPath(): Path {
if (debugOutputPath != null) return debugOutputPath as Path

val dateFormat = "yyyy-MM-dd_HHmmss"
val dateFormatter = DateTimeFormatter.ofPattern(dateFormat)
val folderName = dateFormatter.format(LocalDateTime.now())
val debugOutput = Paths.get(debugOutputPathAsString ?: System.getProperty("user.home"), ".maestro", "tests", folderName)
if (!debugOutput.exists()) {
Files.createDirectories(debugOutput)
}
debugOutputPath = debugOutput
return debugOutput
}

}

private data class CommandDebugWrapper(
Expand Down
13 changes: 11 additions & 2 deletions maestro-cli/src/main/java/maestro/cli/runner/TestRunner.kt
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,21 @@ import maestro.cli.runner.resultview.UiState
import maestro.cli.util.PrintUtils
import maestro.cli.view.ErrorViewUtils
import maestro.debuglog.DebugLogStore
import maestro.debuglog.LogConfig
import maestro.orchestra.MaestroCommand
import maestro.orchestra.MaestroInitFlow
import maestro.orchestra.OrchestraAppState
import maestro.orchestra.util.Env.withEnv
import maestro.orchestra.yaml.YamlCommandReader
import org.slf4j.LoggerFactory
import java.io.File
import java.nio.file.Files
import java.nio.file.Path
import java.nio.file.Paths
import java.time.LocalDateTime
import java.time.format.DateTimeFormatter
import kotlin.concurrent.thread
import kotlin.io.path.absolutePathString

object TestRunner {

Expand All @@ -34,11 +41,13 @@ object TestRunner {
device: Device?,
flowFile: File,
env: Map<String, String>,
resultView: ResultView
resultView: ResultView,
debugOutputPath: Path
): Int {

// debug
val debug = FlowDebugMetadata()

val result = runCatching(resultView, maestro) {
val commands = YamlCommandReader.readCommands(flowFile.toPath())
.withEnv(env)
Expand All @@ -52,7 +61,7 @@ object TestRunner {
)
}

TestDebugReporter.saveFlow(flowFile.name, debug)
TestDebugReporter.saveFlow(flowFile.name, debug, debugOutputPath)
if (debug.exception != null) PrintUtils.err("${debug.exception?.message}")

return if (result.get()?.flowSuccess == true) 0 else 1
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,16 @@ import maestro.cli.util.PrintUtils
import maestro.cli.view.ErrorViewUtils
import maestro.cli.view.TestSuiteStatusView
import maestro.cli.view.TestSuiteStatusView.TestSuiteViewModel
import maestro.debuglog.DebugLogStore
import maestro.debuglog.LogConfig
import maestro.orchestra.Orchestra
import maestro.orchestra.util.Env.withEnv
import maestro.orchestra.workspace.WorkspaceExecutionPlanner
import maestro.orchestra.yaml.YamlCommandReader
import okio.Sink
import org.slf4j.LoggerFactory
import java.io.File
import kotlin.io.path.absolutePathString
import kotlin.math.roundToLong
import kotlin.system.measureTimeMillis
import kotlin.time.Duration.Companion.seconds
Expand All @@ -40,12 +43,14 @@ class TestSuiteInteractor(
input: File,
reportOut: Sink?,
env: Map<String, String>,
debugOutput: String?
): TestExecutionSummary {
return if (input.isFile) {
runTestSuite(
WorkspaceExecutionPlanner.ExecutionPlan(flowsToRun = listOf(input.toPath())),
reportOut,
env,
debugOutput
)
} else {
val plan = WorkspaceExecutionPlanner
Expand All @@ -64,6 +69,7 @@ class TestSuiteInteractor(
plan,
reportOut,
env,
debugOutput
)
}
}
Expand All @@ -72,6 +78,7 @@ class TestSuiteInteractor(
executionPlan: WorkspaceExecutionPlanner.ExecutionPlan,
reportOut: Sink?,
env: Map<String, String>,
debugOutput: String?
): TestExecutionSummary {
val flowResults = mutableListOf<TestExecutionSummary.FlowResult>()

Expand All @@ -83,7 +90,7 @@ class TestSuiteInteractor(
// first run sequence of flows if present
val flowSequence = executionPlan.sequence
for (flow in flowSequence?.flows ?: emptyList()) {
val result = runFlow(flow.toFile(), env, maestro)
val result = runFlow(flow.toFile(), env, maestro, debugOutput)
flowResults.add(result)

if (result.status == FlowStatus.ERROR) {
Expand All @@ -98,7 +105,7 @@ class TestSuiteInteractor(

// proceed to run all other Flows
executionPlan.flowsToRun.forEach { flow ->
val result = runFlow(flow.toFile(), env, maestro)
val result = runFlow(flow.toFile(), env, maestro, debugOutput)

if (result.status == FlowStatus.ERROR) {
passed = false
Expand Down Expand Up @@ -150,6 +157,7 @@ class TestSuiteInteractor(
flowFile: File,
env: Map<String, String>,
maestro: Maestro,
debugOutput: String?
): TestExecutionSummary.FlowResult {
var flowName: String = flowFile.nameWithoutExtension
var flowStatus: FlowStatus
Expand Down Expand Up @@ -185,6 +193,9 @@ class TestSuiteInteractor(
return result.getOrNull()
}

TestDebugReporter.install(debugOutputPathAsString = debugOutput)
val path = TestDebugReporter.getDebugOutputPath()

val flowTimeMillis = measureTimeMillis {
try {
val commands = YamlCommandReader.readCommands(flowFile.toPath())
Expand Down Expand Up @@ -248,7 +259,7 @@ class TestSuiteInteractor(
}
val flowDuration = (flowTimeMillis / 1000f).roundToLong().seconds

TestDebugReporter.saveFlow(flowName, debug)
TestDebugReporter.saveFlow(flowName, debug, path)

TestSuiteStatusView.showFlowCompletion(
TestSuiteViewModel.FlowResult(
Expand Down

0 comments on commit 13d8096

Please sign in to comment.