appium / appium-flutter-driver

Appium Flutter Driver is a test automation tool for Flutter apps on multiple platforms/OSes. Appium Flutter Driver is part of the Appium mobile test automation tool maintained by community
MIT License
469 stars 183 forks source link

driver.elementSendKeys() doesn't work properly in some cases #469

Open tiagodread opened 1 year ago

tiagodread commented 1 year ago

Hello, thanks for maintaining this webdriver!

I noticed that await driver.elementSendKeys(emailField, "example@example.com") doesn't work in some cases, I've built a sample app to test the driver.

I've tried:

await driver.elementSendKeys(element, text) //<--- doesn't work

//OR

await driver.elementClick(element) 
await driver.elementSendKeys(element, text) //<--- doesn't work as well
Sample App code ```dart import 'package:flutter/material.dart'; import 'package:flutter_driver/driver_extension.dart'; void main() { enableFlutterDriverExtension(); runApp(const MyApp()); } class MyApp extends StatelessWidget { const MyApp({super.key}); @override Widget build(BuildContext context) { return MaterialApp( title: 'Test App', theme: ThemeData( primarySwatch: Colors.blue, ), home: const LoginPage(), ); } } class LoginPage extends StatefulWidget { const LoginPage({super.key}); @override _LoginPageState createState() => _LoginPageState(); } class _LoginPageState extends State { final TextEditingController _usernameController = TextEditingController(); final TextEditingController _passwordController = TextEditingController(); String _loginMessage = ''; @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: const Text('Login'), ), body: Center( child: Padding( padding: const EdgeInsets.all(16.0), child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ TextFormField( key: const Key('login-email'), controller: _usernameController, decoration: const InputDecoration( hintText: 'Enter your email', ), ), const SizedBox(height: 16.0), TextFormField( key: const Key('login-password'), controller: _passwordController, decoration: const InputDecoration( hintText: 'Enter your password', ), obscureText: true, ), SizedBox(height: 16.0), ElevatedButton( key: const Key('login-access'), onPressed: () { final username = _usernameController.text; final password = _passwordController.text; if (username == 'example@example.com' && password == 'Mudar@123') { setState(() { _loginMessage = 'Login success'; }); } else { setState(() { _loginMessage = 'Login failed'; }); } }, child: const Text('Login'), ), const SizedBox(height: 16.0), Text(key: const Key('snack-bar-ok'), _loginMessage), ], ), ), ), ); } } ```
Test code ```ts import { byValueKey } from 'appium-flutter-finder' describe('My Login application', () => { it('should login with valid credentials', async () => { const emailField = byValueKey('login-email') const passField = byValueKey('login-password') const loginButton = byValueKey('login-access') const loginSuccessMessage = byValueKey('snack-bar-ok') await driver.elementSendKeys(emailField, 'example@example.com') await driver.elementSendKeys(passField, 'Mudar@123') await driver.elementClick(loginButton) expect(await driver.getElementText(loginSuccessMessage)).toBe('Login success') }) }) ```

However, using a more complex app (I cannot share here the code since due to security), the command does nothing!

looking the logs it seems to sendKeys, but visually on the emulator nothing happened


> wdio run ./config/wdio-av.conf.ts --spec ./test/specs/registration.e2e.ts

Execution of 1 workers started at 2023-05-19T18:47:45.673Z

2023-05-19T18:47:45.688Z INFO @wdio/cli:launcher: Run onPrepare hook
2023-05-19T18:47:45.689Z INFO @wdio/cli:launcher: Run onWorkerStart hook
2023-05-19T18:47:45.689Z INFO @wdio/local-runner: Start worker 0-0 with arg: run,./config/wdio-av.conf.ts,--spec,./test/specs/registration.e2e.ts
2023-05-19T18:47:45.694Z DEBUG @wdio/local-runner: Send command run to worker with cid "0-0"
[0-0] 2023-05-19T18:47:46.435Z INFO @wdio/local-runner: Run worker command: run
[0-0] 2023-05-19T18:47:46.495Z DEBUG @wdio/runner: init remote session
[0-0] RUNNING in Android - file:///test/specs/registration.e2e.ts
[0-0] 2023-05-19T18:47:46.608Z DEBUG @wdio/runner: init remote session
[0-0] 2023-05-19T18:47:46.609Z INFO webdriver: Initiate new session using the WebDriver protocol
[0-0] 2023-05-19T18:47:46.685Z INFO webdriver: [POST] http://127.0.0.1:4723/session
[0-0] 2023-05-19T18:47:46.685Z INFO webdriver: DATA {
[0-0]   capabilities: {
[0-0]     alwaysMatch: {
[0-0]       platformName: 'Android',
[0-0]       'appium:deviceName': 'Pixel 2',
[0-0]       'appium:platformVersion': '11.0',
[0-0]       'appium:automationName': 'flutter',
[0-0]       'appium:app': '/Users/tiagogoes/tiago/mobile-automation-poc/wdio-appium/apps/app-company.apk'
[0-0]     },
[0-0]     firstMatch: [ {} ]
[0-0]   },
[0-0]   desiredCapabilities: {
[0-0]     platformName: 'Android',
[0-0]     'appium:deviceName': 'Pixel 2',
[0-0]     'appium:platformVersion': '11.0',
[0-0]     'appium:automationName': 'flutter',
[0-0]     'appium:app': '/Users/tiagogoes/tiago/mobile-automation-poc/wdio-appium/apps/app-company.apk'
[0-0]   }
[0-0] }
[0-0] 2023-05-19T18:48:12.732Z INFO webdriver: COMMAND elementClick("eyJmaW5kZXJUeXBlIjoiQnlWYWx1ZUtleSIsImtleVZhbHVlU3RyaW5nIjoidW5sb2dnZWQtbmV3LWNsaWVudC1jcmVhdGUtYWNjb3VudC1idG4iLCJrZXlWYWx1ZVR5cGUiOiJTdHJpbmcifQ")
[0-0] 2023-05-19T18:48:12.735Z INFO webdriver: [POST] http://127.0.0.1:4723/session/7b7740fd-5085-4d8a-a9eb-eba22ca131ad/element/eyJmaW5kZXJUeXBlIjoiQnlWYWx1ZUtleSIsImtleVZhbHVlU3RyaW5nIjoidW5sb2dnZWQtbmV3LWNsaWVudC1jcmVhdGUtYWNjb3VudC1idG4iLCJrZXlWYWx1ZVR5cGUiOiJTdHJpbmcifQ/click
[0-0] 2023-05-19T18:48:12.840Z INFO webdriver: RESULT {}
[0-0] 2023-05-19T18:48:12.840Z INFO webdriver: COMMAND elementClick("eyJmaW5kZXJUeXBlIjoiQnlWYWx1ZUtleSIsImtleVZhbHVlU3RyaW5nIjoiZnVsbC1uYW1lLWZpZWxkIiwia2V5VmFsdWVUeXBlIjoiU3RyaW5nIn0")
[0-0] 2023-05-19T18:48:12.841Z INFO webdriver: [POST] http://127.0.0.1:4723/session/7b7740fd-5085-4d8a-a9eb-eba22ca131ad/element/eyJmaW5kZXJUeXBlIjoiQnlWYWx1ZUtleSIsImtleVZhbHVlU3RyaW5nIjoiZnVsbC1uYW1lLWZpZWxkIiwia2V5VmFsdWVUeXBlIjoiU3RyaW5nIn0/click
[0-0] 2023-05-19T18:48:16.338Z INFO webdriver: RESULT {}
[0-0] 2023-05-19T18:48:16.340Z INFO webdriver: COMMAND elementSendKeys("eyJmaW5kZXJUeXBlIjoiQnlWYWx1ZUtleSIsImtleVZhbHVlU3RyaW5nIjoiZnVsbC1uYW1lLWZpZWxkIiwia2V5VmFsdWVUeXBlIjoiU3RyaW5nIn0", "Tiago Goes da Silva")
[0-0] 2023-05-19T18:48:16.340Z INFO webdriver: [POST] http://127.0.0.1:4723/session/7b7740fd-5085-4d8a-a9eb-eba22ca131ad/element/eyJmaW5kZXJUeXBlIjoiQnlWYWx1ZUtleSIsImtleVZhbHVlU3RyaW5nIjoiZnVsbC1uYW1lLWZpZWxkIiwia2V5VmFsdWVUeXBlIjoiU3RyaW5nIn0/value
[0-0] 2023-05-19T18:48:16.340Z INFO webdriver: DATA { text: 'Tiago Goes da Silva' }
[0-0] 2023-05-19T18:48:18.461Z INFO webdriver: RESULT null
[0-0] 2023-05-19T18:48:18.467Z INFO webdriver: COMMAND deleteSession()
[0-0] 2023-05-19T18:48:18.467Z INFO webdriver: [DELETE] http://127.0.0.1:4723/session/7b7740fd-5085-4d8a-a9eb-eba22ca131ad
[0-0] 2023-05-19T18:48:18.830Z INFO webdriver: RESULT null
2023-05-19T18:48:18.943Z DEBUG @wdio/local-runner: Runner 0-0 finished with exit code 0
[0-0] PASSED in Android - file:///test/specs/registration.e2e.ts
2023-05-19T18:48:18.944Z INFO @wdio/cli:launcher: Run onWorkerEnd hook
2023-05-19T18:48:18.944Z INFO @wdio/cli:launcher: Run onComplete hook

 "spec" Reporter:
------------------------------------------------------------------
[undefined Android #0-0] Running: undefined on Android
[undefined Android #0-0] Session ID: 7b7740fd-5085-4d8a-a9eb-eba22ca131ad
[undefined Android #0-0]
[undefined Android #0-0] » /test/specs/registration.e2e.ts
[undefined Android #0-0] Registration
[undefined Android #0-0]    ✓ should register successfully
[undefined Android #0-0]
[undefined Android #0-0] 1 passing (16.1s)

Logs from server

[HTTP] --> POST /session/7b7740fd-5085-4d8a-a9eb-eba22ca131ad/element/eyJmaW5kZXJUeXBlIjoiQnlWYWx1ZUtleSIsImtleVZhbHVlU3RyaW5nIjoidW5sb2dnZWQtbmV3LWNsaWVudC1jcmVhdGUtYWNjb3VudC1idG4iLCJrZXlWYWx1ZVR5cGUiOiJTdHJpbmcifQ/click
[HTTP] {}
[debug] [FlutterDriver@02dd (7b7740fd)] Calling AppiumDriver.click() with args: ["eyJmaW5kZXJUeXBlIjoiQnlWYWx1ZUtleSIsImtleVZhbHVlU3RyaW5nIjoidW5sb2dnZWQtbmV3LWNsaWVudC1jcmVhdGUtYWNjb3VudC1idG4iLCJrZXlWYWx1ZVR5cGUiOiJTdHJpbmcifQ","7b7740fd-5085-4d8a-a9eb-eba22ca131ad"]
[debug] [FlutterDriver] Executing Flutter driver command 'click'
[debug] [FlutterDriver] >>> {"command":"tap","finderType":"ByValueKey","keyValueString":"unlogged-new-client-create-account-btn","keyValueType":"String"}
[debug] [FlutterDriver] <<< {"isError":false,"response":{},"type":"_extensionType","method":"ext.flutter.driver"} | previous command tap
[debug] [FlutterDriver@02dd (7b7740fd)] Responding to client with driver.click() result: {}
[HTTP] <-- POST /session/7b7740fd-5085-4d8a-a9eb-eba22ca131ad/element/eyJmaW5kZXJUeXBlIjoiQnlWYWx1ZUtleSIsImtleVZhbHVlU3RyaW5nIjoidW5sb2dnZWQtbmV3LWNsaWVudC1jcmVhdGUtYWNjb3VudC1idG4iLCJrZXlWYWx1ZVR5cGUiOiJTdHJpbmcifQ/click 200 95 ms - 12
[HTTP]
[HTTP] --> POST /session/7b7740fd-5085-4d8a-a9eb-eba22ca131ad/element/eyJmaW5kZXJUeXBlIjoiQnlWYWx1ZUtleSIsImtleVZhbHVlU3RyaW5nIjoiZnVsbC1uYW1lLWZpZWxkIiwia2V5VmFsdWVUeXBlIjoiU3RyaW5nIn0/click
[HTTP] {}
[debug] [FlutterDriver@02dd (7b7740fd)] Calling AppiumDriver.click() with args: ["eyJmaW5kZXJUeXBlIjoiQnlWYWx1ZUtleSIsImtleVZhbHVlU3RyaW5nIjoiZnVsbC1uYW1lLWZpZWxkIiwia2V5VmFsdWVUeXBlIjoiU3RyaW5nIn0","7b7740fd-5085-4d8a-a9eb-eba22ca131ad"]
[debug] [FlutterDriver] Executing Flutter driver command 'click'
[debug] [FlutterDriver] >>> {"command":"tap","finderType":"ByValueKey","keyValueString":"full-name-field","keyValueType":"String"}
[debug] [FlutterDriver] <<< {"isError":false,"response":{},"type":"_extensionType","method":"ext.flutter.driver"} | previous command tap
[debug] [FlutterDriver@02dd (7b7740fd)] Responding to client with driver.click() result: {}
[HTTP] <-- POST /session/7b7740fd-5085-4d8a-a9eb-eba22ca131ad/element/eyJmaW5kZXJUeXBlIjoiQnlWYWx1ZUtleSIsImtleVZhbHVlU3RyaW5nIjoiZnVsbC1uYW1lLWZpZWxkIiwia2V5VmFsdWVUeXBlIjoiU3RyaW5nIn0/click 200 3365 ms - 12
[HTTP]
[HTTP] --> POST /session/7b7740fd-5085-4d8a-a9eb-eba22ca131ad/element/eyJmaW5kZXJUeXBlIjoiQnlWYWx1ZUtleSIsImtleVZhbHVlU3RyaW5nIjoiZnVsbC1uYW1lLWZpZWxkIiwia2V5VmFsdWVUeXBlIjoiU3RyaW5nIn0/value
[HTTP] {"text":"Tiago Goes da Silva"}
[debug] [FlutterDriver@02dd (7b7740fd)] Calling AppiumDriver.setValue() with args: ["Tiago Goes da Silva","eyJmaW5kZXJUeXBlIjoiQnlWYWx1ZUtleSIsImtleVZhbHVlU3RyaW5nIjoiZnVsbC1uYW1lLWZpZWxkIiwia2V5VmFsdWVUeXBlIjoiU3RyaW5nIn0","7b7740fd-5085-4d8a-a9eb-eba22ca131ad"]
[debug] [FlutterDriver] Executing Flutter driver command 'setValue'
[debug] [FlutterDriver] >>> {"command":"tap","finderType":"ByValueKey","keyValueString":"full-name-field","keyValueType":"String"}
[debug] [FlutterDriver] <<< {"isError":false,"response":{},"type":"_extensionType","method":"ext.flutter.driver"} | previous command tap
[debug] [FlutterDriver@02dd (7b7740fd)] Responding to client with driver.setValue() result: null
[HTTP] <-- POST /session/7b7740fd-5085-4d8a-a9eb-eba22ca131ad/element/eyJmaW5kZXJUeXBlIjoiQnlWYWx1ZUtleSIsImtleVZhbHVlU3RyaW5nIjoiZnVsbC1uYW1lLWZpZWxkIiwia2V5VmFsdWVUeXBlIjoiU3RyaW5nIn0/value 200 2117 ms - 14
[HTTP]
[HTTP] --> DELETE /session/7b7740fd-5085-4d8a-a9eb-eba22ca131ad
[HTTP] {}
[debug] [FlutterDriver@02dd (7b7740fd)] Calling AppiumDriver.deleteSession() with args: ["7b7740fd-5085-4d8a-a9eb-eba22ca131ad"]
[debug] [AppiumDriver@9039] Event 'quitSessionRequested' logged at 1684522098470 (15:48:18 GMT-0300 (Brasilia Standard Time))
[AppiumDriver@9039] Removing session 7b7740fd-5085-4d8a-a9eb-eba22ca131ad from our master session list
[debug] [FlutterDriver] Deleting Flutter Driver session

Any suggestions other than switching the context all the time to NATIVE_APP to deal with inputs (EditText) via xpath??

tiagodread commented 1 year ago

The approach:

[0-0] 2023-05-19T19:09:05.527Z INFO webdriver: [POST] http://127.0.0.1:4723/session/f4d4905a-00ad-4268-bddb-e5fa3a934d85/element/eyJmaW5kZXJUeXBlIjoiQnlWYWx1ZUtleSIsImtleVZhbHVlU3RyaW5nIjoidW5sb2dnZWQtbmV3LWNsaWVudC1jcmVhdGUtYWNjb3VudC1idG4iLCJrZXlWYWx1ZVR5cGUiOiJTdHJpbmcifQ/click
[0-0] 2023-05-19T19:09:05.614Z INFO webdriver: RESULT {}
[0-0] 2023-05-19T19:09:05.614Z INFO webdriver: COMMAND elementClick("eyJmaW5kZXJUeXBlIjoiQnlWYWx1ZUtleSIsImtleVZhbHVlU3RyaW5nIjoiZnVsbC1uYW1lLWZpZWxkIiwia2V5VmFsdWVUeXBlIjoiU3RyaW5nIn0")
[0-0] 2023-05-19T19:09:05.615Z INFO webdriver: [POST] http://127.0.0.1:4723/session/f4d4905a-00ad-4268-bddb-e5fa3a934d85/element/eyJmaW5kZXJUeXBlIjoiQnlWYWx1ZUtleSIsImtleVZhbHVlU3RyaW5nIjoiZnVsbC1uYW1lLWZpZWxkIiwia2V5VmFsdWVUeXBlIjoiU3RyaW5nIn0/click
[0-0] 2023-05-19T19:09:09.049Z INFO webdriver: RESULT {}
[0-0] 2023-05-19T19:09:09.050Z INFO webdriver: COMMAND executeScript("flutter:enterText", <object>)
[0-0] 2023-05-19T19:09:09.051Z INFO webdriver: [POST] http://127.0.0.1:4723/session/f4d4905a-00ad-4268-bddb-e5fa3a934d85/execute/sync
[0-0] 2023-05-19T19:09:09.051Z INFO webdriver: DATA { script: 'flutter:enterText', args: [ 'Tiago Goes da Silva' ] }
[0-0] 2023-05-19T19:09:09.071Z INFO webdriver: RESULT {
[0-0]   isError: false,
[0-0]   response: {},
[0-0]   type: '_extensionType',
[0-0]   method: 'ext.flutter.driver'
[0-0] }

Also doesn't work on emulator, even looking like happened via logs...