Closed hex0cter closed 2 years ago
@hex0cter Below link may help I guess flutter community has not yet exposed finders to find elements and perform action in the basis of index. Work around to assign different key.
Thanks for confirming this @shibupanda. One more question, is there any nice way to check the number of matched elements without getting the exception?
In the example above, before calling element.text
, we don't know if the element exists at all, or if more than one elements are matched. In either case, when I call element.text
, I only get exceptions.
@hex0cter I'm also looking for a solution to the same issue.
Facing same issue, while identifying dynamic list view widget with same type.
Perhaps currently this is a flutter (or flutter_driver by Flutter team) limitation.
+1, it is annoying not having option to get list of elements. I also received "Bad state: Too many elements" recently and was looking for possible solutions.
There are Finders that could return multiple items but it is very hard (imo) to interact with if exposed. _fluttertest has such one abstract class - Finder.
Finder class
Searches a widget tree and returns nodes that match a particular pattern.
allCandidates → Iterable<Element> Returns all the Elements that will be considered by this finder.
Well, as I already spent time on that, here are some obvious things:
Some traces how client <->driver_extension commands work:
Additionally command handler on extension side: https://github.com/flutter/flutter/blob/master/packages/flutter_driver/lib/src/extension/extension.dart#L367
It is not clear how search is done under hood as we can only log client<->driver_extension interaction, but not driver_extension<->app. And here some examples of outgoing/incoming payloads:
[debug] [FlutterDriver] >>> {"command":"waitFor","finderType":"ByText","text":"Skip for now","timeout":10000}
[debug] [FlutterDriver] <<< {"isError":false,"response":{},"type":"_extensionType","method":"ext.flutter.driver"} | previous command waitFor
[debug] [FlutterDriver] >>> {"command":"get_text","finderType":"ByText","text":"Skip for now"}
[debug] [FlutterDriver] <<< {"isError":false,"response":{"text":"Skip for now"},"type":"_extensionType","method":"ext.flutter.driver"} | previous command get_text
[debug] [FlutterDriver] >>> {"command":"tap","finderType":"ByText","text":"Skip for now"}
[debug] [FlutterDriver] <<< {"isError":false,"response":{},"type":"_extensionType","method":"ext.flutter.driver"} | previous command tap
@ehabibov Tell me something, without telling me something. ;)
Anyways, you can approach this problem by using descendant
with firstMatchOnly
:
SerializableFinder findFirst({required SerializableFinder of}) =>
find.descendant(
of: find.byType("MaterialApp"), matching: of, firstMatchOnly: true);
With the finder from appium-flutter-driver, sometimes I got more than one element returned. Then if I do another API call, it returns
Bad state: Too many elements
. For example, in the code below, if there are more than one widgets with the same text:the last line will raise:
If I call
element[0].text
, I will get(<class 'TypeError'>, TypeError("'FlutterElement' object is not subscriptable"), <traceback object at 0x10d001600>)
.So my question is, how can I get one of the elements if the finder matched several widgets? Any help is appreciated. 🙏