I am looking for a way to take a screenshot of device after test failed and before get closed.
I made some improvements on this answer. No need to add an extra dependency for UiAutomator and it also works below api level 18.
public class ScreenshotTestWatcher extends TestWatcher
{
private static Activity currentActivity;
@Override
protected void failed(Throwable e, Description description)
{
Bitmap bitmap;
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2)
{
bitmap = getInstrumentation().getUiAutomation().takeScreenshot();
}
else
{
// only in-app view-elements are visible.
bitmap = Screenshot.capture(getCurrentActivity()).getBitmap();
}
// Save to external storage '/storage/emulated/0/Android/data/[package name app]/cache/screenshots/'.
File folder = new File(getTargetContext().getExternalCacheDir().getAbsolutePath() + "/screenshots/");
if (!folder.exists())
{
folder.mkdirs();
}
storeBitmap(bitmap, folder.getPath() + "/" + getFileName(description));
}
private String getFileName(Description description)
{
String className = description.getClassName();
String methodName = description.getMethodName();
String dateTime = Calendar.getInstance().getTime().toString();
return className + "-" + methodName + "-" + dateTime + ".png";
}
private void storeBitmap(Bitmap bitmap, String path)
{
BufferedOutputStream out = null;
try
{
out = new BufferedOutputStream(new FileOutputStream(path));
bitmap.compress(Bitmap.CompressFormat.PNG, 100, out);
}
catch (IOException e)
{
e.printStackTrace();
}
finally
{
if (out != null)
{
try
{
out.close();
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
}
private static Activity getCurrentActivity()
{
getInstrumentation().runOnMainSync(new Runnable()
{
public void run()
{
Collection resumedActivities = ActivityLifecycleMonitorRegistry.getInstance().getActivitiesInStage(
RESUMED);
if (resumedActivities.iterator().hasNext())
{
currentActivity = (Activity) resumedActivities.iterator().next();
}
}
});
return currentActivity;
}
}
Then include the following line in your test class:
@Rule
public TestRule watcher = new ScreenshotTestWatcher();