将浓缩咖啡与自定义 EditText 结合使用
Use espresso with custom EditText
这是我的部分布局:
<com.rey.material.widget.EditText
android:id="@+id/tagEditorSettings"
android:layout_width="match_parent"
android:layout_height="48dp"
android:layout_marginStart="10dp"
android:layout_toEndOf="@+id/circularProgressbar"
android:hint="@string/tag_name_tag_settings"
android:inputType="text"
android:textSize="18sp"
app:et_dividerColor="@color/my_primary"
app:et_dividerHeight="1dp"
app:et_inputId="@+id/name_input"
app:et_labelEnable="true"
app:et_labelTextSize="14sp"
app:et_supportLines="1" />
和我的测试代码:
onView(withId(R.id.tagEditorSettings))
.perform(click()).perform(clearText());
当我尝试 运行 时,我得到这样的错误:
Caused by: java.lang.RuntimeException: Action will not be performed
because the target view does not match one or more of the following
constraints: (is displayed on the screen to the user and is assignable
from class: class android.widget.EditText)
据我所知,问题出在 "is assignable from class: class android.widget.EditText",但有人可以提供建议,我该如何修复它并在我的案例中使用?
问题:com.rey.material.widget.EditText is extended from Framelayout
and clearText uses ReplaceTextAction作为
public static ViewAction clearText() {
return actionWithAssertions(new ReplaceTextAction(""));
}
其中 ReplaceTextAction
强制执行 view
,一种 EditText
作为
allOf(isDisplayed(), isAssignableFrom(EditText.class));
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
因为 rey...EdiText
不是 EditText
的子类,所以错误
解决方案 : 创建你自己的 ViewAction
作为
public static ViewAction clearTextInCustomView(){
return new ViewAction() {
@SuppressWarnings("unchecked")
@Override
public Matcher<View> getConstraints() {
return allOf(isDisplayed(), isAssignableFrom(com.rey.material.widget.EditText.class));
// ^^^^^^^^^^^^^^^^^^^
// To check that the found view is type of com.rey.material.widget.EditText or it's subclass
}
@Override
public void perform(UiController uiController, View view) {
((com.rey.material.widget.EditText) view).setText("");
}
@Override
public String getDescription() {
return "clear text";
}
};
}
稍后你可以做
onView(withId(R.id.tagEditorSettings))
.perform(click()).perform(clearTextInCustomView());
此自定义 EditText 扩展自 FrameLayout。这就是为什么它抱怨无法从 class android.widget.EditText.
分配目标
但是,这个自定义的 EditText 有一些方法,比如 setText 来设置包含的 EditText 中的文本,定义为:
protected android.widget.EditText mInputView;
这个是 android.widget 包中的 EditText。
您可以创建自定义 ViewAction 来访问此 public 方法:
public static ViewAction setTextEditText(final Matcher<View> matcher,
final String newText) {
return new ViewAction() {
@Override
public Matcher<View> getConstraints() {
return allOf(isDisplayed(), isAssignableFrom(com.rey.material.widget.EditText.class));
}
@Override
public String getDescription() {
return "Update the text from the custom EditText";
}
@Override
public void perform(final UiController uiController, final View view) {
((com.rey.material.widget.EditText) view).setText(newText);
}
};
}
然后,您可以执行自定义ViewAction:
onView(withId(R.id.tagEditorSettings)).setTextEditText(null);
对于 kotlin 解决方案:
fun setTextEditText(
newText: String?
): ViewAction {
return object : ViewAction {
override fun getConstraints(): Matcher<View> {
return CoreMatchers.allOf(
ViewMatchers.isDisplayed(),
ViewMatchers.isAssignableFrom(CustomDefaultInput::class.java)
)
}
override fun getDescription(): String {
return "Update the text from the custom EditText"
}
override fun perform(uiController: UiController?, view: View) {
(view as CustomDefaultInput).textInputEditText.setText(newText)
}
}
}
然后你 运行 与 :
onView(withId(R.id.inputCityName)).perform(setTextEditText(newText = "Ab"))
这是我的部分布局:
<com.rey.material.widget.EditText
android:id="@+id/tagEditorSettings"
android:layout_width="match_parent"
android:layout_height="48dp"
android:layout_marginStart="10dp"
android:layout_toEndOf="@+id/circularProgressbar"
android:hint="@string/tag_name_tag_settings"
android:inputType="text"
android:textSize="18sp"
app:et_dividerColor="@color/my_primary"
app:et_dividerHeight="1dp"
app:et_inputId="@+id/name_input"
app:et_labelEnable="true"
app:et_labelTextSize="14sp"
app:et_supportLines="1" />
和我的测试代码:
onView(withId(R.id.tagEditorSettings))
.perform(click()).perform(clearText());
当我尝试 运行 时,我得到这样的错误:
Caused by: java.lang.RuntimeException: Action will not be performed because the target view does not match one or more of the following constraints: (is displayed on the screen to the user and is assignable from class: class android.widget.EditText)
据我所知,问题出在 "is assignable from class: class android.widget.EditText",但有人可以提供建议,我该如何修复它并在我的案例中使用?
问题:com.rey.material.widget.EditText is extended from Framelayout
and clearText uses ReplaceTextAction作为
public static ViewAction clearText() {
return actionWithAssertions(new ReplaceTextAction(""));
}
其中 ReplaceTextAction
强制执行 view
,一种 EditText
作为
allOf(isDisplayed(), isAssignableFrom(EditText.class));
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
因为 rey...EdiText
不是 EditText
的子类,所以错误
解决方案 : 创建你自己的 ViewAction
作为
public static ViewAction clearTextInCustomView(){
return new ViewAction() {
@SuppressWarnings("unchecked")
@Override
public Matcher<View> getConstraints() {
return allOf(isDisplayed(), isAssignableFrom(com.rey.material.widget.EditText.class));
// ^^^^^^^^^^^^^^^^^^^
// To check that the found view is type of com.rey.material.widget.EditText or it's subclass
}
@Override
public void perform(UiController uiController, View view) {
((com.rey.material.widget.EditText) view).setText("");
}
@Override
public String getDescription() {
return "clear text";
}
};
}
稍后你可以做
onView(withId(R.id.tagEditorSettings))
.perform(click()).perform(clearTextInCustomView());
此自定义 EditText 扩展自 FrameLayout。这就是为什么它抱怨无法从 class android.widget.EditText.
分配目标但是,这个自定义的 EditText 有一些方法,比如 setText 来设置包含的 EditText 中的文本,定义为:
protected android.widget.EditText mInputView;
这个是 android.widget 包中的 EditText。
您可以创建自定义 ViewAction 来访问此 public 方法:
public static ViewAction setTextEditText(final Matcher<View> matcher,
final String newText) {
return new ViewAction() {
@Override
public Matcher<View> getConstraints() {
return allOf(isDisplayed(), isAssignableFrom(com.rey.material.widget.EditText.class));
}
@Override
public String getDescription() {
return "Update the text from the custom EditText";
}
@Override
public void perform(final UiController uiController, final View view) {
((com.rey.material.widget.EditText) view).setText(newText);
}
};
}
然后,您可以执行自定义ViewAction:
onView(withId(R.id.tagEditorSettings)).setTextEditText(null);
对于 kotlin 解决方案:
fun setTextEditText(
newText: String?
): ViewAction {
return object : ViewAction {
override fun getConstraints(): Matcher<View> {
return CoreMatchers.allOf(
ViewMatchers.isDisplayed(),
ViewMatchers.isAssignableFrom(CustomDefaultInput::class.java)
)
}
override fun getDescription(): String {
return "Update the text from the custom EditText"
}
override fun perform(uiController: UiController?, view: View) {
(view as CustomDefaultInput).textInputEditText.setText(newText)
}
}
}
然后你 运行 与 :
onView(withId(R.id.inputCityName)).perform(setTextEditText(newText = "Ab"))