mobile-dev-inc / maestro

Painless Mobile UI Automation
https://maestro.mobile.dev/
Apache License 2.0
5.89k stars 281 forks source link

[Feature Request]Support older Android versions #1207

Open ashishb opened 1 year ago

ashishb commented 1 year ago

Is your feature request related to a problem? Please describe. Some issues show up only on older versions of Android

Describe the solution you'd like Support older versions of Android at least till API 21.

camoles commented 1 year ago

As per my attempts, the minimum android api level on which maestro will run today is 26, but that is not documented anywhere. I made a pull request to fix the documentation. To help further on this issue, I also tried to run on api levels 21 and newer and found that the issue is that, on older versions, maestro is trying to use an adb command that is unsupported there to list packages installed, and then it is not able to continue. I may help with this in the future if I get sponsorship, but as it is today we cannot adopt maestro since supporting api levels 21 and above is a requirement for the project.

camoles commented 1 year ago

Meanwhile, this line indicates that maestro indeed intended to support Android API levels 21 and newer, but still versions older than 26 are broken.

ashishb commented 1 year ago

maestro is trying to use an adb command that is unsupported there to list packages installed, and then it is not able to continue.

Do you know which command is that? I know a few things about ADB and might be able to find a portable replacement.

testifyqa commented 1 year ago

This has affected my team as we need to run specifcally on devices using API 25.

I've had a quick look into this and think I see the issue...

The AndroidDriver has this function which gets called

private fun startInstrumentationSession() {
        val startTime = System.currentTimeMillis()
        val instrumentationCommand = "am instrument -w -m -e debug false " +
            "-e class 'dev.mobile.maestro.MaestroDriverService#grpcServer' " +
            "dev.mobile.maestro.test/androidx.test.runner.AndroidJUnitRunner &\n"

        while (System.currentTimeMillis() - startTime < getStartupTimeout()) {
            instrumentationSession = dadb.openShell(instrumentationCommand)

            if (instrumentationSession.successfullyStarted()) {
                return
            }

            instrumentationSession?.close()
            Thread.sleep(100)
        }
        throw TimeoutException("Maestro instrumentation could not be initialized")
    }

This adb command that is run does not seem to work with that -m flag on API 25 and below.

❯ adb shell am instrument -w -m -e debug false -e class 'dev.mobile.MaestroDriverService#grpcServer' dev.mobile.maestro.test/androidx.test.runner.AndroidJUnitRunner
Error: Unknown option: -m

I reckon I can have a go at raising a PR to fix this command for API 25 and below versions, and use this default one still for API 26 and above, unless someone else beats me to it.

testifyqa commented 1 year ago

I have fixed this and raised a PR here -> https://github.com/mobile-dev-inc/maestro/pull/1527

bartekpacia commented 4 months ago

Can this be closed since #1527 has been merged for more than half a year now?

ashishb commented 4 months ago

@bartekpacia seems like mobile.dev hosted service still does not support this.

maestro cloud --android-api-level 21 ./app/release/app-release.apk .maestro/
Picked up JAVA_TOOL_OPTIONS: -Dapple.awt.UIElement=true

Evaluating workspace...

Uploading Flow(s)...

████████████████████
Upload request failed (400): Android API level not supported. Choose one from [34, 33, 31, 30, 29, 28]
make: *** [testOnMaestroCloud] Error 1
ashishb commented 4 months ago

Infact, it does not work on a local device either

$ maestro --version
1.36.0

This is the failure when I am running emulator (API 22)

$ maestro test .maestro/* Picked up JAVA_TOOL_OPTIONS: -Dapple.awt.UIElement=true Running on emulator-5554

java.io.IOException: pm list packages --user 0 dev.mobile.maestro
    at maestro.drivers.AndroidDriver.shell(AndroidDriver.kt:974)
    at maestro.drivers.AndroidDriver.isPackageInstalled(AndroidDriver.kt:962)
    at maestro.drivers.AndroidDriver.uninstallMaestroDriverApp(AndroidDriver.kt:929)
    at maestro.drivers.AndroidDriver.installMaestroDriverApp(AndroidDriver.kt:890)
    at maestro.drivers.AndroidDriver.installMaestroApks(AndroidDriver.kt:924)
    at maestro.drivers.AndroidDriver.open(AndroidDriver.kt:75)
    at maestro.Maestro$Companion.android(Maestro.kt:606)
    at maestro.cli.session.MaestroSessionManager.createAndroid(MaestroSessionManager.kt:266)
    at maestro.cli.session.MaestroSessionManager.createMaestro(MaestroSessionManager.kt:149)
    at maestro.cli.session.MaestroSessionManager.access$createMaestro(MaestroSessionManager.kt:49)
    at maestro.cli.session.MaestroSessionManager$newSession$session$1.invoke(MaestroSessionManager.kt:82)
    at maestro.cli.session.MaestroSessionManager$newSession$session$1.invoke(MaestroSessionManager.kt:81)
    at maestro.cli.db.KeyValueStore.withExclusiveLock(KeyValueStore.kt:37)
    at maestro.cli.session.SessionStore.withExclusiveLock(SessionStore.kt:74)
    at maestro.cli.session.MaestroSessionManager.newSession(MaestroSessionManager.kt:81)
    at maestro.cli.session.MaestroSessionManager.newSession$default(MaestroSessionManager.kt:58)
    at maestro.cli.command.TestCommand.call(TestCommand.kt:136)
    at maestro.cli.command.TestCommand.call(TestCommand.kt:46)
    at picocli.CommandLine.executeUserObject(CommandLine.java:1933)
    at picocli.CommandLine.access$1200(CommandLine.java:145)
    at picocli.CommandLine$RunLast.executeUserObjectOfLastSubcommandWithSameParent(CommandLine.java:2332)
    at picocli.CommandLine$RunLast.handle(CommandLine.java:2326)
    at picocli.CommandLine$RunLast.handle(CommandLine.java:2291)
    at picocli.CommandLine$AbstractParseResultHandler.execute(CommandLine.java:2159)
    at maestro.cli.DisableAnsiMixin$Companion.executionStrategy(DisableAnsiMixin.kt:22)
    at picocli.CommandLine.execute(CommandLine.java:2058)
    at maestro.cli.AppKt.main(App.kt:117)
Caused by: java.io.IOException: Command failed (shell,v2,raw:pm list packages --user 0 dev.mobile.maestro): closed
    at dadb.adbserver.AdbServer.send$dadb(AdbServer.kt:99)
    at dadb.adbserver.AdbServerDadb.open(AdbServer.kt:138)
    at dadb.Dadb$DefaultImpls.openShell(Dadb.kt:43)
    at dadb.adbserver.AdbServerDadb.openShell(AdbServer.kt:118)
    at dadb.Dadb$DefaultImpls.shell(Dadb.kt:36)
    at dadb.adbserver.AdbServerDadb.shell(AdbServer.kt:118)
    at maestro.drivers.AndroidDriver.shell(AndroidDriver.kt:972)
    ... 26 more
testifyqa commented 4 months ago

It only goes down to API 25 IIRCSent from my iPhoneOn 15 Jul 2024, at 08:26, Ashish Bhatia @.***> wrote: Infact, it does not work on a local device either $ maestro --version 1.36.0

This is the failure when I am running emulator (API 22) $ maestro test .maestro/* Picked up JAVA_TOOL_OPTIONS: -Dapple.awt.UIElement=true Running on emulator-5554 java.io.IOException: pm list packages --user 0 dev.mobile.maestro at maestro.drivers.AndroidDriver.shell(AndroidDriver.kt:974) at maestro.drivers.AndroidDriver.isPackageInstalled(AndroidDriver.kt:962) at maestro.drivers.AndroidDriver.uninstallMaestroDriverApp(AndroidDriver.kt:929) at maestro.drivers.AndroidDriver.installMaestroDriverApp(AndroidDriver.kt:890) at maestro.drivers.AndroidDriver.installMaestroApks(AndroidDriver.kt:924) at maestro.drivers.AndroidDriver.open(AndroidDriver.kt:75) at maestro.Maestro$Companion.android(Maestro.kt:606) at maestro.cli.session.MaestroSessionManager.createAndroid(MaestroSessionManager.kt:266) at maestro.cli.session.MaestroSessionManager.createMaestro(MaestroSessionManager.kt:149) at maestro.cli.session.MaestroSessionManager.access$createMaestro(MaestroSessionManager.kt:49) at maestro.cli.session.MaestroSessionManager$newSession$session$1.invoke(MaestroSessionManager.kt:82) at maestro.cli.session.MaestroSessionManager$newSession$session$1.invoke(MaestroSessionManager.kt:81) at maestro.cli.db.KeyValueStore.withExclusiveLock(KeyValueStore.kt:37) at maestro.cli.session.SessionStore.withExclusiveLock(SessionStore.kt:74) at maestro.cli.session.MaestroSessionManager.newSession(MaestroSessionManager.kt:81) at maestro.cli.session.MaestroSessionManager.newSession$default(MaestroSessionManager.kt:58) at maestro.cli.command.TestCommand.call(TestCommand.kt:136) at maestro.cli.command.TestCommand.call(TestCommand.kt:46) at picocli.CommandLine.executeUserObject(CommandLine.java:1933) at picocli.CommandLine.access$1200(CommandLine.java:145) at picocli.CommandLine$RunLast.executeUserObjectOfLastSubcommandWithSameParent(CommandLine.java:2332) at picocli.CommandLine$RunLast.handle(CommandLine.java:2326) at picocli.CommandLine$RunLast.handle(CommandLine.java:2291) at picocli.CommandLine$AbstractParseResultHandler.execute(CommandLine.java:2159) at maestro.cli.DisableAnsiMixin$Companion.executionStrategy(DisableAnsiMixin.kt:22) at picocli.CommandLine.execute(CommandLine.java:2058) at maestro.cli.AppKt.main(App.kt:117) Caused by: java.io.IOException: Command failed (shell,v2,raw:pm list packages --user 0 dev.mobile.maestro): closed at dadb.adbserver.AdbServer.send$dadb(AdbServer.kt:99) at dadb.adbserver.AdbServerDadb.open(AdbServer.kt:138) at dadb.Dadb$DefaultImpls.openShell(Dadb.kt:43) at dadb.adbserver.AdbServerDadb.openShell(AdbServer.kt:118) at dadb.Dadb$DefaultImpls.shell(Dadb.kt:36) at dadb.adbserver.AdbServerDadb.shell(AdbServer.kt:118) at maestro.drivers.AndroidDriver.shell(AndroidDriver.kt:972) ... 26 more

—Reply to this email directly, view it on GitHub, or unsubscribe.You are receiving this because you commented.Message ID: @.***>