Skip to content

Commit 17e67dc

Browse files
fix: use noop insights by default on maestro (#2131)
1 parent 759d954 commit 17e67dc

File tree

10 files changed

+84
-43
lines changed

10 files changed

+84
-43
lines changed

maestro-cli/src/main/java/maestro/cli/command/PrintHierarchyCommand.kt

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,9 @@ import maestro.cli.DisableAnsiMixin
2626
import maestro.cli.ShowHelpMixin
2727
import maestro.cli.report.TestDebugReporter
2828
import maestro.cli.session.MaestroSessionManager
29-
import maestro.cli.view.green
3029
import maestro.cli.view.yellow
31-
import maestro.utils.Insights
30+
import maestro.utils.CliInsights
31+
import maestro.utils.Insight
3232
import maestro.utils.chunkStringByWordCount
3333
import picocli.CommandLine
3434
import java.lang.StringBuilder
@@ -65,7 +65,7 @@ class PrintHierarchyCommand : Runnable {
6565
deviceId = parent?.deviceId,
6666
platform = parent?.platform,
6767
) { session ->
68-
Insights.onInsightsUpdated {
68+
val callback: (Insight) -> Unit = {
6969
val message = StringBuilder()
7070
val level = it.level.toString().lowercase().replaceFirstChar(Char::uppercase)
7171
message.append(level.yellow() + ": ")
@@ -74,11 +74,17 @@ class PrintHierarchyCommand : Runnable {
7474
}
7575
println(message.toString())
7676
}
77+
val insights = CliInsights
78+
79+
insights.onInsightsUpdated(callback)
80+
7781
val hierarchy = jacksonObjectMapper()
7882
.setSerializationInclusion(JsonInclude.Include.NON_NULL)
7983
.writerWithDefaultPrettyPrinter()
8084
.writeValueAsString(session.maestro.viewHierarchy().root)
8185

86+
insights.unregisterListener(callback)
87+
8288
println(hierarchy)
8389
}
8490
}

maestro-cli/src/main/java/maestro/cli/runner/MaestroCommandRunner.kt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,10 +33,11 @@ import maestro.orchestra.CompositeCommand
3333
import maestro.orchestra.MaestroCommand
3434
import maestro.orchestra.Orchestra
3535
import maestro.orchestra.yaml.YamlCommandReader
36-
import maestro.utils.Insight
36+
import maestro.utils.CliInsights
3737
import org.slf4j.LoggerFactory
3838
import java.util.IdentityHashMap
3939
import maestro.cli.util.ScreenshotUtils
40+
import maestro.utils.Insight
4041

4142
/**
4243
* Knows how to run a list of Maestro commands and update the UI.
@@ -91,6 +92,7 @@ object MaestroCommandRunner {
9192

9293
val orchestra = Orchestra(
9394
maestro = maestro,
95+
insights = CliInsights,
9496
onCommandStart = { _, command ->
9597
logger.info("${command.description()} RUNNING")
9698
commandStatuses[command] = CommandStatus.RUNNING

maestro-cli/src/main/java/maestro/cli/session/MaestroSessionManager.kt

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ import maestro.Maestro
2828
import maestro.cli.device.Device
2929
import maestro.cli.device.PickDeviceInteractor
3030
import maestro.cli.device.Platform
31+
import maestro.utils.CliInsights
3132
import maestro.cli.util.ScreenReporter
3233
import maestro.drivers.AndroidDriver
3334
import maestro.drivers.IOSDriver
@@ -304,7 +305,9 @@ object MaestroSessionManager {
304305
deviceId = deviceId,
305306
xcTestDevice = xcTestDevice,
306307
simctlIOSDevice = simctlIOSDevice,
307-
)
308+
insights = CliInsights
309+
),
310+
insights = CliInsights
308311
)
309312

310313
return Maestro.ios(

maestro-client/src/main/java/maestro/drivers/IOSDriver.kt

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ import kotlin.collections.set
4040

4141
class IOSDriver(
4242
private val iosDevice: IOSDevice,
43+
private val insights: Insights = NoopInsights
4344
) : Driver {
4445

4546
private var appId: String? = null
@@ -138,9 +139,9 @@ class IOSDriver(
138139
"If you are using React native, consider migrating to the new " +
139140
"architecture where view flattening is available. For more information on the " +
140141
"migration process, please visit: https://reactnative.dev/docs/new-architecture-intro"
141-
Insights.report(Insight(message, Insight.Level.INFO))
142+
insights.report(Insight(message, Insight.Level.INFO))
142143
} else {
143-
Insights.report(Insight("", Insight.Level.NONE))
144+
insights.report(Insight("", Insight.Level.NONE))
144145
}
145146
val hierarchy = hierarchyResult.axElement
146147
return mapViewHierarchy(hierarchy)

maestro-ios/src/main/java/ios/LocalIOSDevice.kt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,15 @@ import java.util.UUID
1010
import hierarchy.ViewHierarchy
1111
import maestro.utils.Insight
1212
import maestro.utils.Insights
13+
import maestro.utils.NoopInsights
1314
import java.util.concurrent.Executors
1415
import java.util.concurrent.TimeUnit
1516

1617
class LocalIOSDevice(
1718
override val deviceId: String?,
1819
private val xcTestDevice: XCTestIOSDevice,
1920
private val simctlIOSDevice: SimctlIOSDevice,
21+
private val insights: Insights = NoopInsights
2022
) : IOSDevice {
2123

2224
private val executor by lazy { Executors.newSingleThreadScheduledExecutor() }
@@ -34,7 +36,7 @@ class LocalIOSDevice(
3436
val future = executor.schedule(
3537
{
3638
if (isViewHierarchyInProgress) {
37-
Insights.report(
39+
insights.report(
3840
Insight(
3941
message = "Retrieving the hierarchy is taking longer than usual. This might be due to a " +
4042
"deep hierarchy in the current view. Please wait a bit more to complete the operation.",

maestro-orchestra/src/main/java/maestro/orchestra/Orchestra.kt

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ import maestro.orchestra.yaml.YamlCommandReader
4040
import maestro.utils.Insight
4141
import maestro.utils.Insights
4242
import maestro.utils.MaestroTimer
43+
import maestro.utils.NoopInsights
4344
import maestro.utils.StringUtils.toRegexSafe
4445
import okhttp3.OkHttpClient
4546
import okio.Buffer
@@ -76,11 +77,12 @@ class Orchestra(
7677
private val lookupTimeoutMs: Long = 17000L,
7778
private val optionalLookupTimeoutMs: Long = 7000L,
7879
private val httpClient: OkHttpClient? = null,
80+
private val insights: Insights = NoopInsights,
7981
private val onFlowStart: (List<MaestroCommand>) -> Unit = {},
8082
private val onCommandStart: (Int, MaestroCommand) -> Unit = { _, _ -> },
8183
private val onCommandComplete: (Int, MaestroCommand) -> Unit = { _, _ -> },
8284
private val onCommandFailed: (Int, MaestroCommand, Throwable) -> ErrorResolution = { _, _, e -> throw e },
83-
private val onCommandWarned: (Int, MaestroCommand) -> Unit = { _, _ -> },
85+
private val onCommandWarned: (Int, MaestroCommand) -> Unit = { _, _ -> },
8486
private val onCommandSkipped: (Int, MaestroCommand) -> Unit = { _, _ -> },
8587
private val onCommandReset: (MaestroCommand) -> Unit = {},
8688
private val onCommandMetadataUpdate: (MaestroCommand, CommandMetadata) -> Unit = { _, _ -> },
@@ -186,7 +188,7 @@ class Orchestra(
186188
)
187189
)
188190
}
189-
Insights.onInsightsUpdated(callback)
191+
insights.onInsightsUpdated(callback)
190192

191193
try {
192194
try {
@@ -199,7 +201,7 @@ class Orchestra(
199201
}
200202
} catch (ignored: CommandWarned) {
201203
// Swallow exception, but add a warning as an insight
202-
Insights.report(Insight(message = ignored.message, level = Insight.Level.WARNING))
204+
insights.report(Insight(message = ignored.message, level = Insight.Level.WARNING))
203205
onCommandWarned(index, command)
204206
} catch (ignored: CommandSkipped) {
205207
// Swallow exception
@@ -210,8 +212,9 @@ class Orchestra(
210212
ErrorResolution.FAIL -> return false
211213
ErrorResolution.CONTINUE -> {} // Do nothing
212214
}
215+
} finally {
216+
insights.unregisterListener(callback)
213217
}
214-
Insights.unregisterListener(callback)
215218
}
216219
return true
217220
}
@@ -690,7 +693,7 @@ class Orchestra(
690693
}
691694
} catch (ignored: CommandWarned) {
692695
// Swallow exception, but add a warning as an insight
693-
Insights.report(Insight(message = ignored.message, level = Insight.Level.WARNING))
696+
insights.report(Insight(message = ignored.message, level = Insight.Level.WARNING))
694697
onCommandWarned(index, command)
695698
false
696699
} catch (ignored: CommandSkipped) {

maestro-studio/server/src/main/java/maestro/studio/InsightService.kt

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,9 @@ import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
55
import io.ktor.server.application.*
66
import io.ktor.server.response.*
77
import io.ktor.server.routing.*
8-
import kotlinx.coroutines.*
98
import maestro.studio.BannerMessage.*
109
import maestro.utils.Insight
11-
import maestro.utils.Insights
12-
import kotlin.coroutines.resume
13-
import kotlin.coroutines.suspendCoroutine
10+
import maestro.utils.CliInsights
1411

1512
object InsightService {
1613

@@ -41,7 +38,7 @@ object InsightService {
4138
}
4239

4340
private fun registerInsightUpdateCallback() {
44-
Insights.onInsightsUpdated {
41+
CliInsights.onInsightsUpdated {
4542
currentInsight = it
4643
}
4744
}
Lines changed: 5 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,20 @@
11
package maestro.utils
22

3-
object Insights {
3+
object CliInsights: Insights {
44

55
private var insight: Insight = Insight("", Insight.Level.NONE)
66
private val listeners = mutableListOf<(Insight) -> Unit>()
77

8-
fun report(insight: Insight) {
9-
this.insight = insight
8+
override fun report(insight: Insight) {
9+
CliInsights.insight = insight
1010
listeners.forEach { it.invoke(insight) }
1111
}
1212

13-
fun onInsightsUpdated(callback: (Insight) -> Unit) {
13+
override fun onInsightsUpdated(callback: (Insight) -> Unit) {
1414
listeners.add(callback)
1515
}
1616

17-
fun unregisterListener(callback: (Insight) -> Unit) {
17+
override fun unregisterListener(callback: (Insight) -> Unit) {
1818
listeners.remove(callback)
1919
}
2020
}
21-
22-
data class Insight(
23-
val message: String,
24-
val level: Level
25-
) {
26-
enum class Level {
27-
WARNING,
28-
INFO,
29-
NONE
30-
}
31-
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
package maestro.utils
2+
3+
interface Insights {
4+
5+
fun report(insight: Insight)
6+
7+
fun onInsightsUpdated(callback: (Insight) -> Unit)
8+
9+
fun unregisterListener(callback: (Insight) -> Unit)
10+
}
11+
12+
object NoopInsights: Insights {
13+
14+
override fun report(insight: Insight) {
15+
/* no-op */
16+
}
17+
18+
override fun onInsightsUpdated(callback: (Insight) -> Unit) {
19+
/* no-op */
20+
}
21+
22+
override fun unregisterListener(callback: (Insight) -> Unit) {
23+
/* no-op */
24+
}
25+
26+
}
27+
28+
29+
data class Insight(
30+
val message: String,
31+
val level: Level
32+
) {
33+
enum class Level {
34+
WARNING,
35+
INFO,
36+
NONE
37+
}
38+
}

maestro-utils/src/test/kotlin/InsightTest.kt

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,18 @@
11
import maestro.utils.Insight
2-
import maestro.utils.Insights
2+
import maestro.utils.CliInsights
33
import org.junit.jupiter.api.Assertions.assertEquals
44
import org.junit.jupiter.api.Assertions.assertTrue
55
import org.junit.jupiter.api.Test
66

7-
class InsightsTest {
7+
class CliInsightsTest {
88

99
@Test
1010
fun `report should update insight and notify listeners`() {
1111
val insight = Insight("Test message", Insight.Level.INFO)
1212
var notifiedInsight: Insight? = null
1313

14-
Insights.onInsightsUpdated { notifiedInsight = it }
15-
Insights.report(insight)
14+
CliInsights.onInsightsUpdated { notifiedInsight = it }
15+
CliInsights.report(insight)
1616

1717
assertEquals(insight, notifiedInsight)
1818
}
@@ -22,8 +22,8 @@ class InsightsTest {
2222
val insight = Insight("Test message", Insight.Level.INFO)
2323
var notified = false
2424

25-
Insights.onInsightsUpdated { notified = true }
26-
Insights.report(insight)
25+
CliInsights.onInsightsUpdated { notified = true }
26+
CliInsights.report(insight)
2727

2828
assertTrue(notified)
2929
}
@@ -34,9 +34,9 @@ class InsightsTest {
3434
var notified = false
3535
val listener: (Insight) -> Unit = { notified = true }
3636

37-
Insights.onInsightsUpdated(listener)
38-
Insights.unregisterListener(listener)
39-
Insights.report(insight)
37+
CliInsights.onInsightsUpdated(listener)
38+
CliInsights.unregisterListener(listener)
39+
CliInsights.report(insight)
4040

4141
assertTrue(!notified)
4242
}

0 commit comments

Comments
 (0)