Dmitriy Gaiduk
03/31/2026, 4:22 PMgetInstance method in the Toothpick library.
Any ideas what the problem might be? Or how I can find the error?
Toothpick.openScopes("scope").getInstance(TestClass::class.java)
The Toothpick library is used throughout the entire application, but in the tests, it only freezes after opening a second window in the application.
What's happening:
1. The UI is unavailable in the application. Button clicks don't work.
2. The timeout doesn't work in the UI tests. The test runs indefinitely.
My guess is that this is due to the different thread synchronization mechanisms in Kotlin Coroutines and Java Threads. We use Kotlin Coroutines in the project. Internally, the Toothpick library uses synchronization for Java Threads.
What I did:
1) I ran tests with the composeTestRule.mainClock.autoAdvance = false parameter.
2) I tried using the Kaspresso library.
3) I disabled animations in the Android emulator.
adb shell settings put global window_animation_scale 0
adb shell settings put global transition_animation_scale 0
adb shell settings put global animator_duration_scale 0
4) I ran the jstack -l <pid> command. But I got the error:
state is not ready to participate in attach handshake!
5) I got a thread dump in debug mode. But I didn't find the blocked thread, Thread.State: BLOCKED. All threads are in the WAITING or RUNNABLE state.Dmitriy Gaiduk
03/31/2026, 4:23 PM@RunWith(AndroidJUnit4::class)
@LargeTest
class UiTest {
@get:Rule
val composeTestRule = createAndroidComposeRule<MainActivity>()
@Test
fun authorizationFlow() {
composeTestRule.waitUntil(timeoutMillis = 2000) {
composeTestRule.onAllNodes(
matcher = hasTestTag("phone_input"),
useUnmergedTree = false
).fetchSemanticsNodes()
.isNotEmpty()
}
composeTestRule
.onNodeWithTag("phone_input")
.onChildren()
.filter(hasSetTextAction())
.onFirst()
.performTextInput("12345")
composeTestRule.waitForIdle()
composeTestRule
.onNodeWithTag("continue_button", useUnmergedTree = true)
.performClick()
composeTestRule.waitForIdle()
composeTestRule.waitUntil(timeoutMillis = 5000) {
composeTestRule.onAllNodes(
matcher = hasTestTag("otp_screen"),
useUnmergedTree = false
).fetchSemanticsNodes()
.isNotEmpty()
}
}
}Dmitriy Gaiduk
04/01/2026, 10:55 AM