1 /* 2 * Copyright (C) 2015 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.messaging.ui; 18 19 import android.app.Fragment; 20 import android.app.FragmentManager; 21 import android.content.res.Configuration; 22 import android.view.View; 23 24 /** 25 * Helper class that extends Bugle.ui.ActivityInstrumentationTestCase to provide common behavior 26 * across fragment tests. 27 */ 28 public abstract class FragmentTestCase<T extends Fragment> 29 extends BugleActivityInstrumentationTestCase<TestActivity> { 30 31 protected T mFragment; 32 protected Class<T> mFragmentClass; 33 34 public FragmentTestCase(final Class<T> fragmentClass) { 35 super(TestActivity.class); 36 mFragmentClass = fragmentClass; 37 } 38 39 @Override 40 protected void setUp() throws Exception { 41 super.setUp(); 42 } 43 44 protected T getFragment() { 45 // Fragment creation deferred (typically until test time) so that factory/appcontext is 46 // ready. 47 if (mFragment == null) { 48 try { 49 mFragment = mFragmentClass.newInstance(); 50 } catch (final InstantiationException e) { 51 throw new IllegalStateException("Failed to instantiate fragment"); 52 } catch (final IllegalAccessException e) { 53 throw new IllegalStateException("Failed to instantiate fragment"); 54 } 55 } 56 57 return mFragment; 58 } 59 60 protected void attachFragment() { 61 getActivity().runOnUiThread(new Runnable() { 62 @Override 63 public void run() { 64 final FragmentManager fragmentManager = getActivity().getFragmentManager(); 65 fragmentManager.beginTransaction().add(mFragment, null /* tag */).commit(); 66 } 67 }); 68 69 getInstrumentation().waitForIdleSync(); 70 } 71 72 @Override 73 protected void tearDown() throws Exception { 74 // In landscape mode, sleep for a second first. 75 // The reason is: our UI tests don't wait for the UI thread to finish settling down 76 // before exiting (because they can't know when the UI thread is done). In portrait mode, 77 // things generally work fine here -- the UI thread is done by the time the test is done. 78 // In landscape mode, though, since the launcher is in portrait mode, there is a lot of 79 // extra work that happens in our UI when the app launches into landscape mode, and the 80 // UI is often not done by the time the test finishes running. So then our teardown 81 // nulls out the Factory, and then the UI keeps running and derefs the null factory, 82 // and things blow up. 83 // So ... as a cheap hack, sleep for one second before finishing the teardown of UI 84 // tests, but only do it in landscape mode (so that developers running it in portrait 85 // mode can still run the tests faster). 86 if (this.getInstrumentation().getTargetContext().getResources(). 87 getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) { 88 try { 89 Thread.sleep(1000); 90 } catch (InterruptedException e) { 91 e.printStackTrace(); 92 } 93 } 94 super.tearDown(); 95 } 96 97 protected void clickButton(final View view) { 98 getActivity().runOnUiThread(new Runnable() { 99 @Override 100 public void run() { 101 view.performClick(); 102 } 103 }); 104 getInstrumentation().waitForIdleSync(); 105 } 106 107 protected void setFocus(final View view, final boolean focused) { 108 getActivity().runOnUiThread(new Runnable() { 109 @Override 110 public void run() { 111 if (focused) { 112 view.requestFocus(); 113 } else { 114 view.clearFocus(); 115 } 116 } 117 }); 118 getInstrumentation().waitForIdleSync(); 119 } 120 }