-
Notifications
You must be signed in to change notification settings - Fork 276
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Feature Request] Add support for flutter element keys #1424
Comments
After some research this is what I found: When running a flutter app, there is a way to create and expose the Dart VM Service, which is a JSON RPC web socket. import 'package:flutter_driver/driver_extension.dart';
void main() {
enableFlutterDriverExtension(); // This command
runApp(...);
} With this code above, when the app is started in debug modes, it prints on the stdout the WS url that we should connect. In the example bellow An Observatory debugger and profiler on <device-name> is available at: http://127.0.0.1:58377/uwsLVMKvYvc=/ Thought this service, we can run commands in the VM service, such as tap, getText, longPress, ... Those commands accepts selectors to find the element that the command should perform the action. I've create a repository with a example on how it works: https://github.com/eduardo-pellenz/flutter-vm-service-test |
Seria realmente excelente, também sinto falta |
Also discussed in #128. |
Hey guys, this feature would be very valuable for us, and it's the main pain point about using Maestro on a flutter based app and having good testability in place, any clues on how this could be prioritized? |
Hi, I'm curious to hear what you think about an alternative approach to this problem. I suggest to add a new property to the Semantics widget (and to SemanticsProperties) called In your Flutter UI code, you'd use Semantics(
identifier: 'signin-button',
child: ElevatedButton(
onPressed: () { /* ... */ },
child: const Text('Sign in'),
),
) could be interacted with using - tapOn:
id: 'signin-button' Here's a bit larger example: DetailsTest appId: com.example.example
---
- tapOn:
id: some-switch
- assertVisible:
id: some-switch
enabled: true
- tapOn:
id: some-button
- assertVisible:
id: some-button-tapped
- assertVisible:
id: some-text App import 'package:flutter/material.dart';
void main() {
runApp(const ExampleApp());
}
class ExampleApp extends StatelessWidget {
const ExampleApp({super.key});
@override
Widget build(BuildContext context) {
return const MaterialApp(
home: Scaffold(
body: ExampleScreen(),
),
);
}
}
class ExampleScreen extends StatefulWidget {
const ExampleScreen({super.key});
@override
State<ExampleScreen> createState() => _ExampleScreenState();
}
class _ExampleScreenState extends State<ExampleScreen> {
bool switchValue = true;
@override
Widget build(BuildContext context) {
return Center(
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: [
const Spacer(),
const Text('Demo of Semantics.identifier'),
const Spacer(),
Semantics(
identifier: 'some-switch',
label: 'Toggle exposing accessibility identifier to semantics',
child: Switch(
value: switchValue,
onChanged: (newValue) {
setState(() {
switchValue = newValue;
});
},
),
),
Semantics(
identifier: 'some-button',
child: ElevatedButton(
onPressed: () {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Semantics(
identifier: 'some-button-tapped',
child: const Text('Tapped button'),
),
),
);
},
child: const Text('Toggle'),
),
),
Semantics(
identifier: 'some-text',
child: const Text('Some text'),
),
Semantics(
identifier: 'some-blue-container',
label: 'A blue container',
child: Container(
width: 100,
height: 100,
color: Colors.blue,
),
),
const Spacer(),
],
),
);
}
} and a demo: demo.movand since it's all native semantics, it also works seamlessly in Studio:
Why not expose keys directly to Maestro?Exposing Flutter's keys to Maestro is a complex task. Using And yet another reason not to do it: if you look Flutter API docs for the Key class and Widget.key field, you'll see it says that a key is for "controlling how one widget replaces another (e.g. in a list)". The key's purpose is not to uniquely identify a widget for UI testing. That's what semantics properties like Android's I think adding |
@eduardo-pellenz @tiagodread and any others following this thread: we would really appreciate your thoughts on this as quite some work has gone into this by @bartekpacia to come up with a good solution for Flutter in Maestro, so please let us know what you think 🙂 |
hey @axelniklasson and @bartekpacia, it's actually a great ideia and would work perfectly for our use case! If you need help with the flutter PRs, just let me know! |
Hey @bartekpacia, @axelniklasson, great work, I agree 100%. We started using Semantics label for it, which is better than coordinates on screen (allowing us run on multiple screen resolutions), however, it's not the ideal approach thinking from a11y perspective itself, we ended up thinking more about: how to use this property to serve for both purposes (a11y/UI testing). Having |
Hi, I've got an exciting update for you all: we contributed this feature to Flutter and it's available on the latest beta version (3.19.0-0.1.pre, released on 10th January). This means it will become available in the new stable version sometime in February. Thank you for the feedback! If you want to start using it now:
The documentation update is underway. |
Hey folks, closing this issue out since this support has made it's way into Flutter now and you can use it today following these instructions. Huge kudos to @bartekpacia for spearheading this effort from our side and getting this merged 🎉 Hope y'all like it! |
This issue has been automatically locked since there has not been any recent activity after it was closed. If you are still experiencing a similar problem, please file a new issue. Make sure to follow the template and provide all the information necessary to reproduce the issue. |
Is your feature request related to a problem? Please describe.
It would be really nice to be able to query elements using Flutters
ValueKey
instead of having to rely on Semantics.Describe the solution you'd like
I would like to be able to query elements using those keys.
Describe alternatives you've considered
I have tried to configure
Semantics
for a page of our app, but it's really time consuming and we need to care about translations too. And also, we don't want to mess with the accessibility tree of our app right now.Additional context
I have seen that other tools support this functionality, so it's possible to implement. I just don't know how complex that would be.
I'm going to do a small research on this feature. I'll send in this issue more information later.
The text was updated successfully, but these errors were encountered: