@@ -34,12 +34,15 @@ import kotlinx.coroutines.CoroutineScope
3434import kotlinx.coroutines.Dispatchers
3535import kotlinx.coroutines.Job
3636import kotlinx.coroutines.MainScope
37+ import kotlinx.coroutines.TimeoutCancellationException
3738import kotlinx.coroutines.channels.Channel
3839import kotlinx.coroutines.flow.collect
3940import kotlinx.coroutines.flow.takeWhile
4041import kotlinx.coroutines.launch
4142import kotlinx.coroutines.test.TestResult
4243import kotlinx.coroutines.test.runTest
44+ import kotlinx.coroutines.withContext
45+ import kotlinx.coroutines.withTimeout
4346import kotlinx.coroutines.yield
4447import org.w3c.dom.Element
4548import org.w3c.dom.HTMLCanvasElement
@@ -103,13 +106,23 @@ internal interface OnCanvasTests {
103106 ) {
104107 ComposeViewport (viewportContainerId = containerId, configure = configure, content = content)
105108
106- suspendCoroutine { continuation ->
107- // This helps reduce the flakiness.
108- // A potential cause of flakiness: the default Coroutine Dispatcher regularly postpones
109- // the resumption of the tasks in its queue to the next frame.
110- // (it does so to let the event loop run / release the single thread)
111- // I don't expect any issue from doing this, since a test will suspend and won't do anything.
112- window.requestAnimationFrame { continuation.resumeWith(Result .success(it)) }
109+ withContext(Dispatchers .Default ) {
110+ val timeoutDuration = 1 .seconds
111+ try {
112+ // Using withTimeout here for diagnostic. Some flaky tests fail due to timeout. But there is nothing else except this suspend call.
113+ withTimeout(timeoutDuration) {
114+ suspendCoroutine<Unit > { continuation ->
115+ // This helps reduce the flakiness.
116+ // A potential cause of flakiness: the default Coroutine Dispatcher regularly postpones
117+ // the resumption of the tasks in its queue to the next frame.
118+ // (it does so to let the event loop run / release the single thread)
119+ // I don't expect any issue from doing this, since a test will suspend and won't do anything.
120+ window.requestAnimationFrame { continuation.resumeWith(Result .success(Unit )) }
121+ }
122+ }
123+ } catch (e: TimeoutCancellationException ) {
124+ throw AssertionError (" Timed out ($timeoutDuration ) waiting for AnimationFrame" , e)
125+ }
113126 }
114127 }
115128
@@ -158,6 +171,18 @@ internal interface OnCanvasTests {
158171 WebApplicationScope (this ).body()
159172 }
160173 }
174+
175+ suspend fun <T > Channel<T>.receiveWithTimeout (timeout : Duration = 2.seconds): T {
176+ return withContext(Dispatchers .Default ) {
177+ try {
178+ withTimeout(timeout) {
179+ this @receiveWithTimeout.receive()
180+ }
181+ } catch (e: TimeoutCancellationException ) {
182+ throw AssertionError (" Timed out ($timeout ) waiting for value on channel" , e)
183+ }
184+ }
185+ }
161186}
162187
163188internal fun <T > Channel<T>.sendFromScope (value : T , scope : CoroutineScope = MainScope ()) {
0 commit comments