| | package com.b44t.messenger; |
| |
|
| | import static androidx.test.espresso.Espresso.onView; |
| | import static androidx.test.espresso.action.ViewActions.typeText; |
| | import static androidx.test.espresso.matcher.ViewMatchers.isRoot; |
| | import static androidx.test.espresso.matcher.ViewMatchers.withHint; |
| | import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation; |
| |
|
| | import android.app.Activity; |
| | import android.content.ComponentName; |
| | import android.content.Context; |
| | import android.content.Intent; |
| | import android.view.View; |
| |
|
| | import androidx.annotation.NonNull; |
| | import androidx.test.espresso.NoMatchingViewException; |
| | import androidx.test.espresso.UiController; |
| | import androidx.test.espresso.ViewAction; |
| | import androidx.test.espresso.ViewInteraction; |
| | import androidx.test.espresso.util.TreeIterables; |
| | import androidx.test.ext.junit.rules.ActivityScenarioRule; |
| |
|
| | import org.hamcrest.Matcher; |
| | import org.thoughtcrime.securesms.ConversationListActivity; |
| | import org.thoughtcrime.securesms.R; |
| | import org.thoughtcrime.securesms.connect.AccountManager; |
| | import org.thoughtcrime.securesms.connect.DcHelper; |
| | import org.thoughtcrime.securesms.util.AccessibilityUtil; |
| | import org.thoughtcrime.securesms.util.Prefs; |
| | import org.thoughtcrime.securesms.util.Util; |
| |
|
| | public class TestUtils { |
| | private static int createdAccountId = 0; |
| | private static boolean resetEnterSends = false; |
| |
|
| | public static void cleanupCreatedAccount(Context context) { |
| | DcAccounts accounts = DcHelper.getAccounts(context); |
| | if (createdAccountId != 0) { |
| | accounts.removeAccount(createdAccountId); |
| | createdAccountId = 0; |
| | } |
| | } |
| |
|
| | public static void cleanup() { |
| | Context context = getInstrumentation().getTargetContext(); |
| | cleanupCreatedAccount(context); |
| | if (resetEnterSends) { |
| | Prefs.setEnterSendsEnabled(getInstrumentation().getTargetContext(), false); |
| | } |
| | } |
| |
|
| | public static void createOfflineAccount() { |
| | Context context = getInstrumentation().getTargetContext(); |
| | cleanupCreatedAccount(context); |
| | createdAccountId = AccountManager.getInstance().beginAccountCreation(context); |
| | DcContext c = DcHelper.getContext(context); |
| | c.setConfig("configured_addr", "alice@example.org"); |
| | c.setConfig("configured_mail_pw", "abcd"); |
| | c.setConfig("configured", "1"); |
| | } |
| |
|
| | @NonNull |
| | public static ActivityScenarioRule<ConversationListActivity> getOfflineActivityRule(boolean useExistingChats) { |
| | Intent intent = |
| | Intent.makeMainActivity( |
| | new ComponentName(getInstrumentation().getTargetContext(), ConversationListActivity.class)); |
| | if (!useExistingChats) { |
| | createOfflineAccount(); |
| | } |
| | prepare(); |
| | return new ActivityScenarioRule<>(intent); |
| | } |
| |
|
| | @NonNull |
| | public static <T extends Activity> ActivityScenarioRule<T> getOnlineActivityRule(Class<T> activityClass) { |
| | Context context = getInstrumentation().getTargetContext(); |
| | AccountManager.getInstance().beginAccountCreation(context); |
| | prepare(); |
| | return new ActivityScenarioRule<>(new Intent(getInstrumentation().getTargetContext(), activityClass)); |
| | } |
| |
|
| | private static void prepare() { |
| | Prefs.setBooleanPreference(getInstrumentation().getTargetContext(), Prefs.DOZE_ASKED_DIRECTLY, true); |
| | if (!AccessibilityUtil.areAnimationsDisabled(getInstrumentation().getTargetContext())) { |
| | throw new RuntimeException("To run the tests, disable animations at Developer options' " + |
| | "-> 'Window/Transition/Animator animation scale' -> Set all 3 to 'off'"); |
| | } |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | |
| | private static ViewAction searchFor(Matcher<View> matcher) { |
| | return new ViewAction() { |
| |
|
| | public Matcher<View> getConstraints() { |
| | return isRoot(); |
| | } |
| |
|
| | public String getDescription() { |
| | return "searching for view $matcher in the root view"; |
| | } |
| |
|
| | public void perform(UiController uiController, View view) { |
| |
|
| | Iterable<View> childViews = TreeIterables.breadthFirstViewTraversal(view); |
| |
|
| | |
| | for (View it : childViews) { |
| | if (matcher.matches(it)) { |
| | |
| | return; |
| | } |
| | } |
| |
|
| | throw new NoMatchingViewException.Builder() |
| | .withRootView(view) |
| | .withViewMatcher(matcher) |
| | .build(); |
| | } |
| | }; |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | public static ViewInteraction waitForView( |
| | Matcher<View> viewMatcher, |
| | int waitMillis, |
| | int waitMillisPerTry |
| | ) { |
| |
|
| | |
| | int maxTries = (int) (waitMillis / waitMillisPerTry); |
| |
|
| | int tries = 0; |
| |
|
| | for (int i = 0; i < maxTries; i++) |
| | try { |
| | |
| | tries++; |
| |
|
| | |
| | onView(isRoot()).perform(searchFor(viewMatcher)); |
| |
|
| | |
| | return onView(viewMatcher); |
| |
|
| | } catch (Exception e) { |
| | if (tries == maxTries) { |
| | throw e; |
| | } |
| | Util.sleep(waitMillisPerTry); |
| | } |
| |
|
| | throw new RuntimeException("Error finding a view matching $viewMatcher"); |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | public static void pressSend() { |
| | if (!Prefs.isEnterSendsEnabled(getInstrumentation().getTargetContext())) { |
| | resetEnterSends = true; |
| | Prefs.setEnterSendsEnabled(getInstrumentation().getTargetContext(), true); |
| | } |
| | waitForView(withHint(R.string.chat_input_placeholder), 10000, 100).perform(typeText("\n")); |
| | } |
| | } |
| |
|