Skip to content

Commit 9ddfa9e

Browse files
@W-21933885: [MSDK Android] App Attestation Implementation (Add explicit timeouts to ScreenLockActivityScenarioTest)
- Add global 30-second timeout rule for all tests - Add configurable timeout parameter to waitForCondition helper (default: 10s) - Set 15-second timeouts for accessibility event tests (most prone to delays) - Add timeout validation with clear error messages - Poll condition every 50ms with explicit timeout checking These timeouts provide additional safety for Firebase Test Lab devices that may have slower accessibility service processing or CPU constraints.)
1 parent 0f15179 commit 9ddfa9e

1 file changed

Lines changed: 42 additions & 10 deletions

File tree

libs/test/SalesforceSDKTest/src/com/salesforce/androidsdk/ui/ScreenLockActivityScenarioTest.kt

Lines changed: 42 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -85,8 +85,11 @@ import io.mockk.verify
8585
import org.junit.Assert.assertEquals
8686
import org.junit.Assert.assertFalse
8787
import org.junit.Assert.assertTrue
88+
import org.junit.Rule
8889
import org.junit.Test
90+
import org.junit.rules.Timeout
8991
import org.junit.runner.RunWith
92+
import java.util.concurrent.TimeUnit
9093

9194
/**
9295
* IdlingResource that waits for a condition to become true.
@@ -117,15 +120,32 @@ class ViewModelIdlingResource(
117120
/**
118121
* Helper function to wait for a condition using IdlingResource.
119122
* Automatically registers and unregisters the idling resource.
123+
*
124+
* @param resourceName Name for the idling resource (for debugging)
125+
* @param condition Lambda that returns true when the condition is met
126+
* @param timeoutSeconds Maximum time to wait for the condition (default: 10 seconds)
127+
* @param block Code to execute once the condition is met
120128
*/
121129
inline fun <T> waitForCondition(
122130
resourceName: String,
123131
noinline condition: () -> Boolean,
132+
timeoutSeconds: Long = 10,
124133
block: () -> T
125134
): T {
126135
val idlingResource = ViewModelIdlingResource(resourceName, condition)
127136
IdlingRegistry.getInstance().register(idlingResource)
128137
try {
138+
val startTime = System.currentTimeMillis()
139+
val timeoutMillis = TimeUnit.SECONDS.toMillis(timeoutSeconds)
140+
141+
// Wait for condition with timeout
142+
while (!condition()) {
143+
if (System.currentTimeMillis() - startTime > timeoutMillis) {
144+
throw AssertionError("Timeout waiting for condition '$resourceName' after ${timeoutSeconds}s")
145+
}
146+
Thread.sleep(50) // Poll every 50ms
147+
}
148+
129149
return block()
130150
} finally {
131151
IdlingRegistry.getInstance().unregister(idlingResource)
@@ -135,6 +155,13 @@ inline fun <T> waitForCondition(
135155
@RunWith(AndroidJUnit4::class)
136156
class ScreenLockActivityScenarioTest {
137157

158+
/**
159+
* Global timeout rule for all tests in this class.
160+
* Each test will timeout after 30 seconds to accommodate slower Firebase Test Lab devices.
161+
*/
162+
@get:Rule
163+
val globalTimeout: Timeout = Timeout(30, TimeUnit.SECONDS)
164+
138165
@Test
139166
fun screenLockActivity_appliesDefaults_whenCreated() {
140167
launch<ScreenLockActivity>(
@@ -707,7 +734,7 @@ class ScreenLockActivityScenarioTest {
707734
errString = errorString
708735
)
709736

710-
// Wait for accessibility event to be sent
737+
// Wait for accessibility event to be sent (longer timeout for accessibility)
711738
waitForCondition(
712739
resourceName = "AccessibilityEventSent",
713740
condition = {
@@ -717,7 +744,8 @@ class ScreenLockActivityScenarioTest {
717744
} catch (e: AssertionError) {
718745
false
719746
}
720-
}
747+
},
748+
timeoutSeconds = 15
721749
) {
722750
verify(exactly = 1) { accessibilityManager.sendAccessibilityEvent(capture(capturingSlot)) }
723751
assertTrue(capturingSlot.captured.text.toString().contains(authenticationErrorString))
@@ -764,7 +792,7 @@ class ScreenLockActivityScenarioTest {
764792
errString = errorString
765793
)
766794

767-
// Wait for accessibility event to be sent
795+
// Wait for accessibility event to be sent (longer timeout for accessibility)
768796
waitForCondition(
769797
resourceName = "AccessibilityEventSent",
770798
condition = {
@@ -774,7 +802,8 @@ class ScreenLockActivityScenarioTest {
774802
} catch (e: AssertionError) {
775803
false
776804
}
777-
}
805+
},
806+
timeoutSeconds = 15
778807
) {
779808
verify(exactly = 1) { accessibilityManager.sendAccessibilityEvent(capture(capturingSlot)) }
780809
assertTrue(capturingSlot.captured.text.toString().contains(authenticationErrorString))
@@ -820,7 +849,7 @@ class ScreenLockActivityScenarioTest {
820849
screenLockManager = screenLockManager,
821850
)
822851

823-
// Wait for accessibility event to be sent
852+
// Wait for accessibility event to be sent (longer timeout for accessibility)
824853
waitForCondition(
825854
resourceName = "AccessibilityEventSent",
826855
condition = {
@@ -830,7 +859,8 @@ class ScreenLockActivityScenarioTest {
830859
} catch (e: AssertionError) {
831860
false
832861
}
833-
}
862+
},
863+
timeoutSeconds = 15
834864
) {
835865
verify(exactly = 1) { accessibilityManager.sendAccessibilityEvent(capture(capturingSlot)) }
836866
assertTrue(capturingSlot.captured.text.toString().contains(activity.getString(sf__screen_lock_auth_success)))
@@ -874,7 +904,7 @@ class ScreenLockActivityScenarioTest {
874904
screenLockManager = null,
875905
)
876906

877-
// Wait for accessibility event to be sent
907+
// Wait for accessibility event to be sent (longer timeout for accessibility)
878908
waitForCondition(
879909
resourceName = "AccessibilityEventSent",
880910
condition = {
@@ -884,7 +914,8 @@ class ScreenLockActivityScenarioTest {
884914
} catch (e: AssertionError) {
885915
false
886916
}
887-
}
917+
},
918+
timeoutSeconds = 15
888919
) {
889920
verify(exactly = 1) { accessibilityManager.sendAccessibilityEvent(capture(capturingSlot)) }
890921
assertTrue(capturingSlot.captured.text.toString().contains(activity.getString(sf__screen_lock_auth_success)))
@@ -928,7 +959,7 @@ class ScreenLockActivityScenarioTest {
928959
sdkConfiguration = AndroidSdkConfigurationQ
929960
)
930961

931-
// Wait for accessibility event to be sent
962+
// Wait for accessibility event to be sent (longer timeout for accessibility)
932963
waitForCondition(
933964
resourceName = "AccessibilityEventSent",
934965
condition = {
@@ -938,7 +969,8 @@ class ScreenLockActivityScenarioTest {
938969
} catch (e: AssertionError) {
939970
false
940971
}
941-
}
972+
},
973+
timeoutSeconds = 15
942974
) {
943975
verify(exactly = 1) { accessibilityManager.sendAccessibilityEvent(capture(capturingSlot)) }
944976
assertTrue(capturingSlot.captured.text.toString().contains(activity.getString(sf__screen_lock_auth_success)))

0 commit comments

Comments
 (0)