mobile-dev-inc / maestro Goto Github PK
View Code? Open in Web Editor NEWPainless Mobile UI Automation
Home Page: https://maestro.mobile.dev/
License: Apache License 2.0
Painless Mobile UI Automation
Home Page: https://maestro.mobile.dev/
License: Apache License 2.0
Hello,
Here is my flow:
appId: com.android.settings
---
- launchApp
- tapOn:
below:
text: "Apps"
Below or event Above keywords don't work in the Android app settings (Android 12).
Maestro selects the first element of the list instead.
Here is a video:
import maestro_android.MaestroDriverGrpc
import maestro_android.deviceInfoRequest
import maestro_android.tapRequest
import maestro_android.viewHierarchyRequest
above classess not found.
When I run a test, the app state should be reset. Otherwise, the tests won't be deterministic (for my use case).
For example: After a fresh install, we show a GDPR screen and after the user accepts it, it won't be shown again.
It's mainly an issue while I am writing tests locally. I always need to reset the app by hand.
On https://maestro.mobile.dev/ embrases should be embraces I tihnk
I'm trying out version 1.4.0 of Maestro on a Jetpack Compose app, and wrote this yaml:
appId: dev.sanskar.photoplay
---
- launchApp
- tapOn: "Thor: Love and Thunder"
- tapOn: "Add To Watchlist"
- tapOn: "MCU"
- tapOn: "Save"
- back
- tapOn: "Thor: Love and Thunder"
- tapOn: "Add To Watchlist"
But, as observed in the video, there are multiple taps on the MCU entry. I was expecting only one tap to happen. Could it be because the list recomposes on tap?
A couple questions since the documentation for running on CI is a bit sparse: https://maestro.mobile.dev/getting-started/running-flows-on-ci
Here is a video demo of the bug: https://www.youtube.com/watch?v=CxzJXZMOhIY
Even though only one tap action was specified, four tap-actions are being invoked on the view.
The app is just a androidx.appcompat.widget.SwitchCompat
in a FrameLayout
, no additional logic on the view. Same happens with com.google.android.material.switchmaterial.SwitchMaterial
It would be nice to be able to have tapOn: button
find a button with text == My button with a long name
. Today we need to write tapOn: .*button.*
. Same request for the id
matcher.
I download java because when run maestro test /Users/paponsupamongkonchai/MaestroYAML/flow_ios_test.yaml
first time log of terminal introduce downlod Java for run command of maestro
Then download and install Java so I run again in terminal maestro test /Users/paponsupamongkonchai/MaestroYAML/flow_ios_test.yaml
it's show this message about version Java not support in Java version 55.0
=======See Log Below=======
paponsupamongkonchai@Papons-MacBook-Pro ~ % maestro test /Users/paponsupamongkonchai/MaestroYAML/flow_ios_test.yaml
Exception in thread "main" java.lang.UnsupportedClassVersionError: idb/CompanionServiceGrpc has been compiled by a more recent version of the Java Runtime (class file version 55.0), this version of the Java Runtime only recognizes class file versions up to 52.0
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClass(ClassLoader.java:756)
at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
at java.net.URLClassLoader.defineClass(URLClassLoader.java:473)
at java.net.URLClassLoader.access$100(URLClassLoader.java:74)
at java.net.URLClassLoader$1.run(URLClassLoader.java:369)
at java.net.URLClassLoader$1.run(URLClassLoader.java:363)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:362)
at java.lang.ClassLoader.loadClass(ClassLoader.java:418)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:355)
at java.lang.ClassLoader.loadClass(ClassLoader.java:351)
at ios.idb.IdbIOSDevice.<init>(IdbIOSDevice.kt:58)
at maestro.Maestro$Companion.ios(Maestro.kt:291)
at maestro.Maestro$Companion.ios(Maestro.kt:287)
at maestro.cli.util.MaestroFactory.createIos(MaestroFactory.kt:58)
at maestro.cli.util.MaestroFactory.autoDetectPlatform(MaestroFactory.kt:66)
at maestro.cli.util.MaestroFactory.createMaestro(MaestroFactory.kt:33)
at maestro.cli.command.TestCommand.call(TestCommand.kt:58)
at maestro.cli.command.TestCommand.call(TestCommand.kt:30)
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 picocli.CommandLine.execute(CommandLine.java:2058)
at maestro.cli.AppKt.main(App.kt:74)
I'm not sure what this would look like from a cross-platform perspective, but it would be useful to be able to launch directly into a specific screen (perhaps with a specific intent). One counter argument is that maestro should only be able to do what a user can. That said, launching a specific Activity feels like a pretty common need.
I am trying to tap on a particular icon, using its viewId. I use tapOn: "like_icon".
I have tried to click on some views by their Id but none has worked for me.
Would be nice to be able to open the app with a deep link:
Directly after starting our app a notification is shown because a foreground service is started. But also directly after starting the app I want to click on an item in the toolbar. Unfortunately most of the time maestro clicks on the notification instead of waiting until the notification is gone and the toolbar item is not obscured. Can I manually add some waiting time here or how can I handle this? Thanks!
After launching my App, I need to tap on a specific XY location on the home screen. But the view is already tapped on the splash screen, before the home screen loads. The same happens when there is a loading screen, and you need to tap on the location after the screen is loaded.
In my case when run idb_companion --udid {id of the iOS device} .
Result not show same tutorial it's show "Companion will stay alive if target goes offline" only
In the iOS app that we're testing, user session data persists to the keychain, even after removing and re-installing the app. Due to this a clearState
property does not seem to be sufficient to get a clean state of the app in a such a scenario, as the previously logged in user will stay logged in.
In Appium we found a workaround for this being to force reset iOS Simulator itself when establishing session capabilities, as it is not capable of cleaning the keychain for a specific app (frankly, not sure that iOS even allows this technically).
Is something like clearing keychain info or a clean simulator restart command possibly coming in future versions of Maestro?
We have the ability to swipe via coordinates today, but that's brittle and difficult to figure out what the right coordinates are. It would be nice to be able to say "Swipe left 1 inch starting from this view".
Would love to have the option to copy the text from a view so it can be checked against some other view. This would also bring in discussion a new assert - assertTextEquals - or something similar.
Hello,
Here is my flow:
appId: com.apple.MobileAddressBook
---
- launchApp
- tapOn: "John Appleseed"
- tapOn: "Modifier"
- tapOn: "Ajouter un numéro"
- inputText: 123123
- tapOn: "OK"
And running it on a French simulator gives ""
instead of 123123
:
eg:
- launchApp:
clearState: true
permissions: { notifications: 'YES', location: 'always' }
Hello,
On iOS, when running maestro hierarchy
, the command ends with:
Sep 03, 2022 9:59:57 AM io.grpc.internal.ManagedChannelOrphanWrapper$ManagedChannelReference cleanQueue
SEVERE: *~*~*~ Channel ManagedChannelImpl{logId=1, target=localhost:7001} was not shutdown properly!!! ~*~*~*
Make sure to call shutdown()/shutdownNow() and wait until awaitTermination() returns true.
java.lang.RuntimeException: ManagedChannel allocation site
at io.grpc.internal.ManagedChannelOrphanWrapper$ManagedChannelReference.<init>(ManagedChannelOrphanWrapper.java:93)
at io.grpc.internal.ManagedChannelOrphanWrapper.<init>(ManagedChannelOrphanWrapper.java:53)
at io.grpc.internal.ManagedChannelOrphanWrapper.<init>(ManagedChannelOrphanWrapper.java:44)
at io.grpc.internal.ManagedChannelImplBuilder.build(ManagedChannelImplBuilder.java:630)
at io.grpc.internal.AbstractManagedChannelImplBuilder.build(AbstractManagedChannelImplBuilder.java:297)
at maestro.drivers.AndroidDriver.<init>(AndroidDriver.kt:55)
at maestro.Maestro$Companion.android(Maestro.kt:297)
at maestro.Maestro$Companion.android$default(Maestro.kt:296)
at maestro.cli.util.MaestroFactory.createAndroid(MaestroFactory.kt:54)
at maestro.cli.util.MaestroFactory.autoDetectPlatform(MaestroFactory.kt:63)
at maestro.cli.util.MaestroFactory.createMaestro(MaestroFactory.kt:33)
at maestro.cli.command.PrintHierarchyCommand.run(PrintHierarchyCommand.kt:36)
at picocli.CommandLine.executeUserObject(CommandLine.java:1919)
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 picocli.CommandLine.execute(CommandLine.java:2058)
at maestro.cli.AppKt.main(App.kt:74)
Hello everyone, is there a way to tap on a compose component with
Modifier.testTag("email_test_id")
- tapOn:
optional: false
id: "email_test_id"
Background
Sometimes we need to manipulate some other services that we cannot do via the apps UI, it would be useful if we could call some of our own external functions.
Example
In order to log in to my account, I need to enter a pin code sent via text.
I can retrieve this pincode via a /pin
endpoint.
By running his function and storing the variable returned, I can continue with my tests
yaml example:
- launchApp
- tapOn:
id: "LoginButton"
- inputText: "+1234567890"
- tapOn:
id: "Next"
- function: loginPin()
output: { LOGIN_PIN }
- inputText: ${{ LOGIN_PIN }}
Is this in any projected roadmap at all?
Hi there! I have a few questions:
Thank you!
I was trying to make a test to verify a snackbar appears. But the snackbar seems to dissappear (long delay) before Maestro can detect it. I am basically asserting visibility on the snackbar text.
Am I doing something wrong?
The hierarchy
command seems like such a great improvement compared to endless nesting you have to scroll through in Appium's inspector tree view! However, it seems to only return text
and bounds
attributes for the found views at the moment but not the id
, for instance.
Are more attributes output support is planned in future? Thanks!
We've been trying maestro intertnally and it's great btw!
Some of our tests require long press actions but I don't think that's currently supported. Is it something we missed in the documentation?
Or if indeed not supported, any plans for it?
I can only see getting started steps for mac and Linux.
Does maestro currently support windows?
If not do you have a timeline for when we could expect to have windows support?
Something like:
- stopApp
- stopApp:
appId: {package name or bundle id}
I want to clear the text field and input a new value.
Double tap "emulating" for text selection does not work because it has a delay
- tapOn: "http.*"
- tapOn: "http.*"
Flow:
appId: com.delivery.boy.fl
---
- launchApp
- tapOn:
id: ".*button_menu"
- tapOn: "Server Address"
# want to select text and replace it
- tapOn: "http.*"
- tapOn: "http.*"
- inputText: "http://url:80/"
# want to select text and replace it
- tapOn: "ok"
- back
- back
- tapOn: "Login"
- inputText: "p1"
- tapOn: "Password"
- inputText: "0000"
- tapOn:
id: ".*button_login"
How can i do this? Thanks in advance for your reply.
Hello,
I have been trying maestro for a PoC in my company cause the project it seems promising (congratulations). But it seems the project is in an early stage due to the lack o functionality(timeout configuration, grab elements by data-testid(or other attributes), scroll to a specific element, dynamic content etc.
I am interested in seeing how the tool evolves, is there a public roadmap?
Thanks in advance 😄
There is some confusion as for which fields to expect in maestro hierarchy
output. I.e. clickable
attribute is set to null
when it is missing but resource-id
is just missing from the output entirely.
Currently, Maestro only works over the network (or on a local emulator) and does not support USB-connected devices due to a limitation in dadb
It seems maestro does not support tap on flutter elements using key. This will be helpful to automate app build in flutter - similar to id/text, support for key for flutter element will help.
Looking at the documentation, I understand that there is a way to explicitly connect to a specific physical Android device over WiFi pairing, whereas in case with emulators Maestro is expected to always automatically connect to any emulator that is currently running.
That is unfortunately does not work for me and I'm not entirely sure where to look for troubleshooting steps 🤔
When I execute adb devices
I get the following output, which is what I expect - got one single Android emulator currently running on my machine:
List of devices attached
emulator-5554 device`
However, when I try to obtain the hierarchy or execute a flow (e.g. maestro -p android hierarchy
), I get the following error
java.lang.IllegalStateException: No android devices found.
at maestro.cli.util.MaestroFactory.createAndroid(MaestroFactory.kt:51)
at maestro.cli.util.MaestroFactory.createMaestro(MaestroFactory.kt:35)
at maestro.cli.command.PrintHierarchyCommand.run(PrintHierarchyCommand.kt:36)
at picocli.CommandLine.executeUserObject(CommandLine.java:1919)
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 picocli.CommandLine.execute(CommandLine.java:2058)
at maestro.cli.AppKt.main(App.kt:74)
What would you suggest to try to make it work? Are there perhaps any troubleshooting steps that could be added to the documentation for cases like this?
How I would like to use Maestro:
Developers can write tests with the Maestro CLI locally and add them to a folder in our app repository.
For running them on the CI, I would use the programmatic approach and create a small script to get all files from this folder and run them one by one with the programmatic approach.
Why? Our CI system runs on Linux, so I can not install the Maestro CLI with brew.
As stated in the screenshot below, instead of writing [email protected]
, the driver does not write the @ symbol but adds the quotes instead
Recording:
https://youtu.be/smpECXx0B1Y?t=524
maestro hierarchy
times out if you're running maestro -c test
in another window. This is actually a very common use case while iterating on a flow. We should support running both simulataneously.
I've tried to add Maestro to my project with this PR and after running the tests on GitHub Actions, I received the following error:
java.util.concurrent.TimeoutException: Maestro Android driver did not start up in time
at maestro.drivers.AndroidDriver.awaitLaunch(AndroidDriver.kt:104)
at maestro.drivers.AndroidDriver.open(AndroidDriver.kt:78)
at maestro.Maestro$Companion.android(Maestro.kt:305)
at maestro.Maestro$Companion.android$default(Maestro.kt:303)
at maestro.cli.util.MaestroFactory.createAndroid(MaestroFactory.kt:54)
at maestro.cli.util.MaestroFactory.createMaestro(MaestroFactory.kt:35)
at maestro.cli.command.TestCommand.call(TestCommand.kt:58)
at maestro.cli.command.TestCommand.call(TestCommand.kt:30)
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:2[159](https://github.com/AdamMc331/TOA/runs/8240575616?check_suite_focus=true#step:5:163))
at picocli.CommandLine.execute(CommandLine.java:2058)
at maestro.cli.AppKt.main(App.kt:74)
Additional notes:
Here is my action workflow setup:
- name: Run Tests
uses: reactivecircus/android-emulator-runner@v2
with:
api-level: 29
script: |
maestro --platform android test maestro_tests/login.yaml
maestro --platform android test maestro_tests/create_task.yaml
maestro --platform android test maestro_tests/mark_task_as_done.yaml
maestro --platform android test maestro_tests/undo_mark_task_as_done.yaml
The maestro commands should run as soon as the emulator is up and running. I noticed that my APK was not yet installed, so I am trying this again with that step first, but I don't think they're related, as I would have expected some package not found error & not a driver timeout.
Would be nice to have "subflows" wich can be written without an appId
or launchApp
command and they can be called from other flows.
Our use case: When we want to test our checkout flow the user needs to enter the billing details (name, phone number etc.) after this the user can select a payment method. Of course, we want to test the checkout flow with different payment methods but currently, we need to do a lot of copy and paste because of the billing details screen which is error-prone and annoying ;)
Today, the constructor parameter is unused:
maestro/maestro-client/src/main/java/maestro/Errors.kt
Lines 26 to 29 in b367a2c
Is there any command planned to take screenshots?
This would be very handy to document changes between different versions of an app.
When integrating Maestro in a CI, it could be handly to run a set of flows in one go
The provided examples only mention iOS and Android. Given that React native compiles to native components, it should work in theory. Do you have any guidance for React Native apps?
Would be nice to have a command to scroll to a specific view in the list.
E.g.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.