diff --git a/.gitignore b/.gitignore
index c22074e917..f1a52102ac 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,4 +1,5 @@
.DS_Store
+.idea/
# Ignore Gradle project-specific cache directory
.gradle
diff --git a/CHANGELOG.md b/CHANGELOG.md
index ea450186a4..76814e5cd1 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -24,10 +24,10 @@ Fixes:
- Fix: not working when iOS simulator is in landscape orientation ([caveats apply](https://github.com/mobile-dev-inc/maestro/pull/1974#issuecomment-2346074593)) ([#1974](https://github.com/mobile-dev-inc/maestro/pull/1974))
- Fix: confusing error message "BlockingCoroutine is cancelling" ([#2036](https://github.com/mobile-dev-inc/maestro/pull/2036))
- Fix: AI-powered commands crashing when Anthropic is used ([#2033](https://github.com/mobile-dev-inc/maestro/pull/2033))
-- Fix: display warnings generated by AI-powered commands in CLI output when `optional: true` ([#2026](https://github.com/mobile-dev-inc/maestro/pull/2026))
-- Fix: visual bug with emojis having slightly different length in `maestro test`'s interactive CLI output ([#2016](https://github.com/mobile-dev-inc/maestro/pull/2016))
+- Fix: display warnings generated by AI-powered commands in CLI output when `optional: true` ([#2026](https://github.com/mobile-dev-inc/maestro/pull/2026))
+- Fix: visual bug with emojis having slightly different length in `maestro test`'s interactive CLI output ([#2016](https://github.com/mobile-dev-inc/maestro/pull/2016))
- Fix: no tests being run when flowsOrder specified all tests in the workspace ([#2003](https://github.com/mobile-dev-inc/maestro/pull/2003))
-- Fix: using integers from JavaScript outputs causing a deserialization error ([#1788](https://github.com/mobile-dev-inc/maestro/pull/1788) by [Muhammed Furkan Boran](https://github.com/boranfrkn))
+- Fix: using integers from JavaScript outputs causing a deserialization error ([#1788](https://github.com/mobile-dev-inc/maestro/pull/1788) by [Muhammed Furkan Boran](https://github.com/boranfrkn))
- Fix: delete temporary APKs after using them ([#1947](https://github.com/mobile-dev-inc/maestro/pull/1947) by [Tarek Belkahia](https://github.com/tokou))
- Fix: allow env vars in `setLocation` and `travel` commands ([#1988](https://github.com/mobile-dev-inc/maestro/pull/1988) by [Prasanta Biswas](https://github.com/prasanta-biswas))
- Fix: error message when specifying `--format` together with `--continuous` #1948 ([#1948](https://github.com/mobile-dev-inc/maestro/pull/1948) by [Tarek Belkahia](https://github.com/tokou))
@@ -37,6 +37,22 @@ Chores:
- Chore: make Maestro build & compile on Java 17 ([#2008](https://github.com/mobile-dev-inc/maestro/pull/2008))
- Chore: Migrate all Gradle buildscripts to Gradle Kotlin DSL ([#1994](https://github.com/mobile-dev-inc/maestro/pull/1994))
+=== My Changes ===
+
+## 1.38.2
+
+Released on 2024-09-26
+
+- change install script to rasyid7
+- update README
+- change version checker to own repo
+- [add sleep feature on maestro](https://github.com/rasyid7/maestro/commit/2a8575583af3aaf71de23c7def902db30041fa06)
+- [fix tags include from OR to AND](https://github.com/rasyid7/maestro/commit/9949f1b204e86dedb3f2912ffdfa65cca2e6121f)
+
+-- note: need to implement another [--parallel option](https://github.com/rasyid7/maestro/commit/3d291ee0145c9e925a3fa1702a26e49230b6ec03)
+
+=======
+
## 1.38.1
Released on 2024-08-30
@@ -89,7 +105,7 @@ Released on 2024-07-29
### Bug fixes
-- Fix `FileNotFoundException: ~.maestro/sessions` ([#1843](https://github.com/mobile-dev-inc/maestro/pull/1843))
+- Fix `FileNotFoundException: ~.maestro/sessions` ([#1843](https://github.com/mobile-dev-inc/maestro/pull/1843))
## 1.37.2 - 2024-07-29
diff --git a/README.md b/README.md
index 1339c0fd08..0cc068fde1 100644
--- a/README.md
+++ b/README.md
@@ -2,6 +2,14 @@
Maestro is the easiest way to automate UI testing for your mobile app.
+> [!NOTE]
+>
+> **Full documentation for Maestro can be found at [maestro.mobile.dev](https://maestro.mobile.dev)**
+>
+> Since this is forked REPO, to install this maestro, please use
+>
+> `curl -Ls "https://raw.githubusercontent.com/rasyid7/maestro/main/scripts/install.sh" | bash`
+
## Why Maestro?
diff --git a/gradle.properties b/gradle.properties
index 35378f46aa..7c27f833b6 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -2,7 +2,7 @@ android.useAndroidX=true
android.enableJetifier=true
kotlin.code.style=official
GROUP=dev.mobile
-VERSION_NAME=1.38.1
+VERSION_NAME=1.38.2
POM_DESCRIPTION=Maestro is a server-driven platform-agnostic library that allows to drive tests for both iOS and Android using the same implementation through an intuitive API.
POM_URL=https://github.com/mobile-dev-inc/maestro
POM_SCM_URL=https://github.com/mobile-dev-inc/maestro
diff --git a/maestro-cli/gradle.properties b/maestro-cli/gradle.properties
index 000e8f711c..0f85fb6c76 100644
--- a/maestro-cli/gradle.properties
+++ b/maestro-cli/gradle.properties
@@ -1 +1 @@
-CLI_VERSION=1.38.1
+CLI_VERSION=1.38.2
diff --git a/maestro-cli/src/main/java/maestro/cli/App.kt b/maestro-cli/src/main/java/maestro/cli/App.kt
index c50a238f9a..7db68d9d57 100644
--- a/maestro-cli/src/main/java/maestro/cli/App.kt
+++ b/maestro-cli/src/main/java/maestro/cli/App.kt
@@ -148,16 +148,10 @@ fun main(args: Array) {
if (newVersion != null) {
Updates.fetchChangelogAsync()
System.err.println()
- val changelog = Updates.getChangelog()
- val anchor = newVersion.toString().replace(".", "")
- System.err.println(listOf(
- "A new version of the Maestro CLI is available ($newVersion).\n",
- "See what's new:",
- "https://github.com/mobile-dev-inc/maestro/blob/main/CHANGELOG.md#$anchor",
- ChangeLogUtils.print(changelog),
- "Upgrade command:",
- "curl -Ls \"https://get.maestro.mobile.dev\" | bash",
- ).joinToString("\n").box())
+ System.err.println(
+ ("A new version of the Maestro CLI is available ($newVersion). Upgrade command:\n" +
+ "curl -Ls \"https://raw.githubusercontent.com/rasyid7/maestro/main/scripts/install.sh\" | bash").box()
+ )
}
if (commandLine.isVersionHelpRequested) {
diff --git a/maestro-cli/src/main/java/maestro/cli/api/ApiClient.kt b/maestro-cli/src/main/java/maestro/cli/api/ApiClient.kt
index 16ed950c30..3a85d71203 100644
--- a/maestro-cli/src/main/java/maestro/cli/api/ApiClient.kt
+++ b/maestro-cli/src/main/java/maestro/cli/api/ApiClient.kt
@@ -88,7 +88,7 @@ class ApiClient(
fun getLatestCliVersion(): CliVersion {
val request = Request.Builder()
.header("X-FRESH-INSTALL", if (!Analytics.hasRunBefore) "true" else "false")
- .url("$baseUrl/maestro/version")
+ .url("https://raw.githubusercontent.com/rasyid7/maestro/main/version")
.get()
.build()
diff --git a/maestro-client/src/main/java/maestro/Maestro.kt b/maestro-client/src/main/java/maestro/Maestro.kt
index 1876e8365c..16a8fec3b3 100644
--- a/maestro-client/src/main/java/maestro/Maestro.kt
+++ b/maestro-client/src/main/java/maestro/Maestro.kt
@@ -581,6 +581,12 @@ class Maestro(
ScreenshotUtils.waitUntilScreenIsStatic(timeout, SCREENSHOT_DIFF_THRESHOLD, driver)
}
+ fun sleep(time: Long?) {
+ val time = time ?: ANIMATION_TIMEOUT_MS
+ LOGGER.info("Sleep for $time ms")
+ Thread.sleep(time)
+ }
+
fun setProxy(
host: String = SocketUtils.localIp(),
port: Int
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 eed7c3d390..1c728895e3 100644
--- a/maestro-orchestra-models/src/main/java/maestro/orchestra/Commands.kt
+++ b/maestro-orchestra-models/src/main/java/maestro/orchestra/Commands.kt
@@ -37,7 +37,7 @@ sealed interface Command {
fun visible(): Boolean = true
val label: String?
-
+
val optional: Boolean
}
@@ -864,6 +864,21 @@ data class WaitForAnimationToEndCommand(
}
}
+data class SleepCommand(
+ val time: Long?,
+ override val label: String? = null,
+ override val optional: Boolean = false,
+) : Command {
+
+ override fun description(): String {
+ return label ?: "Sleep for $time ms"
+ }
+
+ override fun evaluateScripts(jsEngine: JsEngine): Command {
+ return this
+ }
+}
+
data class EvalScriptCommand(
val scriptString: String,
override val label: String? = null,
diff --git a/maestro-orchestra-models/src/main/java/maestro/orchestra/MaestroCommand.kt b/maestro-orchestra-models/src/main/java/maestro/orchestra/MaestroCommand.kt
index bb7090f5b3..46943dc850 100644
--- a/maestro-orchestra-models/src/main/java/maestro/orchestra/MaestroCommand.kt
+++ b/maestro-orchestra-models/src/main/java/maestro/orchestra/MaestroCommand.kt
@@ -67,6 +67,7 @@ data class MaestroCommand(
val addMediaCommand: AddMediaCommand? = null,
val setAirplaneModeCommand: SetAirplaneModeCommand? = null,
val toggleAirplaneModeCommand: ToggleAirplaneModeCommand? = null,
+ val sleepCommand: SleepCommand? = null,
) {
constructor(command: Command) : this(
@@ -109,6 +110,7 @@ data class MaestroCommand(
addMediaCommand = command as? AddMediaCommand,
setAirplaneModeCommand = command as? SetAirplaneModeCommand,
toggleAirplaneModeCommand = command as? ToggleAirplaneModeCommand,
+ sleepCommand = command as? SleepCommand,
)
fun asCommand(): Command? = when {
@@ -151,6 +153,7 @@ data class MaestroCommand(
addMediaCommand != null -> addMediaCommand
setAirplaneModeCommand != null -> setAirplaneModeCommand
toggleAirplaneModeCommand != null -> toggleAirplaneModeCommand
+ sleepCommand != null -> sleepCommand
else -> null
}
diff --git a/maestro-orchestra/src/main/java/maestro/orchestra/Orchestra.kt b/maestro-orchestra/src/main/java/maestro/orchestra/Orchestra.kt
index 33b68efaae..53c96afcba 100644
--- a/maestro-orchestra/src/main/java/maestro/orchestra/Orchestra.kt
+++ b/maestro-orchestra/src/main/java/maestro/orchestra/Orchestra.kt
@@ -295,6 +295,7 @@ class Orchestra(
is AddMediaCommand -> addMediaCommand(command.mediaPaths)
is SetAirplaneModeCommand -> setAirplaneMode(command)
is ToggleAirplaneModeCommand -> toggleAirplaneMode()
+ is SleepCommand -> sleepCommand(command)
else -> true
}.also { mutating ->
if (mutating) {
@@ -435,6 +436,11 @@ class Orchestra(
return true
}
+ private fun sleepCommand(command: SleepCommand): Boolean {
+ maestro.sleep(command.time)
+ return true
+ }
+
private fun defineVariablesCommand(command: DefineVariablesCommand): Boolean {
command.env.forEach { (name, value) ->
jsEngine.putEnv(name, value)
diff --git a/maestro-orchestra/src/main/java/maestro/orchestra/workspace/WorkspaceExecutionPlanner.kt b/maestro-orchestra/src/main/java/maestro/orchestra/workspace/WorkspaceExecutionPlanner.kt
index 48b14574f0..cb1a5d5f85 100644
--- a/maestro-orchestra/src/main/java/maestro/orchestra/workspace/WorkspaceExecutionPlanner.kt
+++ b/maestro-orchestra/src/main/java/maestro/orchestra/workspace/WorkspaceExecutionPlanner.kt
@@ -101,10 +101,17 @@ object WorkspaceExecutionPlanner {
val config = configPerFlowFile[it]
val tags = config?.tags ?: emptyList()
- (allIncludeTags.isEmpty() || tags.any(allIncludeTags::contains))
+ (allIncludeTags.isEmpty() || allIncludeTags.all { includeTag -> tags.contains(includeTag) })
&& (allExcludeTags.isEmpty() || !tags.any(allExcludeTags::contains))
}
+ println("")
+ println("Number flows to run: ${allFlows.size}")
+ println("Flows to run:")
+ for (flow in allFlows) {
+ println(" * ${flow.fileName.toString().substringBeforeLast(".")}")
+ }
+
if (allFlows.isEmpty()) {
val message = """
|Include / Exclude tags did not match any Flows:
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 447b22ee6c..ecda3b72f8 100644
--- a/maestro-orchestra/src/main/java/maestro/orchestra/yaml/YamlFluentCommand.kt
+++ b/maestro-orchestra/src/main/java/maestro/orchestra/yaml/YamlFluentCommand.kt
@@ -79,6 +79,7 @@ data class YamlFluentCommand(
val addMedia: YamlAddMedia? = null,
val setAirplaneMode: YamlSetAirplaneMode? = null,
val toggleAirplaneMode: YamlToggleAirplaneMode? = null,
+ val sleep: YamlSleepCommand? = null,
) {
@SuppressWarnings("ComplexMethod")
@@ -251,8 +252,16 @@ data class YamlFluentCommand(
val tapRepeat = TapRepeat(2, delay)
listOf(tapCommand(doubleTapOn, tapRepeat = tapRepeat))
}
- setAirplaneMode != null -> listOf(MaestroCommand(SetAirplaneModeCommand(setAirplaneMode.value, setAirplaneMode.label, setAirplaneMode.optional)))
- toggleAirplaneMode != null -> listOf(MaestroCommand(ToggleAirplaneModeCommand(toggleAirplaneMode.label, toggleAirplaneMode.optional)))
+ setAirplaneMode != null -> listOf(MaestroCommand(SetAirplaneModeCommand(setAirplaneMode.value, setAirplaneMode.label)))
+ toggleAirplaneMode != null -> listOf(MaestroCommand(ToggleAirplaneModeCommand(toggleAirplaneMode.label)))
+ sleep != null -> listOf(
+ MaestroCommand(
+ SleepCommand(
+ time = sleep.time,
+ label = sleep.label
+ )
+ )
+ )
else -> throw SyntaxError("Invalid command: No mapping provided for $this")
}
}
@@ -726,6 +735,10 @@ data class YamlFluentCommand(
assertNoDefectsWithAI = YamlAssertNoDefectsWithAI()
)
+ "sleep" -> YamlFluentCommand(
+ sleep = YamlSleepCommand(time = null)
+ )
+
else -> throw SyntaxError("Invalid command: \"$stringCommand\"")
}
}
diff --git a/maestro-orchestra/src/main/java/maestro/orchestra/yaml/YamlSleepCommand.kt b/maestro-orchestra/src/main/java/maestro/orchestra/yaml/YamlSleepCommand.kt
new file mode 100644
index 0000000000..1f938ae691
--- /dev/null
+++ b/maestro-orchestra/src/main/java/maestro/orchestra/yaml/YamlSleepCommand.kt
@@ -0,0 +1,16 @@
+package maestro.orchestra.yaml
+
+import com.fasterxml.jackson.annotation.JsonCreator
+
+data class YamlSleepCommand(
+ val time: Long?,
+ val label: String? = null,
+) {
+ companion object {
+ @JvmStatic
+ @JsonCreator(mode = JsonCreator.Mode.DELEGATING)
+ fun create(time: Long): YamlSleepCommand {
+ return YamlSleepCommand(time = time)
+ }
+ }
+}
diff --git a/maestro-orchestra/src/test/java/maestro/orchestra/MaestroCommandSerializationTest.kt b/maestro-orchestra/src/test/java/maestro/orchestra/MaestroCommandSerializationTest.kt
index b962514b43..436b4f15e9 100644
--- a/maestro-orchestra/src/test/java/maestro/orchestra/MaestroCommandSerializationTest.kt
+++ b/maestro-orchestra/src/test/java/maestro/orchestra/MaestroCommandSerializationTest.kt
@@ -587,6 +587,32 @@ internal class MaestroCommandSerializationTest {
.isEqualTo(command)
}
+ @Test
+ fun `serialize SleepCommand`() {
+ // given
+ val command = MaestroCommand(
+ SleepCommand(time = 1000)
+ )
+
+ // when
+ val serializedCommandJson = command.toJson()
+ val deserializedCommand = objectMapper.readValue(serializedCommandJson, MaestroCommand::class.java)
+
+ // then
+ @Language("json")
+ val expectedJson = """
+ {
+ "sleepCommand" : {
+ "time" : 1000
+ }
+ }
+ """.trimIndent()
+ assertThat(serializedCommandJson)
+ .isEqualTo(expectedJson)
+ assertThat(deserializedCommand)
+ .isEqualTo(command)
+ }
+
private fun MaestroCommand.toJson(): String =
objectMapper
.writerWithDefaultPrettyPrinter()
diff --git a/maestro-orchestra/src/test/java/maestro/orchestra/workspace/WorkspaceExecutionPlannerTest.kt b/maestro-orchestra/src/test/java/maestro/orchestra/workspace/WorkspaceExecutionPlannerTest.kt
index f66d1cf3e6..2589dab184 100644
--- a/maestro-orchestra/src/test/java/maestro/orchestra/workspace/WorkspaceExecutionPlannerTest.kt
+++ b/maestro-orchestra/src/test/java/maestro/orchestra/workspace/WorkspaceExecutionPlannerTest.kt
@@ -258,7 +258,6 @@ internal class WorkspaceExecutionPlannerTest {
assertThat(plan.flowsToRun).containsExactly(
path("/workspaces/010_global_include_tags/flowA.yaml"),
path("/workspaces/010_global_include_tags/flowA_subflow.yaml"),
- path("/workspaces/010_global_include_tags/flowB.yaml"),
)
}
diff --git a/scripts/install.sh b/scripts/install.sh
index a7f21069df..cf6477a068 100755
--- a/scripts/install.sh
+++ b/scripts/install.sh
@@ -90,9 +90,9 @@ mkdir -p "$maestro_tmp_folder"
if [ -z "$MAESTRO_VERSION" ]; then
- download_url="https://github.com/mobile-dev-inc/maestro/releases/latest/download/maestro.zip"
+ download_url="https://github.com/rasyid7/maestro/releases/latest/download/maestro.zip"
else
- download_url="https://github.com/mobile-dev-inc/maestro/releases/download/cli-$MAESTRO_VERSION/maestro.zip"
+ download_url="https://github.com/rasyid7/maestro/releases/download/cli-$MAESTRO_VERSION/maestro.zip"
fi
maestro_zip_file="${maestro_tmp_folder}/maestro.zip"
diff --git a/version b/version
new file mode 100644
index 0000000000..2c959a01bb
--- /dev/null
+++ b/version
@@ -0,0 +1 @@
+{"major":1,"minor":38,"patch":2}
\ No newline at end of file