2626
2727import android .os .Build ;
2828import android .util .Log ;
29+ import android .view .InputDevice ;
30+ import android .view .MotionEvent ;
2931import android .view .View ;
3032import android .widget .SearchView ;
3133import androidx .test .espresso .InjectEventSecurityException ;
3638import androidx .test .espresso .remote .annotation .RemoteMsgField ;
3739import androidx .test .espresso .util .HumanReadables ;
3840import java .util .Locale ;
41+ import javax .annotation .Nullable ;
3942import org .hamcrest .Matcher ;
4043
4144/** Enables typing text on views. */
@@ -48,6 +51,9 @@ public final class TypeTextAction implements ViewAction {
4851 @ RemoteMsgField (order = 1 )
4952 final boolean tapToFocus ;
5053
54+ // The click action to use when tapping to focus is needed before typing in text.
55+ @ Nullable final GeneralClickAction clickAction ;
56+
5157 /**
5258 * Constructs {@link TypeTextAction} with given string. If the string is empty it results in no-op
5359 * (nothing is typed). By default this action sends a tap event to the center of the view to
@@ -56,7 +62,7 @@ public final class TypeTextAction implements ViewAction {
5662 * @param stringToBeTyped String To be typed by {@link TypeTextAction}
5763 */
5864 public TypeTextAction (String stringToBeTyped ) {
59- this (stringToBeTyped , true );
65+ this (stringToBeTyped , true , defaultClickAction () );
6066 }
6167
6268 /**
@@ -68,9 +74,25 @@ public TypeTextAction(String stringToBeTyped) {
6874 */
6975 @ RemoteMsgConstructor
7076 public TypeTextAction (String stringToBeTyped , boolean tapToFocus ) {
77+ this (stringToBeTyped , tapToFocus , null );
78+ }
79+
80+ /**
81+ * Constructs {@link TypeTextAction} with given string. If the string is empty it results in no-op
82+ * (nothing is typed).
83+ *
84+ * @param stringToBeTyped String To be typed by {@link TypeTextAction}
85+ * @param tapToFocus indicates whether a tap should be sent to the underlying view before typing.
86+ * @param clickAction the click action instance to use when tapping to focus. Can be {@code null}
87+ * if {@code tapToFocus} is false. If {@code tapToFocus} is true but no {@code clickAction} is
88+ * specified, a default click action will be used for tapping.
89+ */
90+ public TypeTextAction (
91+ String stringToBeTyped , boolean tapToFocus , GeneralClickAction clickAction ) {
7192 checkNotNull (stringToBeTyped );
7293 this .stringToBeTyped = stringToBeTyped ;
7394 this .tapToFocus = tapToFocus ;
95+ this .clickAction = clickAction ;
7496 }
7597
7698 @ SuppressWarnings ("unchecked" )
@@ -100,8 +122,12 @@ public void perform(UiController uiController, View view) {
100122
101123 if (tapToFocus ) {
102124 // Perform a click.
103- new GeneralClickAction (Tap .SINGLE , GeneralLocation .CENTER , Press .FINGER )
104- .perform (uiController , view );
125+ if (clickAction == null ) {
126+ // Uses the default click action if none is specified.
127+ defaultClickAction ().perform (uiController , view );
128+ } else {
129+ clickAction .perform (uiController , view );
130+ }
105131 uiController .loopMainThreadUntilIdle ();
106132 }
107133
@@ -128,4 +154,13 @@ public void perform(UiController uiController, View view) {
128154 public String getDescription () {
129155 return String .format (Locale .ROOT , "type text(%s)" , stringToBeTyped );
130156 }
157+
158+ private static GeneralClickAction defaultClickAction () {
159+ return new GeneralClickAction (
160+ Tap .SINGLE ,
161+ GeneralLocation .CENTER ,
162+ Press .FINGER ,
163+ InputDevice .SOURCE_UNKNOWN ,
164+ MotionEvent .BUTTON_PRIMARY );
165+ }
131166}
0 commit comments