[android] Fix robolectric test after AndroidX migration

This commit is contained in:
Torsten Grote
2019-10-16 17:10:46 -03:00
parent a592c05146
commit 9d31a0a536
4 changed files with 158 additions and 165 deletions

View File

@@ -90,15 +90,10 @@ dependencies {
implementation project(path: ':bramble-core', configuration: 'default')
implementation project(':bramble-android')
// implementation 'androidx.legacy:legacy-support-v4:1.0.0'
implementation 'androidx.appcompat:appcompat:1.1.0'
// implementation 'androidx.legacy:legacy-preference-v14:1.0.0'
implementation 'androidx.preference:preference:1.1.0'
implementation 'androidx.cardview:cardview:1.0.0'
implementation 'androidx.annotation:annotation:1.1.0'
implementation 'androidx.exifinterface:exifinterface:1.0.0'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
implementation 'androidx.lifecycle:lifecycle-extensions:2.1.0'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
implementation 'com.google.android.material:material:1.0.0'
implementation 'ch.acra:acra:4.11'
@@ -121,17 +116,21 @@ dependencies {
compileOnly 'javax.annotation:jsr250-api:1.0'
def espressoVersion = '3.2.0'
def jmockVersion = '2.8.2'
testImplementation project(path: ':bramble-api', configuration: 'testOutput')
testImplementation project(path: ':bramble-core', configuration: 'testOutput')
testImplementation 'org.robolectric:robolectric:4.3'
testImplementation 'org.robolectric:shadows-support-v4:3.3.2'
testImplementation 'androidx.test:runner:1.2.0'
testImplementation 'androidx.test.ext:junit:1.1.1'
testImplementation 'androidx.fragment:fragment-testing:1.1.0'
testImplementation "androidx.test.espresso:espresso-core:$espressoVersion"
testImplementation 'org.robolectric:robolectric:4.3.1'
testImplementation 'org.mockito:mockito-core:3.1.0'
testImplementation 'junit:junit:4.12'
testImplementation "org.jmock:jmock:2.8.2"
testImplementation "org.jmock:jmock-junit4:2.8.2"
testImplementation "org.jmock:jmock-legacy:2.8.2"
testImplementation "org.jmock:jmock:$jmockVersion"
testImplementation "org.jmock:jmock-junit4:$jmockVersion"
testImplementation "org.jmock:jmock-legacy:$jmockVersion"
def espressoVersion = '3.2.0'
androidTestImplementation "androidx.test.espresso:espresso-core:$espressoVersion"
androidTestImplementation "androidx.test.espresso:espresso-contrib:$espressoVersion"
androidTestImplementation "androidx.test.espresso:espresso-intents:$espressoVersion"

View File

@@ -1,115 +0,0 @@
package org.briarproject.briar.android.account;
import com.google.android.material.textfield.TextInputLayout;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import org.briarproject.briar.R;
import org.briarproject.briar.android.TestBriarApplication;
import org.briarproject.briar.android.login.StrengthMeter;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
import static junit.framework.Assert.assertEquals;
import static org.briarproject.bramble.api.crypto.PasswordStrengthEstimator.NONE;
import static org.briarproject.bramble.api.crypto.PasswordStrengthEstimator.QUITE_STRONG;
import static org.briarproject.bramble.api.crypto.PasswordStrengthEstimator.QUITE_WEAK;
import static org.briarproject.bramble.api.crypto.PasswordStrengthEstimator.STRONG;
import static org.briarproject.bramble.api.crypto.PasswordStrengthEstimator.WEAK;
import static org.junit.Assert.assertNotEquals;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import static org.robolectric.shadows.support.v4.SupportFragmentTestUtil.startFragment;
@RunWith(RobolectricTestRunner.class)
@Config(sdk = 21, application = TestBriarApplication.class)
public class SetPasswordFragmentTest {
private SetPasswordFragment passwordFragment = new SetPasswordFragment();
private EditText passwordEntry;
private EditText passwordConfirmation;
private TextInputLayout passwordConfirmationWrapper;
private StrengthMeter strengthMeter;
private Button createAccountButton;
@Mock
private SetupController setupController;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
startFragment(passwordFragment, SetupActivity.class);
View v = passwordFragment.getView();
passwordEntry = v.findViewById(R.id.password_entry);
passwordConfirmation = v.findViewById(R.id.password_confirm);
passwordConfirmationWrapper =
v.findViewById(R.id.password_confirm_wrapper);
strengthMeter = v.findViewById(R.id.strength_meter);
createAccountButton = v.findViewById(R.id.next);
}
@Test
public void testCreateAccountUI() {
String safePass = "really.safe.password";
passwordFragment.setupController = setupController;
when(setupController.needToShowDozeFragment()).thenReturn(false);
when(setupController.estimatePasswordStrength(safePass))
.thenReturn(STRONG);
passwordEntry.setText(safePass);
passwordConfirmation.setText(safePass);
// Confirm that the create account button is clickable
assertEquals(createAccountButton.isEnabled(), true);
createAccountButton.performClick();
// assert controller has been called properly
verify(setupController, times(1)).setPassword(safePass);
verify(setupController, times(1)).createAccount();
}
@Test
public void testStrengthMeterUI() {
// Test the meters' progress and color for several values
testStrengthMeter("1234567890ab", STRONG, StrengthMeter.GREEN);
testStrengthMeter("123456789", QUITE_STRONG, StrengthMeter.LIME);
testStrengthMeter("123456", QUITE_WEAK, StrengthMeter.YELLOW);
testStrengthMeter("123", WEAK, StrengthMeter.ORANGE);
testStrengthMeter("", NONE, StrengthMeter.RED);
}
private void testStrengthMeter(String pass, float strength, int color) {
passwordEntry.setText(pass);
assertEquals(strengthMeter.getProgress(),
(int) (strengthMeter.getMax() * strength));
assertEquals(color, strengthMeter.getColor());
}
@Test
public void testPasswordMatchUI() {
// Password mismatch
passwordEntry.setText("really.safe.password");
passwordConfirmation.setText("really.safe.pass");
assertEquals(createAccountButton.isEnabled(), false);
assertEquals(passwordConfirmationWrapper.getError(),
passwordFragment.getString(R.string.passwords_do_not_match));
// Button enabled
passwordEntry.setText("really.safe.pass");
passwordConfirmation.setText("really.safe.pass");
// Confirm that the password mismatch error message is not visible
assertNotEquals(passwordConfirmationWrapper.getError(),
passwordFragment.getString(R.string.passwords_do_not_match));
// Passwords match, so button should be enabled
assertEquals(createAccountButton.isEnabled(), true);
}
}

View File

@@ -1,47 +1,147 @@
package org.briarproject.briar.android.account;
import com.google.android.material.textfield.TextInputLayout;
import android.widget.EditText;
import android.view.View;
import org.briarproject.briar.R;
import org.briarproject.briar.android.TestBriarApplication;
import org.junit.Assert;
import org.junit.Before;
import org.briarproject.briar.android.login.StrengthMeter;
import org.hamcrest.Description;
import org.hamcrest.Matcher;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.MockitoAnnotations;
import org.robolectric.Robolectric;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
import static junit.framework.Assert.assertEquals;
import androidx.test.espresso.matcher.BoundedMatcher;
import androidx.test.ext.junit.rules.ActivityScenarioRule;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import static androidx.test.espresso.Espresso.onView;
import static androidx.test.espresso.action.ViewActions.clearText;
import static androidx.test.espresso.action.ViewActions.click;
import static androidx.test.espresso.action.ViewActions.replaceText;
import static androidx.test.espresso.action.ViewActions.typeText;
import static androidx.test.espresso.assertion.ViewAssertions.doesNotExist;
import static androidx.test.espresso.assertion.ViewAssertions.matches;
import static androidx.test.espresso.matcher.ViewMatchers.isDisplayed;
import static androidx.test.espresso.matcher.ViewMatchers.isEnabled;
import static androidx.test.espresso.matcher.ViewMatchers.withId;
import static androidx.test.espresso.matcher.ViewMatchers.withText;
import static org.briarproject.bramble.api.crypto.PasswordStrengthEstimator.NONE;
import static org.briarproject.bramble.api.crypto.PasswordStrengthEstimator.QUITE_STRONG;
import static org.briarproject.bramble.api.crypto.PasswordStrengthEstimator.QUITE_WEAK;
import static org.briarproject.bramble.api.crypto.PasswordStrengthEstimator.STRONG;
import static org.briarproject.bramble.api.crypto.PasswordStrengthEstimator.WEAK;
import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_AUTHOR_NAME_LENGTH;
import static org.briarproject.bramble.util.StringUtils.getRandomString;
import static org.briarproject.briar.android.login.StrengthMeter.GREEN;
import static org.briarproject.briar.android.login.StrengthMeter.LIME;
import static org.briarproject.briar.android.login.StrengthMeter.ORANGE;
import static org.briarproject.briar.android.login.StrengthMeter.RED;
import static org.briarproject.briar.android.login.StrengthMeter.YELLOW;
import static org.hamcrest.Matchers.not;
@RunWith(RobolectricTestRunner.class)
@RunWith(AndroidJUnit4.class)
@Config(sdk = 21, application = TestBriarApplication.class)
public class SetupActivityTest {
private SetupActivity setupActivity;
private TextInputLayout nicknameEntryWrapper;
private EditText nicknameEntry;
@Rule
public ActivityScenarioRule<SetupActivity> rule =
new ActivityScenarioRule<>(SetupActivity.class);
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
setupActivity = Robolectric.setupActivity(SetupActivity.class);
nicknameEntryWrapper =
setupActivity.findViewById(R.id.nickname_entry_wrapper);
nicknameEntry = setupActivity.findViewById(R.id.nickname_entry);
@Test
public void testNicknameTooLongErrorShown() {
String longNick = getRandomString(MAX_AUTHOR_NAME_LENGTH + 1);
onView(withId(R.id.nickname_entry)).perform(typeText(longNick));
// Nickname should be too long
onView(withText(R.string.name_too_long)).check(matches(isDisplayed()));
}
@Test
public void testNicknameUI() {
Assert.assertNotNull(setupActivity);
String longNick = getRandomString(MAX_AUTHOR_NAME_LENGTH + 1);
nicknameEntry.setText(longNick);
// Nickname should be too long
assertEquals(nicknameEntryWrapper.getError(),
setupActivity.getString(R.string.name_too_long));
public void testPasswordMatchUI() {
moveToSetPasswordFragment();
// error shown when passwords don't match, button is disabled
onView(withId(R.id.password_entry)).perform(typeText("123456"));
onView(withId(R.id.password_confirm)).perform(typeText("654321"));
onView(withText(R.string.passwords_do_not_match))
.check(matches(isDisplayed()));
onView(withId(R.id.next)).check(matches(not(isEnabled())));
// confirming correct password, removes error, enables button
onView(withId(R.id.password_confirm)).perform(clearText());
onView(withId(R.id.password_confirm)).perform(replaceText("123456"));
onView(withText(R.string.passwords_do_not_match)).check(doesNotExist());
onView(withId(R.id.next)).check(matches(isEnabled()));
// clicking the button shows progress bar, no doze because SDK_INT==21
onView(withId(R.id.next)).perform(click());
onView(withId(R.id.progress)).check(matches(isDisplayed()));
}
@Test
public void testStrengthMeterUI() {
moveToSetPasswordFragment();
onView(withId(R.id.password_entry)).perform(typeText("1234567890ab"));
onView(withId(R.id.strength_meter))
.check(matches(strengthAndColor(STRONG, GREEN)));
onView(withId(R.id.password_entry)).perform(clearText());
onView(withId(R.id.password_entry)).perform(typeText("123456789"));
onView(withId(R.id.strength_meter))
.check(matches(strengthAndColor(QUITE_STRONG, LIME)));
onView(withId(R.id.password_entry)).perform(clearText());
onView(withId(R.id.password_entry)).perform(typeText("123456"));
onView(withId(R.id.strength_meter))
.check(matches(strengthAndColor(QUITE_WEAK, YELLOW)));
onView(withId(R.id.password_entry)).perform(clearText());
onView(withId(R.id.password_entry)).perform(typeText("123"));
onView(withId(R.id.strength_meter))
.check(matches(strengthAndColor(WEAK, ORANGE)));
onView(withId(R.id.password_entry)).perform(clearText());
onView(withId(R.id.strength_meter))
.check(matches(strengthAndColor(NONE, RED)));
}
private void moveToSetPasswordFragment() {
onView(withId(R.id.nickname_entry)).perform(typeText("test"));
onView(withId(R.id.next)).perform(click());
onView(withId(R.id.password_entry)).check(matches(isDisplayed()));
}
private Matcher<View> strengthAndColor(float strength, int color) {
return new StrengthMeterMatcher(strength, color);
}
static class StrengthMeterMatcher
extends BoundedMatcher<View, StrengthMeter> {
private final float strength;
private final int color;
private StrengthMeterMatcher(float strength, int color) {
super(StrengthMeter.class);
this.strength = strength;
this.color = color;
}
@Override
public void describeTo(Description description) {
description.appendText("is enabled");
}
@Override
public boolean matchesSafely(StrengthMeter view) {
boolean strengthMatches =
view.getProgress() == (int) (view.getMax() * strength);
boolean colorMatches = color == view.getColor();
return strengthMatches && colorMatches;
}
}
}

View File

@@ -1,5 +1,6 @@
dependencyVerification {
verify = [
'androidx.activity:activity-ktx:1.0.0:activity-ktx-1.0.0.aar:be4d4c7e51a42fedb0bc6e68e9c3eba3603d3bbc2ef468689694369f98eab6c7',
'androidx.activity:activity:1.0.0:activity-1.0.0.aar:d1bc9842455c2e534415d88c44df4d52413b478db9093a1ba36324f705f44c3d',
'androidx.annotation:annotation:1.1.0:annotation-1.1.0.jar:d38d63edb30f1467818d50aaf05f8a692dea8b31392a049bfa991b159ad5b692',
'androidx.appcompat:appcompat-resources:1.1.0:appcompat-resources-1.1.0.aar:19944d32b46551a17c347e21894b95837fbd7baaafc9e2082794344f222f7361',
@@ -18,6 +19,8 @@ dependencyVerification {
'androidx.documentfile:documentfile:1.0.0:documentfile-1.0.0.aar:865a061ef2fad16522f8433536b8d47208c46ff7c7745197dfa1eeb481869487',
'androidx.drawerlayout:drawerlayout:1.0.0:drawerlayout-1.0.0.aar:9402442cdc5a43cf62fb14f8cf98c63342d4d9d9b805c8033c6cf7e802749ac1',
'androidx.exifinterface:exifinterface:1.0.0:exifinterface-1.0.0.aar:ee48be10aab8f54efff4c14b77d11e10b9eeee4379d5ef6bf297a2923c55cc11',
'androidx.fragment:fragment-ktx:1.1.0:fragment-ktx-1.1.0.aar:d40e525a57f21814fe8754e69c7306224ca30ed33f33c17c329b91bd839de94e',
'androidx.fragment:fragment-testing:1.1.0:fragment-testing-1.1.0.aar:c4ae4a296df1a05708f7fde215784c7171084d0801fdc3ad12a2163a8ced2a4c',
'androidx.fragment:fragment:1.1.0:fragment-1.1.0.aar:a14c8b8f2153f128e800fbd266a6beab1c283982a29ec570d2cc05d307d81496',
'androidx.interpolator:interpolator:1.0.0:interpolator-1.0.0.aar:33193135a64fe21fa2c35eec6688f1a76e512606c0fc83dc1b689e37add7732a',
'androidx.legacy:legacy-support-core-ui:1.0.0:legacy-support-core-ui-1.0.0.aar:0d1260c6e7e6a337f875df71b516931e703f716e90889817cd3a20fa5ac3d947',
@@ -29,6 +32,7 @@ dependencyVerification {
'androidx.lifecycle:lifecycle-process:2.1.0:lifecycle-process-2.1.0.aar:8cddd0c7f4927bbf71fb71fca000786df82cc597c99463d6916ccbe4a205a9ac',
'androidx.lifecycle:lifecycle-runtime:2.1.0:lifecycle-runtime-2.1.0.aar:e5173897b965e870651e83d9d5af1742d3f532d58863223a390ce3a194c8312b',
'androidx.lifecycle:lifecycle-service:2.1.0:lifecycle-service-2.1.0.aar:23516745f34f16ff7850bb1eadd55cf193dd789cba428de4bca120433e3bfd69',
'androidx.lifecycle:lifecycle-viewmodel-ktx:2.1.0:lifecycle-viewmodel-ktx-2.1.0.aar:16a66d966f6a5c201e724dad836d85fcfa528a891ae5ae0e5f7556ab5bc7575f',
'androidx.lifecycle:lifecycle-viewmodel:2.1.0:lifecycle-viewmodel-2.1.0.aar:ba55fb7ac1b2828d5327cda8acf7085d990b2b4c43ef336caa67686249b8523d',
'androidx.loader:loader:1.0.0:loader-1.0.0.aar:11f735cb3b55c458d470bed9e25254375b518b4b1bad6926783a7026db0f5025',
'androidx.localbroadcastmanager:localbroadcastmanager:1.0.0:localbroadcastmanager-1.0.0.aar:e71c328ceef5c4a7d76f2d86df1b65d65fe2acf868b1a4efd84a3f34336186d8',
@@ -42,6 +46,7 @@ dependencyVerification {
'androidx.test.espresso:espresso-core:3.2.0:espresso-core-3.2.0.aar:beb4712c2520c1da30ac1f25506871f16ea5b83ee686ece5a258769df1a01e15',
'androidx.test.espresso:espresso-idling-resource:3.2.0:espresso-idling-resource-3.2.0.aar:c1a0454fe95788122ba652c3ecff7ec538c7e27de206aed970f2809fb8090d09',
'androidx.test.espresso:espresso-intents:3.2.0:espresso-intents-3.2.0.aar:b13347a543d1fe957bc901281caed8b8f8a475f702779c851fafdfed7b9467c1',
'androidx.test.ext:junit:1.1.1:junit-1.1.1.aar:449df418d2916a0f86fe7dafb1edb09480fafb6e995d5c751c7d0d1970d4ae72',
'androidx.test.uiautomator:uiautomator:2.2.0:uiautomator-2.2.0.aar:2838e9d961dbffefbbd229a2bd4f6f82ac4fb2462975862a9e75e9ed325a3197',
'androidx.test:core:1.2.0:core-1.2.0.aar:c88b739b1c499afb792374be19b9cf829e89567f26441a74f664c0cf8de158a4',
'androidx.test:monitor:1.2.0:monitor-1.2.0.aar:fc97ca3f00f8ca30b7d5167fbd8736756048e2cc4f8e92dc891106751a5baeef',
@@ -181,10 +186,15 @@ dependencyVerification {
'org.hamcrest:hamcrest-integration:1.3:hamcrest-integration-1.3.jar:70f418efbb506c5155da5f9a5a33262ea08a9e4d7fea186aa9015c41a7224ac2',
'org.hamcrest:hamcrest-library:1.3:hamcrest-library-1.3.jar:711d64522f9ec410983bd310934296da134be4254a125080a0416ec178dfad1c',
'org.jetbrains.kotlin:kotlin-reflect:1.3.50:kotlin-reflect-1.3.50.jar:64583199ea5a54aefd1bd1595288925f784226ee562d1dd279011c6075b3d7a4',
'org.jetbrains.kotlin:kotlin-stdlib-common:1.3.31:kotlin-stdlib-common-1.3.31.jar:d6e9c54c1e6c4df21be9395de558665544c6bdc8f8076ea7518f089f82cd34fc',
'org.jetbrains.kotlin:kotlin-stdlib-common:1.3.50:kotlin-stdlib-common-1.3.50.jar:8ce678e88e4ba018b66dacecf952471e4d7dfee156a8a819760a5a5ff29d323c',
'org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.3.50:kotlin-stdlib-jdk7-1.3.50.jar:9a026639e76212f8d57b86d55b075394c2e009f1979110751d34c05c5f75d57b',
'org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.3.50:kotlin-stdlib-jdk8-1.3.50.jar:1b351fb6e09c14b55525c74c1f4cf48942eae43c348b7bc764a5e6e423d4da0c',
'org.jetbrains.kotlin:kotlin-stdlib:1.3.31:kotlin-stdlib-1.3.31.jar:f38c84326543e66ed4895b20fb3ea0fca527fd5a040e1f49d0946ecf3d2b3b23',
'org.jetbrains.kotlin:kotlin-stdlib:1.3.50:kotlin-stdlib-1.3.50.jar:e6f05746ee0366d0b52825a090fac474dcf44082c9083bbb205bd16976488d6c',
'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.1.1:kotlinx-coroutines-android-1.1.1.jar:ed6fc7d667d5c11d187894789d7bf6cf8fedccb0be75fde795b8686582a1fe32',
'org.jetbrains.kotlinx:kotlinx-coroutines-core-common:1.1.1:kotlinx-coroutines-core-common-1.1.1.jar:033732168fd3a68a7d788294321106ae13536eae8459382a85cc1f17f88572e7',
'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.1.1:kotlinx-coroutines-core-1.1.1.jar:ac423f8a0aa4b4e74529696ff82c0171f81a8c8ab182a1965dff25e69c1f7844',
'org.jetbrains.trove4j:trove4j:20160824:trove4j-20160824.jar:1917871c8deb468307a584680c87a44572f5a8b0b98c6d397fc0f5f86596dbe7',
'org.jetbrains:annotations:13.0:annotations-13.0.jar:ace2a10dc8e2d5fd34925ecac03e4988b2c0f851650c94b8cef49ba1bd111478',
'org.jmock:jmock-junit4:2.8.2:jmock-junit4-2.8.2.jar:f7ee4df4f7bd7b7f1cafad3b99eb74d579f109d5992ff625347352edb55e674c',
@@ -204,18 +214,17 @@ dependencyVerification {
'org.ow2.asm:asm-util:7.0:asm-util-7.0.jar:75fbbca440ef463f41c2b0ab1a80abe67e910ac486da60a7863cbcb5bae7e145',
'org.ow2.asm:asm:6.0:asm-6.0.jar:dd8971c74a4e697899a8e95caae4ea8760ea6c486dc6b97b1795e75760420461',
'org.ow2.asm:asm:7.0:asm-7.0.jar:b88ef66468b3c978ad0c97fd6e90979e56155b4ac69089ba7a44e9aa7ffe9acf',
'org.robolectric:annotations:4.3:annotations-4.3.jar:8c10ec1a43ea8346b094a08eaf0aefbaaf749e1a80f10de6a70e7f8788735d03',
'org.robolectric:junit:4.3:junit-4.3.jar:aaef4e59bd99e227e1a0563461363201d0b292e0703a46ea0153c576ebc686a2',
'org.robolectric:pluginapi:4.3:pluginapi-4.3.jar:33cbde3e210cc4b7916195ef1e074b32bddc0a9d72d50dce4f935cc0919f4a63',
'org.robolectric:plugins-maven-dependency-resolver:4.3:plugins-maven-dependency-resolver-4.3.jar:020bcfc6edbd242272dee688b68f2128b9bbcaabf1a03ae7637b913c83c64b9c',
'org.robolectric:resources:4.3:resources-4.3.jar:739bb0d381dfc8f45abab17ac375e7e8e1156ddaa46963cbad827511794d3617',
'org.robolectric:robolectric:4.3:robolectric-4.3.jar:c8137bad762615a28eb321465b04d6e5b0df00687125f22178479452d80e0b82',
'org.robolectric:sandbox:4.3:sandbox-4.3.jar:c1fed5bb01925c6498bddb53a4dd5e97e11d2e9fe0dc9c5336572b6829dc0ffa',
'org.robolectric:shadowapi:4.3:shadowapi-4.3.jar:731c9bbad67a21d86303032a8f4128ec7041b9c256ac08943f46a816307a5765',
'org.robolectric:shadows-framework:4.3:shadows-framework-4.3.jar:0ca9dfcad19c565fc0301f737f8ef01906a2ea89e6ef92ca5aaf2c8915fca119',
'org.robolectric:shadows-support-v4:3.3.2:shadows-support-v4-3.3.2.jar:6f689264738266e70fe08db7c04b7b5a75155994f4e3f7f311960d90486bf005',
'org.robolectric:utils-reflector:4.3:utils-reflector-4.3.jar:e75c5d758f6c714825b331cf3e203f9233b509a0dcafa7dd296870acd6096ea4',
'org.robolectric:utils:4.3:utils-4.3.jar:7a5159a8990d5ab68d2728609bf520db7c963574e7c4faffa3fef45242c8ea7c',
'org.robolectric:annotations:4.3.1:annotations-4.3.1.jar:ce679af70c22620b5752aa6c1555d0653198d6370e9a93fe71b8eaaebc5ffaf6',
'org.robolectric:junit:4.3.1:junit-4.3.1.jar:60c85ea7fd652bc4e57567cbd3c41c5d32f2c678e212b713cefa6c63570451ce',
'org.robolectric:pluginapi:4.3.1:pluginapi-4.3.1.jar:229256a260a1d8e8d33613a3de7ccd639661a7061251c1974975ed427428b468',
'org.robolectric:plugins-maven-dependency-resolver:4.3.1:plugins-maven-dependency-resolver-4.3.1.jar:0d6c577fdefe254659ffba5c0564d7e00c69f03e99a4ebb6c150419834cdb703',
'org.robolectric:resources:4.3.1:resources-4.3.1.jar:93033237006b51541f8e93d65940f9040367775937d0ce9ac3f4ef72771c51b8',
'org.robolectric:robolectric:4.3.1:robolectric-4.3.1.jar:3ef4267112ba581ee2a7ad37859bf61571404f07df85b8ad1da054f90eb57a5a',
'org.robolectric:sandbox:4.3.1:sandbox-4.3.1.jar:405f73400d717e083b25af92fa7866a76765dd4e97cf7fd046023d4f05375a9f',
'org.robolectric:shadowapi:4.3.1:shadowapi-4.3.1.jar:a63d13e7f3816f28ac33eea71a15c7f3f0053ecd01b08cc1e1e119af35ca1197',
'org.robolectric:shadows-framework:4.3.1:shadows-framework-4.3.1.jar:9c69db134cdd79be751856a148020fd9b32b086bb491846eedc0a1106fcadd5e',
'org.robolectric:utils-reflector:4.3.1:utils-reflector-4.3.1.jar:9d7bf2557947d44d6f3ed76ec5231e8b72e33eb61c65ac9e149ad307b0eb936c',
'org.robolectric:utils:4.3.1:utils-4.3.1.jar:6f9e406cd667019a5450e473c4e2d372bff9c9ab6ef55aafcbc9843109cb1519',
'tools.fastlane:screengrab:1.2.0:screengrab-1.2.0.aar:af4ee23bb06f94404d3ab18e2ea69db8265539fc8da29f9ee45b7e472684ba83',
'uk.co.samuelwall:material-tap-target-prompt:3.0.0:material-tap-target-prompt-3.0.0.aar:e4d3c472b2d378e39a6535b7788e6c790fc9dde2d7659974e006ed8c7260911d',
]