Hans-Christoph Steiner 2018-08-14 12:52:06 +02:00
parent 2f038d81e0
commit fd7acd6304
6 changed files with 98 additions and 2 deletions

View File

@ -177,6 +177,7 @@ dependencies {
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2' androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
androidTestImplementation 'com.android.support.test:runner:1.0.2' androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'com.android.support.test:rules:1.0.2' androidTestImplementation 'com.android.support.test:rules:1.0.2'
androidTestImplementation 'com.android.support.test.uiautomator:uiautomator-v18:2.1.3'
} }
checkstyle { checkstyle {

View File

@ -50,6 +50,7 @@
</issue> </issue>
<issue id="ProtectedPermissions" severity="error"> <issue id="ProtectedPermissions" severity="error">
<ignore path="src/debug/AndroidManifest.xml"/>
<ignore path="src/full/AndroidManifest.xml"/> <ignore path="src/full/AndroidManifest.xml"/>
</issue> </issue>

View File

@ -1,9 +1,11 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<!-- package name must be unique so suffix with "tests" so package loader doesn't ignore us --> <!-- package name must be unique so suffix with "tests" so package loader doesn't ignore us -->
<manifest xmlns:android="http://schemas.android.com/apk/res/android" <manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="org.fdroid.fdroid.tests" package="org.fdroid.fdroid.tests"
android:versionCode="1" android:versionCode="1"
android:versionName="1.0"> android:versionName="1.0">
<uses-sdk tools:overrideLibrary="android.support.test.uiautomator.v18"/>
<!-- We add an application tag here just so that we can indicate that <!-- We add an application tag here just so that we can indicate that
this package needs to link against the android.test library, this package needs to link against the android.test library,
which is needed when building test cases. --> which is needed when building test cases. -->

View File

@ -1,19 +1,25 @@
package org.fdroid.fdroid; package org.fdroid.fdroid;
import android.app.Instrumentation;
import android.support.test.InstrumentationRegistry;
import android.support.test.espresso.IdlingPolicies; import android.support.test.espresso.IdlingPolicies;
import android.support.test.espresso.ViewInteraction; import android.support.test.espresso.ViewInteraction;
import android.support.test.filters.LargeTest; import android.support.test.filters.LargeTest;
import android.support.test.rule.ActivityTestRule; import android.support.test.rule.ActivityTestRule;
import android.support.test.runner.AndroidJUnit4; import android.support.test.runner.AndroidJUnit4;
import android.support.test.uiautomator.UiDevice;
import android.util.Log; import android.util.Log;
import android.view.View; import android.view.View;
import org.fdroid.fdroid.views.BannerUpdatingRepos; import org.fdroid.fdroid.views.BannerUpdatingRepos;
import org.fdroid.fdroid.views.main.MainActivity; import org.fdroid.fdroid.views.main.MainActivity;
import org.hamcrest.Matchers; import org.hamcrest.Matchers;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Rule; import org.junit.Rule;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
import java.io.IOException;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import static android.support.test.espresso.Espresso.onView; import static android.support.test.espresso.Espresso.onView;
@ -37,8 +43,25 @@ import static org.junit.Assert.assertTrue;
public class MainActivityEspressoTest { public class MainActivityEspressoTest {
public static final String TAG = "MainActivityEspressoTest"; public static final String TAG = "MainActivityEspressoTest";
static { @BeforeClass
public static void classSetUp() {
IdlingPolicies.setIdlingResourceTimeout(10, TimeUnit.MINUTES); IdlingPolicies.setIdlingResourceTimeout(10, TimeUnit.MINUTES);
IdlingPolicies.setMasterPolicyTimeout(10, TimeUnit.MINUTES);
Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation();
try {
UiDevice.getInstance(instrumentation)
.executeShellCommand("pm grant "
+ instrumentation.getTargetContext().getPackageName()
+ " android.permission.SET_ANIMATION_SCALE");
} catch (IOException e) {
e.printStackTrace();
}
SystemAnimations.disableAll(InstrumentationRegistry.getTargetContext());
}
@AfterClass
public static void classTearDown() {
SystemAnimations.enableAll(InstrumentationRegistry.getTargetContext());
} }
@Rule @Rule
@ -130,7 +153,7 @@ public class MainActivityEspressoTest {
} }
@Test @Test
public void showLatest() throws InterruptedException { public void showLatest() {
if (!BuildConfig.FLAVOR.startsWith("full")) { if (!BuildConfig.FLAVOR.startsWith("full")) {
return; return;
} }

View File

@ -0,0 +1,62 @@
package org.fdroid.fdroid;
import android.Manifest;
import android.content.Context;
import android.content.pm.PackageManager;
import android.os.IBinder;
import android.util.Log;
import java.lang.reflect.Method;
/**
* @see <a href="https://artemzin.com/blog/easiest-way-to-give-set_animation_scale-permission-for-your-ui-tests-on-android/>EASIEST WAY TO GIVE SET_ANIMATION_SCALE PERMISSION FOR YOUR UI TESTS ON ANDROID</a>
* @see <a href="https://gist.github.com/xrigau/11284124>Disable animations for Espresso tests</a>
*/
class SystemAnimations {
public static final String TAG = "SystemAnimations";
private static final float DISABLED = 0.0f;
private static final float DEFAULT = 1.0f;
static void disableAll(Context context) {
int permStatus = context.checkCallingOrSelfPermission(Manifest.permission.SET_ANIMATION_SCALE);
if (permStatus == PackageManager.PERMISSION_GRANTED) {
Log.i(TAG, "Manifest.permission.SET_ANIMATION_SCALE PERMISSION_GRANTED");
setSystemAnimationsScale(DISABLED);
} else {
Log.i(TAG, "Disabling Manifest.permission.SET_ANIMATION_SCALE failed: " + permStatus);
}
}
static void enableAll(Context context) {
int permStatus = context.checkCallingOrSelfPermission(Manifest.permission.SET_ANIMATION_SCALE);
if (permStatus == PackageManager.PERMISSION_GRANTED) {
Log.i(TAG, "Manifest.permission.SET_ANIMATION_SCALE PERMISSION_GRANTED");
setSystemAnimationsScale(DEFAULT);
} else {
Log.i(TAG, "Enabling Manifest.permission.SET_ANIMATION_SCALE failed: " + permStatus);
}
}
private static void setSystemAnimationsScale(float animationScale) {
try {
Class<?> windowManagerStubClazz = Class.forName("android.view.IWindowManager$Stub");
Method asInterface = windowManagerStubClazz.getDeclaredMethod("asInterface", IBinder.class);
Class<?> serviceManagerClazz = Class.forName("android.os.ServiceManager");
Method getService = serviceManagerClazz.getDeclaredMethod("getService", String.class);
Class<?> windowManagerClazz = Class.forName("android.view.IWindowManager");
Method setAnimationScales = windowManagerClazz.getDeclaredMethod("setAnimationScales", float[].class);
Method getAnimationScales = windowManagerClazz.getDeclaredMethod("getAnimationScales");
IBinder windowManagerBinder = (IBinder) getService.invoke(null, "window");
Object windowManagerObj = asInterface.invoke(null, windowManagerBinder);
float[] currentScales = (float[]) getAnimationScales.invoke(windowManagerObj);
for (int i = 0; i < currentScales.length; i++) {
currentScales[i] = animationScale;
}
setAnimationScales.invoke(windowManagerObj, new Object[]{currentScales});
} catch (Exception e) {
Log.e(TAG, "Could not change animation scale to " + animationScale + " :'(");
}
}
}

View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- This file should be outside of release manifest (in this case app/src/mock/Manifest.xml -->
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<!--required to enable/disable system animations from the app itself during Espresso test runs-->
<uses-permission android:name="android.permission.SET_ANIMATION_SCALE"/>
</manifest>