Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to stub select images intent using Espresso intents?

This is first time I am using espresso intents, I followed IntentsBasicSamle provided in the android-testing project but no solved.

In my app I have a activity where user selects multiple images and then returned images are shown in the gridview, Now by using the espresso intents I want to mock this without going to actual image picker and return some specified images everytime.

No error but still opens the image chooser window when I run the test. I feel I am doing it wrong but I am not getting how it works.

I am testing using apk.

This is how photo picker is called

App code

This is how I am calling select images Intent and result is handled in onActivityResult.

if (ApiUtils.checkApiLevel(18)) {
        //API18+
        intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true);
    }
    intent.setAction(Intent.ACTION_GET_CONTENT);
    startActivityForResult(Intent.createChooser(intent,      getActivity().getString(R.string.fragment_image_selection_select_picture)), 1);

Testing Code

@RunWith(AndroidJUnit4.class)
@LargeTest
public class ImagesTests {

private static final String LAUNCHER_ACTIVITY_FULL_CLASSNAME = "com.company.recorder.RecorderActivity";
private static Class<? extends Activity> activityClass;
private ServiceValidatorIdlingResource serviceValidatorIdlingResource;

static {
    try {
        activityClass = (Class<? extends Activity>) Class.forName(LAUNCHER_ACTIVITY_FULL_CLASSNAME);
    } catch (ClassNotFoundException e) {
        throw new RuntimeException(e);
    }
}

/**
 * Change espresso default view idling time
 * so that test can wait for long time
 */
@Before
public void registerWaitService() {
    EspressoSolo.setIdlingResourceTimeout(30);

    Instrumentation.ActivityResult result = createImageCaptureActivityResultStub();

    // Stub the Intent.
    intending(hasAction(Intent.ACTION_GET_CONTENT)).respondWith(result);

   //For API 18 and above
    intending(hasAction(Intent.EXTRA_ALLOW_MULTIPLE)).respondWith(result);

    //intending(not(isInternal())).respondWith(result);
}

private Instrumentation.ActivityResult createImageCaptureActivityResultStub() {
    // Put the drawable in a bundle.
    Bundle bundle = new Bundle();
    Uri imageUri = Uri.parse(ContentResolver.SCHEME_ANDROID_RESOURCE + "://" +
            InstrumentationRegistry.getTargetContext().getPackageName()+ '/' +
            InstrumentationRegistry.getTargetContext().getResources().getResourceTypeName(R.drawable.abc_ic_menu_copy_mtrl_am_alpha) + '/' +
            InstrumentationRegistry.getTargetContext().getResources().getResourceEntryName(R.drawable.abc_ic_menu_copy_mtrl_am_alpha) );

    Parcelable parcelable = (Parcelable)imageUri;

    ArrayList<Parcelable> parcels = new ArrayList<>();
    parcels.add(parcelable);

    bundle.putParcelableArrayList(Intent.EXTRA_STREAM, parcels);

    // Create the Intent that will include the bundle.
    Intent resultData = new Intent();
    resultData.putExtras(bundle);

    // Create the ActivityResult with the Intent.
    return new Instrumentation.ActivityResult(Activity.RESULT_OK, resultData);
}

@Rule
public IntentsTestRule<?> mIntentsRule = new IntentsTestRule<>(
        activityClass);


/**
 * In this test images are taken during the recording
 * add the images taken during the recording through add photos card
 * displayed after recording is stopped.
 *
 * @throws Exception
 */
@Test
public void testAddImagesFromPhotosCard() throws Exception {

    onView(withId(Recorder.getId("recorderpage_record"))).perform(click());

    Log.d("called", "other package");
    IdlingResource idlingResource0 = new RecordingWaitIdlingResource(5000);
    Espresso.registerIdlingResources(idlingResource0);

    Log.d("called", "other package");
    onView(withId(Recorder.getId("card_topText"))).perform(click());
    Espresso.unregisterIdlingResources(idlingResource0);
    onView(withId(Recorder.getId("recorderpage_stop"))).perform(click());
    //Log.d("called", "other package");
    IdlingResource idlingResource2 = new RecordingWaitIdlingResource(2000);
    Espresso.registerIdlingResources(idlingResource2);
    onView(withId(Recorder.getId("recorderpage_statustext")))
            .perform(click());
    Espresso.unregisterIdlingResources(idlingResource2);

    onView(withId(Recorder.getId("pager"))).perform(swipeLeft());

    onData(allOf()).onChildView(withId(Recorder.getId("recordsOverflow"))).
            atPosition(0).perform(click());

    IdlingResource idlingResource3 = new RecordingWaitIdlingResource(2000);
    Espresso.registerIdlingResources(idlingResource3);
    onData(allOf()).onChildView(withId(Recorder.getId("recordsOverflow"))).
            atPosition(0).perform(click());
    Espresso.unregisterIdlingResources(idlingResource3);
    onView(withText("Add an image")).perform(click());

    Instrumentation.ActivityResult result = createImageCaptureActivityResultStub();
    intending(toPackage("com.android.documentsui")).respondWith(result);

     /* I actually dont know which preinstalled app is opened by intent, I saw this com.android.documentsui, also tried with photos and gallery package names */

    intending(toPackage("com.android.documentsui.DocumentsActivity")).respondWith(result);

    intending(hasAction(Intent.ACTION_GET_CONTENT)).respondWith(result);

    //Now click on add images
    onView(withId(Recorder.getId("menu_fragment_imagewizard_selection_add"))).perform(click());

    //Just waits for 2seconds
    IdlingResource idlingResource4 = new RecordingWaitIdlingResource(2000);
    Espresso.registerIdlingResources(idlingResource4);
    onView(withText("Add images")).perform(click());
    Espresso.unregisterIdlingResources(idlingResource4);

}
}
like image 983
Shivaraj Patil Avatar asked Aug 21 '15 14:08

Shivaraj Patil


1 Answers

Finally, This is what worked for me, posting my answer

Bundle bundle = new Bundle();
    ArrayList<Parcelable> parcels = new ArrayList<>();
    Intent resultData = new Intent();
    Uri uri1 = Uri.parse("file://mnt/sdcard/img01.jpg");
    Parcelable parcelable1 = (Parcelable) uri1;
    parcels.add(parcelable1);
    bundle.putParcelableArrayList(Intent.EXTRA_STREAM, parcels);
    // Create the Intent that will include the bundle.
    resultData.putExtras(bundle);

    intending(not(isInternal())).respondWith(new Instrumentation.ActivityResult(Activity.RESULT_OK, resultData));

Permissions

 @Rule public GrantPermissionRule permissionRule = GrantPermissionRule.grant(android.Manifest.permission.YOUR_PERMISSION; 
like image 53
Shivaraj Patil Avatar answered Oct 04 '22 03:10

Shivaraj Patil