Search code examples
androidflutterintegration-testingandroid-permissions

flutter location permission from integration test not working


I am trying to write integration_test for my location app. I need to allow location permission from my integration_test.

I have set ANDROID_SDK_ROOT in my windows environment variable. I have tested from command prompt & Android Studio terminal and it shows fine from both. https://i.ibb.co/4gDPs3Z/echo-android-sdk-root.jpg

Unfortunately, I am getting ANDROID_SDK_ROOT value null from Platform.environment. I have attached screen shot https://i.ibb.co/t2Y3fBc/android-sdk-root-not-found.jpg

If I hard coded envVars to my windows machine's android location C:/Users/User/AppData/Local/Android/Sdk/platform-tools/adb.exe, then it throws error

No such file or directory Command: C:/Users/User/AppData/Local/Android/Sdk/platform-tools/adb.exe shell pm grant com.dealerapp.mlink android.permission.ACCESS_COARSE_LOCATION

below is my source code

Future<void> grantLocationPermission() async{

    final Map<String, String> envVars = Platform.environment;
    print('evnVars = $envVars');
    print('ANDROID_SDK_ROOT = ${envVars['ANDROID_SDK_ROOT']}');
    final String adbPath = envVars['ANDROID_SDK_ROOT']! + '/platform-tools/adb.exe';
    
    await Process.run(adbPath, [
      'shell',
      'pm',
      'grant',
      'com.abcd.efgh', //my app package
      'android.permission.ACCESS_COARSE_LOCATION'
    ]);
    await Process.run(adbPath, [
      'shell',
      'pm',
      'grant',
      'com.abcd.efgh', //my app package
      'android.permission.ACCESS_FINE_LOCATION'
    ]);
    await integrationDriver();
}

Any suggesion will be highly appreciated. Thanks in Advance.


Solution

  • This will not work because envVars will give you environment variables of the system where its getting executed. And since you are executing in emulator then platform is Android [print(Platform.isAndroid) and see] Also if you debug you will see the environment variable is not set.

    As you might have already figured, integration tests cannot interact with native popups. So following are the only ways I found to fix this

    1. Have a test driver: I could only solve the problem using steps below
    • Create a folder "test_driver"
    • Add a file "integration_test_driver.dart"
    • Add following content into the file
    Future<void> main() async {
      await Process.run(
       'adb',
       [
         'shell',
         'pm',
         'grant',
         'com.example.<your app name>', // TODO: Update this
         'android.permission.ACCESS_COARSE_LOCATION'
       ],
     );
     // TODO: Add more permissions as required
     await integrationDriver();
    }
    
    • Create a folder "integration_test"
    • Add a file "app_test.dart" and add your test here
    • Run test using command
      flutter drive --driver=test_driver/integration_test_driver.dart --target=integration_test/app_test.dart
    • You need to do this only once, after that running the tests directly from Test Explorer will not show pop
    • To show the dialog again revoke the permissions using below command in terminal
      adb shell pm revoke com.example.aries_fe android.permission.ACCESS_COARSE_LOCATION
    1. Crude way (not suggested)
      1. Find the x,y coordinate where you can see the option you want to click on popup
      2. call tester.tapAt(const Offset(x,y)) in your test

    Notes:

    • Script with below lines does not work. I wonder why this does not work. Will investigate this further.
    adb shell pm grant com.example.<your app name> android.permission.ACCESS_COARSE_LOCATION 
    flutter test integration_test/login_test.dart
    
    • setUpApp() does not work either.