Skip to content
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

Unable to set text in textfield #96

Open
rohitbhoite opened this issue Sep 16, 2024 · 20 comments
Open

Unable to set text in textfield #96

rohitbhoite opened this issue Sep 16, 2024 · 20 comments

Comments

@rohitbhoite
Copy link

rohitbhoite commented Sep 16, 2024

I am having below widget in one form and using [email protected] driver

TextField(
                  key: Key("editText"),
                  decoration: InputDecoration(
                    border: OutlineInputBorder(),
                    hintText: 'Enter a search term',
                  ),
                ),

I am trying to set the text using below code but its not working. I also tried using sendKeys method but its not working as well.

await browser.flutterByValueKey$("editText").addValue("a");

Got below error:

image

Have checked below code as well but somehow its not working
https://github.com/AppiumTestDistribution/appium-flutter-integration-driver/blob/main/test/specs/test.e2e.js

Logs

[0-0] 2024-09-16T12:55:22.079Z INFO webdriver: COMMAND elementClick("00000000-0000-0035-0000-006500000003")
[0-0] 2024-09-16T12:55:22.079Z INFO webdriver: [POST] http://127.0.0.1:4723/session/a8061f2f-407f-49e2-9d29-1d77ae7d499c/element/00000000-0000-0035-0000-006500000003/click
[0-0] 2024-09-16T12:55:22.153Z INFO webdriver: RESULT null
[0-0] 2024-09-16T12:55:22.153Z INFO webdriver: COMMAND flutterByValueKey$("<Screenshot[base64]>")
[0-0] 2024-09-16T12:55:22.153Z INFO webdriver: COMMAND flutterByValueKey("key", "<Screenshot[base64]>")
[0-0] 2024-09-16T12:55:22.153Z INFO webdriver: [POST] http://127.0.0.1:4723/session/a8061f2f-407f-49e2-9d29-1d77ae7d499c/element
[0-0] 2024-09-16T12:55:22.153Z INFO webdriver: DATA { using: 'key', value: 'editText' }
[0-0] 2024-09-16T12:55:22.471Z INFO webdriver: RESULT {
[0-0]   'element-6066-11e4-a52e-4f735466cecf': '3ad998dc-3ad9-98dc-3ad9-98dc3ad998dc',
[0-0]   ELEMENT: '3ad998dc-3ad9-98dc-3ad9-98dc3ad998dc'
[0-0] }
[0-0] 2024-09-16T12:55:22.472Z INFO webdriver: RESULT Element {
[0-0]   sessionId: 'a8061f2f-407f-49e2-9d29-1d77ae7d499c',
[0-0]   elementId: '3ad998dc-3ad9-98dc-3ad9-98dc3ad998dc',
[0-0]   ELEMENT: '3ad998dc-3ad9-98dc-3ad9-98dc3ad998dc',
[0-0]   selector: '',
[0-0]   parent: Browser {
[0-0]     sessionId: 'a8061f2f-407f-49e2-9d29-1d77ae7d499c',
[0-0]     capabilities: {
[0-0]       subcommand: 'server',
[0-0]       address: '0.0.0.0',
[0-0]       basePath: '/',
[0-0]       port: 4723,
[0-0]       extraArgs: [],
[0-0]       allowCors: false,
[0-0]       allowInsecure: [],
[0-0]       callbackPort: 4723,
[0-0]       debugLogSpacing: false,
[0-0]       denyInsecure: [],
[0-0]       keepAliveTimeout: 600,
[0-0]       localTimezone: false,
[0-0]       loglevel: 'debug',
[0-0]       logFormat: 'text',
[0-0]       logNoColors: false,
[0-0]       logTimestamp: false,
[0-0]       pluginsImportChunkSize: 7,
[0-0]       driversImportChunkSize: 3,
[0-0]       longStacktrace: false,
[0-0]       noPermsCheck: false,
[0-0]       relaxedSecurityEnabled: false,
[0-0]       sessionOverride: false,
[0-0]       strictCaps: false,
[0-0]       useDrivers: [],
[0-0]       usePlugins: [],
[0-0]       tmpDir: '/var/folders/sf/3f3dyp3n3fg0rbmxm_m51rvr0000gn/T',
[0-0]       browserName: '',
[0-0]       platformName: 'Android',
[0-0]       webSocketUrl: true,
[0-0]       app: '/Users/rohit_bhoite/mobile_ui/build/app/outputs/flutter-apk/app-dev-debug.apk',
[0-0]       deviceName: 'emulator-5554',
[0-0]       automationName: 'FlutterIntegration',
[0-0]       commandTimeout: 240,
[0-0]       newCommandTimeout: 240,
[0-0]       fastReset: true,
[0-0]       skipUninstall: true
[0-0]     },
[0-0]     addCommand: [Function (anonymous)],
[0-0]     overwriteCommand: [Function (anonymous)],
[0-0]     addLocatorStrategy: [Function (anonymous)]
[0-0]   },
[0-0]   emit: [Function: bound ],
[0-0]   isReactElement: false,
[0-0]   isShadowElement: false,
[0-0]   addCommand: [Function (anonymous)],
[0-0]   overwriteCommand: [Function (anonymous)]
[0-0] }
[0-0] Error in "1st AppiumFlutterIntegrationDriver test using appium latest.Flutter counter demo app"
Error: Malformed type for "text" parameter of command elementSendKeys
Expected: string
Actual: object

For more info see https://w3c.github.io/webdriver/#dfn-element-send-keys

    at Context.<anonymous> (/Users/rohit_bhoite/demo-js/webdriverio/appium-app/examples/appium-flutter-integration/test/specs/flutter.spec.ts:41:10)
[0-0] 2024-09-16T12:55:22.489Z INFO webdriver: COMMAND deleteSession()
[0-0] 2024-09-16T12:55:22.489Z INFO webdriver: [DELETE] http://127.0.0.1:4723/session/a8061f2f-407f-49e2-9d29-1d77ae7d499c
[0-0] 2024-09-16T12:55:22.957Z INFO webdriver: RESULT null
[0-0] FAILED in Android - file:///test/specs/flutter.spec.ts

Code:
appium_test.dart file

import 'package:appium_flutter_server/appium_flutter_server.dart';
import 'package:testint/main.dart';

void main() {
  initializeTest(app: const MyApp());
}

main.dart file

import 'package:flutter/material.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        // This is the theme of your application.
        //
        // TRY THIS: Try running your application with "flutter run". You'll see
        // the application has a purple toolbar. Then, without quitting the app,
        // try changing the seedColor in the colorScheme below to Colors.green
        // and then invoke "hot reload" (save your changes or press the "hot
        // reload" button in a Flutter-supported IDE, or press "r" if you used
        // the command line to start the app).
        //
        // Notice that the counter didn't reset back to zero; the application
        // state is not lost during the reload. To reset the state, use hot
        // restart instead.
        //
        // This works for code too, not just values: Most code changes can be
        // tested with just a hot reload.
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
        useMaterial3: true,
      ),
      home: const MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key, required this.title});

  // This widget is the home page of your application. It is stateful, meaning
  // that it has a State object (defined below) that contains fields that affect
  // how it looks.

  // This class is the configuration for the state. It holds the values (in this
  // case the title) provided by the parent (in this case the App widget) and
  // used by the build method of the State. Fields in a Widget subclass are
  // always marked "final".

  final String title;

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  int _counter = 0;
  bool _showProgress = false;
  void _incrementCounter() async {
    setState(() {
      _showProgress = true;
    });
    await Future.delayed(Duration(seconds: 2));
    setState(() {
      // This call to setState tells the Flutter framework that something has
      // changed in this State, which causes it to rerun the build method below
      // so that the display can reflect the updated values. If we changed
      // _counter without calling setState(), then the build method would not be
      // called again, and so nothing would appear to happen.
      _counter++;
      _showProgress = false;
    });
  }

  void _decrementCounter() async {
    setState(() {
      _showProgress = true;
    });
    await Future.delayed(Duration(seconds: 2));
    setState(() {
      // This call to setState tells the Flutter framework that something has
      // changed in this State, which causes it to rerun the build method below
      // so that the display can reflect the updated values. If we changed
      // _counter without calling setState(), then the build method would not be
      // called again, and so nothing would appear to happen.
      _counter--;
      _showProgress = false;
    });
  }

  @override
  Widget build(BuildContext context) {
    // This method is rerun every time setState is called, for instance as done
    // by the _incrementCounter method above.
    //
    // The Flutter framework has been optimized to make rerunning build methods
    // fast, so that you can just rebuild anything that needs updating rather
    // than having to individually change instances of widgets.
    return Scaffold(
      appBar: AppBar(
        // TRY THIS: Try changing the color here to a specific color (to
        // Colors.amber, perhaps?) and trigger a hot reload to see the AppBar
        // change color while the other colors stay the same.
        backgroundColor: Theme.of(context).colorScheme.inversePrimary,
        // Here we take the value from the MyHomePage object that was created by
        // the App.build method, and use it to set our appbar title.
        title: Text(widget.title),
      ),
      body: Center(
        // Center is a layout widget. It takes a single child and positions it
        // in the middle of the parent.
        child: Column(
          // Column is also a layout widget. It takes a list of children and
          // arranges them vertically. By default, it sizes itself to fit its
          // children horizontally, and tries to be as tall as its parent.
          //
          // Column has various properties to control how it sizes itself and
          // how it positions its children. Here we use mainAxisAlignment to
          // center the children vertically; the main axis here is the vertical
          // axis because Columns are vertical (the cross axis would be
          // horizontal).
          //
          // TRY THIS: Invoke "debug painting" (choose the "Toggle Debug Paint"
          // action in the IDE, or press "p" in the console), to see the
          // wireframe for each widget.
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            if (_showProgress) CircularProgressIndicator(),
            const Text(
              'You have pushed the button this many times:',
            ),
            Semantics(
              value: 'counter_value',
              child: Text(
                '$_counter',
                style: Theme.of(context).textTheme.headlineMedium,
              ),
            ),
            TextField(
              key: Key("editText"),
              decoration: InputDecoration(
                border: OutlineInputBorder(),
                hintText: 'Enter a search term',
              ),
            ),
            ElevatedButton(
                key: const Key("decrement"),
                onPressed: () {},
                child: IconButton(
                  onPressed: () {
                    _decrementCounter();
                  },
                  icon: Icon(Icons.remove),
                )),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        key: const Key('increment'),
        onPressed: _incrementCounter,
        tooltip: 'Increment',
        child: const Icon(Icons.add),
      ), // This trailing comma makes auto-formatting nicer for build methods.
    );
  }
}
@saikrishna321
Copy link
Member

Please share full server logs pls

@rohitbhoite
Copy link
Author

One more observation is If I generate a build for testing using command flutter run apk --debug --flavor dev -t integration_test/appium_test.dart and If I try to add any text manually in textfield, it does not allow me to type any text. Is this expected?

@rbhoite-clgx
Copy link

image

Also tried setting text using appium inspector send Keys function and it did not work either.

@rohitbhoite
Copy link
Author

@saikrishna321 Is there any other way to implement this?

@saikrishna321
Copy link
Member

@rohitbhoite can you share sample apk?

@saikrishna321
Copy link
Member

@rohitbhoite Can you push the sample code to github repo. Can't download from unknown source.

@rohitbhoite
Copy link
Author

Can you try with above main.dart file .Its just a single file. Have added code in the description section
I am using ./gradlew app:assembleDebug -Ptarget=pwd/../integration_test/appium_test.dart to generate the build

@rohitbhoite
Copy link
Author

Thank you for your prompt response :)

@rohitbhoite
Copy link
Author

@saikrishna321 did you get a chance to check it

@saikrishna321
Copy link
Member

@rohitbhoite I'm unable to reproduce this issue. Everything works fine

   it.only('Issue test', async () => {
      await performLogin();
      await openScreen('Issue');
      await browser
         .flutterByValueKey$('editText').addValue("I'm typing in the text field");
   })

Logs: https://gist.github.com/saikrishna321/e2ff4f339a96a42676fbacab4c617864#file-flutter-issue-L354-L363

@lmendes21
Copy link

@saikrishna321 I'm experiencing the exact same issue. My app initialized from the appium.dart is not allowing me to send keys.
It is correctly identifying the element, it can even clear the element but not send keys.

Like mentioned above, I cannot add keys manually either, the keyboard is not displayed and a dart like pointer is instead.

This must be related how the app is being initialized, am I missing something? Some configuration, pluggin? My app is from a multiprovider, however I tried a very simple code and the exact same thing happened?

void main() {
  initializeTest(app: const TextFieldExampleApp());
}

class TextFieldExampleApp extends StatelessWidget {
  const TextFieldExampleApp({super.key});
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: const Text('Obscured Textfield')),
        body: const Center(
          child: ObscuredTextFieldSample(),
        ),
      ),
    );
  }
}

class ObscuredTextFieldSample extends StatelessWidget {
  const ObscuredTextFieldSample({super.key});
  @override
  Widget build(BuildContext context) {
    return const SizedBox(
      width: 250,
      child: TextField(
        key: ValueKey("email_input"),
        obscureText: true,
        decoration: InputDecoration(
          border: OutlineInputBorder(),
          labelText: 'Password',
        ),
      ),
    );
  }
}

@saikrishna321
Copy link
Member

Thanks for sharing a sample code snippet. Will get back.

@lmendes21
Copy link

@saikrishna321 any updates on this?

@saikrishna321
Copy link
Member

@lmendes21 Sorry was snowed with work. Will see this soon. Thanks.

@siva-regunathan
Copy link

Guys any update on above issue? i am facing the same issue

@sudharsan-selvaraj
Copy link
Member

@siva-regunathan I will look into to. Meanwhile can you share the error logs from client and server as gist?

@siva-regunathan
Copy link

siva-regunathan commented Dec 16, 2024

We are testing with one small test.
Error:
`[0-0] Error in "My Login application.should login with valid credentials"
Error: Malformed type for "text" parameter of command elementSendKeys
Expected: string
Actual: object

For more info see https://w3c.github.io/webdriver/#dfn-element-send-keys

[0-0] 2024-12-16T13:24:15.693Z INFO webdriver: COMMAND deleteSession()
[0-0] 2024-12-16T13:24:15.693Z INFO webdriver: [DELETE] http://127.0.0.1:4723/wd/hub/session/3f521d2d-0ded-4e22-a6a0-b480325141f4
[0-0] 2024-12-16T13:24:15.921Z INFO webdriver: RESULT null
[0-0] FAILED in Android - file:///test/specs/test.e2e.js
2024-12-16T13:24:16.033Z INFO @wdio/cli:launcher: Run onWorkerEnd hook
2024-12-16T13:24:16.033Z INFO @wdio/cli:launcher: Run onComplete hook
2024-12-16T13:24:16.033Z INFO @wdio/appium-service: Killing entire Appium tree

Spec Files: 0 passed, 1 failed, 1 total (100% completed) in 00:00:13

2024-12-16T13:24:16.036Z INFO @wdio/local-runner: Shutting down spawned worker
2024-12-16T13:24:16.052Z INFO @wdio/appium-service: Process and its children successfully terminated
2024-12-16T13:24:16.288Z INFO @wdio/local-runner: Waiting for 0 to shut down gracefully
2024-12-16T13:24:16.288Z INFO @wdio/local-runner: shutting down
`

Test file:
`const { driver } = require('@wdio/globals')
const assert = require('assert')

class SecurePage {
async sample() {

await browser.flutterByValueKey$('EmailTextField').clearValue();
await browser.flutterByValueKey$('EmailTextField').setValue('sample');

}

}

module.exports = new SecurePage();
`

UI Code: Container( decoration: BoxDecoration( borderRadius: const BorderRadius.all(Radius.circular(5)), boxShadow: <BoxShadow>[ BoxShadow( color: vm.error == null ? AppColors.g25 : AppColors.e600, blurRadius: 4, ), ], ), child: TextField( key: const Key('EmailTextField'), controller: vm.inputFieldController, decoration: const InputDecoration( labelText: 'Enter something', border: OutlineInputBorder(), ), ), ), );

@siva-regunathan
Copy link

@sudharsan-selvaraj I felt like its a keyboard issue, even if i manually open the test build keyboard doesn’t appear. Only the back space is working from the system. We are trying this on Emulator

@siva-regunathan
Copy link

@sudharsan-selvaraj Any updates on this? Our testing is currently on hold due to this issue.

@saikrishna321
Copy link
Member

saikrishna321 commented Dec 20, 2024

@siva-regunathan Can you tell me flutter-server version, WDIO client version and flutter-integration-driver version?
Can you please provide a sample apk and wdio demo project.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants