android - 如何使用 Espresso 点击可点击的跨度?

标签 android testing android-espresso

我有一个 TextView ,里面有多个可点击的范围。我希望能够测试点击这些跨度。

我尝试设置一个自定义 ViewAction,它会在 TextView 中找到 clickablespans,然后将它们的文本与所需文本匹配,然后单击该文本的 xy 坐标。但是,添加到 TextView 的跨度似乎不是 ClickableSpan 类型,而是添加跨度的 fragment 。

因此,我无法区分链接跨度。有更好的方法吗?

添加跨度:

Util.addClickableSpan(spannableString, string, linkedString, new      ClickableSpan() {
@Override
public void onClick(View textView) {}
});

tvAcceptTc.setText(spannableString);
tvAcceptTc.setMovementMethod(LinkMovementMethod.getInstance());

实用方法:

public static void addClickableSpan(SpannableString spannableString,
                              String text,
                              String subText,
                              ClickableSpan clickableSpan) {
        int start = text.indexOf(subText);
        int end = text.indexOf(subText) + subText.length();
        int flags = Spanned.SPAN_EXCLUSIVE_EXCLUSIVE;

        spannableString.setSpan(clickableSpan, start, end, flags);
}

定义 ViewAction:

@Override
        public void perform(UiController uiController, View view) {
            uiController.loopMainThreadUntilIdle();
            if (view instanceof TextView) {

                TextView textView = (TextView) view;
                Layout textViewLayout = textView.getLayout();


                SpannableString fullSpannable = new SpannableString(textView.getText());

                Object[] spans = fullSpannable.getSpans(0, fullSpannable.length(), Object.class);

                ClickableSpan span = null;
                for (Object object : spans) {
                    if (object instanceof BaseFragment) {
                        ClickableSpan foundSpan = (ClickableSpan)object;
                        int spanStart = fullSpannable.getSpanStart(foundSpan);
                        int spanEnd = fullSpannable.getSpanEnd(foundSpan);
                        if (fullSpannable.subSequence(spanStart, spanEnd).equals(aSubstring)) {
                            //Found the correct span!
                            span = foundSpan;
                        }
                    }
                } ... go on to click the xy-coordinates

最佳答案

这是我的解决方案。它更简单,因为我们不需要找到坐标。找到 ClickableSpan 后,我们只需单击它:

public static ViewAction clickClickableSpan(final CharSequence textToClick) {
    return new ViewAction() {
        @Override
        public Matcher<View> getConstraints() {
            return Matchers.instanceOf(TextView.class);
        }

        @Override
        public String getDescription() {
            return "clicking on a ClickableSpan";
        }

        @Override
        public void perform(UiController uiController, View view) {
            TextView textView = (TextView) view;
            SpannableString spannableString = (SpannableString) textView.getText();

            if (spannableString.length() == 0) {
                // TextView is empty, nothing to do
                throw new NoMatchingViewException.Builder()
                        .includeViewHierarchy(true)
                        .withRootView(textView)
                        .build();
            }

            // Get the links inside the TextView and check if we find textToClick
            ClickableSpan[] spans = spannableString.getSpans(0, spannableString.length(), ClickableSpan.class);
            if (spans.length > 0) {
                ClickableSpan spanCandidate;
                for (ClickableSpan span : spans) {
                    spanCandidate = span;
                    int start = spannableString.getSpanStart(spanCandidate);
                    int end = spannableString.getSpanEnd(spanCandidate);
                    CharSequence sequence = spannableString.subSequence(start, end);
                    if (textToClick.toString().equals(sequence.toString())) {
                        span.onClick(textView);
                        return;
                    }
                }
            }

            // textToClick not found in TextView
            throw new NoMatchingViewException.Builder()
                    .includeViewHierarchy(true)
                    .withRootView(textView)
                    .build();

        }
    };
}

现在您可以像这样使用我们的自定义 ViewAction:

    onView(withId(R.id.myTextView)).perform(clickClickableSpan("myLink"));

关于android - 如何使用 Espresso 点击可点击的跨度?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38314077/

相关文章:

android - 禁用上下文操作栏并长按复制/粘贴

go - 欺骗 grpc UnaryHandler 以在 Go 中对 gRPC 进行单元测试

android - Espresso : How to call evaluateJavascript() on a WebView

Android:Espresso:WireMock java.lang.NoClassDefFoundError:解析失败:Lcom/google/common/io/Resources;

android - Facebook SDK 错误 :Argument 'applicationId' cannot be null

android - 是否有可能在 android 中获取 twitter 用户的电子邮件地址?如果是,那么如何?

android - 在 TextWatcher 中更改文本后未更新 EditText

testing - Jmeter分布式测试

c++ - 如何在一台本地机器/主机上对简单的 tcp 客户端/服务器进行单元测试?

Android Espresso 断言问题