[go: nahoru, domu]

Disable blinking cursor in tests by default

The blinking cursor is a poster child example of an infinite animation.
As long as we don't have a solution in place to properly deal with
infinite animations, we disable the blinking cursor in tests to avoid
tests from timing out just because there is a TextField that has focus
in the test.

I moved the TextField tests for the cursor to a separate test class, so
we can explicitly enable (and manually control) the blinking cursor for
thoses tests.

Bug: 151940543
Test: ./gradlew ui:ui-foundation:cC ui:ui-material:cC ui:ui-test:cC
Change-Id: I12984b8f43f6b587aa5cd9aabeaea96309e9086b
diff --git a/ui/ui-foundation/src/androidTest/java/androidx/ui/foundation/SoftwareKeyboardTest.kt b/ui/ui-foundation/src/androidTest/java/androidx/ui/foundation/SoftwareKeyboardTest.kt
index 5716a5e..1eb2871 100644
--- a/ui/ui-foundation/src/androidTest/java/androidx/ui/foundation/SoftwareKeyboardTest.kt
+++ b/ui/ui-foundation/src/androidTest/java/androidx/ui/foundation/SoftwareKeyboardTest.kt
@@ -44,9 +44,7 @@
 @RunWith(JUnit4::class)
 class SoftwareKeyboardTest {
     @get:Rule
-    val composeTestRule = createComposeRule().also {
-        it.clockTestRule.pauseClock()
-    }
+    val composeTestRule = createComposeRule()
 
     @Test
     fun textField_onTextLayoutCallback() {
diff --git a/ui/ui-foundation/src/androidTest/java/androidx/ui/foundation/TextFieldCursorTest.kt b/ui/ui-foundation/src/androidTest/java/androidx/ui/foundation/TextFieldCursorTest.kt
new file mode 100644
index 0000000..155dd8c
--- /dev/null
+++ b/ui/ui-foundation/src/androidTest/java/androidx/ui/foundation/TextFieldCursorTest.kt
@@ -0,0 +1,159 @@
+/*
+ * Copyright 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.ui.foundation
+
+import android.graphics.Bitmap
+import android.os.Build
+import androidx.test.filters.LargeTest
+import androidx.test.filters.SdkSuppress
+import androidx.ui.core.Modifier
+import androidx.ui.graphics.Color
+import androidx.ui.graphics.RectangleShape
+import androidx.ui.input.TextFieldValue
+import androidx.ui.layout.padding
+import androidx.ui.layout.preferredSize
+import androidx.ui.test.assertPixels
+import androidx.ui.test.assertShape
+import androidx.ui.test.captureToBitmap
+import androidx.ui.test.createComposeRule
+import androidx.ui.test.doClick
+import androidx.ui.test.find
+import androidx.ui.test.hasInputMethodsSupport
+import androidx.ui.test.waitForIdle
+import androidx.ui.text.TextStyle
+import androidx.ui.unit.Density
+import androidx.ui.unit.Dp
+import androidx.ui.unit.IntSize
+import androidx.ui.unit.dp
+import org.junit.Rule
+import org.junit.Test
+import java.util.concurrent.CountDownLatch
+import java.util.concurrent.TimeUnit
+import kotlin.math.roundToInt
+
+@LargeTest
+class TextFieldCursorTest {
+
+    @get:Rule
+    val composeTestRule = createComposeRule(disableBlinkingCursor = false).also {
+        it.clockTestRule.pauseClock()
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = Build.VERSION_CODES.O)
+    fun textFieldFocused_cursorRendered() = with(composeTestRule.density) {
+        val width = 10.dp
+        val height = 20.dp
+        val latch = CountDownLatch(1)
+        composeTestRule.setContent {
+            TextField(
+                value = TextFieldValue(),
+                >
+                textStyle = TextStyle(color = Color.White, background = Color.White),
+                modifier = Modifier.preferredSize(width, height).drawBackground(Color.White),
+                cursorColor = Color.Red,
+                 focused ->
+                    if (focused) latch.countDown()
+                }
+            )
+        }
+        find(hasInputMethodsSupport()).doClick()
+        assert(latch.await(1, TimeUnit.SECONDS))
+
+        waitForIdle()
+
+        composeTestRule.clockTestRule.advanceClock(100)
+        with(composeTestRule.density) {
+            find(hasInputMethodsSupport())
+                .captureToBitmap()
+                .assertCursor(2.dp, this)
+        }
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = Build.VERSION_CODES.O)
+    fun cursorBlinkingAnimation() = with(composeTestRule.density) {
+        val width = 10.dp
+        val height = 20.dp
+        val latch = CountDownLatch(1)
+        composeTestRule.setContent {
+            // The padding helps if the test is run accidentally in landscape. Landscape makes
+            // the cursor to be next to the navigation bar which affects the red color to be a bit
+            // different - possibly anti-aliasing.
+            Box(Modifier.padding(10.dp)) {
+                TextField(
+                    value = TextFieldValue(),
+                    >
+                    textStyle = TextStyle(color = Color.White, background = Color.White),
+                    modifier = Modifier.preferredSize(width, height).drawBackground(Color.White),
+                    cursorColor = Color.Red,
+                     focused ->
+                        if (focused) latch.countDown()
+                    }
+                )
+            }
+        }
+
+        find(hasInputMethodsSupport()).doClick()
+        assert(latch.await(1, TimeUnit.SECONDS))
+
+        waitForIdle()
+
+        // cursor visible first 500 ms
+        composeTestRule.clockTestRule.advanceClock(100)
+        with(composeTestRule.density) {
+            find(hasInputMethodsSupport())
+                .captureToBitmap()
+                .assertCursor(2.dp, this)
+        }
+
+        // cursor invisible during next 500 ms
+        composeTestRule.clockTestRule.advanceClock(700)
+        find(hasInputMethodsSupport())
+            .captureToBitmap()
+            .assertShape(
+                density = composeTestRule.density,
+                shape = RectangleShape,
+                shapeColor = Color.White,
+                backgroundColor = Color.White,
+                shapeOverlapPixelCount = 0.0f
+            )
+    }
+
+    private fun Bitmap.assertCursor(cursorWidth: Dp, density: Density) {
+        val halfCursorWidth = (with(density) { cursorWidth.toIntPx() } / 2f).roundToInt()
+        val width = width
+        val height = height
+        this.assertPixels(
+            IntSize(width, height)
+        ) { position ->
+            if (position.x >= halfCursorWidth - 1 && position.x < halfCursorWidth + 1) {
+                // skip some pixels around cursor
+                null
+            } else if (position.y < 5 || position.y > height - 5) {
+                // skip some pixels vertically
+                null
+            } else if (position.x in 0..halfCursorWidth) {
+                // cursor
+                Color.Red
+            } else {
+                // text field background
+                Color.White
+            }
+        }
+    }
+}
diff --git a/ui/ui-foundation/src/androidTest/java/androidx/ui/foundation/TextFieldOnValueChangeTextFieldValueTest.kt b/ui/ui-foundation/src/androidTest/java/androidx/ui/foundation/TextFieldOnValueChangeTextFieldValueTest.kt
index f120305..64f61c06 100644
--- a/ui/ui-foundation/src/androidTest/java/androidx/ui/foundation/TextFieldOnValueChangeTextFieldValueTest.kt
+++ b/ui/ui-foundation/src/androidTest/java/androidx/ui/foundation/TextFieldOnValueChangeTextFieldValueTest.kt
@@ -57,9 +57,7 @@
 @RunWith(JUnit4::class)
 class TextFieldOnValueChangeTextFieldValueTest {
     @get:Rule
-    val composeTestRule = createComposeRule().also {
-        it.clockTestRule.pauseClock()
-    }
+    val composeTestRule = createComposeRule()
 
     val onValueChange: (androidx.ui.input.TextFieldValue) -> Unit = mock()
 
diff --git a/ui/ui-foundation/src/androidTest/java/androidx/ui/foundation/TextFieldTest.kt b/ui/ui-foundation/src/androidTest/java/androidx/ui/foundation/TextFieldTest.kt
index 6726476a..c009349 100644
--- a/ui/ui-foundation/src/androidTest/java/androidx/ui/foundation/TextFieldTest.kt
+++ b/ui/ui-foundation/src/androidTest/java/androidx/ui/foundation/TextFieldTest.kt
@@ -16,7 +16,6 @@
 
 package androidx.ui.foundation
 
-import android.graphics.Bitmap
 import android.os.Build
 import androidx.compose.Composable
 import androidx.compose.MutableState
@@ -39,13 +38,11 @@
 import androidx.ui.input.TextInputService
 import androidx.ui.layout.Row
 import androidx.ui.layout.fillMaxSize
-import androidx.ui.layout.padding
 import androidx.ui.layout.preferredSize
 import androidx.ui.layout.preferredWidth
 import androidx.ui.savedinstancestate.savedInstanceState
 import androidx.ui.test.StateRestorationTester
 import androidx.ui.test.assert
-import androidx.ui.test.assertPixels
 import androidx.ui.test.assertShape
 import androidx.ui.test.captureToBitmap
 import androidx.ui.test.createComposeRule
@@ -55,13 +52,8 @@
 import androidx.ui.test.hasImeAction
 import androidx.ui.test.hasInputMethodsSupport
 import androidx.ui.test.runOnIdleCompose
-import androidx.ui.test.waitForIdle
 import androidx.ui.text.TextLayoutResult
 import androidx.ui.text.TextRange
-import androidx.ui.text.TextStyle
-import androidx.ui.unit.Density
-import androidx.ui.unit.Dp
-import androidx.ui.unit.IntSize
 import androidx.ui.unit.dp
 import com.google.common.truth.Truth.assertThat
 import com.nhaarman.mockitokotlin2.any
@@ -76,17 +68,12 @@
 import org.junit.Test
 import org.junit.runner.RunWith
 import org.junit.runners.JUnit4
-import java.util.concurrent.CountDownLatch
-import java.util.concurrent.TimeUnit
-import kotlin.math.roundToInt
 
 @SmallTest
 @RunWith(JUnit4::class)
 class TextFieldTest {
     @get:Rule
-    val composeTestRule = createComposeRule().also {
-        it.clockTestRule.pauseClock()
-    }
+    val composeTestRule = createComposeRule()
 
     private val DefaultTextFieldWidth = 280.dp
 
@@ -445,92 +432,6 @@
     }
 
     @Test
-    @SdkSuppress(minSdkVersion = Build.VERSION_CODES.O)
-    fun textFieldFocused_cursorRendered() = with(composeTestRule.density) {
-        val width = 10.dp
-        val height = 20.dp
-        val latch = CountDownLatch(1)
-        composeTestRule.setContent {
-            TextField(
-                value = androidx.ui.input.TextFieldValue(),
-                >
-                textStyle = TextStyle(color = Color.White, background = Color.White),
-                modifier = Modifier.preferredSize(width, height).drawBackground(Color.White),
-                cursorColor = Color.Red,
-                 focused ->
-                    if (focused) latch.countDown()
-                }
-            )
-        }
-        find(hasInputMethodsSupport()).doClick()
-        assert(latch.await(1, TimeUnit.SECONDS))
-
-        waitForIdle()
-
-        composeTestRule.clockTestRule.advanceClock(100)
-        with(composeTestRule.density) {
-            find(hasInputMethodsSupport())
-                .captureToBitmap()
-                .assertCursor(2.dp, this)
-        }
-    }
-
-    @Test
-    @SdkSuppress(minSdkVersion = Build.VERSION_CODES.O)
-    fun cursorBlinkingAnimation() = with(composeTestRule.density) {
-        val width = 10.dp
-        val height = 20.dp
-        val latch = CountDownLatch(1)
-        composeTestRule.setContent {
-            // The padding helps if the test is run accidentally in landscape. Landscape makes
-            // the cursor to be next to the navigation bar which affects the red color to be a bit
-            // different - possibly anti-aliasing.
-            Box(Modifier.padding(10.dp)) {
-                TextField(
-                    value = androidx.ui.input.TextFieldValue(),
-                    >
-                    textStyle = TextStyle(color = Color.White, background = Color.White),
-                    modifier = Modifier.preferredSize(width, height).drawBackground(Color.White),
-                    cursorColor = Color.Red,
-                     focused ->
-                        if (focused) latch.countDown()
-                    }
-                )
-            }
-        }
-
-        find(hasInputMethodsSupport()).doClick()
-        assert(latch.await(1, TimeUnit.SECONDS))
-
-        waitForIdle()
-
-        // cursor visible first 500 ms
-        composeTestRule.clockTestRule.advanceClock(100)
-        with(composeTestRule.density) {
-            find(hasInputMethodsSupport())
-                .captureToBitmap()
-                .assertCursor(2.dp, this)
-        }
-
-        // cursor invisible during next 500 ms
-        composeTestRule.clockTestRule.advanceClock(700)
-
-        // TODO: There seems to be an issue on Pixel that we capture the bitmap too early and
-        // perform the assert while the cursor is still there.
-        waitForIdle()
-
-        find(hasInputMethodsSupport())
-            .captureToBitmap()
-            .assertShape(
-                density = composeTestRule.density,
-                shape = RectangleShape,
-                shapeColor = Color.White,
-                backgroundColor = Color.White,
-                shapeOverlapPixelCount = 0.0f
-            )
-    }
-
-    @Test
     fun defaultSemantics() {
         composeTestRule.setContent {
             TextField(
@@ -558,27 +459,4 @@
         find(hasInputMethodsSupport())
             .assert(hasImeAction(ImeAction.Search))
     }
-
-    private fun Bitmap.assertCursor(cursorWidth: Dp, density: Density) {
-        val halfCursorWidth = (with(density) { cursorWidth.toIntPx() } / 2f).roundToInt()
-        val width = width
-        val height = height
-        this.assertPixels(
-            IntSize(width, height)
-        ) { position ->
-            if (position.x >= halfCursorWidth - 1 && position.x < halfCursorWidth + 1) {
-                // skip some pixels around cursor
-                null
-            } else if (position.y < 5 || position.y > height - 5) {
-                // skip some pixels vertically
-                null
-            } else if (position.x in 0..halfCursorWidth) {
-                // cursor
-                Color.Red
-            } else {
-                // text field background
-                Color.White
-            }
-        }
-    }
 }
diff --git a/ui/ui-foundation/src/main/java/androidx/ui/foundation/TextField.kt b/ui/ui-foundation/src/main/java/androidx/ui/foundation/TextField.kt
index a5cce64..4b8ea49 100644
--- a/ui/ui-foundation/src/main/java/androidx/ui/foundation/TextField.kt
+++ b/ui/ui-foundation/src/main/java/androidx/ui/foundation/TextField.kt
@@ -20,6 +20,7 @@
 import androidx.animation.Infinite
 import androidx.animation.KeyframesBuilder
 import androidx.animation.RepeatableBuilder
+import androidx.annotation.RestrictTo
 import androidx.compose.Composable
 import androidx.compose.Immutable
 import androidx.compose.Stable
@@ -55,6 +56,14 @@
 import androidx.ui.text.TextRange
 import androidx.ui.text.TextStyle
 import androidx.ui.unit.dp
+import org.jetbrains.annotations.TestOnly
+
+// TODO(b/151940543): Remove this variable when we have a solution for idling animations
+/** @suppress */
+@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
+var blinkingCursorEnabled: Boolean = true
+    @TestOnly
+    set
 
 /**
  * A class holding information about the editing state.
@@ -254,15 +263,20 @@
     val animColor = animatedColor(cursorColor)
     onCommit(cursorColor, cursorState.focused, fullModel.value) {
         if (cursorNeeded) {
-            animColor.animateTo(Color.Transparent, anim = RepeatableBuilder<Color>().apply {
-                iterations = Infinite
-                animation = KeyframesBuilder<Color>().apply {
-                    duration = 1000
-                    cursorColor at 0
-                    cursorColor at 499
-                    Color.Transparent at 500
-                }
-            })
+            // TODO(b/151940543): Disable blinking in tests until we handle idling animations
+            if (blinkingCursorEnabled) {
+                animColor.animateTo(Color.Transparent, anim = RepeatableBuilder<Color>().apply {
+                    iterations = Infinite
+                    animation = KeyframesBuilder<Color>().apply {
+                        duration = 1000
+                        cursorColor at 0
+                        cursorColor at 499
+                        Color.Transparent at 500
+                    }
+                })
+            } else {
+                animColor.snapTo(cursorColor)
+            }
         } else {
             animColor.snapTo(Color.Transparent)
         }
diff --git a/ui/ui-material/src/androidTest/java/androidx/ui/material/FilledTextFieldTest.kt b/ui/ui-material/src/androidTest/java/androidx/ui/material/FilledTextFieldTest.kt
index 408cc6b..077bc1d 100644
--- a/ui/ui-material/src/androidTest/java/androidx/ui/material/FilledTextFieldTest.kt
+++ b/ui/ui-material/src/androidTest/java/androidx/ui/material/FilledTextFieldTest.kt
@@ -100,9 +100,7 @@
             "fugiat nulla pariatur."
 
     @get:Rule
-    val testRule = createComposeRule().also {
-        it.clockTestRule.pauseClock()
-    }
+    val testRule = createComposeRule()
 
     @Test
     fun testTextFieldMinimumHeight() {
diff --git a/ui/ui-test/api/0.1.0-dev14.txt b/ui/ui-test/api/0.1.0-dev14.txt
index c10248e..3e96191 100644
--- a/ui/ui-test/api/0.1.0-dev14.txt
+++ b/ui/ui-test/api/0.1.0-dev14.txt
@@ -362,11 +362,11 @@
   }
 
   public final class AndroidComposeTestRule<T extends androidx.activity.ComponentActivity> implements androidx.ui.test.ComposeTestRule {
-    ctor public AndroidComposeTestRule(androidx.test.ext.junit.rules.ActivityScenarioRule<T> activityRule, androidx.compose.Recomposer? recomposer, boolean disableTransitions);
+    ctor public AndroidComposeTestRule(androidx.test.rule.ActivityTestRule<T> activityTestRule, androidx.compose.Recomposer? recomposer, boolean disableTransitions);
     method public org.junit.runners.model.Statement apply(org.junit.runners.model.Statement base, org.junit.runner.Description? description);
     method public androidx.ui.test.ComposeTestCaseSetup forGivenContent(kotlin.jvm.functions.Function0<kotlin.Unit> composable);
     method public androidx.ui.test.ComposeTestCaseSetup forGivenTestCase(androidx.ui.test.ComposeTestCase testCase);
-    method public androidx.test.ext.junit.rules.ActivityScenarioRule<T> getActivityRule();
+    method public androidx.test.rule.ActivityTestRule<T> getActivityTestRule();
     method public androidx.ui.test.AnimationClockTestRule getClockTestRule();
     method public androidx.ui.unit.Density getDensity();
     method public android.util.DisplayMetrics getDisplayMetrics();
diff --git a/ui/ui-test/api/api_lint.ignore b/ui/ui-test/api/api_lint.ignore
index b999d45..9ed2298 100644
--- a/ui/ui-test/api/api_lint.ignore
+++ b/ui/ui-test/api/api_lint.ignore
@@ -1,3 +1,3 @@
 // Baseline format: 1.0
-MissingNullability: androidx.ui.test.android.AndroidComposeTestRuleKt#AndroidComposeTestRule(androidx.compose.Recomposer, boolean):
+MissingNullability: androidx.ui.test.android.AndroidComposeTestRuleKt#AndroidComposeTestRule(androidx.compose.Recomposer, boolean, boolean):
     Missing nullability on method `AndroidComposeTestRule` return
diff --git a/ui/ui-test/api/current.txt b/ui/ui-test/api/current.txt
index c10248e..aae1c4c 100644
--- a/ui/ui-test/api/current.txt
+++ b/ui/ui-test/api/current.txt
@@ -137,7 +137,7 @@
   }
 
   public final class ComposeTestRuleKt {
-    method public static androidx.ui.test.ComposeTestRule createComposeRule(androidx.compose.Recomposer? recomposer = null, boolean disableTransitions = false);
+    method public static androidx.ui.test.ComposeTestRule createComposeRule(androidx.compose.Recomposer? recomposer = null, boolean disableTransitions = false, boolean disableBlinkingCursor = true);
   }
 
   public final class DisableTransitions implements org.junit.rules.TestRule {
@@ -362,7 +362,7 @@
   }
 
   public final class AndroidComposeTestRule<T extends androidx.activity.ComponentActivity> implements androidx.ui.test.ComposeTestRule {
-    ctor public AndroidComposeTestRule(androidx.test.ext.junit.rules.ActivityScenarioRule<T> activityRule, androidx.compose.Recomposer? recomposer, boolean disableTransitions);
+    ctor public AndroidComposeTestRule(androidx.test.ext.junit.rules.ActivityScenarioRule<T> activityRule, androidx.compose.Recomposer? recomposer, boolean disableTransitions, boolean disableBlinkingCursor);
     method public org.junit.runners.model.Statement apply(org.junit.runners.model.Statement base, org.junit.runner.Description? description);
     method public androidx.ui.test.ComposeTestCaseSetup forGivenContent(kotlin.jvm.functions.Function0<kotlin.Unit> composable);
     method public androidx.ui.test.ComposeTestCaseSetup forGivenTestCase(androidx.ui.test.ComposeTestCase testCase);
@@ -383,7 +383,7 @@
   }
 
   public final class AndroidComposeTestRuleKt {
-    method public static inline <reified T extends androidx.activity.ComponentActivity> androidx.ui.test.android.AndroidComposeTestRule<T>! AndroidComposeTestRule(androidx.compose.Recomposer? recomposer = null, boolean disableTransitions = false);
+    method public static inline <reified T extends androidx.activity.ComponentActivity> androidx.ui.test.android.AndroidComposeTestRule<T>! AndroidComposeTestRule(androidx.compose.Recomposer? recomposer = null, boolean disableTransitions = false, boolean disableBlinkingCursor = true);
   }
 
   public final class ComposeIdlingResourceKt {
diff --git a/ui/ui-test/api/public_plus_experimental_0.1.0-dev14.txt b/ui/ui-test/api/public_plus_experimental_0.1.0-dev14.txt
index c10248e..3e96191 100644
--- a/ui/ui-test/api/public_plus_experimental_0.1.0-dev14.txt
+++ b/ui/ui-test/api/public_plus_experimental_0.1.0-dev14.txt
@@ -362,11 +362,11 @@
   }
 
   public final class AndroidComposeTestRule<T extends androidx.activity.ComponentActivity> implements androidx.ui.test.ComposeTestRule {
-    ctor public AndroidComposeTestRule(androidx.test.ext.junit.rules.ActivityScenarioRule<T> activityRule, androidx.compose.Recomposer? recomposer, boolean disableTransitions);
+    ctor public AndroidComposeTestRule(androidx.test.rule.ActivityTestRule<T> activityTestRule, androidx.compose.Recomposer? recomposer, boolean disableTransitions);
     method public org.junit.runners.model.Statement apply(org.junit.runners.model.Statement base, org.junit.runner.Description? description);
     method public androidx.ui.test.ComposeTestCaseSetup forGivenContent(kotlin.jvm.functions.Function0<kotlin.Unit> composable);
     method public androidx.ui.test.ComposeTestCaseSetup forGivenTestCase(androidx.ui.test.ComposeTestCase testCase);
-    method public androidx.test.ext.junit.rules.ActivityScenarioRule<T> getActivityRule();
+    method public androidx.test.rule.ActivityTestRule<T> getActivityTestRule();
     method public androidx.ui.test.AnimationClockTestRule getClockTestRule();
     method public androidx.ui.unit.Density getDensity();
     method public android.util.DisplayMetrics getDisplayMetrics();
diff --git a/ui/ui-test/api/public_plus_experimental_current.txt b/ui/ui-test/api/public_plus_experimental_current.txt
index c10248e..aae1c4c 100644
--- a/ui/ui-test/api/public_plus_experimental_current.txt
+++ b/ui/ui-test/api/public_plus_experimental_current.txt
@@ -137,7 +137,7 @@
   }
 
   public final class ComposeTestRuleKt {
-    method public static androidx.ui.test.ComposeTestRule createComposeRule(androidx.compose.Recomposer? recomposer = null, boolean disableTransitions = false);
+    method public static androidx.ui.test.ComposeTestRule createComposeRule(androidx.compose.Recomposer? recomposer = null, boolean disableTransitions = false, boolean disableBlinkingCursor = true);
   }
 
   public final class DisableTransitions implements org.junit.rules.TestRule {
@@ -362,7 +362,7 @@
   }
 
   public final class AndroidComposeTestRule<T extends androidx.activity.ComponentActivity> implements androidx.ui.test.ComposeTestRule {
-    ctor public AndroidComposeTestRule(androidx.test.ext.junit.rules.ActivityScenarioRule<T> activityRule, androidx.compose.Recomposer? recomposer, boolean disableTransitions);
+    ctor public AndroidComposeTestRule(androidx.test.ext.junit.rules.ActivityScenarioRule<T> activityRule, androidx.compose.Recomposer? recomposer, boolean disableTransitions, boolean disableBlinkingCursor);
     method public org.junit.runners.model.Statement apply(org.junit.runners.model.Statement base, org.junit.runner.Description? description);
     method public androidx.ui.test.ComposeTestCaseSetup forGivenContent(kotlin.jvm.functions.Function0<kotlin.Unit> composable);
     method public androidx.ui.test.ComposeTestCaseSetup forGivenTestCase(androidx.ui.test.ComposeTestCase testCase);
@@ -383,7 +383,7 @@
   }
 
   public final class AndroidComposeTestRuleKt {
-    method public static inline <reified T extends androidx.activity.ComponentActivity> androidx.ui.test.android.AndroidComposeTestRule<T>! AndroidComposeTestRule(androidx.compose.Recomposer? recomposer = null, boolean disableTransitions = false);
+    method public static inline <reified T extends androidx.activity.ComponentActivity> androidx.ui.test.android.AndroidComposeTestRule<T>! AndroidComposeTestRule(androidx.compose.Recomposer? recomposer = null, boolean disableTransitions = false, boolean disableBlinkingCursor = true);
   }
 
   public final class ComposeIdlingResourceKt {
diff --git a/ui/ui-test/api/restricted_0.1.0-dev14.txt b/ui/ui-test/api/restricted_0.1.0-dev14.txt
index c10248e..3e96191 100644
--- a/ui/ui-test/api/restricted_0.1.0-dev14.txt
+++ b/ui/ui-test/api/restricted_0.1.0-dev14.txt
@@ -362,11 +362,11 @@
   }
 
   public final class AndroidComposeTestRule<T extends androidx.activity.ComponentActivity> implements androidx.ui.test.ComposeTestRule {
-    ctor public AndroidComposeTestRule(androidx.test.ext.junit.rules.ActivityScenarioRule<T> activityRule, androidx.compose.Recomposer? recomposer, boolean disableTransitions);
+    ctor public AndroidComposeTestRule(androidx.test.rule.ActivityTestRule<T> activityTestRule, androidx.compose.Recomposer? recomposer, boolean disableTransitions);
     method public org.junit.runners.model.Statement apply(org.junit.runners.model.Statement base, org.junit.runner.Description? description);
     method public androidx.ui.test.ComposeTestCaseSetup forGivenContent(kotlin.jvm.functions.Function0<kotlin.Unit> composable);
     method public androidx.ui.test.ComposeTestCaseSetup forGivenTestCase(androidx.ui.test.ComposeTestCase testCase);
-    method public androidx.test.ext.junit.rules.ActivityScenarioRule<T> getActivityRule();
+    method public androidx.test.rule.ActivityTestRule<T> getActivityTestRule();
     method public androidx.ui.test.AnimationClockTestRule getClockTestRule();
     method public androidx.ui.unit.Density getDensity();
     method public android.util.DisplayMetrics getDisplayMetrics();
diff --git a/ui/ui-test/api/restricted_current.txt b/ui/ui-test/api/restricted_current.txt
index c10248e..aae1c4c 100644
--- a/ui/ui-test/api/restricted_current.txt
+++ b/ui/ui-test/api/restricted_current.txt
@@ -137,7 +137,7 @@
   }
 
   public final class ComposeTestRuleKt {
-    method public static androidx.ui.test.ComposeTestRule createComposeRule(androidx.compose.Recomposer? recomposer = null, boolean disableTransitions = false);
+    method public static androidx.ui.test.ComposeTestRule createComposeRule(androidx.compose.Recomposer? recomposer = null, boolean disableTransitions = false, boolean disableBlinkingCursor = true);
   }
 
   public final class DisableTransitions implements org.junit.rules.TestRule {
@@ -362,7 +362,7 @@
   }
 
   public final class AndroidComposeTestRule<T extends androidx.activity.ComponentActivity> implements androidx.ui.test.ComposeTestRule {
-    ctor public AndroidComposeTestRule(androidx.test.ext.junit.rules.ActivityScenarioRule<T> activityRule, androidx.compose.Recomposer? recomposer, boolean disableTransitions);
+    ctor public AndroidComposeTestRule(androidx.test.ext.junit.rules.ActivityScenarioRule<T> activityRule, androidx.compose.Recomposer? recomposer, boolean disableTransitions, boolean disableBlinkingCursor);
     method public org.junit.runners.model.Statement apply(org.junit.runners.model.Statement base, org.junit.runner.Description? description);
     method public androidx.ui.test.ComposeTestCaseSetup forGivenContent(kotlin.jvm.functions.Function0<kotlin.Unit> composable);
     method public androidx.ui.test.ComposeTestCaseSetup forGivenTestCase(androidx.ui.test.ComposeTestCase testCase);
@@ -383,7 +383,7 @@
   }
 
   public final class AndroidComposeTestRuleKt {
-    method public static inline <reified T extends androidx.activity.ComponentActivity> androidx.ui.test.android.AndroidComposeTestRule<T>! AndroidComposeTestRule(androidx.compose.Recomposer? recomposer = null, boolean disableTransitions = false);
+    method public static inline <reified T extends androidx.activity.ComponentActivity> androidx.ui.test.android.AndroidComposeTestRule<T>! AndroidComposeTestRule(androidx.compose.Recomposer? recomposer = null, boolean disableTransitions = false, boolean disableBlinkingCursor = true);
   }
 
   public final class ComposeIdlingResourceKt {
diff --git a/ui/ui-test/src/androidTest/java/androidx/ui/test/TextActionsTest.kt b/ui/ui-test/src/androidTest/java/androidx/ui/test/TextActionsTest.kt
index bfb5f05..967c45b 100644
--- a/ui/ui-test/src/androidTest/java/androidx/ui/test/TextActionsTest.kt
+++ b/ui/ui-test/src/androidTest/java/androidx/ui/test/TextActionsTest.kt
@@ -40,9 +40,7 @@
     private val fieldTag = "Field"
 
     @get:Rule
-    val composeTestRule = createComposeRule().also {
-        it.clockTestRule.pauseClock()
-    }
+    val composeTestRule = createComposeRule()
 
     @Composable
     fun TextFieldUi(
diff --git a/ui/ui-test/src/main/java/androidx/ui/test/ComposeTestRule.kt b/ui/ui-test/src/main/java/androidx/ui/test/ComposeTestRule.kt
index ba4fd69..ac8f4b0 100644
--- a/ui/ui-test/src/main/java/androidx/ui/test/ComposeTestRule.kt
+++ b/ui/ui-test/src/main/java/androidx/ui/test/ComposeTestRule.kt
@@ -94,5 +94,10 @@
  */
 fun createComposeRule(
     recomposer: Recomposer? = null,
-    disableTransitions: Boolean = false
-): ComposeTestRule = AndroidComposeTestRule<ComponentActivity>(recomposer, disableTransitions)
+    disableTransitions: Boolean = false,
+    disableBlinkingCursor: Boolean = true
+): ComposeTestRule = AndroidComposeTestRule<ComponentActivity>(
+    recomposer,
+    disableTransitions,
+    disableBlinkingCursor
+)
diff --git a/ui/ui-test/src/main/java/androidx/ui/test/android/AndroidComposeTestRule.kt b/ui/ui-test/src/main/java/androidx/ui/test/android/AndroidComposeTestRule.kt
index f400715..389fc72 100644
--- a/ui/ui-test/src/main/java/androidx/ui/test/android/AndroidComposeTestRule.kt
+++ b/ui/ui-test/src/main/java/androidx/ui/test/android/AndroidComposeTestRule.kt
@@ -25,6 +25,7 @@
 import androidx.test.ext.junit.rules.ActivityScenarioRule
 import androidx.ui.animation.transitionsEnabled
 import androidx.ui.core.setContent
+import androidx.ui.foundation.blinkingCursorEnabled
 import androidx.ui.input.textInputServiceFactory
 import androidx.ui.test.AnimationClockTestRule
 import androidx.ui.test.ComposeTestCase
@@ -50,7 +51,8 @@
  */
 inline fun <reified T : ComponentActivity> AndroidComposeTestRule(
     recomposer: Recomposer? = null,
-    disableTransitions: Boolean = false
+    disableTransitions: Boolean = false,
+    disableBlinkingCursor: Boolean = true
 ): AndroidComposeTestRule<T> {
     // TODO(b/138993381): By launching custom activities we are losing control over what content is
     // already there. This is issue in case the user already set some compose content and decides
@@ -59,7 +61,8 @@
     return AndroidComposeTestRule(
         ActivityScenarioRule(T::class.java),
         recomposer,
-        disableTransitions
+        disableTransitions,
+        disableBlinkingCursor
     )
 }
 
@@ -74,7 +77,8 @@
     //  work with any kind of Activity launcher.
     val activityRule: ActivityScenarioRule<T>,
     val recomposer: Recomposer? = null,
-    private val disableTransitions: Boolean = false
+    private val disableTransitions: Boolean = false,
+    private val disableBlinkingCursor: Boolean = true
 ) : ComposeTestRule {
 
     private fun getActivity(): T {
@@ -170,6 +174,7 @@
 
         private fun beforeEvaluate() {
             transitionsEnabled = !disableTransitions
+            blinkingCursorEnabled = !disableBlinkingCursor
             AndroidOwnerRegistry.setupRegistry()
             FirstDrawRegistry.setupRegistry()
             registerComposeWithEspresso()
@@ -181,6 +186,7 @@
 
         private fun afterEvaluate() {
             transitionsEnabled = true
+            blinkingCursorEnabled = true
             AndroidOwnerRegistry.tearDownRegistry()
             FirstDrawRegistry.tearDownRegistry()
             // Dispose the content