diff --git a/maestro-orchestra-models/src/main/java/maestro/orchestra/Commands.kt b/maestro-orchestra-models/src/main/java/maestro/orchestra/Commands.kt index 1790cbada0..8c59f3efec 100644 --- a/maestro-orchestra-models/src/main/java/maestro/orchestra/Commands.kt +++ b/maestro-orchestra-models/src/main/java/maestro/orchestra/Commands.kt @@ -27,7 +27,6 @@ import maestro.TapRepeat import maestro.js.JsEngine import maestro.orchestra.util.Env.evaluateScripts import maestro.orchestra.util.InputRandomTextHelper -import java.nio.file.Path sealed interface Command { @@ -52,11 +51,15 @@ data class SwipeCommand( val elementSelector: ElementSelector? = null, val startRelative: String? = null, val endRelative: String? = null, - val duration: Long = DEFAULT_DURATION_IN_MILLIS + val duration: Long = DEFAULT_DURATION_IN_MILLIS, + val label: String? = null, ) : Command { override fun description(): String { return when { + label != null -> { + label + } elementSelector != null && direction != null -> { "Swiping in $direction direction on ${elementSelector.description()}" } @@ -95,13 +98,14 @@ data class ScrollUntilVisibleCommand( val scrollDuration: Long, val visibilityPercentage: Int, val timeout: Long = DEFAULT_TIMEOUT_IN_MILLIS, - val centerElement: Boolean + val centerElement: Boolean, + val label: String? = null ) : Command { val visibilityPercentageNormalized = (visibilityPercentage / 100).toDouble() override fun description(): String { - return "Scrolling $direction until ${selector.description()} is visible." + return label ?: "Scrolling $direction until ${selector.description()} is visible." } override fun evaluateScripts(jsEngine: JsEngine): ScrollUntilVisibleCommand { @@ -118,7 +122,9 @@ data class ScrollUntilVisibleCommand( } } -class ScrollCommand : Command { +class ScrollCommand( + val label: String? = null, +) : Command { override fun equals(other: Any?): Boolean { if (this === other) return true @@ -135,7 +141,7 @@ class ScrollCommand : Command { } override fun description(): String { - return "Scroll vertically" + return label ?: "Scroll vertically" } override fun evaluateScripts(jsEngine: JsEngine): ScrollCommand { @@ -143,7 +149,9 @@ class ScrollCommand : Command { } } -class BackPressCommand : Command { +class BackPressCommand( + val label: String? = null, +) : Command { override fun equals(other: Any?): Boolean { if (this === other) return true @@ -160,7 +168,7 @@ class BackPressCommand : Command { } override fun description(): String { - return "Press back" + return label ?: "Press back" } override fun evaluateScripts(jsEngine: JsEngine): BackPressCommand { @@ -168,7 +176,9 @@ class BackPressCommand : Command { } } -class HideKeyboardCommand : Command { +class HideKeyboardCommand( + val label: String? = null, +) : Command { override fun equals(other: Any?): Boolean { if (this === other) return true @@ -185,7 +195,7 @@ class HideKeyboardCommand : Command { } override fun description(): String { - return "Hide Keyboard" + return label ?: "Hide Keyboard" } override fun evaluateScripts(jsEngine: JsEngine): HideKeyboardCommand { @@ -195,10 +205,11 @@ class HideKeyboardCommand : Command { data class CopyTextFromCommand( val selector: ElementSelector, + val label: String? = null, ) : Command { override fun description(): String { - return "Copy text from element with ${selector.description()}" + return label ?: "Copy text from element with ${selector.description()}" } override fun evaluateScripts(jsEngine: JsEngine): CopyTextFromCommand { @@ -208,10 +219,12 @@ data class CopyTextFromCommand( } } -class PasteTextCommand : Command { +data class PasteTextCommand( + val label: String? = null, +) : Command { override fun description(): String { - return "Paste text" + return label ?: "Paste text" } override fun evaluateScripts(jsEngine: JsEngine): PasteTextCommand { @@ -225,11 +238,12 @@ data class TapOnElementCommand( val waitUntilVisible: Boolean? = null, val longPress: Boolean? = null, val repeat: TapRepeat? = null, - val waitToSettleTimeoutMs: Int? = null + val waitToSettleTimeoutMs: Int? = null, + val label: String? = null ) : Command { override fun description(): String { - return "${tapOnDescription(longPress, repeat)} on ${selector.description()}" + return label ?: "${tapOnDescription(longPress, repeat)} on ${selector.description()}" } override fun evaluateScripts(jsEngine: JsEngine): TapOnElementCommand { @@ -251,11 +265,12 @@ data class TapOnPointCommand( val retryIfNoChange: Boolean? = null, val waitUntilVisible: Boolean? = null, val longPress: Boolean? = null, - val repeat: TapRepeat? = null + val repeat: TapRepeat? = null, + val label: String? = null ) : Command { override fun description(): String { - return "${tapOnDescription(longPress, repeat)} on point ($x, $y)" + return label ?: "${tapOnDescription(longPress, repeat)} on point ($x, $y)" } override fun evaluateScripts(jsEngine: JsEngine): TapOnPointCommand { @@ -268,11 +283,12 @@ data class TapOnPointV2Command( val retryIfNoChange: Boolean? = null, val longPress: Boolean? = null, val repeat: TapRepeat? = null, - val waitToSettleTimeoutMs: Int? = null + val waitToSettleTimeoutMs: Int? = null, + val label: String? = null ) : Command { override fun description(): String { - return "${tapOnDescription(longPress, repeat)} on point ($point)" + return label ?: "${tapOnDescription(longPress, repeat)} on point ($point)" } override fun evaluateScripts(jsEngine: JsEngine): TapOnPointV2Command { @@ -288,9 +304,13 @@ data class AssertCommand( val visible: ElementSelector? = null, val notVisible: ElementSelector? = null, val timeout: Long? = null, + val label: String? = null, ) : Command { override fun description(): String { + if (label != null){ + return label + } val timeoutStr = timeout?.let { " within $timeout ms" } ?: "" if (visible != null) { return "Assert visible ${visible.description()}" + timeoutStr @@ -325,6 +345,7 @@ data class AssertCommand( data class AssertConditionCommand( val condition: Condition, private val timeout: String? = null, + val label: String? = null, ) : Command { fun timeoutMs(): Long? { @@ -332,7 +353,7 @@ data class AssertConditionCommand( } override fun description(): String { - return "Assert that ${condition.description()}" + return label ?: "Assert that ${condition.description()}" } override fun evaluateScripts(jsEngine: JsEngine): Command { @@ -344,11 +365,12 @@ data class AssertConditionCommand( } data class InputTextCommand( - val text: String + val text: String, + val label: String? = null, ) : Command { override fun description(): String { - return "Input text $text" + return label ?: "Input text $text" } override fun evaluateScripts(jsEngine: JsEngine): InputTextCommand { @@ -365,9 +387,14 @@ data class LaunchAppCommand( val stopApp: Boolean? = null, var permissions: Map? = null, val launchArguments: Map? = null, + val label: String? = null, ) : Command { override fun description(): String { + if (label != null){ + return label + } + var result = if (clearState != true) { "Launch app \"$appId\"" } else { @@ -402,10 +429,11 @@ data class LaunchAppCommand( data class ApplyConfigurationCommand( val config: MaestroConfig, + val label: String? = null, ) : Command { override fun description(): String { - return "Apply configuration" + return label ?: "Apply configuration" } override fun evaluateScripts(jsEngine: JsEngine): ApplyConfigurationCommand { @@ -420,11 +448,14 @@ data class ApplyConfigurationCommand( data class OpenLinkCommand( val link: String, val autoVerify: Boolean? = null, - val browser: Boolean? = null + val browser: Boolean? = null, + val label: String? = null, ) : Command { override fun description(): String { - return if (browser == true) { + return if (label != null) { + label + } else if (browser == true) { if (autoVerify == true) "Open $link with auto verification in browser" else "Open $link in browser" } else { if (autoVerify == true) "Open $link with auto verification" else "Open $link" @@ -440,9 +471,11 @@ data class OpenLinkCommand( data class PressKeyCommand( val code: KeyCode, + val label: String? = null, ) : Command { + override fun description(): String { - return "Press ${code.description} key" + return label ?: "Press ${code.description} key" } override fun evaluateScripts(jsEngine: JsEngine): PressKeyCommand { @@ -453,10 +486,13 @@ data class PressKeyCommand( data class EraseTextCommand( val charactersToErase: Int?, + val label: String? = null, ) : Command { override fun description(): String { - return if (charactersToErase != null) { + return if (label != null) { + label + } else if (charactersToErase != null) { "Erase $charactersToErase characters" } else { "Erase text" @@ -471,10 +507,11 @@ data class EraseTextCommand( data class TakeScreenshotCommand( val path: String, + val label: String? = null ) : Command { override fun description(): String { - return "Take screenshot $path" + return label ?: "Take screenshot $path" } override fun evaluateScripts(jsEngine: JsEngine): TakeScreenshotCommand { @@ -486,10 +523,11 @@ data class TakeScreenshotCommand( data class StopAppCommand( val appId: String, + val label: String? = null ) : Command { override fun description(): String { - return "Stop $appId" + return label ?: "Stop $appId" } override fun evaluateScripts(jsEngine: JsEngine): Command { @@ -501,10 +539,11 @@ data class StopAppCommand( data class ClearStateCommand( val appId: String, + val label: String? = null, ) : Command { override fun description(): String { - return "Clear state of $appId" + return label ?: "Clear state of $appId" } override fun evaluateScripts(jsEngine: JsEngine): Command { @@ -514,10 +553,12 @@ data class ClearStateCommand( } } -class ClearKeychainCommand : Command { +class ClearKeychainCommand( + val label: String? = null, +) : Command { override fun description(): String { - return "Clear keychain" + return label ?: "Clear keychain" } override fun evaluateScripts(jsEngine: JsEngine): Command { @@ -543,6 +584,7 @@ enum class InputRandomType { data class InputRandomCommand( val inputType: InputRandomType? = InputRandomType.TEXT, val length: Int? = 8, + val label: String? = null, ) : Command { fun genRandomString(): String { @@ -559,7 +601,7 @@ data class InputRandomCommand( } override fun description(): String { - return "Input text random $inputType" + return label ?: "Input text random $inputType" } override fun evaluateScripts(jsEngine: JsEngine): InputRandomCommand { @@ -572,6 +614,7 @@ data class RunFlowCommand( val condition: Condition? = null, val sourceDescription: String? = null, val config: MaestroConfig?, + val label: String? = null, ) : CompositeCommand { override fun subCommands(): List { @@ -583,6 +626,8 @@ data class RunFlowCommand( } override fun description(): String { + if (label != null) return label + val runDescription = if (sourceDescription != null) { "Run $sourceDescription" } else { @@ -608,10 +653,11 @@ data class RunFlowCommand( data class SetLocationCommand( val latitude: Double, val longitude: Double, + val label: String? = null ) : Command { override fun description(): String { - return "Set location (${latitude}, ${longitude})" + return label ?: "Set location (${latitude}, ${longitude})" } override fun evaluateScripts(jsEngine: JsEngine): SetLocationCommand { @@ -623,6 +669,7 @@ data class RepeatCommand( val times: String? = null, val condition: Condition? = null, val commands: List, + val label: String? = null, ) : CompositeCommand { override fun subCommands(): List { @@ -637,6 +684,9 @@ data class RepeatCommand( val timesInt = times?.toIntOrNull() ?: 1 return when { + label != null -> { + label + } condition != null && timesInt > 1 -> { "Repeat while ${condition.description()} (up to $timesInt times)" } @@ -658,10 +708,11 @@ data class RepeatCommand( data class DefineVariablesCommand( val env: Map, + val label: String? = null, ) : Command { override fun description(): String { - return "Define variables" + return label ?: "Define variables" } override fun evaluateScripts(jsEngine: JsEngine): DefineVariablesCommand { @@ -680,11 +731,14 @@ data class RunScriptCommand( val script: String, val env: Map = emptyMap(), val sourceDescription: String, - val condition: Condition? + val condition: Condition?, + val label: String? = null ) : Command { override fun description(): String { - return if (condition == null) { + return if (label != null) { + label + } else if (condition == null) { "Run $sourceDescription" } else { "Run $sourceDescription when ${condition.description()}" @@ -703,10 +757,12 @@ data class RunScriptCommand( } data class WaitForAnimationToEndCommand( - val timeout: Long? + val timeout: Long?, + val label: String? = null ) : Command { + override fun description(): String { - return "Wait for animation to end" + return label ?: "Wait for animation to end" } override fun evaluateScripts(jsEngine: JsEngine): Command { @@ -716,10 +772,11 @@ data class WaitForAnimationToEndCommand( data class EvalScriptCommand( val scriptString: String, + val label: String? = null, ) : Command { override fun description(): String { - return "Run $scriptString" + return label ?: "Run $scriptString" } override fun evaluateScripts(jsEngine: JsEngine): Command { @@ -731,6 +788,7 @@ data class EvalScriptCommand( data class TravelCommand( val points: List, val speedMPS: Double? = null, + val label: String? = null, ) : Command { data class GeoPoint( @@ -756,7 +814,7 @@ data class TravelCommand( } override fun description(): String { - return "Travel path ${points.joinToString { "(${it.latitude}, ${it.longitude})" }}" + return label ?: "Travel path ${points.joinToString { "(${it.latitude}, ${it.longitude})" }}" } override fun evaluateScripts(jsEngine: JsEngine): Command { @@ -765,10 +823,13 @@ data class TravelCommand( } -data class StartRecordingCommand(val path: String) : Command { +data class StartRecordingCommand( + val path: String, + val label: String? = null, +) : Command { override fun description(): String { - return "Start recording $path" + return label ?: "Start recording $path" } override fun evaluateScripts(jsEngine: JsEngine): StartRecordingCommand { @@ -791,10 +852,13 @@ data class AddMediaCommand(val mediaPaths: List): Command { } } -class StopRecordingCommand : Command { + +data class StopRecordingCommand( + val label: String? = null, +) : Command { override fun description(): String { - return "Stop recording" + return label ?: "Stop recording" } override fun evaluateScripts(jsEngine: JsEngine): Command { diff --git a/maestro-orchestra-models/src/main/java/maestro/orchestra/Condition.kt b/maestro-orchestra-models/src/main/java/maestro/orchestra/Condition.kt index 0eac7803e8..5aa679e9e1 100644 --- a/maestro-orchestra-models/src/main/java/maestro/orchestra/Condition.kt +++ b/maestro-orchestra-models/src/main/java/maestro/orchestra/Condition.kt @@ -8,7 +8,8 @@ data class Condition( val platform: Platform? = null, val visible: ElementSelector? = null, val notVisible: ElementSelector? = null, - val scriptCondition: String? = null + val scriptCondition: String? = null, + val label: String? = null, ) { fun evaluateScripts(jsEngine: JsEngine): Condition { @@ -20,6 +21,10 @@ data class Condition( } fun description(): String { + if(label != null){ + return label + } + val descriptions = mutableListOf() platform?.let { diff --git a/maestro-orchestra/src/main/java/maestro/orchestra/yaml/YamlAction.kt b/maestro-orchestra/src/main/java/maestro/orchestra/yaml/YamlAction.kt new file mode 100644 index 0000000000..fa5a0c2f94 --- /dev/null +++ b/maestro-orchestra/src/main/java/maestro/orchestra/yaml/YamlAction.kt @@ -0,0 +1,21 @@ +package maestro.orchestra.yaml + +data class YamlActionBack( + val label: String? = null, +) + +data class YamlActionClearKeychain( + val label: String? = null, +) + +data class YamlActionHideKeyboard( + val label: String? = null, +) + +data class YamlActionPasteText( + val label: String? = null, +) + +data class YamlActionScroll( + val label: String? = null, +) \ No newline at end of file diff --git a/maestro-orchestra/src/main/java/maestro/orchestra/yaml/YamlAssertTrue.kt b/maestro-orchestra/src/main/java/maestro/orchestra/yaml/YamlAssertTrue.kt new file mode 100644 index 0000000000..001cd082a5 --- /dev/null +++ b/maestro-orchestra/src/main/java/maestro/orchestra/yaml/YamlAssertTrue.kt @@ -0,0 +1,30 @@ +package maestro.orchestra.yaml + +import com.fasterxml.jackson.annotation.JsonCreator + +data class YamlAssertTrue( + val condition: String? = null, + val label: String? = null, +){ + companion object { + + @JvmStatic + @JsonCreator(mode = JsonCreator.Mode.DELEGATING) + fun parse(condition: Any): YamlAssertTrue { + val evaluatedCondition = when (condition) { + is String -> condition + is Int, is Long, is Char, is Boolean, is Float, is Double -> condition.toString() + is Map<*, *> -> { + val evaluatedCondition = condition.getOrDefault("condition", "") as String + val label = condition.getOrDefault("label", "") as String + return YamlAssertTrue(evaluatedCondition, label) + } + else -> throw UnsupportedOperationException("Cannot deserialize assert true with data type ${condition.javaClass}") + } + return YamlAssertTrue( + condition = evaluatedCondition, + ) + } + } +} + diff --git a/maestro-orchestra/src/main/java/maestro/orchestra/yaml/YamlClearState.kt b/maestro-orchestra/src/main/java/maestro/orchestra/yaml/YamlClearState.kt index c7fdfb1256..4d2a51acb1 100644 --- a/maestro-orchestra/src/main/java/maestro/orchestra/yaml/YamlClearState.kt +++ b/maestro-orchestra/src/main/java/maestro/orchestra/yaml/YamlClearState.kt @@ -4,6 +4,7 @@ import com.fasterxml.jackson.annotation.JsonCreator data class YamlClearState( val appId: String? = null, + val label: String? = null, ) { companion object { @JvmStatic diff --git a/maestro-orchestra/src/main/java/maestro/orchestra/yaml/YamlCondition.kt b/maestro-orchestra/src/main/java/maestro/orchestra/yaml/YamlCondition.kt index a401728fa0..7f68f4fec3 100644 --- a/maestro-orchestra/src/main/java/maestro/orchestra/yaml/YamlCondition.kt +++ b/maestro-orchestra/src/main/java/maestro/orchestra/yaml/YamlCondition.kt @@ -9,4 +9,5 @@ data class YamlCondition( val visible: YamlElementSelectorUnion? = null, val notVisible: YamlElementSelectorUnion? = null, val `true`: String? = null, + val label: String? = null, ) diff --git a/maestro-orchestra/src/main/java/maestro/orchestra/yaml/YamlElementSelector.kt b/maestro-orchestra/src/main/java/maestro/orchestra/yaml/YamlElementSelector.kt index 7ed8f9e699..7f9f75e988 100644 --- a/maestro-orchestra/src/main/java/maestro/orchestra/yaml/YamlElementSelector.kt +++ b/maestro-orchestra/src/main/java/maestro/orchestra/yaml/YamlElementSelector.kt @@ -49,5 +49,6 @@ data class YamlElementSelector( val repeat: Int? = null, val delay: Int? = null, val waitToSettleTimeoutMs: Int? = null, - val childOf: YamlElementSelectorUnion? = null + val childOf: YamlElementSelectorUnion? = null, + val label: String? = null ) : YamlElementSelectorUnion diff --git a/maestro-orchestra/src/main/java/maestro/orchestra/yaml/YamlEraseTextUnion.kt b/maestro-orchestra/src/main/java/maestro/orchestra/yaml/YamlEraseTextUnion.kt index d4e041b4d8..cb488b8d51 100644 --- a/maestro-orchestra/src/main/java/maestro/orchestra/yaml/YamlEraseTextUnion.kt +++ b/maestro-orchestra/src/main/java/maestro/orchestra/yaml/YamlEraseTextUnion.kt @@ -2,7 +2,10 @@ package maestro.orchestra.yaml import com.fasterxml.jackson.annotation.JsonCreator -data class YamlEraseText(val charactersToErase: Int? = null) { +data class YamlEraseText( + val charactersToErase: Int? = null, + val label: String? = null, +) { companion object { diff --git a/maestro-orchestra/src/main/java/maestro/orchestra/yaml/YamlEvalScript.kt b/maestro-orchestra/src/main/java/maestro/orchestra/yaml/YamlEvalScript.kt new file mode 100644 index 0000000000..7a7ab55b76 --- /dev/null +++ b/maestro-orchestra/src/main/java/maestro/orchestra/yaml/YamlEvalScript.kt @@ -0,0 +1,31 @@ +package maestro.orchestra.yaml + +import com.fasterxml.jackson.annotation.JsonCreator +import java.lang.UnsupportedOperationException + +data class YamlEvalScript( + val script: String, + val label: String? = null, +){ + companion object { + + @JvmStatic + @JsonCreator(mode = JsonCreator.Mode.DELEGATING) + fun parse(script: Any): YamlEvalScript { + val evalScript = when (script) { + is String -> script + is Map<*, *> -> { + val evaluatedScript = script.getOrDefault("script", "") as String + val label = script.getOrDefault("label", "") as String + return YamlEvalScript(evaluatedScript, label) + } + is Int, is Long, is Char, is Boolean, is Float, is Double -> script.toString() + else -> throw UnsupportedOperationException("Cannot deserialize evaluate script with data type ${script.javaClass}") + } + return YamlEvalScript( + script = evalScript, + ) + } + } +} + diff --git a/maestro-orchestra/src/main/java/maestro/orchestra/yaml/YamlExtendedWaitUntil.kt b/maestro-orchestra/src/main/java/maestro/orchestra/yaml/YamlExtendedWaitUntil.kt index 7eb90753bd..a07bcc8795 100644 --- a/maestro-orchestra/src/main/java/maestro/orchestra/yaml/YamlExtendedWaitUntil.kt +++ b/maestro-orchestra/src/main/java/maestro/orchestra/yaml/YamlExtendedWaitUntil.kt @@ -4,4 +4,5 @@ data class YamlExtendedWaitUntil( val visible: YamlElementSelectorUnion? = null, val notVisible: YamlElementSelectorUnion? = null, val timeout: String? = null, + val label: String? = null ) diff --git a/maestro-orchestra/src/main/java/maestro/orchestra/yaml/YamlFluentCommand.kt b/maestro-orchestra/src/main/java/maestro/orchestra/yaml/YamlFluentCommand.kt index 76d23363d2..fbccdcafad 100644 --- a/maestro-orchestra/src/main/java/maestro/orchestra/yaml/YamlFluentCommand.kt +++ b/maestro-orchestra/src/main/java/maestro/orchestra/yaml/YamlFluentCommand.kt @@ -40,9 +40,13 @@ data class YamlFluentCommand( val longPressOn: YamlElementSelectorUnion? = null, val assertVisible: YamlElementSelectorUnion? = null, val assertNotVisible: YamlElementSelectorUnion? = null, - val assertTrue: String? = null, - val action: String? = null, - val inputText: String? = null, + val assertTrue: YamlAssertTrue? = null, + val back: YamlActionBack? = null, + val clearKeychain: YamlActionClearKeychain? = null, + val hideKeyboard: YamlActionHideKeyboard? = null, + val pasteText: YamlActionPasteText? = null, + val scroll: YamlActionScroll? = null, + val inputText: YamlInputText? = null, val inputRandomText: YamlInputRandomText? = null, val inputRandomNumber: YamlInputRandomNumber? = null, val inputRandomEmail: YamlInputRandomEmail? = null, @@ -51,8 +55,9 @@ data class YamlFluentCommand( val swipe: YamlSwipe? = null, val openLink: YamlOpenLink? = null, val openBrowser: String? = null, - val pressKey: String? = null, + val pressKey: YamlPressKey? = null, val eraseText: YamlEraseText? = null, + val action: String? = null, val takeScreenshot: YamlTakeScreenshot? = null, val extendedWaitUntil: YamlExtendedWaitUntil? = null, val stopApp: YamlStopApp? = null, @@ -63,7 +68,7 @@ data class YamlFluentCommand( val copyTextFrom: YamlElementSelectorUnion? = null, val runScript: YamlRunScript? = null, val waitForAnimationToEnd: YamlWaitForAnimationToEndCommand? = null, - val evalScript: String? = null, + val evalScript: YamlEvalScript? = null, val scrollUntilVisible: YamlScrollUntilVisible? = null, val travel: YamlTravelCommand? = null, val startRecording: YamlStartRecording? = null, @@ -80,18 +85,20 @@ data class YamlFluentCommand( assertVisible != null -> listOf( MaestroCommand( AssertConditionCommand( - Condition( + condition = Condition( visible = toElementSelector(assertVisible), - ) + ), + label = (assertVisible as? YamlElementSelector)?.label ) ) ) assertNotVisible != null -> listOf( MaestroCommand( AssertConditionCommand( - Condition( + condition = Condition( notVisible = toElementSelector(assertNotVisible), - ) + ), + label = (assertNotVisible as? YamlElementSelector)?.label ) ) ) @@ -99,8 +106,9 @@ data class YamlFluentCommand( MaestroCommand( AssertConditionCommand( Condition( - scriptCondition = assertTrue, - ) + scriptCondition = assertTrue.condition, + ), + label = assertTrue.label ) ) ) @@ -109,31 +117,37 @@ data class YamlFluentCommand( addMediaCommand = addMediaCommand(addMedia, flowPath) ) ) - inputText != null -> listOf(MaestroCommand(InputTextCommand(inputText))) - inputRandomText != null -> listOf(MaestroCommand(InputRandomCommand(inputType = InputRandomType.TEXT, length = inputRandomText.length))) - inputRandomNumber != null -> listOf(MaestroCommand(InputRandomCommand(inputType = InputRandomType.NUMBER, length = inputRandomNumber.length))) - inputRandomEmail != null -> listOf(MaestroCommand(InputRandomCommand(inputType = InputRandomType.TEXT_EMAIL_ADDRESS))) - inputRandomPersonName != null -> listOf(MaestroCommand(InputRandomCommand(inputType = InputRandomType.TEXT_PERSON_NAME))) + inputText != null -> listOf(MaestroCommand(InputTextCommand(text = inputText.text, label = inputText.label))) + inputRandomText != null -> listOf(MaestroCommand(InputRandomCommand(inputType = InputRandomType.TEXT, length = inputRandomText.length, label = inputRandomText.label))) + inputRandomNumber != null -> listOf(MaestroCommand(InputRandomCommand(inputType = InputRandomType.NUMBER, length = inputRandomNumber.length, label = inputRandomNumber.label))) + inputRandomEmail != null -> listOf(MaestroCommand(InputRandomCommand(inputType = InputRandomType.TEXT_EMAIL_ADDRESS, label = inputRandomEmail.label))) + inputRandomPersonName != null -> listOf(MaestroCommand(InputRandomCommand(inputType = InputRandomType.TEXT_PERSON_NAME, label = inputRandomPersonName.label))) swipe != null -> listOf(swipeCommand(swipe)) - openLink != null -> listOf(MaestroCommand(OpenLinkCommand(openLink.link, openLink.autoVerify, openLink.browser))) - pressKey != null -> listOf(MaestroCommand(PressKeyCommand(code = KeyCode.getByName(pressKey) ?: throw SyntaxError("Unknown key name: $pressKey")))) + openLink != null -> listOf(MaestroCommand(OpenLinkCommand(link = openLink.link, autoVerify = openLink.autoVerify, browser = openLink.browser, label = openLink.label))) + pressKey != null -> listOf(MaestroCommand(PressKeyCommand(code = KeyCode.getByName(pressKey.key) ?: throw SyntaxError("Unknown key name: $pressKey"), label = pressKey.label))) eraseText != null -> listOf(eraseCommand(eraseText)) action != null -> listOf( when (action) { "back" -> MaestroCommand(BackPressCommand()) - "hide keyboard" -> MaestroCommand(HideKeyboardCommand()) + "hideKeyboard" -> MaestroCommand(HideKeyboardCommand()) "scroll" -> MaestroCommand(ScrollCommand()) "clearKeychain" -> MaestroCommand(ClearKeychainCommand()) "pasteText" -> MaestroCommand(PasteTextCommand()) else -> error("Unknown navigation target: $action") } ) - takeScreenshot != null -> listOf(MaestroCommand(TakeScreenshotCommand(takeScreenshot.path))) + back != null -> listOf(MaestroCommand(BackPressCommand(label = back.label))) + clearKeychain != null -> listOf(MaestroCommand(ClearKeychainCommand(label = clearKeychain.label))) + hideKeyboard != null -> listOf(MaestroCommand(HideKeyboardCommand(label = hideKeyboard.label))) + pasteText != null -> listOf(MaestroCommand(PasteTextCommand(label = pasteText.label))) + scroll != null -> listOf(MaestroCommand(ScrollCommand(label = scroll.label))) + takeScreenshot != null -> listOf(MaestroCommand(TakeScreenshotCommand(path = takeScreenshot.path, label = takeScreenshot.label))) extendedWaitUntil != null -> listOf(extendedWait(extendedWaitUntil)) stopApp != null -> listOf( MaestroCommand( StopAppCommand( appId = stopApp.appId ?: appId, + label = stopApp.label ) ) ) @@ -141,6 +155,7 @@ data class YamlFluentCommand( MaestroCommand( maestro.orchestra.ClearStateCommand( appId = clearState.appId ?: appId, + label = clearState.label ) ) ) @@ -150,6 +165,7 @@ data class YamlFluentCommand( SetLocationCommand( latitude = setLocation.latitude, longitude = setLocation.longitude, + label = setLocation.label ) ) ) @@ -165,27 +181,30 @@ data class YamlFluentCommand( env = runScript.env, sourceDescription = runScript.file, condition = runScript.`when`?.toCondition(), + label = runScript.label ) ) ) waitForAnimationToEnd != null -> listOf( MaestroCommand( WaitForAnimationToEndCommand( - timeout = waitForAnimationToEnd.timeout + timeout = waitForAnimationToEnd.timeout, + label = waitForAnimationToEnd.label ) ) ) evalScript != null -> listOf( MaestroCommand( EvalScriptCommand( - scriptString = evalScript, + scriptString = evalScript.script, + label = evalScript.label ) ) ) scrollUntilVisible != null -> listOf(scrollUntilVisibleCommand(scrollUntilVisible)) travel != null -> listOf(travelCommand(travel)) - startRecording != null -> listOf(MaestroCommand(StartRecordingCommand(startRecording.path))) - stopRecording != null -> listOf(MaestroCommand(StopRecordingCommand())) + startRecording != null -> listOf(MaestroCommand(StartRecordingCommand(startRecording.path, startRecording.label))) + stopRecording != null -> listOf(MaestroCommand(StopRecordingCommand(stopRecording.label))) doubleTapOn != null -> { val yamlDelay = (doubleTapOn as? YamlElementSelector)?.delay?.toLong() val delay = if (yamlDelay != null && yamlDelay >= 0) yamlDelay else TapOnElementCommand.DEFAULT_REPEAT_DELAY @@ -247,7 +266,8 @@ data class YamlFluentCommand( commands = commands, condition = runFlow.`when`?.toCondition(), sourceDescription = runFlow.file, - config + config = config, + label = runFlow.label ) ) } @@ -272,6 +292,7 @@ data class YamlFluentCommand( ) }, speedMPS = command.speed, + label = command.label, ) ) } @@ -282,14 +303,15 @@ data class YamlFluentCommand( condition = repeat.`while`?.toCondition(), commands = repeat.commands .flatMap { it.toCommands(flowPath, appId) }, + label = repeat.label, ) ) private fun eraseCommand(eraseText: YamlEraseText): MaestroCommand { return if (eraseText.charactersToErase != null) { - MaestroCommand(EraseTextCommand(charactersToErase = eraseText.charactersToErase)) + MaestroCommand(EraseTextCommand(charactersToErase = eraseText.charactersToErase, label = eraseText.label)) } else { - MaestroCommand(EraseTextCommand(charactersToErase = null)) + MaestroCommand(EraseTextCommand(charactersToErase = null, label = eraseText.label)) } } @@ -358,6 +380,7 @@ data class YamlFluentCommand( AssertConditionCommand( condition = condition, timeout = command.timeout, + label = command.label, ) ) } @@ -371,6 +394,7 @@ data class YamlFluentCommand( stopApp = command.stopApp, permissions = command.permissions, launchArguments = command.arguments, + label = command.label, ) ) } @@ -383,6 +407,7 @@ data class YamlFluentCommand( val retryIfNoChange = (tapOn as? YamlElementSelector)?.retryTapIfNoChange ?: true val waitUntilVisible = (tapOn as? YamlElementSelector)?.waitUntilVisible ?: false val point = (tapOn as? YamlElementSelector)?.point + val label = (tapOn as? YamlElementSelector)?.label val delay = (tapOn as? YamlElementSelector)?.delay?.toLong() val repeat = tapRepeat ?: (tapOn as? YamlElementSelector)?.repeat?.let { @@ -403,7 +428,8 @@ data class YamlFluentCommand( retryIfNoChange = retryIfNoChange, longPress = longPress, repeat = repeat, - waitToSettleTimeoutMs = waitToSettleTimeoutMs + waitToSettleTimeoutMs = waitToSettleTimeoutMs, + label = label ) ) } else { @@ -414,7 +440,8 @@ data class YamlFluentCommand( waitUntilVisible = waitUntilVisible, longPress = longPress, repeat = repeat, - waitToSettleTimeoutMs = waitToSettleTimeoutMs + waitToSettleTimeoutMs = waitToSettleTimeoutMs, + label = label ) ) } @@ -422,7 +449,7 @@ data class YamlFluentCommand( private fun swipeCommand(swipe: YamlSwipe): MaestroCommand { when (swipe) { - is YamlSwipeDirection -> return MaestroCommand(SwipeCommand(direction = swipe.direction, duration = swipe.duration)) + is YamlSwipeDirection -> return MaestroCommand(SwipeCommand(direction = swipe.direction, duration = swipe.duration, label = swipe.label)) is YamlCoordinateSwipe -> { val start = swipe.start val end = swipe.end @@ -441,11 +468,11 @@ data class YamlFluentCommand( } endPoint = Point(endPoints[0], endPoints[1]) - return MaestroCommand(SwipeCommand(startPoint = startPoint, endPoint = endPoint, duration = swipe.duration)) + return MaestroCommand(SwipeCommand(startPoint = startPoint, endPoint = endPoint, duration = swipe.duration, label = swipe.label)) } is YamlRelativeCoordinateSwipe -> { return MaestroCommand( - SwipeCommand(startRelative = swipe.start, endRelative = swipe.end, duration = swipe.duration) + SwipeCommand(startRelative = swipe.start, endRelative = swipe.end, duration = swipe.duration, label = swipe.label) ) } is YamlSwipeElement -> return swipeElementCommand(swipe) @@ -463,7 +490,8 @@ data class YamlFluentCommand( swipeCommand = SwipeCommand( direction = swipeElement.direction, elementSelector = toElementSelector(swipeElement.from), - duration = swipeElement.duration + duration = swipeElement.duration, + label = swipeElement.label, ) ) } @@ -517,11 +545,20 @@ data class YamlFluentCommand( private fun copyTextFromCommand( copyText: YamlElementSelectorUnion ): MaestroCommand { - return MaestroCommand( - CopyTextFromCommand( - selector = toElementSelector(copyText) + return if (copyText is StringElementSelector) { + MaestroCommand( + CopyTextFromCommand( + selector = toElementSelector(copyText) + ) ) - ) + } else { + MaestroCommand( + CopyTextFromCommand( + selector = toElementSelector(copyText), + label = (copyText as? YamlElementSelector)?.label + ) + ) + } } private fun scrollUntilVisibleCommand(yaml: YamlScrollUntilVisible): MaestroCommand { @@ -538,7 +575,8 @@ data class YamlFluentCommand( timeout = timeout, scrollDuration = yaml.speedToDuration(), visibilityPercentage = visibility, - centerElement = yaml.centerElement + centerElement = yaml.centerElement, + label = yaml.label ) ) } @@ -549,6 +587,7 @@ data class YamlFluentCommand( visible = visible?.let { toElementSelector(it) }, notVisible = notVisible?.let { toElementSelector(it) }, scriptCondition = `true`?.trim(), + label = label ) } @@ -581,7 +620,7 @@ data class YamlFluentCommand( ) "clearKeychain" -> YamlFluentCommand( - action = "clearKeychain" + clearKeychain = YamlActionClearKeychain(), ) "eraseText" -> YamlFluentCommand( @@ -605,23 +644,23 @@ data class YamlFluentCommand( ) "back" -> YamlFluentCommand( - action = "back" + back = YamlActionBack(), ) "hide keyboard", "hideKeyboard" -> YamlFluentCommand( - action = "hide keyboard" + hideKeyboard = YamlActionHideKeyboard(), ) "pasteText" -> YamlFluentCommand( - action = "pasteText" + pasteText = YamlActionPasteText(), ) "scroll" -> YamlFluentCommand( - action = "scroll" + scroll = YamlActionScroll(), ) "waitForAnimationToEnd" -> YamlFluentCommand( - waitForAnimationToEnd = YamlWaitForAnimationToEndCommand(null) + waitForAnimationToEnd = YamlWaitForAnimationToEndCommand(timeout = null) ) "stopRecording" -> YamlFluentCommand( diff --git a/maestro-orchestra/src/main/java/maestro/orchestra/yaml/YamlInputRandomText.kt b/maestro-orchestra/src/main/java/maestro/orchestra/yaml/YamlInputRandomText.kt index 96e8ccc2e8..73743a8746 100644 --- a/maestro-orchestra/src/main/java/maestro/orchestra/yaml/YamlInputRandomText.kt +++ b/maestro-orchestra/src/main/java/maestro/orchestra/yaml/YamlInputRandomText.kt @@ -21,12 +21,18 @@ package maestro.orchestra.yaml data class YamlInputRandomText( val length: Int?, + val label: String? = null, ) data class YamlInputRandomNumber( val length: Int?, + val label: String? = null, ) -class YamlInputRandomEmail +data class YamlInputRandomEmail( + val label: String? = null, +) -class YamlInputRandomPersonName +data class YamlInputRandomPersonName( + val label: String? = null, +) diff --git a/maestro-orchestra/src/main/java/maestro/orchestra/yaml/YamlInputText.kt b/maestro-orchestra/src/main/java/maestro/orchestra/yaml/YamlInputText.kt new file mode 100644 index 0000000000..5fc1eaf1d9 --- /dev/null +++ b/maestro-orchestra/src/main/java/maestro/orchestra/yaml/YamlInputText.kt @@ -0,0 +1,29 @@ +package maestro.orchestra.yaml + +import com.fasterxml.jackson.annotation.JsonCreator +import java.lang.UnsupportedOperationException + +data class YamlInputText( + val text: String, + val label: String? = null, +) { + + companion object { + + @JvmStatic + @JsonCreator(mode = JsonCreator.Mode.DELEGATING) + fun parse(text: Any): YamlInputText { + val inputText = when (text) { + is String -> text + is Map<*, *> -> { + val input = text.getOrDefault("text", "") as String + val label = text.getOrDefault("label", "") as String + return YamlInputText(input, label) + } + is Int, is Long, is Char, is Boolean, is Float, is Double -> text.toString() + else -> throw UnsupportedOperationException("Cannot deserialize input text with data type ${text.javaClass}") + } + return YamlInputText(text = inputText) + } + } +} diff --git a/maestro-orchestra/src/main/java/maestro/orchestra/yaml/YamlLaunchApp.kt b/maestro-orchestra/src/main/java/maestro/orchestra/yaml/YamlLaunchApp.kt index fcff19614c..1b74cacdb7 100644 --- a/maestro-orchestra/src/main/java/maestro/orchestra/yaml/YamlLaunchApp.kt +++ b/maestro-orchestra/src/main/java/maestro/orchestra/yaml/YamlLaunchApp.kt @@ -28,6 +28,7 @@ data class YamlLaunchApp( val stopApp: Boolean?, val permissions: Map?, val arguments: Map?, + val label: String? = null ) { companion object { diff --git a/maestro-orchestra/src/main/java/maestro/orchestra/yaml/YamlOpenLink.kt b/maestro-orchestra/src/main/java/maestro/orchestra/yaml/YamlOpenLink.kt index 414a99cc15..4745082bec 100644 --- a/maestro-orchestra/src/main/java/maestro/orchestra/yaml/YamlOpenLink.kt +++ b/maestro-orchestra/src/main/java/maestro/orchestra/yaml/YamlOpenLink.kt @@ -2,7 +2,12 @@ package maestro.orchestra.yaml import com.fasterxml.jackson.annotation.JsonCreator -data class YamlOpenLink(val link: String, val browser: Boolean = false, val autoVerify: Boolean = false) { +data class YamlOpenLink( + val link: String, + val browser: Boolean = false, + val autoVerify: Boolean = false, + val label: String? = null, +) { companion object { @JvmStatic diff --git a/maestro-orchestra/src/main/java/maestro/orchestra/yaml/YamlPressKey.kt b/maestro-orchestra/src/main/java/maestro/orchestra/yaml/YamlPressKey.kt new file mode 100644 index 0000000000..0661180e08 --- /dev/null +++ b/maestro-orchestra/src/main/java/maestro/orchestra/yaml/YamlPressKey.kt @@ -0,0 +1,16 @@ +package maestro.orchestra.yaml + +import com.fasterxml.jackson.annotation.JsonCreator + +data class YamlPressKey ( + val key: String, + val label: String? = null, +){ + companion object { + @JvmStatic + @JsonCreator(mode = JsonCreator.Mode.DELEGATING) + fun parse(key: String) = YamlPressKey( + key = key, + ) + } +} \ No newline at end of file diff --git a/maestro-orchestra/src/main/java/maestro/orchestra/yaml/YamlRepeatCommand.kt b/maestro-orchestra/src/main/java/maestro/orchestra/yaml/YamlRepeatCommand.kt index c278461f0b..a8a9afe619 100644 --- a/maestro-orchestra/src/main/java/maestro/orchestra/yaml/YamlRepeatCommand.kt +++ b/maestro-orchestra/src/main/java/maestro/orchestra/yaml/YamlRepeatCommand.kt @@ -3,5 +3,6 @@ package maestro.orchestra.yaml data class YamlRepeatCommand( val times: String? = null, val `while`: YamlCondition? = null, - val commands: List + val commands: List, + val label: String? = null, ) diff --git a/maestro-orchestra/src/main/java/maestro/orchestra/yaml/YamlRunFlow.kt b/maestro-orchestra/src/main/java/maestro/orchestra/yaml/YamlRunFlow.kt index 52a7d26e69..b38e0b600a 100644 --- a/maestro-orchestra/src/main/java/maestro/orchestra/yaml/YamlRunFlow.kt +++ b/maestro-orchestra/src/main/java/maestro/orchestra/yaml/YamlRunFlow.kt @@ -7,6 +7,7 @@ data class YamlRunFlow( val `when`: YamlCondition? = null, val env: Map = emptyMap(), val commands: List? = null, + val label: String? = null, ) { companion object { diff --git a/maestro-orchestra/src/main/java/maestro/orchestra/yaml/YamlRunScript.kt b/maestro-orchestra/src/main/java/maestro/orchestra/yaml/YamlRunScript.kt index 1aaeed10e1..f2d4f5e132 100644 --- a/maestro-orchestra/src/main/java/maestro/orchestra/yaml/YamlRunScript.kt +++ b/maestro-orchestra/src/main/java/maestro/orchestra/yaml/YamlRunScript.kt @@ -6,6 +6,7 @@ data class YamlRunScript( val file: String, val env: Map = emptyMap(), val `when`: YamlCondition? = null, + val label: String? = null, ) { companion object { diff --git a/maestro-orchestra/src/main/java/maestro/orchestra/yaml/YamlScrollUntilVisible.kt b/maestro-orchestra/src/main/java/maestro/orchestra/yaml/YamlScrollUntilVisible.kt index ded71a9e1d..c7967248da 100644 --- a/maestro-orchestra/src/main/java/maestro/orchestra/yaml/YamlScrollUntilVisible.kt +++ b/maestro-orchestra/src/main/java/maestro/orchestra/yaml/YamlScrollUntilVisible.kt @@ -11,7 +11,8 @@ data class YamlScrollUntilVisible( val timeout: Long = ScrollUntilVisibleCommand.DEFAULT_TIMEOUT_IN_MILLIS, val speed: Int = ScrollUntilVisibleCommand.DEFAULT_SCROLL_DURATION, val visibilityPercentage: Int = ScrollUntilVisibleCommand.DEFAULT_ELEMENT_VISIBILITY_PERCENTAGE, - val centerElement: Boolean = ScrollUntilVisibleCommand.DEFAULT_CENTER_ELEMENT + val centerElement: Boolean = ScrollUntilVisibleCommand.DEFAULT_CENTER_ELEMENT, + val label: String? = null ) { fun speedToDuration(): Long { return (1000 * (100 - speed).toDouble() / 100).toLong() + 1 diff --git a/maestro-orchestra/src/main/java/maestro/orchestra/yaml/YamlSetLocation.kt b/maestro-orchestra/src/main/java/maestro/orchestra/yaml/YamlSetLocation.kt index 24cf2b1f91..d80b28a8c3 100644 --- a/maestro-orchestra/src/main/java/maestro/orchestra/yaml/YamlSetLocation.kt +++ b/maestro-orchestra/src/main/java/maestro/orchestra/yaml/YamlSetLocation.kt @@ -5,4 +5,5 @@ import com.fasterxml.jackson.annotation.JsonCreator data class YamlSetLocation @JsonCreator constructor( val latitude: Double, val longitude: Double, + val label: String? = null, ) diff --git a/maestro-orchestra/src/main/java/maestro/orchestra/yaml/YamlStartRecording.kt b/maestro-orchestra/src/main/java/maestro/orchestra/yaml/YamlStartRecording.kt index f1ce775504..e2dfd09c3d 100644 --- a/maestro-orchestra/src/main/java/maestro/orchestra/yaml/YamlStartRecording.kt +++ b/maestro-orchestra/src/main/java/maestro/orchestra/yaml/YamlStartRecording.kt @@ -3,7 +3,8 @@ package maestro.orchestra.yaml import com.fasterxml.jackson.annotation.JsonCreator data class YamlStartRecording( - val path: String + val path: String, + val label: String? = null, ) { companion object { @@ -18,4 +19,6 @@ data class YamlStartRecording( } } -class YamlStopRecording +data class YamlStopRecording( + val label: String? = null, +) diff --git a/maestro-orchestra/src/main/java/maestro/orchestra/yaml/YamlStopApp.kt b/maestro-orchestra/src/main/java/maestro/orchestra/yaml/YamlStopApp.kt index 1b6530450c..63f7a9b031 100644 --- a/maestro-orchestra/src/main/java/maestro/orchestra/yaml/YamlStopApp.kt +++ b/maestro-orchestra/src/main/java/maestro/orchestra/yaml/YamlStopApp.kt @@ -4,6 +4,7 @@ import com.fasterxml.jackson.annotation.JsonCreator data class YamlStopApp( val appId: String? = null, + val label: String? = null, ) { companion object { diff --git a/maestro-orchestra/src/main/java/maestro/orchestra/yaml/YamlSwipe.kt b/maestro-orchestra/src/main/java/maestro/orchestra/yaml/YamlSwipe.kt index 6ff9b15ef9..e6b1145f58 100644 --- a/maestro-orchestra/src/main/java/maestro/orchestra/yaml/YamlSwipe.kt +++ b/maestro-orchestra/src/main/java/maestro/orchestra/yaml/YamlSwipe.kt @@ -15,18 +15,24 @@ import maestro.directionValueOfOrNull @JsonDeserialize(using = YamlSwipeDeserializer::class) interface YamlSwipe { val duration: Long + val label: String? } -data class YamlSwipeDirection(val direction: SwipeDirection, override val duration: Long = DEFAULT_DURATION_IN_MILLIS) : YamlSwipe -data class YamlCoordinateSwipe(val start: String, val end: String, override val duration: Long = DEFAULT_DURATION_IN_MILLIS) : YamlSwipe -data class YamlRelativeCoordinateSwipe(val start: String, val end: String, override val duration: Long = DEFAULT_DURATION_IN_MILLIS) : YamlSwipe +data class YamlSwipeDirection( + val direction: SwipeDirection, override val duration: Long = DEFAULT_DURATION_IN_MILLIS, + override val label: String? = null +) : YamlSwipe +data class YamlCoordinateSwipe(val start: String, val end: String, override val duration: Long = DEFAULT_DURATION_IN_MILLIS, override val label: String? = null) : YamlSwipe + +data class YamlRelativeCoordinateSwipe(val start: String, val end: String, override val duration: Long = DEFAULT_DURATION_IN_MILLIS, override val label: String? = null) : YamlSwipe @JsonDeserialize(`as` = YamlSwipeElement::class) data class YamlSwipeElement( @JsonFormat(with = [JsonFormat.Feature.ACCEPT_CASE_INSENSITIVE_PROPERTIES]) val direction: SwipeDirection, val from: YamlElementSelectorUnion, - override val duration: Long = DEFAULT_DURATION_IN_MILLIS + override val duration: Long = DEFAULT_DURATION_IN_MILLIS, + override val label: String? = null ) : YamlSwipe private const val DEFAULT_DURATION_IN_MILLIS = 400L @@ -38,13 +44,14 @@ class YamlSwipeDeserializer : JsonDeserializer() { val root: TreeNode = mapper.readTree(parser) val input = root.fieldNames().asSequence().toList() val duration = getDuration(root) + val label = getLabel(root) when { input.contains("start") || input.contains("end") -> { check(root.get("direction") == null) { "You cannot provide direction with start/end swipe." } check(root.get("start") != null && root.get("end") != null) { "You need to provide both start and end coordinates, to swipe with coordinates" } - return resolveCoordinateSwipe(root, duration) + return resolveCoordinateSwipe(root, duration, label) } input.contains("direction") -> { check(root.get("start") == null && root.get("end") == null) { @@ -60,7 +67,7 @@ class YamlSwipeDeserializer : JsonDeserializer() { } val isDirectionalSwipe = input == listOf("direction", "duration") || input == listOf("direction") return if (isDirectionalSwipe) { - YamlSwipeDirection(SwipeDirection.valueOf(direction.uppercase()), duration) + YamlSwipeDirection(SwipeDirection.valueOf(direction.uppercase()), duration, label) } else { mapper.convertValue(root, YamlSwipeElement::class.java) } @@ -77,7 +84,7 @@ class YamlSwipeDeserializer : JsonDeserializer() { } } - private fun resolveCoordinateSwipe(root: TreeNode, duration: Long): YamlSwipe { + private fun resolveCoordinateSwipe(root: TreeNode, duration: Long, label: String?): YamlSwipe { when { isRelativeSwipe(root) -> { val start = root.path("start").toString().replace("\"", "") @@ -103,13 +110,15 @@ class YamlSwipeDeserializer : JsonDeserializer() { return YamlRelativeCoordinateSwipe( start, end, - duration + duration, + label, ) } else -> return YamlCoordinateSwipe( root.path("start").toString().replace("\"", ""), root.path("end").toString().replace("\"", ""), - duration + duration, + label, ) } } @@ -126,4 +135,12 @@ class YamlSwipeDeserializer : JsonDeserializer() { } } + private fun getLabel(root: TreeNode): String? { + return if (root.path("label").isMissingNode) { + null + } else { + root.path("label").toString() + } + } + } \ No newline at end of file diff --git a/maestro-orchestra/src/main/java/maestro/orchestra/yaml/YamlTakeScreenshot.kt b/maestro-orchestra/src/main/java/maestro/orchestra/yaml/YamlTakeScreenshot.kt index 70492b91d8..47fc69380a 100644 --- a/maestro-orchestra/src/main/java/maestro/orchestra/yaml/YamlTakeScreenshot.kt +++ b/maestro-orchestra/src/main/java/maestro/orchestra/yaml/YamlTakeScreenshot.kt @@ -3,7 +3,8 @@ package maestro.orchestra.yaml import com.fasterxml.jackson.annotation.JsonCreator data class YamlTakeScreenshot( - val path: String + val path: String, + val label: String? = null ) { companion object { diff --git a/maestro-orchestra/src/main/java/maestro/orchestra/yaml/YamlTravelCommand.kt b/maestro-orchestra/src/main/java/maestro/orchestra/yaml/YamlTravelCommand.kt index 6f54ea7665..ec3b6843a3 100644 --- a/maestro-orchestra/src/main/java/maestro/orchestra/yaml/YamlTravelCommand.kt +++ b/maestro-orchestra/src/main/java/maestro/orchestra/yaml/YamlTravelCommand.kt @@ -3,4 +3,5 @@ package maestro.orchestra.yaml data class YamlTravelCommand( val points: List, val speed: Double? = null, + val label: String? = null, ) \ No newline at end of file diff --git a/maestro-orchestra/src/main/java/maestro/orchestra/yaml/YamlWaitForAnimationToEndCommand.kt b/maestro-orchestra/src/main/java/maestro/orchestra/yaml/YamlWaitForAnimationToEndCommand.kt index c8a595118f..59a0bf2263 100644 --- a/maestro-orchestra/src/main/java/maestro/orchestra/yaml/YamlWaitForAnimationToEndCommand.kt +++ b/maestro-orchestra/src/main/java/maestro/orchestra/yaml/YamlWaitForAnimationToEndCommand.kt @@ -1,5 +1,6 @@ package maestro.orchestra.yaml data class YamlWaitForAnimationToEndCommand( - val timeout: Long? + val timeout: Long?, + val label: String? = null, ) \ No newline at end of file diff --git a/maestro-orchestra/src/test/java/maestro/orchestra/MaestroCommandSerializationTest.kt b/maestro-orchestra/src/test/java/maestro/orchestra/MaestroCommandSerializationTest.kt index 4f74762d46..1a1b052fc8 100644 --- a/maestro-orchestra/src/test/java/maestro/orchestra/MaestroCommandSerializationTest.kt +++ b/maestro-orchestra/src/test/java/maestro/orchestra/MaestroCommandSerializationTest.kt @@ -19,6 +19,7 @@ internal class MaestroCommandSerializationTest { retryIfNoChange = false, waitUntilVisible = true, longPress = false, + label = "My Tap" ) ) @@ -37,7 +38,8 @@ internal class MaestroCommandSerializationTest { }, "retryIfNoChange" : false, "waitUntilVisible" : true, - "longPress" : false + "longPress" : false, + "label" : "My Tap" } } """.trimIndent() @@ -58,6 +60,7 @@ internal class MaestroCommandSerializationTest { retryIfNoChange = false, waitUntilVisible = true, longPress = false, + label = "My TapOnPoint" ) ) @@ -74,7 +77,8 @@ internal class MaestroCommandSerializationTest { "y" : 100, "retryIfNoChange" : false, "waitUntilVisible" : true, - "longPress" : false + "longPress" : false, + "label" : "My TapOnPoint" } } """.trimIndent() @@ -92,6 +96,7 @@ internal class MaestroCommandSerializationTest { point = "20,30", retryIfNoChange = false, longPress = false, + label = "My TapOnPointV2" ) ) @@ -106,7 +111,8 @@ internal class MaestroCommandSerializationTest { "tapOnPointV2Command" : { "point" : "20,30", "retryIfNoChange" : false, - "longPress" : false + "longPress" : false, + "label" : "My TapOnPointV2" } } """.trimIndent() diff --git a/maestro-orchestra/src/test/java/maestro/orchestra/MaestroCommandTest.kt b/maestro-orchestra/src/test/java/maestro/orchestra/MaestroCommandTest.kt index b82d1f2a18..db6a9a41f9 100644 --- a/maestro-orchestra/src/test/java/maestro/orchestra/MaestroCommandTest.kt +++ b/maestro-orchestra/src/test/java/maestro/orchestra/MaestroCommandTest.kt @@ -29,4 +29,17 @@ internal class MaestroCommandTest { assertThat(description) .isEqualTo("Press back") } + + @Test + fun `description (with a label)`() { + // given + val maestroCommand = MaestroCommand(SetLocationCommand(12.5266, 78.2150, "Set Location to Test Laboratory")) + + // when + val description = maestroCommand.description() + + // then + assertThat(description) + .isEqualTo("Set Location to Test Laboratory") + } } diff --git a/maestro-orchestra/src/test/java/maestro/orchestra/yaml/YamlCommandReaderTest.kt b/maestro-orchestra/src/test/java/maestro/orchestra/yaml/YamlCommandReaderTest.kt index f744653dac..cb1e310cc0 100644 --- a/maestro-orchestra/src/test/java/maestro/orchestra/yaml/YamlCommandReaderTest.kt +++ b/maestro-orchestra/src/test/java/maestro/orchestra/yaml/YamlCommandReaderTest.kt @@ -3,15 +3,46 @@ package maestro.orchestra.yaml import com.google.common.truth.Truth.assertThat import java.nio.file.FileSystems import java.nio.file.Paths +import maestro.KeyCode +import maestro.ScrollDirection +import maestro.TapRepeat import maestro.orchestra.ApplyConfigurationCommand +import maestro.orchestra.AssertConditionCommand import maestro.orchestra.BackPressCommand +import maestro.orchestra.ClearKeychainCommand +import maestro.orchestra.ClearStateCommand import maestro.orchestra.Command +import maestro.orchestra.Condition +import maestro.orchestra.CopyTextFromCommand +import maestro.orchestra.ElementSelector +import maestro.orchestra.EraseTextCommand +import maestro.orchestra.EvalScriptCommand +import maestro.orchestra.HideKeyboardCommand +import maestro.orchestra.InputRandomCommand +import maestro.orchestra.InputRandomType +import maestro.orchestra.InputTextCommand import maestro.orchestra.LaunchAppCommand import maestro.orchestra.MaestroCommand import maestro.orchestra.MaestroConfig import maestro.orchestra.MaestroOnFlowComplete import maestro.orchestra.MaestroOnFlowStart +import maestro.orchestra.OpenLinkCommand +import maestro.orchestra.PasteTextCommand +import maestro.orchestra.PressKeyCommand +import maestro.orchestra.RepeatCommand +import maestro.orchestra.RunFlowCommand +import maestro.orchestra.RunScriptCommand import maestro.orchestra.ScrollCommand +import maestro.orchestra.ScrollUntilVisibleCommand +import maestro.orchestra.SetLocationCommand +import maestro.orchestra.StartRecordingCommand +import maestro.orchestra.StopAppCommand +import maestro.orchestra.StopRecordingCommand +import maestro.orchestra.TakeScreenshotCommand +import maestro.orchestra.TapOnElementCommand +import maestro.orchestra.TapOnPointV2Command +import maestro.orchestra.TravelCommand +import maestro.orchestra.WaitForAnimationToEndCommand import maestro.orchestra.error.SyntaxError import maestro.orchestra.yaml.junit.YamlCommandsExtension import maestro.orchestra.yaml.junit.YamlExceptionExtension @@ -280,6 +311,303 @@ internal class YamlCommandReaderTest { ) } + @Test + fun labels( + @YamlFile("023_labels.yaml") commands: List, + ) { + assertThat(commands).containsExactly( + ApplyConfigurationCommand( + config=MaestroConfig( + appId="com.example.app" + ) + ), + + // Taps + TapOnElementCommand( + selector = ElementSelector(idRegex = "foo"), + retryIfNoChange = true, + waitUntilVisible = false, + longPress = false, + label = "Tap on the important button" + ), + TapOnElementCommand( + selector = ElementSelector(idRegex = "foo"), + retryIfNoChange = true, + waitUntilVisible = false, + longPress = false, + repeat = TapRepeat( + repeat = 2, + delay = 100L + ), + label = "Tap on the important button twice" + ), + TapOnElementCommand( + selector = ElementSelector(idRegex = "foo"), + retryIfNoChange = true, + waitUntilVisible = false, + longPress = true, + label = "Press and hold the important button" + ), + TapOnPointV2Command( + point = "50%,50%", + retryIfNoChange = true, + longPress = false, + label = "Tap on the middle of the screen" + ), + + //Assertions + AssertConditionCommand( + condition = Condition(visible = ElementSelector(idRegex = "bar")), + label = "Check that the important number is visible" + ), + AssertConditionCommand( + condition = Condition(notVisible = ElementSelector(idRegex = "bar2")), + label = "Check that the secret number is invisible" + ), + AssertConditionCommand( + condition = Condition( + scriptCondition = "\${5 == 5}" + ), + label = "Check that five is still what we think it is" + ), + + + // Inputs + InputTextCommand( + text = "correct horse battery staple", + label = "Enter my secret password" + ), + InputRandomCommand( + inputType = InputRandomType.TEXT_EMAIL_ADDRESS, + label = "Enter a random email address" + ), + InputRandomCommand( + inputType = InputRandomType.TEXT_PERSON_NAME, + length = 8, + label = "Enter a random person's name" + ), + InputRandomCommand( + inputType = InputRandomType.NUMBER, + length = 5, + label = "Enter a random number" + ), + InputRandomCommand( + inputType = InputRandomType.TEXT, + length = 20, + label = "Enter a random string" + ), + PressKeyCommand( + code = KeyCode.ENTER, + label = "Press the enter key" + ), + + // Other + BackPressCommand( + label = "Go back to the previous screen" + ), + ClearKeychainCommand( + label = "Clear the keychain" + ), + ClearStateCommand( + appId = "com.example.app", + label = "Wipe the app state" + ), + CopyTextFromCommand( + selector = ElementSelector(idRegex = "foo"), + label = "Copy the important text" + ), + EraseTextCommand( + charactersToErase = 5, + label = "Erase the last 5 characters" + ), + AssertConditionCommand( + condition = Condition(visible = ElementSelector(textRegex="Some important text")), + timeout = "1000", + label = "Wait until the important text is visible" + ), + EvalScriptCommand( + scriptString = "return 5;", + label = "Get the number 5" + ), + HideKeyboardCommand( + label = "Hide the keyboard" + ), + LaunchAppCommand( + appId = "com.some.other", + clearState = true, + label = "Launch some other app" + ), + OpenLinkCommand( + link = "https://www.example.com", + autoVerify = false, + browser = false, + label = "Open the example website" + ), + PasteTextCommand( + label = "Paste the important text" + ), + RunFlowCommand( + config = null, + commands = commands( + AssertConditionCommand( + condition = Condition(scriptCondition = "\${5 == 5}") + ) + ), + label = "Check that five is still what we think it is" + ), + RunScriptCommand( + script = "const myNumber = 1 + 1;", + condition = null, + sourceDescription = "023_runScript_test.js", + label = "Run some special calculations" + ), + ScrollCommand( + label = "Scroll down" + ), + ScrollUntilVisibleCommand( + selector = ElementSelector(textRegex = "Footer"), + direction = ScrollDirection.DOWN, + timeout = 20000, + scrollDuration = 601, + visibilityPercentage = 100, + label = "Scroll to the bottom", + centerElement = false + ), + SetLocationCommand( + latitude = 12.5266, + longitude = 78.2150, + label = "Set Location to Test Laboratory" + ), + StartRecordingCommand( + path = "recording.mp4", + label = "Start recording a video" + ), + StopAppCommand( + appId = "com.some.other", + label = "Stop that other app from running" + ), + StopRecordingCommand( + label = "Stop recording the video" + ), + TakeScreenshotCommand( + path = "baz", + label = "Snap this for later evaluation" + ), + TravelCommand( + points = listOf( + TravelCommand.GeoPoint(0.0,0.0), + TravelCommand.GeoPoint(0.1,0.0), + TravelCommand.GeoPoint(0.1,0.1), + TravelCommand.GeoPoint(0.0,0.1), + ), + speedMPS = 2000.0, + label = "Run around the north pole" + ), + WaitForAnimationToEndCommand( + timeout = 4000, + label = "Wait for the thing to stop spinning" + ), + RepeatCommand( + condition = Condition(visible = ElementSelector(textRegex = "Some important text")), + commands = listOf( + MaestroCommand( + command = TapOnElementCommand( + selector = ElementSelector(idRegex = "foo"), + retryIfNoChange = true, + waitUntilVisible = false, + longPress = false, + label = "Tap on the important button" + ) + ), + MaestroCommand( + command = TapOnElementCommand( + selector = ElementSelector(idRegex = "bar"), + retryIfNoChange = true, + waitUntilVisible = false, + longPress = false, + label = "Tap on the other important button" + ) + ) + ), + label = "Tap the 2 buttons until the text goes away" + ), + ) + } + + @Test + fun commands_with_string_non_string(@YamlFile("024_string_non_string_commands.yaml") commands: List,) { + assertThat(commands).containsExactly( + ApplyConfigurationCommand( + config= MaestroConfig(appId= "com.example.app") + ), + InputTextCommand(text = "correct horse battery staple"), + InputTextCommand(text = "correct horse battery staple"), + InputTextCommand(text = "4"), + InputTextCommand(text = "false"), + InputTextCommand(text = "1683113805263"), + InputTextCommand(text = "4.12"), + AssertConditionCommand( + condition = Condition( + scriptCondition = "true" + ) + ), + AssertConditionCommand( + condition = Condition( + scriptCondition = "323" + ) + ), + EvalScriptCommand( + scriptString = "true" + ), + EvalScriptCommand( + scriptString = "2 + 1" + ), + EvalScriptCommand( + scriptString = "2" + ), + EvalScriptCommand( + scriptString = "false == false" + ), + TapOnElementCommand( + ElementSelector( + textRegex = "Hello", + ), + retryIfNoChange = true, + waitUntilVisible = false, + longPress = false + ), + TapOnElementCommand( + selector = ElementSelector(textRegex = "Hello"), + repeat = TapRepeat(2, TapOnElementCommand.DEFAULT_REPEAT_DELAY), + retryIfNoChange = true, + waitUntilVisible = false, + longPress = false + ), + TapOnElementCommand( + selector = ElementSelector(textRegex = "Hello"), + longPress = true, + retryIfNoChange = true, + waitUntilVisible = false + ), + AssertConditionCommand( + condition = Condition( + visible = ElementSelector(textRegex = "Hello"), + ), + ), + CopyTextFromCommand(ElementSelector(textRegex = "Hello")), + BackPressCommand(), + BackPressCommand(), + HideKeyboardCommand(), + HideKeyboardCommand(), + ScrollCommand(), + ScrollCommand(), + ClearKeychainCommand(), + ClearKeychainCommand(), + PasteTextCommand(), + PasteTextCommand(), + ) + } + private fun commands(vararg commands: Command): List = commands.map(::MaestroCommand).toList() } diff --git a/maestro-orchestra/src/test/resources/YamlCommandReaderTest/023_labels.yaml b/maestro-orchestra/src/test/resources/YamlCommandReaderTest/023_labels.yaml new file mode 100644 index 0000000000..2319bcd4a5 --- /dev/null +++ b/maestro-orchestra/src/test/resources/YamlCommandReaderTest/023_labels.yaml @@ -0,0 +1,127 @@ +appId: com.example.app +--- +# Taps +- tapOn: + id: "foo" + label: "Tap on the important button" +- doubleTapOn: + id: "foo" + label: "Tap on the important button twice" +- longPressOn: + id: "foo" + label: "Press and hold the important button" +- tapOn: + point: 50%,50% + label: "Tap on the middle of the screen" + +# Assertions +- assertVisible: + id: "bar" + label: "Check that the important number is visible" +- assertNotVisible: + id: "bar2" + label: "Check that the secret number is invisible" +- assertTrue: + condition: ${5 == 5} + label: "Check that five is still what we think it is" + +# Inputs +- inputText: + text: "correct horse battery staple" + label: "Enter my secret password" +- inputRandomEmail: + label: "Enter a random email address" +- inputRandomPersonName: + label: "Enter a random person's name" +- inputRandomNumber: + length: 5 + label: "Enter a random number" +- inputRandomText: + length: 20 + label: "Enter a random string" +- pressKey: + key: "enter" + label: "Press the enter key" + +# Other +- back: + label: "Go back to the previous screen" +- clearKeychain: + label: "Clear the keychain" +- clearState: + label: "Wipe the app state" +- copyTextFrom: + id: "foo" + label: "Copy the important text" +- eraseText: + charactersToErase: 5 + label: "Erase the last 5 characters" +- extendedWaitUntil: + visible: "Some important text" + timeout: 1000 + label: "Wait until the important text is visible" +- evalScript: + script: "return 5;" + label: "Get the number 5" +- hideKeyboard: + label: "Hide the keyboard" +- launchApp: + appId: "com.some.other" + clearState: true + label: "Launch some other app" +- openLink: + link: "https://www.example.com" + label: "Open the example website" +- pasteText: + label: "Paste the important text" +- runFlow: + commands: + - assertTrue: ${5 == 5} + label: "Check that five is still what we think it is" +- runScript: + file: "023_runScript_test.js" + label: "Run some special calculations" +- scroll: + label: "Scroll down" +- scrollUntilVisible: + element: "Footer" + label: "Scroll to the bottom" +- setLocation: + latitude: 12.5266 + longitude: 78.2150 + label: "Set Location to Test Laboratory" +- startRecording: + path: "recording.mp4" + label: "Start recording a video" +- stopApp: + appId: "com.some.other" + label: "Stop that other app from running" +- stopRecording: + label: "Stop recording the video" +- takeScreenshot: + path: "baz" + label: "Snap this for later evaluation" +- travel: + points: + - 0.0,0.0 + - 0.1,0.0 + - 0.1,0.1 + - 0.0,0.1 + speed: 2000 + label: "Run around the north pole" +- waitForAnimationToEnd: + timeout: 4000 + label: "Wait for the thing to stop spinning" + +# Repeats +- repeat: + while: + visible: "Some important text" + commands: + - tapOn: + id: "foo" + label: "Tap on the important button" + - tapOn: + id: "bar" + label: "Tap on the other important button" + label: "Tap the 2 buttons until the text goes away" diff --git a/maestro-orchestra/src/test/resources/YamlCommandReaderTest/023_runScript_test.js b/maestro-orchestra/src/test/resources/YamlCommandReaderTest/023_runScript_test.js new file mode 100644 index 0000000000..0649426563 --- /dev/null +++ b/maestro-orchestra/src/test/resources/YamlCommandReaderTest/023_runScript_test.js @@ -0,0 +1 @@ +const myNumber = 1 + 1; \ No newline at end of file diff --git a/maestro-orchestra/src/test/resources/YamlCommandReaderTest/024_string_non_string_commands.yaml b/maestro-orchestra/src/test/resources/YamlCommandReaderTest/024_string_non_string_commands.yaml new file mode 100644 index 0000000000..753390e640 --- /dev/null +++ b/maestro-orchestra/src/test/resources/YamlCommandReaderTest/024_string_non_string_commands.yaml @@ -0,0 +1,30 @@ +appId: com.example.app +--- +- inputText: "correct horse battery staple" +- inputText: correct horse battery staple +- inputText: 4 +- inputText: false +- inputText: 1683113805263 +- inputText: 4.12 +- assertTrue: true +- assertTrue: 323 +- evalScript: true +- evalScript: 2 + 1 +- evalScript: 2 +- evalScript: false == false +- tapOn: "Hello" +- doubleTapOn: "Hello" +- longPressOn: "Hello" +- assertVisible: "Hello" +- copyTextFrom: "Hello" +- back +- action: back +- hideKeyboard +- action: hideKeyboard +- scroll +- action: scroll +- clearKeychain +- action: clearKeychain +- pasteText +- action: pasteText + diff --git a/maestro-test/src/test/kotlin/maestro/test/IntegrationTest.kt b/maestro-test/src/test/kotlin/maestro/test/IntegrationTest.kt index bc86accd64..d0e0070595 100644 --- a/maestro-test/src/test/kotlin/maestro/test/IntegrationTest.kt +++ b/maestro-test/src/test/kotlin/maestro/test/IntegrationTest.kt @@ -1105,7 +1105,6 @@ class IntegrationTest { driver.assertEvents( listOf( Event.HideKeyboard, - Event.HideKeyboard, ) ) } @@ -2348,7 +2347,7 @@ class IntegrationTest { } @Test - fun `085 - Open link with auto verify`() { + fun `Case 085 - Open link with auto verify`() { // Given val commands = readCommands("085_open_link_auto_verify") @@ -2369,7 +2368,7 @@ class IntegrationTest { } @Test - fun `086 - launchApp sets all permissions to allow`() { + fun `Case 086 - launchApp sets all permissions to allow`() { // Given val commands = readCommands("086_launchApp_sets_all_permissions_to_allow") val driver = driver {} @@ -2390,7 +2389,7 @@ class IntegrationTest { } @Test - fun `087 - launchApp with all permissions to deny`() { + fun `Case 087 - launchApp with all permissions to deny`() { // Given val commands = readCommands("087_launchApp_with_all_permissions_to_deny") val driver = driver {} @@ -2411,7 +2410,7 @@ class IntegrationTest { } @Test - fun `088 - launchApp with all permissions to deny and notification to allow`() { + fun `Case 088 - launchApp with all permissions to deny and notification to allow`() { // Given val commands = readCommands("088_launchApp_with_all_permissions_to_deny_and_notification_to_allow") val driver = driver {} @@ -2432,7 +2431,7 @@ class IntegrationTest { } @Test - fun `089 - launchApp with SMS permissions`() { + fun `Case 089 - launchApp with SMS permissions`() { // Given val commands = readCommands("089_launchApp_with_sms_permission_group_to_allow") val driver = driver {} @@ -2453,7 +2452,7 @@ class IntegrationTest { } @Test - fun `090 - Travel`() { + fun `Case 090 - Travel`() { // Given val commands = readCommands("090_travel") val driver = driver {} @@ -2476,7 +2475,7 @@ class IntegrationTest { } @Test - fun `091 - Assert visible by index`() { + fun `Case 091 - Assert visible by index`() { // Given val commands = readCommands("091_assert_visible_by_index") val driver = driver { @@ -2504,7 +2503,7 @@ class IntegrationTest { } @Test - fun `092 - Log messages`() { + fun `Case 092 - Log messages`() { // Given val commands = readCommands("092_log_messages") val driver = driver { @@ -2530,7 +2529,7 @@ class IntegrationTest { } @Test - fun `093 - JS default values`() { + fun `Case 093 - JS default values`() { // Given val commands = readCommands("093_js_default_value") val driver = driver { @@ -2547,7 +2546,7 @@ class IntegrationTest { } @Test - fun `094 - Subflow with inlined commands`() { + fun `Case 094 - Subflow with inlined commands`() { // Given val commands = readCommands("094_runFlow_inline") val driver = driver { @@ -2563,7 +2562,7 @@ class IntegrationTest { } @Test - fun `095 - Launch arguments`() { + fun `Case 095 - Launch arguments`() { // Given val commands = readCommands("095_launch_arguments") val driver = driver { @@ -2588,7 +2587,7 @@ class IntegrationTest { } @Test - fun `096 - platform condition`() { + fun `Case 096 - platform condition`() { // Given val commands = readCommands("096_platform_condition") val driver = driver { diff --git a/maestro-test/src/test/resources/010_scroll.yaml b/maestro-test/src/test/resources/010_scroll.yaml index feb1a7caee..bd91ecc5c6 100644 --- a/maestro-test/src/test/resources/010_scroll.yaml +++ b/maestro-test/src/test/resources/010_scroll.yaml @@ -1,3 +1,3 @@ appId: com.example.app --- -- action: scroll \ No newline at end of file +- scroll \ No newline at end of file diff --git a/maestro-test/src/test/resources/011_back_press.yaml b/maestro-test/src/test/resources/011_back_press.yaml index 521a119731..cd7d0c53d2 100644 --- a/maestro-test/src/test/resources/011_back_press.yaml +++ b/maestro-test/src/test/resources/011_back_press.yaml @@ -1,3 +1,3 @@ appId: com.example.app --- -- action: back \ No newline at end of file +- back \ No newline at end of file diff --git a/maestro-test/src/test/resources/039_hide_keyboard.yaml b/maestro-test/src/test/resources/039_hide_keyboard.yaml index ce590549db..93ab4f21ed 100644 --- a/maestro-test/src/test/resources/039_hide_keyboard.yaml +++ b/maestro-test/src/test/resources/039_hide_keyboard.yaml @@ -1,4 +1,3 @@ appId: com.example.app --- -- action: hide keyboard - hideKeyboard \ No newline at end of file