How to Automate Biometrics (Android edition)
Tags: webdriverIO, appium, testing, biometrics
Published: 2020-05-12 09:57:52

Some sprints ago, me and my team, during the sprint planning event, we were discussing the implementation of touchID on login in our React Native App. 

I have started the POC of Biometrics (as I have never done it in the past), so I could have a clear view if would be possible to automate on Android platform using an Android 9.0 emulator.

After a bit of research, I saw all solutions that I have found on the web (i don't know if I've missed any, sorry for that) are instructed how to add a fingerprint manually and then using an `adb` command to pass it in the biometric alert and make the valid login. 

Then I have checked if there are any `adb` commands that will make my life easier and **BOOM**....

*With the power of Appium and WebdriverIO!!!*

![With the power of Appium and WebdriverIO](https://dev-to-uploads.s3.amazonaws.com/i/8vs7g9z5fzufuvxl9kgb.jpg)

I came to the following solution:

First of all, I took notes on how those actions can be done manually:

* Go to Android `Settings`.
* Tap on `Security & Location`.
* Add `Screen Lock`, there are several types such as `Pin`, `Pattern`, `Swipe`, `Password` (I chose `Pin`).
* You have to follow the wizard of your choice. 
* Then you tap on `Fingerprint`.
* There is again a wizard to follow
* Then I should open my app
* Go to Login screen and provide the fingerprint on Biometrics Alert

That's it! Now let's automate!

I have configured Appium with `--relaxed-security` flag in `wdio.conf.js`, so Appium can accept `adb` commands

```javascript
services: [
        [
            'appium',
            {
              args: {
                  '--relaxed-security': true
            },
              command: 'appium'
            },
        ],
    ]
``` 

Next, the real fun starts!

The first 4 manual steps I found out that could be done like this:

```javascript
browser.execute('mobile: shell', {
  command: 'am start -a android.settings.SECURITY_SETTINGS && locksettings set-pin 1234'
});
```

After that, as I am still in Android `Security Settings` I need to tap on `Fingerprint` using Appium desktop I found the selector and click on it:

```javascript
$('android=new UiSelector().text("Fingerprint")').click();
``` 

The Fingerprint wizard is open and there is a `Next` button, using the same approach as above:

```javascript
$('android=new UiSelector().resourceId("com.android.settings:id/fingerprint_next_button")').click();     
```

I need to provide the pin I have setup on `Screen Lock` and tap keyboard's `Done` button:

```javascript
browser.execute('mobile: shell', { 
  command: 'input text 1234 && input keyevent 66'
}); 
```

Then the wizard prompts the user to touch the sensor (this should be done 3 times), here Appium provides us the `.fingerPrint(fingerprintId)` method, that actually executes an `adb` command `adb -e emu finger touch fingerprintId`:

```javascript
for (let i = 1; i <= 3; i++) {
    browser.pause(1500);
    browser.fingerPrint(1);
  }
```

The final step of the wizard is to tap on `Done` button:

```javascript
$('android=new UiSelector().resourceId("com.android.settings:id/next_button")').click();
```

After that, we should start our App. This is again provided by Appium using ` .startActivity("com.example", "ActivityName");` method. In my example is:

```javascript
browser.startActivity('com.reactnativesampleapp', 'com.reactnativesampleapp.MainActivity');    
```

What remains is to actually login into the app using biometrics:

![Execution of Login Test using Biometrics](https://dev-to-uploads.s3.amazonaws.com/i/6jzwh1bysd0kdqfcsanv.gif)

For more info you can check here:

https://github.com/gromanas/ReactNativeSampleApp/blob/master/README.md