Skip to content

Commit

Permalink
Merge branch 'master' of github.com:Karumi/Shot
Browse files Browse the repository at this point in the history
  • Loading branch information
pedrovgs committed Mar 8, 2021
2 parents 84ce351 + a3a32d2 commit fa0fa6d
Show file tree
Hide file tree
Showing 4 changed files with 92 additions and 6 deletions.
Original file line number Diff line number Diff line change
@@ -1,23 +1,24 @@
package com.karumi.shot.compose

import android.graphics.Bitmap
import android.os.Build
import androidx.annotation.RequiresApi
import androidx.compose.ui.test.SemanticsNodeInteraction
import com.google.gson.annotations.SerializedName
import com.karumi.shot.permissions.AndroidStoragePermissions

class ComposeScreenshot(
private val session: ScreenshotTestSession,
private val saver: ScreenshotSaver
private val saver: ScreenshotSaver,
private val permissions: AndroidStoragePermissions
) {

fun saveScreenshot(bitmap: Bitmap, data: ScreenshotMetadata) {
permissions.checkPermissions()
saver.saveScreenshot(ScreenshotToSave(ScreenshotSource.Bitmap(bitmap), data))
session.add(data)
}

@RequiresApi(Build.VERSION_CODES.O)
fun saveScreenshot(node: SemanticsNodeInteraction, data: ScreenshotMetadata) {
permissions.checkPermissions()
saver.saveScreenshot(ScreenshotToSave(ScreenshotSource.Node(node), data))
session.add(data)
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.karumi.shot.compose

import android.app.Instrumentation
import com.karumi.shot.permissions.AndroidStoragePermissions

class ComposeScreenshotRunner {
companion object {
Expand All @@ -10,7 +11,8 @@ class ComposeScreenshotRunner {
fun onCreate(instrumentation: Instrumentation) {
composeScreenshot = ComposeScreenshot(
session = ScreenshotTestSession(),
saver = ScreenshotSaver(instrumentation.context.packageName, SemanticsNodeBitmapGenerator())
saver = ScreenshotSaver(instrumentation.context.packageName, SemanticsNodeBitmapGenerator()),
permissions = AndroidStoragePermissions(instrumentation)
)
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
package com.karumi.shot.permissions;

import android.app.Instrumentation;
import android.app.UiAutomation;
import android.content.Context;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.ParcelFileDescriptor;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Locale;

public class AndroidStoragePermissions {
private static final String WRITE_PERMISSION = "android.permission.WRITE_EXTERNAL_STORAGE";
private static final String READ_PERMISSION = "android.permission.READ_EXTERNAL_STORAGE";
private static final String[] REQUIRED_PERMISSIONS =
new String[]{WRITE_PERMISSION, READ_PERMISSION};

private final Instrumentation instrumentation;

public AndroidStoragePermissions(Instrumentation instrumentation) {
this.instrumentation = instrumentation;
}

public void checkPermissions() {
Context testAppContext = instrumentation.getContext();
for (String permission : REQUIRED_PERMISSIONS) {
if ((permission.equals(READ_PERMISSION) && Build.VERSION.SDK_INT < 16)
|| testAppContext.checkCallingOrSelfPermission(permission)
== PackageManager.PERMISSION_GRANTED) {
continue;
}
if (Build.VERSION.SDK_INT < 23) {
throw new RuntimeException("We need " + permission + " permission for screenshot tests");
}
Context targetContext = instrumentation.getTargetContext();
grantPermission(targetContext, permission);
grantPermission(testAppContext, permission);
}
}

private void grantPermission(Context context, String permission) {
if (Build.VERSION.SDK_INT < 23) {
return;
}
UiAutomation automation = instrumentation.getUiAutomation();
String command =
String.format(Locale.ENGLISH, "pm grant %s %s", context.getPackageName(), permission);
ParcelFileDescriptor pfd = automation.executeShellCommand(command);
InputStream stream = new FileInputStream(pfd.getFileDescriptor());
try {
byte[] buffer = new byte[1024];
while (stream.read(buffer) != -1) {
// Consume stdout to ensure the command completes
}
} catch (IOException ignored) {
} finally {
try {
stream.close();
} catch (IOException ignored) {
}
try {
pfd.close();
} catch (IOException ignored) {
}
}
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.karumi.shot.compose

import androidx.compose.ui.test.SemanticsNodeInteraction
import com.karumi.shot.permissions.AndroidStoragePermissions
import com.nhaarman.mockito_kotlin.*
import junit.framework.TestCase.assertEquals
import org.junit.Before
Expand All @@ -24,9 +25,12 @@ class ComposeScreenshotTest {
@Mock
private lateinit var node: SemanticsNodeInteraction

@Mock
private lateinit var permissions: AndroidStoragePermissions

@Before
fun setUp() {
composeScreenshot = ComposeScreenshot(ScreenshotTestSession(), screenshotSaver)
composeScreenshot = ComposeScreenshot(ScreenshotTestSession(), screenshotSaver, permissions)
}

@Test
Expand All @@ -39,6 +43,15 @@ class ComposeScreenshotTest {
assertEquals(expectedSessionMetadata, composeScreenshot.saveMetadata().getScreenshotSessionMetadata())
}

@Test
fun grantsStoragePermissionsWhenSavingAnyMetadata() {
val data = anyScreenshotMetadata

composeScreenshot.saveScreenshot(node, data)

verify(permissions).checkPermissions()
}

@Test
fun wheneverANewScreenshotIsSavedTheNodeAssociatedIsSavedIntoTheSdCard() {
val data = anyScreenshotMetadata
Expand Down

0 comments on commit fa0fa6d

Please sign in to comment.