1*21373fa4SWill Schurman // Copyright 2015-present 650 Industries. All rights reserved. 2*21373fa4SWill Schurman package host.exp.exponent 3*21373fa4SWill Schurman 4*21373fa4SWill Schurman import android.Manifest 5*21373fa4SWill Schurman import android.content.Intent 6*21373fa4SWill Schurman import android.net.Uri 7*21373fa4SWill Schurman import androidx.test.InstrumentationRegistry 8*21373fa4SWill Schurman import androidx.test.espresso.Espresso 9*21373fa4SWill Schurman import androidx.test.espresso.IdlingResource 10*21373fa4SWill Schurman import androidx.test.espresso.assertion.ViewAssertions 11*21373fa4SWill Schurman import androidx.test.espresso.matcher.ViewMatchers 12*21373fa4SWill Schurman import androidx.test.rule.GrantPermissionRule 13*21373fa4SWill Schurman import androidx.test.uiautomator.By 14*21373fa4SWill Schurman import androidx.test.uiautomator.Until 15*21373fa4SWill Schurman import host.exp.exponent.annotations.ExpoAlwaysPassThroughFilter 16*21373fa4SWill Schurman import host.exp.exponent.annotations.ExpoSdkVersionTest 17*21373fa4SWill Schurman import host.exp.exponent.annotations.ExpoTestSuiteTest 18*21373fa4SWill Schurman import host.exp.exponent.generated.ExponentBuildConstants 19*21373fa4SWill Schurman import host.exp.exponent.kernel.KernelConfig 20*21373fa4SWill Schurman import host.exp.exponent.utils.* 21*21373fa4SWill Schurman import org.json.JSONException 22*21373fa4SWill Schurman import org.json.JSONObject 23*21373fa4SWill Schurman import org.junit.* 24*21373fa4SWill Schurman import org.junit.rules.RuleChain 25*21373fa4SWill Schurman import org.junit.runner.RunWith 26*21373fa4SWill Schurman import org.junit.runners.MethodSorters 27*21373fa4SWill Schurman 28*21373fa4SWill Schurman @RunWith(ExpoTestRunner::class) 29*21373fa4SWill Schurman @FixMethodOrder(MethodSorters.NAME_ASCENDING) 30*21373fa4SWill Schurman class TestSuiteTests : BaseTestClass() { 31*21373fa4SWill Schurman private lateinit var loadingScreenIdlingResource: IdlingResource 32*21373fa4SWill Schurman private lateinit var elapsedTimeIdlingResource: ElapsedTimeIdlingResource 33*21373fa4SWill Schurman private lateinit var jsTestRunnerIdlingResource: JSTestRunnerIdlingResource 34*21373fa4SWill Schurman 35*21373fa4SWill Schurman @Before beforenull36*21373fa4SWill Schurman fun before() { 37*21373fa4SWill Schurman loadingScreenIdlingResource = LoadingScreenIdlingResource() 38*21373fa4SWill Schurman elapsedTimeIdlingResource = ElapsedTimeIdlingResource() 39*21373fa4SWill Schurman jsTestRunnerIdlingResource = JSTestRunnerIdlingResource() 40*21373fa4SWill Schurman Espresso.registerIdlingResources( 41*21373fa4SWill Schurman loadingScreenIdlingResource, 42*21373fa4SWill Schurman elapsedTimeIdlingResource, 43*21373fa4SWill Schurman jsTestRunnerIdlingResource 44*21373fa4SWill Schurman ) 45*21373fa4SWill Schurman KernelConfig.FORCE_UNVERSIONED_PUBLISHED_EXPERIENCES = false 46*21373fa4SWill Schurman } 47*21373fa4SWill Schurman 48*21373fa4SWill Schurman @After afternull49*21373fa4SWill Schurman fun after() { 50*21373fa4SWill Schurman Espresso.unregisterIdlingResources( 51*21373fa4SWill Schurman loadingScreenIdlingResource, 52*21373fa4SWill Schurman elapsedTimeIdlingResource, 53*21373fa4SWill Schurman jsTestRunnerIdlingResource 54*21373fa4SWill Schurman ) 55*21373fa4SWill Schurman KernelConfig.FORCE_UNVERSIONED_PUBLISHED_EXPERIENCES = false 56*21373fa4SWill Schurman } 57*21373fa4SWill Schurman 58*21373fa4SWill Schurman private var haveContactsBeenAdded = false ensureContactsAddednull59*21373fa4SWill Schurman private fun ensureContactsAdded() { 60*21373fa4SWill Schurman if (haveContactsBeenAdded) { 61*21373fa4SWill Schurman return 62*21373fa4SWill Schurman } 63*21373fa4SWill Schurman haveContactsBeenAdded = true 64*21373fa4SWill Schurman TestContacts.add(InstrumentationRegistry.getTargetContext()) 65*21373fa4SWill Schurman } 66*21373fa4SWill Schurman runTestSuiteTestnull67*21373fa4SWill Schurman private fun runTestSuiteTest(testSuiteUriString: String, shouldAddDeepLink: Boolean) { 68*21373fa4SWill Schurman var testSuiteUri = Uri.parse(testSuiteUriString) 69*21373fa4SWill Schurman ensureContactsAdded() 70*21373fa4SWill Schurman if (shouldAddDeepLink) { 71*21373fa4SWill Schurman val deepLink = TestConfig.get().toString() 72*21373fa4SWill Schurman testSuiteUri = Uri.withAppendedPath(testSuiteUri, "/--/$deepLink") 73*21373fa4SWill Schurman } 74*21373fa4SWill Schurman 75*21373fa4SWill Schurman // Launch the app 76*21373fa4SWill Schurman val context = InstrumentationRegistry.getContext() 77*21373fa4SWill Schurman val intent = Intent(Intent.ACTION_VIEW, testSuiteUri) 78*21373fa4SWill Schurman intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) 79*21373fa4SWill Schurman context.startActivity(intent) 80*21373fa4SWill Schurman 81*21373fa4SWill Schurman // Wait for the app to appear 82*21373fa4SWill Schurman uiDevice.wait(Until.hasObject(By.pkg("host.exp.exponent").depth(0)), LAUNCH_TIMEOUT.toLong()) 83*21373fa4SWill Schurman 84*21373fa4SWill Schurman // Need this to wait on idling resources 85*21373fa4SWill Schurman Espresso.onView(ExponentMatchers.withTestId("test_suite_container")) 86*21373fa4SWill Schurman .check(ViewAssertions.matches(ViewMatchers.isEnabled())) 87*21373fa4SWill Schurman val result = jsTestRunnerIdlingResource.testResult 88*21373fa4SWill Schurman try { 89*21373fa4SWill Schurman val jsonObject = JSONObject(result) 90*21373fa4SWill Schurman val numFailed = jsonObject.getInt("failed") 91*21373fa4SWill Schurman if (jsonObject.has("results")) { 92*21373fa4SWill Schurman testReporterRule.logTestInfo(jsonObject.getString("results")) 93*21373fa4SWill Schurman } 94*21373fa4SWill Schurman if (jsonObject.has("failures")) { 95*21373fa4SWill Schurman testReporterRule.logTestInfo(jsonObject.getString("failures")) 96*21373fa4SWill Schurman } 97*21373fa4SWill Schurman if (numFailed > 0) { 98*21373fa4SWill Schurman throw AssertionError("$numFailed JS test(s) failed") 99*21373fa4SWill Schurman } 100*21373fa4SWill Schurman } catch (e: JSONException) { 101*21373fa4SWill Schurman throw AssertionError("JSON error $e") 102*21373fa4SWill Schurman } 103*21373fa4SWill Schurman } 104*21373fa4SWill Schurman 105*21373fa4SWill Schurman private val testReporterRule = TestReporterRule() 106*21373fa4SWill Schurman 107*21373fa4SWill Schurman @Rule 108*21373fa4SWill Schurman @JvmField 109*21373fa4SWill Schurman val chain: RuleChain = RuleChain.outerRule(testReporterRule).around(RetryTestRule(2)) 110*21373fa4SWill Schurman 111*21373fa4SWill Schurman @Rule 112*21373fa4SWill Schurman @JvmField 113*21373fa4SWill Schurman val permissionRule: GrantPermissionRule = GrantPermissionRule.grant( 114*21373fa4SWill Schurman Manifest.permission.SYSTEM_ALERT_WINDOW, Manifest.permission.READ_CONTACTS, 115*21373fa4SWill Schurman Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION, 116*21373fa4SWill Schurman Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE, 117*21373fa4SWill Schurman Manifest.permission.READ_CALENDAR, Manifest.permission.WRITE_CALENDAR 118*21373fa4SWill Schurman ) 119*21373fa4SWill Schurman 120*21373fa4SWill Schurman @Test 121*21373fa4SWill Schurman @ExpoTestSuiteTest 122*21373fa4SWill Schurman @ExpoSdkVersionTest("UNVERSIONED") sdkUnversionedTestSuitenull123*21373fa4SWill Schurman fun sdkUnversionedTestSuite() { 124*21373fa4SWill Schurman if (!isCurrentTestSuiteAvailable) { 125*21373fa4SWill Schurman return 126*21373fa4SWill Schurman } 127*21373fa4SWill Schurman KernelConfig.FORCE_UNVERSIONED_PUBLISHED_EXPERIENCES = true 128*21373fa4SWill Schurman runTestSuiteTest(ExponentBuildConstants.TEST_APP_URI, true) 129*21373fa4SWill Schurman } 130*21373fa4SWill Schurman 131*21373fa4SWill Schurman @Test 132*21373fa4SWill Schurman @ExpoAlwaysPassThroughFilter junitIsSillyAndWillFailIfThereIsntOneTestRunPerFilenull133*21373fa4SWill Schurman fun junitIsSillyAndWillFailIfThereIsntOneTestRunPerFile() { 134*21373fa4SWill Schurman } 135*21373fa4SWill Schurman 136*21373fa4SWill Schurman companion object { 137*21373fa4SWill Schurman @BeforeClass 138*21373fa4SWill Schurman @JvmStatic beforeClassnull139*21373fa4SWill Schurman fun beforeClass() { 140*21373fa4SWill Schurman BaseTestClass.beforeClass() 141*21373fa4SWill Schurman 142*21373fa4SWill Schurman // Press home 143*21373fa4SWill Schurman uiDevice.pressHome() 144*21373fa4SWill Schurman val launcherPackage = uiDevice.launcherPackageName 145*21373fa4SWill Schurman uiDevice.wait(Until.hasObject(By.pkg(launcherPackage).depth(0)), LAUNCH_TIMEOUT.toLong()) 146*21373fa4SWill Schurman } 147*21373fa4SWill Schurman 148*21373fa4SWill Schurman val isCurrentTestSuiteAvailable: Boolean 149*21373fa4SWill Schurman get() = ExponentBuildConstants.TEST_APP_URI != "" 150*21373fa4SWill Schurman } 151*21373fa4SWill Schurman } 152