disable all animations in emulator for Espresso tests
* https://gist.github.com/xrigau/11284124 * https://gist.github.com/xrigau/ea8d306e0a751fafb1e6 * https://artemzin.com/blog/easiest-way-to-give-set_animation_scale-permission-for-your-ui-tests-on-android/ * https://github.com/finn-no/android_emulator_hacks * https://gist.github.com/caipivara/9371a79a7222a156ddad
This commit is contained in:
		
							parent
							
								
									2f038d81e0
								
							
						
					
					
						commit
						fd7acd6304
					
				@ -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 {
 | 
				
			||||||
 | 
				
			|||||||
@ -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>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -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. -->
 | 
				
			||||||
 | 
				
			|||||||
@ -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;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
				
			|||||||
@ -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 + " :'(");
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										7
									
								
								app/src/debug/AndroidManifest.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								app/src/debug/AndroidManifest.xml
									
									
									
									
									
										Normal 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>
 | 
				
			||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user