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 
FragmentTestCase(final Class<T> fragmentClass)34     public FragmentTestCase(final Class<T> fragmentClass) {
35         super(TestActivity.class);
36         mFragmentClass = fragmentClass;
37     }
38 
39     @Override
setUp()40     protected void setUp() throws Exception {
41       super.setUp();
42     }
43 
getFragment()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 
attachFragment()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
tearDown()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 
clickButton(final View view)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 
setFocus(final View view, final boolean focused)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 }