Mohit Wadhwa
Mohit Wadhwa

Reputation: 131

Espresso : how to click on image click button on phone camera

I am writing tests using espresso,my app intends to phone camera, where i press the click button manually,and then it migrates to the next screen,I am not able to automate the image click button in test code,how can i access camera using code through which i can do the same. Thanks.

Upvotes: 1

Views: 2600

Answers (2)

Kristy Welsh
Kristy Welsh

Reputation: 8510

I know this is late, but it's something I struggled with myself and I would like to post an answer to help someone else. Here is how you click the camera button from a chooser (after you set it up), you use UIAutomator, as suggested by PunitD in the comments of the original post. This will pick up from where the test is showing a chooser on the screen.

public static final int waitTimeNativeApi = 6000;

public static void await(int time) {
        try {
            Thread.sleep(time);
        } catch (InterruptedException e) {
            Log.e(TAG, "Interrupted while sleeping");
        }
    }

private void takePhoto() {

    boolean usePixels = true;

    UiDevice device = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
    UiObject titleTextUI = device.findObject(new UiSelector()
            .className("android.widget.TextView")
            .text("Camera")
    );

    try {
        titleTextUI.clickTopLeft();

        if (usePixels) {
            takePhotoForPixels(device);
        } else {
            takePhotoForSamsung(device);
        }

    } catch (UiObjectNotFoundException unofe) {
        unofe.printStackTrace();
    }


}

private void takePhotoForPixels(UiDevice device) {

    // close the app selector to go back to our app so we can carry on with Espresso

    await(waitTimeNativeApi);

    //TAP on the camera icon
    device.click(device.getDisplayWidth() / 2, device.getDisplayHeight() - 100);

    await(waitTimeNativeApi);

    //Get the OK button
    device.click(device.getDisplayWidth() / 2, device.getDisplayHeight() - 100);

    await(waitTimeNativeApi);

}

private void takePhotoForSamsung(UiDevice device) throws UiObjectNotFoundException {

    // close the app selector to go back to our app so we can carry on with Espresso
    UiObject titleTextUI = device.findObject(new UiSelector()
            .className("android.widget.TextView")
            .text("Camera")
    );

    titleTextUI.clickTopLeft();

    await(waitTimeNativeApi);

    //TAP on the camera icon
    device.click(device.getDisplayWidth() / 2, device.getDisplayHeight() - 50);

    //Get the OK button
    UiObject cameraOkUi = device.findObject(new UiSelector()
            .className("android.widget.TextView")
            .text("OK")
    );

    cameraOkUi.click();

    await(waitTimeNativeApi);

}

In this way, you will take an actual photo and get the results back in onActivityResult.

Upvotes: 0

jeprubio
jeprubio

Reputation: 18002

You should not open the camera intent or you'll have no way of getting any resulting image back from it (without pressing the camera button manually).

Have a look at the Stubbing out the Camera section of this website: https://guides.codepath.com/android/UI-Testing-with-Espresso#stubbing-out-the-camera

This way you test your activity by simulating an actual image "returned" to your app from the Camera.

Update

And this is the method I use to get a bitmap to test:

public static Bitmap getTestBitmap(Context context, String resourceName) {
    Resources resources = context.getResources();
    Bitmap ret = null;
    int imageResource = resources.getIdentifier(
            resourceName, "drawable", context.getPackageName());

    Uri pictureUri = Uri.parse(ContentResolver.SCHEME_ANDROID_RESOURCE + "://"
            + resources.getResourcePackageName(imageResource) + '/'
            + resources.getResourceTypeName(imageResource) + '/'
            + resources.getResourceEntryName(imageResource));
    try {
        ret = MediaStore.Images.Media.getBitmap(context.getContentResolver(), pictureUri);
    } catch (Exception e) {
    }
    return ret;
}

And then I save the bitmap in internal storage and get the uri:

public static Uri saveToInternalStorage(Context context, Bitmap bitmapImage, String fileName) {
    ContextWrapper cw = new ContextWrapper(context);
    // path to /data/data/yourapp/app_data/pictures
    File directory = cw.getDir("pictures", Context.MODE_PRIVATE);
    // Create imageDir
    File mypath = new File(directory, fileName);

    FileOutputStream fos = null;
    try {
        fos = new FileOutputStream(mypath);
        // Use the compress method on the BitMap object to write image to the OutputStream
        bitmapImage.compress(Bitmap.CompressFormat.PNG, 100, fos);
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        try {
            fos.close();
        } catch (Exception e) {
        }
    }


    return Uri.fromFile(new File(mypath.getAbsolutePath()));
}

Upvotes: 1

Related Questions