Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Espresso ViewAction for Spoon Screenshot
import android.app.Activity;
import android.content.Context;
import android.content.ContextWrapper;
import android.support.test.espresso.UiController;
import android.support.test.espresso.ViewAction;
import android.view.View;
import com.squareup.spoon.Spoon;
import org.hamcrest.Matcher;
import org.hamcrest.Matchers;
import static android.support.test.espresso.Espresso.onView;
import static android.support.test.espresso.matcher.ViewMatchers.isRoot;
public final class SpoonScreenshotAction implements ViewAction {
private final String tag;
private final String testClass;
private final String testMethod;
public SpoonScreenshotAction(String tag, String testClass, String testMethod) {
this.tag = tag;
this.testClass = testClass;
this.testMethod = testMethod;
}
@Override public Matcher<View> getConstraints() {
return Matchers.anything();
}
@Override public String getDescription() {
return "Taking a screenshot using spoon.";
}
@Override public void perform(UiController uiController, View view) {
Spoon.screenshot(getActivity(view), tag, testClass, testMethod);
}
private static Activity getActivity(View view) {
Context context = view.getContext();
while (!(context instanceof Activity)) {
if (context instanceof ContextWrapper) {
context = ((ContextWrapper) context).getBaseContext();
} else {
throw new IllegalStateException("Got a context of class "
+ context.getClass()
+ " and I don't know how to get the Activity from it");
}
}
return (Activity) context;
}
/** This must be called directly from your test method. */
public static void perform(String tag) {
StackTraceElement[] trace = Thread.currentThread().getStackTrace();
String testClass = trace[3].getClassName();
String testMethod = trace[3].getMethodName();
onView(isRoot()).perform(new SpoonScreenshotAction(tag, testClass, testMethod));
}
}
@edenman

This comment has been minimized.

Copy link
Owner Author

@edenman edenman commented Mar 16, 2015

If you want to take a screenshot from a test method, you can use the convenience SpoonScreenshotAction.perform("my_screen"). If you're calling from a helper method, you'll have to adjust the stacktrace wizardry or just manually create a SpoonScreenshotAction with the class/method names populated, and then pass that into the normal espresso perform method.

@FuadBalashov

This comment has been minimized.

Copy link

@FuadBalashov FuadBalashov commented May 11, 2016

I ran into issues with the getConstraints() method returning an Object of type Matcher I ended up returning a new IsAnything(); object in it's place. Not sure if its the best solution but I figured Id leave it here if someone needs it. I found the solution in the SO link below.

http://stackoverflow.com/questions/33255294/error-when-use-anything-in-android-testing-incompatible-types-required-match

@sebaslogen

This comment has been minimized.

Copy link

@sebaslogen sebaslogen commented May 13, 2017

In Android 7+ the getActivity(view) code fails because view.getContext() does not have access to the enclosing activity anymore.

Instead, the code below works in Android 7+ and 6:

private static Activity getActivity(final View view) {
    return (Activity) view.findViewById(android.R.id.content).getContext();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.