Reputation: 1993
If I have an "AppCompatTextView" element that I can access by:
onView(withId(R.id.allergies_text))
From Layout Inspector:
Is there a way I can access the text of the element in Android Studio? (to access whatever text is there... not check if some text exists in the element)
I tried to do:
val tv = onView(withId(R.id.medical_summary_text_view)) as TextView
val text = text.text.toString()
print(text)
But I get the error:
android.support.test.espresso.ViewInteraction cannot be cast to android.widget.TextView
Upvotes: 8
Views: 16406
Reputation: 6351
Updated for newer versions of Espresso (Java):
activityScenarioRule.getScenario().onActivity(activity -> {
allergies[0] =((TextView) activity.findViewById(R.id.allergies_text)).getText().toString();
});```
Upvotes: 0
Reputation: 422
When you really want to have the text and not only match it with another value or empty, I post the full final working solution in Java (Not Kotlin) based on the algoritghm of @Mesut GUNES
public class TextHelpers {
public static String getText(ViewInteraction matcher){
final String[] text = new String[1];
ViewAction va = new ViewAction() {
@Override
public Matcher<View> getConstraints() {
return isAssignableFrom(TextView.class);
}
@Override
public String getDescription(){
return "Text of the view";
}
@Override
public void perform(UiController uiController,View view) {
TextView tv = (TextView) view;
text[0] = tv.getText().toString();
}
};
matcher.perform(va);
return text[0];
}
}
So, in your test you can call it like that:
TextHelpers.getText(Espresso.onView(withId(R.id.element)));
It works for all controls extending TextView, so it does on EditText too.
Upvotes: 0
Reputation: 7421
You can get the text of the ViewInteraction
by the following function:
fun getText(matcher: ViewInteraction): String {
var text = String()
matcher.perform(object : ViewAction {
override fun getConstraints(): Matcher<View> {
return isAssignableFrom(TextView::class.java)
}
override fun getDescription(): String {
return "Text of the view"
}
override fun perform(uiController: UiController, view: View) {
val tv = view as TextView
text = tv.text.toString()
}
})
return text
}
val numberResult: ViewInteraction = onView(withId(R.id.txNumberResult))
var searchText = getText(numberResult)
Upvotes: 5
Reputation: 186
I faced a similar issue and this is what ended up working for me:
if you have an activity rule
var activityRule = ActivityTestRule(MainActivity::class.java, true, false)
then you can do something like this:
activityRule.launchActivity(null)
val textView: TextView = activityRule.activity.findViewById(R.id.some_text_view)
val text = textView.text
I think this may be more along the lines of what the original poster was looking for.
Upvotes: 0
Reputation: 18022
You should create a matcher to access to that element value.
For instance, you can check if it's text has some value:
Matcher<View> hasValueEqualTo(final String content) {
return new TypeSafeMatcher<View>() {
@Override
public void describeTo(Description description) {
description.appendText("Has EditText/TextView the value: " + content);
}
@Override
public boolean matchesSafely(View view) {
if (!(view instanceof TextView) && !(view instanceof EditText)) {
return false;
}
if (view != null) {
String text;
if (view instanceof TextView) {
text = ((TextView) view).getText().toString();
} else {
text = ((EditText) view).getText().toString();
}
return (text.equalsIgnoreCase(content));
}
return false;
}
};
}
And call it this way:
onView(withId(R.id.medical_summary_text_view))
.check(matches(hasValueEqualTo(value)));
or you can edit this matcher to return just whether the text is empty or not:
Matcher<View> textViewHasValue() {
return new TypeSafeMatcher<View>() {
@Override
public void describeTo(Description description) {
description.appendText("The TextView/EditText has value");
}
@Override
public boolean matchesSafely(View view) {
if (!(view instanceof TextView) && !(view instanceof EditText)) {
return false;
}
if (view != null) {
String text;
if (view instanceof TextView) {
text = ((TextView) view).getText().toString();
} else {
text = ((EditText) view).getText().toString();
}
return (!TextUtils.isEmpty(text));
}
return false;
}
};
}
And call it this way:
onView(withId(R.id.medical_summary_text_view))
.check(matches(textViewHasValue()));
Upvotes: 7