@@ -11,9 +11,9 @@ import androidx.test.ext.junit.runners.AndroidJUnit4
1111import androidx.test.platform.app.InstrumentationRegistry
1212import androidx.test.runner.lifecycle.ActivityLifecycleMonitorRegistry
1313import androidx.test.runner.lifecycle.Stage
14- import androidx.test.uiautomator.UiDevice
15- import androidx.test.uiautomator.UiSelector
1614import androidx.test.uiautomator.By
15+ import androidx.test.uiautomator.UiDevice
16+ import androidx.test.uiautomator.Until
1717import com.iterable.iterableapi.IterableApi
1818import com.iterable.iterableapi.IterableInAppMessage
1919import com.iterable.iterableapi.IterableInAppLocation
@@ -38,6 +38,10 @@ class InAppMessageIntegrationTest : BaseIntegrationTest() {
3838 private const val TAG = " InAppMessageIntegrationTest"
3939 private const val TEST_CAMPAIGN_ID = TestConstants .TEST_INAPP_CAMPAIGN_ID
4040 private const val TEST_EVENT_NAME = " test_inapp_event"
41+
42+ // SDK-170: ample wait so a slow CI emulator (SurfaceSyncGroup timeouts in logs) can
43+ // finish drawing MainActivity before we look for the button. Local cost: 0 (passes fast).
44+ private const val BTN_IN_APP_TIMEOUT_MS = 30_000L
4145 }
4246
4347 private lateinit var uiDevice: UiDevice
@@ -100,16 +104,22 @@ class InAppMessageIntegrationTest : BaseIntegrationTest() {
100104
101105 Log .d(TAG , " 🔧 MainActivity is ready!" )
102106
103- // Step 2: Click the "In-App Messages" button to navigate to InAppMessageTestActivity
104- Log .d(TAG , " 🔧 Step 2: Clicking 'In-App Messages' button..." )
105- val inAppButton = uiDevice.findObject(UiSelector ().resourceId(" com.iterable.integration.tests:id/btnInAppMessages" ))
106- if (inAppButton.exists()) {
107+ // Step 2: Click the "In-App Messages" button to navigate to InAppMessageTestActivity.
108+ // SDK-170: Lifecycle.RESUMED does not guarantee the layout is drawn — under CI load
109+ // (SurfaceSyncGroup transaction-ready timeouts), `findObject(...).exists()` ran ~2s
110+ // after RESUMED and returned false because the button view was not yet present in the
111+ // accessibility tree. `uiDevice.wait(Until.findObject(...))` polls until the node
112+ // appears or the timeout elapses.
113+ Log .d(TAG , " 🔧 Step 2: Waiting for and clicking 'In-App Messages' button..." )
114+ val inAppButton = uiDevice.wait(
115+ Until .findObject(By .res(" com.iterable.integration.tests" , " btnInAppMessages" )),
116+ BTN_IN_APP_TIMEOUT_MS
117+ )
118+ if (inAppButton != null ) {
107119 inAppButton.click()
108120 Log .d(TAG , " 🔧 Clicked In-App Messages button successfully" )
109121 } else {
110- // Take screenshot for debugging
111- // uiDevice.takeScreenshot(File("/sdcard/Download/InAppButtonNotFound.png"))
112- Log .e(TAG , " ❌ In-App Messages button not found!" )
122+ Log .e(TAG , " ❌ In-App Messages button not found within ${BTN_IN_APP_TIMEOUT_MS } ms (current package: ${uiDevice.currentPackageName} )" )
113123 Assert .fail(" In-App Messages button not found in MainActivity" )
114124 }
115125
0 commit comments