21

In Flutter end-to-end testing, a permission is to be allowed during the test. driver.tap(find.text("ALLOW") does not work. How to click "ALLOW".

enter image description here

Kyaw Tun
  • 12,447
  • 10
  • 56
  • 83

4 Answers4

19

You can grant the permissions before running the test.

import 'dart:io';
import 'package:path/path.dart';

// ...

setUpAll(() async {
  final envVars = Platform.environment;
  final adbPath = join(
    envVars['ANDROID_SDK_ROOT'] ?? envVars['ANDROID_HOME'],
    'platform-tools',
    Platform.isWindows ? 'adb.exe' : 'adb',
  );
  await Process.run(adbPath, [
    'shell',
    'pm',
    'grant',
    'com.example.yourapp', // replace with your app id
    'android.permission.RECORD_AUDIO'
  ]);
  driver = await FlutterDriver.connect();
});
apaatsio
  • 3,073
  • 1
  • 22
  • 18
11

Other answers will not help you if you are using the latest Flutter Integration Testing as there we don't require FlutterDriver to connect.

So now, you need to add the below code in test_driver.dart file where we initialize integrationDriver()

Future<void> main() async {
    final Map<String, String> envVars = Platform.environment;
    String? adbPath = join(envVars['ANDROID_SDK_ROOT'] ?? envVars['ANDROID_HOME']!,
      'platform-tools',
      Platform.isWindows ? 'adb.exe' : 'adb',
    );
  await Process.run(adbPath , ['shell' ,'pm', 'grant', 'com.example', 'android.permission.CAMERA']);
  await Process.run(adbPath , ['shell' ,'pm', 'grant', 'com.example', 'android.permission.WRITE_EXTERNAL_STORAGE']);
  await integrationDriver();
}

This change is required as FlutterDriver makes the connection once you initialized and connect it, but the new flow of integration testing already had a connection, so we need to initialize it before the connection happens.

To run code, use the below command on terminal, as you see for better result I have created two folder,

  1. test_driver: Contains the driver code mentioned above.

  2. integration_test: Contains test files.

    flutter drive --driver=test_driver/test_driver.dart --target=integration_test/my_test.dart
    
Jitesh Mohite
  • 31,138
  • 12
  • 157
  • 147
4

Try Patrol – it makes cases like yours easy to handle!

  1. First, set up Patrol in your app
  2. Install patrol_clidart pub global activate patrol_cli

Once you get the initial setup done, you'll able to write in your tests:

await $.native.grantPermissionWhenInUse();

To run this test, simply type patrol test.

In contrast to the other answers from Susovan, apaatsio and Jitesha, Patrol works on iOS and Android.

Full code example

// integration_test/recording_test.dart
import 'package:patrol/patrol.dart';

void main() {
  patrolTest( // patrolTest() instead of testWidgets()
    'records sounds and saves it to internal storage',
    nativeAutomation: true,
    (PatrolTester $) async { // PatrolTester instead of WidgetTester
      await $.pumpWidget(YourAppWidget()); // replace with your own

      await $('Record').tap(); // Patrol's custom finders syntax (optional)
      await $.native.grantPermissionWhenInUse();
    },
  );
}

To run it:

patrol test

More about Patrol

Patrol is available on pub.dev and has extensive documentation. Here's a succinct overview of the native features it supports.

Apart from interacting with native features, Patrol has:

Bartek Pacia
  • 1,085
  • 3
  • 15
  • 37
2

for me above code is not working don't know why

then i'm tried with below code and its working

setUpAll(() async {

      await Process.run('add_adb_path/adb.exe' , ['shell' ,'pm', 'grant', 'add_app_package_name', 'android.permission.ACCESS_MEDIA_LOCATION']);
      await Process.run('add_adb_path/adb.exe' , ['shell' ,'pm', 'grant', 'add_app_package_name', 'android.permission.READ_EXTERNAL_STORAGE']);
      await Process.run('add_adb_path/adb.exe' , ['shell' ,'pm', 'grant', 'add_app_package_name', 'android.permission.WRITE_EXTERNAL_STORAGE']);


      driver = await FlutterDriver.connect();
    });