How to enable/disable app permission using Appium?

Viewed 14763

My app need the multiple app permission. I need to check how my app behaves by allowing or denying the different permission. How can i enable/disable the app permission from the appium to create the multiple scenario?

For example lets say my app need to permissions: permission1 and permission2.

scenario 1 = allow permission1 allow permission2

scenario 2 = allow permission1 deny permission2

scenario 3 = deny permission1 allow permission2

scenario 4 = deny permission1 deny permission2
7 Answers

The above answers didn't resolve my problem. I solved this problem by using the the caps of "autoGrantPermissions".

Setup:

desired_caps['autoGrantPermissions'] = True

You will have to disable the noReset caps to False, otherwise it won't work. See reference here: http://appium.io/docs/en/writing-running-appium/caps/

One solution would be to go to Settings app and automate the scenario within that. You can go to Settings app (in fact, any iOS system app) by providing the bundle ID. For settings app it's com.apple.Preferences

I am using ruby, but the idea might be the similar for other clients.

def launch_settings_app
    @driver.execute_script('mobile: launchApp', {'bundleId': "com.apple.Preferences"});
end

You can find other bundle IDs here https://emm.how/t/ios-11-list-of-default-apps-and-bundle-id-s/465 Or using command line - this will return bundle ids for all installed apps on your device: ideviceinstaller -u device_udid -l

Before you launch/initialise the appium driver, just give all the required permissions to the respective app through adb command as below so that the ALLOW pop up won't be displayed:

        adb -s yourDeviceSerialNumber shell pm grant your.app.packagename android.permission.READ_EXTERNAL_STORAGE
        adb -s yourDeviceSerialNumber shell pm grant your.app.packagename android.permission.WRITE_EXTERNAL_STORAGE
        adb -s yourDeviceSerialNumber shell pm grant your.app.packagename android.permission.ACCESS_FINE_LOCATION
        adb -s yourDeviceSerialNumber shell pm grant your.app.packagename android.permission.CAMERA
        adb -s yourDeviceSerialNumber shell pm grant your.app.packagename android.permission.READ_CONTACTS

You can call these through your automation code for android

OR

There is appium capabilities to grant permission : autoGrantPermissions Appium automatically determine which permissions your app requires and grant them to the app on install. Defaults to false. If noReset is true, this capability doesn't work.

http://appium.io/docs/en/writing-running-appium/caps/

As per your needs you can't control the permission dialog from capabilities so you should use:

//for allow button
driver.findElement(By.id("com.android.packageinstaller:id/permission_allow_button")).click();
//or
driver.findElement(By.xpath("//*[@text='ALLOW']")).click();

//For deny button
driver.findElement(By.id("com.android.packageinstaller:id/permission_deny_button")).click();
//or
driver.findElement(By.xpath("//*[@text='DENY']")).click();

You should invoke the app package and app capability properly... So when you are working with your app, then set the package and activity to your app, when the android activity comes, invoke the package and activity for native android...Also be sure to set the package and activity to your app after you are done with the permissions... Please find the code below:

public static void main(String[] args) throws MalformedURLException {
    // TODO Auto-generated method stub

    File f=new File("src");
    File fs=new File(f,"app-debug.apk");

    DesiredCapabilities cap=new DesiredCapabilities();
    cap.setCapability(MobileCapabilityType.DEVICE_NAME, "emulator-5554");
    cap.setCapability(MobileCapabilityType.APP, fs.getAbsolutePath());

    cap.setCapability("appPackage", "yourAppPackageName");
    cap.setCapability("appActivity", "yourAppActivityName");

    AndroidDriver<AndroidElement> driver=new AndroidDriver<AndroidElement>(new URL("http://127.0.0.1:4723/wd/hub"),cap);
    cap.setCapability("appPackage", "com.google.android.packageinstaller");
    cap.setCapability("appActivity", "com.android.packageinstaller.permission.ui.GrantPermissionsActivity");
    driver.findElementById("com.android.packageinstaller:id/permission_allow_button").click();

I found the solution for android using adb shell command.

 String packageName= ((AndroidDriver) driver).getCurrentPackage();
 String grantCameraPermission= "adb shell pm grant " + packageName +" android.permission.CAMERA";
 String grantLocationPermission= "adb shell pm grant " + packageName +" android.permission.ACCESS_FINE_LOCATION";
 String revokeCameraPermission= "adb shell pm revoke " + packageName +" android.permission.CAMERA";
 String revokeLocationPermission= "adb shell pm revoke " + packageName +" android.permission.ACCESS_FINE_LOCATION";
        try {
            Runtime.getRuntime().exec(grantCameraPermission);
            Runtime.getRuntime().exec(revokeLocationPermission);

        } catch (IOException e) {
            e.printStackTrace();
        }

Here is the list of the Android Permission

For those who just started with appium and python, and are wondering how to add this capability, this is how my conftest.py file looks like:

My versions: Python 3.9 Appium: 1.21.0 Pytest: 6.2.4

capabilities = {
  "platformName": "Android",
  "platformVersion": "11.0",
  "deviceName": "emulator-5554",
  "automationName": "Appium",
  "app": r"C:\Project\app-universal-release.apk",
  **'autoGrantPermissions':'true'**
}

This works for me while I am developing a positive scenario test. This is not for negative testing. For that, the capabilities must not have the above.

The result:

All popup requirements(permissions) will be already be given.

Common ones are: Location, Folder, Camera etc

Related