Spoon and Cucumber take screenshot

Hi guys,

Today I will post the code that I’ve improved to make the Cucumber take the screenshots and spoon use them:

Your helper class:

public void takeScreenshot() {
    String[] formattedInfo = treatFeatureScenarioStrings();
    mFeature = formattedInfo[0];
    mScenario = formattedInfo[1];

    if (mScenario == null) {
        throw new ScreenshotException("Error taking screenshot: I'm missing a 
valid test mScenario to attach the screenshot to");
    }
    mSolo.waitForActivity(mSolo.getCurrentActivity().getLocalClassName());
    String tag = Thread.currentThread().getStackTrace()[3].getMethodName();
    ScreenshotTaker.screenshot(mSolo.getCurrentActivity(), 
mSolo.getCurrentViews(), 
tag, mFeature, mScenario);
}

 

/*
This method is formatting the mScenario info to get the mFeature and 
mScenario namesand format them for the same format which Spoon is 
using. The name mFeature needs to follow this
pattern: Feature Test something and mScenario: Scenario Test something
- First letter of the first word of mScenario in uppercase, the same 
for mFeature
- All the others letters need to be in lowercase
- Before mFeature's name put the word Feature and before mScenario's 
name put the word Scenario
- When Scenario Outline the prefix of the scenario needs to be diferent
*/

private String[] treatFeatureScenarioStrings() {
    String mFeatureCap = mScenarioInfo[0].substring(0, 1).toUpperCase() 
+ mScenarioInfo[0].substring(1);
    String mScenarioCap = mScenarioInfo[1].substring(0, 1).toUpperCase() 
+ mScenarioInfo[1].substring(1);
    mFeature = "Feature " + mFeatureCap.replace("-", " ");
    mScenario = "Scenario " + mScenarioCap.replace("-", " ");

    if (mScenarioInfo.length > 2) {
        mScenario = "Scenario Outline " + mScenarioCap.replace("-", " ");
    }

    return new String[]{mFeature, mScenario};
}

private static class ScreenshotException extends RuntimeException {
    ScreenshotException(final String message) {
        super(message);
    }
}

 

ScreenshotTaker class:

import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.os.Build;
import android.os.Environment;
import android.util.Log;
import android.view.View;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Set;
import timber.log.Timber;
import static org.assertj.core.api.Assertions.assertThat;
public abstract class ScreenshotTaker {
private static Set<String> mClearedOutputDirectories = new HashSet();
 static final String NAME_SEPARATOR = "_";
 static final String SPOON_SCREENSHOTS = "spoon-screenshots";
 public static File screenshot(Activity activity, ArrayList<View> views
, String tag, String testClassName, String testMethodName) {
 return screenshot(activity, getRecentDecorView(views), tag, 
testClassName, testMethodName);
 }
public static File screenshot(Activity activity, View view, String tag, 
String testClassName, String testMethodName) {
 try {
 if (view == null) {
 File viewFile = null;
 Log.e("Spoon", "Unable to take screenshot of this view, because it is 
null.");
 return viewFile;
 }
File parentFolder = obtainScreenshotDirectory
(activity.getApplicationContext(), testClassName, testMethodName);
 assertThat(parentFolder).isNotNull();
 final String screenshotName = System.currentTimeMillis() + 
NAME_SEPARATOR + tag + ".png";
 File screenshotFile = new File(parentFolder, screenshotName);
getBitmapOfView(view, activity, screenshotFile);
 Log.d("Spoon", "Captured screenshot \'" + tag + "\'.");
 return screenshotFile;
 } catch (Exception var7) {
 return null;
 }
}
 private static void getBitmapOfView(final View view, Activity activity
, final File screenShotFile) {
 activity.runOnUiThread(new Runnable() {
 @Override
 public void run() {
 view.destroyDrawingCache();
 view.buildDrawingCache(false);
 Bitmap orig = view.getDrawingCache();
 android.graphics.Bitmap.Config config = null;
 if (orig == null) {
 Timber.e("Bitmap is null");
 } else {
 config = orig.getConfig();
 if (config == null) {
 config = android.graphics.Bitmap.Config.ARGB_8888;
 }
 Bitmap mBitmap = orig.copy(config, false);
FileOutputStream mFileOutput = null;
 try {
 mFileOutput = new FileOutputStream(screenShotFile);
 if (mFileOutput != null) {
 mBitmap.compress(Bitmap.CompressFormat.PNG, 100, mFileOutput);
 screenShotFile.setReadable(true, false);
 }
 mFileOutput.flush();
 mFileOutput.close();
 } catch (IOException e) {
 e.printStackTrace();
 }
 orig.recycle();
 view.destroyDrawingCache();
 }
 }
 });
 }
private static File obtainScreenshotDirectory(Context context, 
String testClassName, String testMethodName) {
 return filesDirectory(context, SPOON_SCREENSHOTS, testClassName, 
testMethodName);
 }
private static File filesDirectory(Context context, String directoryType,
 String testClassName, String testMethodName) {
 File directory = null;
 if (Build.VERSION.SDK_INT >= 21) {
 directory = new File(Environment.getExternalStorageDirectory(), "app_" + 
directoryType);
 } else {
 directory = context.getDir(directoryType, 1);
 }
if (!mClearedOutputDirectories.contains(directoryType)) {
 deletePath(directory, false);
 mClearedOutputDirectories.add(directoryType);
 }
File dirClass1 = new File(directory, testClassName);
 File dirMethod = new File(dirClass1, testMethodName);
if (!dirMethod.exists()) {
 createDir(dirMethod);
 }
return dirMethod;
 }
private static void createDir(File dir) {
 File parent = dir.getParentFile();
 if (!parent.exists()) {
 createDir(parent);
 }
if (!dir.exists() && !dir.mkdirs()) {
 Timber.e("Unable to create output dir: " + dir.getAbsolutePath());
 } else {
 Chmod.chmodPlusRWX(dir);
 }
 }
 private static void deletePath(File path, boolean inclusive) {
 if (path.isDirectory()) {
 File[] children = path.listFiles();
 if (children != null) {
 File[] arr$ = children;
 int len$ = children.length;
for (int i$ = 0; i$ < len$; ++i$) {
 File child = arr$[i$];
 deletePath(child, true);
 }
 }
 }
if (inclusive) {
 path.delete();
 }
}
/**
 * Returns the most recent DecorView
 *
 * @param views the views to check
 * @return the most recent DecorView
 */
public static final View getRecentDecorView(ArrayList<View> views) {
 if (views == null) {
 Timber.e("Error in getRecentDecorView: 0 views passed in.");
 return null;
 }
final View[] decorViews = new View[views.size()];
 int i = 0;
 View view;
for (int j = 0; j < views.size(); j++) {
 view = views.get(j);
 if (view != null && view.getClass().getName()
 .equals("com.android.internal.policy.impl.PhoneWindow$DecorView")) {
 decorViews[i] = view;
 i++;
 }
 }
 return getRecentContainer(decorViews);
 }
/**
 * Returns the most recent view container
 *
 * @param views the views to check
 * @return the most recent view container
 */
private static final View getRecentContainer(View[] views) {
 View container = null;
 long drawingTime = 0;
 View view;
for (int i = 0; i < views.length; i++) {
 view = views[i];
 if (view != null && view.isShown() && view.hasWindowFocus() && 
view.getDrawingTime() > drawingTime) {
 container = view;
 drawingTime = view.getDrawingTime();
 }
 }
 return container;
 }
}

Please fell free to improve if you have any comment and suggestion it would be great !
Thank you guys, see you next week !

Advertisements
  1. No comments yet.
  1. No trackbacks yet.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: