mobile-dev-inc / maestro

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

`tapOn` text YES/NO gets translated into true/false #1575

Open fantpmas opened 11 months ago

fantpmas commented 11 months ago

Describe the bug Tapping on YES or NO labels does not work.

To Reproduce

  1. Have dialogue with YES or NO labels
  2. -tapOn: YES

Expected behavior YES option is tapped.

Screenshots Screenshot 2023-11-06 at 14 39 23 Maestro Studio shows success, but button is not tapped.

Environment information (please complete the following information):

Additional context This does work:


tapOn:
  text: ^YES$
meatnordrink commented 11 months ago

At least myself and one other person have encountered this bug, according to the Maestro Slack.

felipevolpone commented 11 months ago

@fantpmas can you provide the screen view hierarchy? Run maestro hierarchy and paste the output

fantpmas commented 10 months ago

Here you go: hierarchy.txt

felipevolpone commented 8 months ago

Does the same happen when running with maestro test testing.yaml ?

fantpmas commented 8 months ago

Yes, the issue is pretty clear if you look at the logs: Screenshot 2024-02-22 at 15 48 00

This works fine by the way:

- tapOn:
    text: 'YES'
felipevolpone commented 8 months ago

Oh if it works with quotes it seems a bug in the process of converting the yaml to maestro object, I'd guess that it's converting YES to boolean instead of string

bartekpacia commented 3 months ago

Yeah, it's a problem with YAML[^1]. YES, yes are aliases for true. NO, no are aliases for false. This is working as intended.

I'm afraid there's not much we can do apart from updating the docs to encourage users to use double quotes.

Below is a repro:

Flutter app example code Paste into `main.dart` and `flutter run`. ```dart import 'package:flutter/material.dart'; class ExampleApp extends StatefulWidget { const ExampleApp({super.key}); @override State createState() => _ExampleAppState(); } class _ExampleAppState extends State { int count = 0; @override Widget build(BuildContext context) { return MaterialApp( home: Scaffold( appBar: AppBar(title: const Text('demo')), body: Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Text('Count $count'), const Text('YES/yes to increase, NO/no to decrease'), TextButton( onPressed: () { setState(() => count++); }, child: const Text('YES'), ), TextButton( onPressed: () { setState(() => count++); }, child: const Text('yes'), ), TextButton( onPressed: () { setState(() => count--); }, child: const Text('NO'), ), TextButton( onPressed: () { setState(() => count--); }, child: const Text('no'), ), ], ), ), ), ); } } ```
Successful flow example ```yaml appId: com.example.example --- - launchApp - tapOn: "YES" - tapOn: "yes" - assertVisible: Count 2 - tapOn: "NO" - tapOn: "no" - assertVisible: Count 0 ``` ``` Running on emulator-5554 ║ ║ > Flow ║ ║ ✅ Launch app "com.example.example" ║ ✅ Tap on "YES" ║ ✅ Tap on "yes" ║ ✅ Assert that "Count 2" is visible ║ ✅ Tap on "NO" ║ ✅ Tap on "no" ║ ✅ Assert that "Count 0" is visible ║ ```
Failing flow example ```yaml appId: com.example.example --- - launchApp - tapOn: YES - tapOn: yes - assertVisible: Count 2 - tapOn: NO - tapOn: no - assertVisible: Count 0 ``` ``` Running on emulator-5554 ║ ║ > Flow ║ ║ ✅ Launch app "com.example.example" ║ ❌ Tap on "true" ║ 🔲 Tap on "true" ║ 🔲 Assert that "Count 2" is visible ║ 🔲 Tap on "false" ║ 🔲 Tap on "false" ║ 🔲 Assert that "Count 0" is visible ║ ```

[^1]: A fun read: https://noyaml.com