如何从Android Oreo中禁用espresso测试的新自动填充功能

问题描述 投票:18回答:6

使用sdk 26在Android设备上运行测试会导致它们失败,因为当espresso尝试点击它们时,新的Autofill功能会隐藏字段。

我在firebase测试实验室运行我的测试,所以我不能在我的测试设备上手动禁用它们。

一些图片:

1. Password is visible before clicking username field.

enter image description here

2. After clicking username field password field is hidden by this Autofill dialog:

enter image description here

3. After login it shows another Fill dialog:

enter image description here

Espresso无法点击现在的密码字段,因为自动填充对话框隐藏了我的字段和fail

使用AutofillManager#disableAutofillServices()只禁用#2。对话但#3。还在那里。

如何在测试设备上禁用自动填充?

android testing android-espresso android-testing android-autofill-manager
6个回答
3
投票

adb shell pm disable com.google.android.gms/com.google.android.gms.autofill.service.AutofillService

这应该禁用自动填充服务。与手动关闭系统设置中的自动填充服务相同。它至少在模拟器上工作。但这需要root访问权限。

禁用自动填充服务的另一种方法是更改​​autofill_service设置。

adb shell settings put secure autofill_service null


7
投票

根据文档,您可以使用AutofillManager#disableAutofillServices() API禁用自动填充服务:

如果调用此API的应用启用了自动填充服务,则会禁用它们。

用法:


    val autofillManager: AutofillManager = context.getSystemService(AutofillManager::class.java)
    autofillManager.disableAutofillServices()

您可以在测试的@Before步骤中执行此操作。


3
投票

我很幸运在Espresso测试期间禁用自动填充,只要输入文本,就会应用自定义ViewActions。

            .onView(...)
            .perform(
                    new ViewAction() {
                        @Override
                        public Matcher<View> getConstraints() {
                            return Matchers.any(View.class);
                        }

                        @Override
                        public String getDescription() {
                            return "Marking view not important for autofill";
                        }

                        @Override
                        public void perform(UiController uiController, View view) {
                            // Required to disable autofill suggestions during tests on API 26+
                            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                                view.setImportantForAutofill(View.IMPORTANT_FOR_AUTOFILL_NO);
                            }
                        }
                    })
            .perform(click())
            .perform(clearText())
            .perform(typeText(textToType))
            .perform(
                    new ViewAction() {
                        @Override
                        public Matcher<View> getConstraints() {
                            return Matchers.any(View.class);
                        }

                        @Override
                        public String getDescription() {
                            return "Dismissing autofill picker";
                        }

                        @Override
                        public void perform(UiController uiController, View view) {
                            // Required to dismiss the autofill picker during tests on API 26+
                            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                                AutofillManager autofillManager =
                                        view.getContext()
                                                .getSystemService(AutofillManager.class);
                                if (autofillManager != null) autofillManager.cancel();
                            }
                        }
                    });

2
投票

基于@Alan K解决方案的替代代码组织。

创建类DisableAutofillAction:

public class DisableAutofillAction implements ViewAction {

    @Override
    public Matcher<View> getConstraints() {
        return Matchers.any(View.class);
    }

    @Override
    public String getDescription() {
        return "Dismissing autofill picker";
    }

    @Override
    public void perform(UiController uiController, View view) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {

            AutofillManager autofillManager = view.getContext().getSystemService(AutofillManager.class);

            if (autofillManager != null) {
                autofillManager.cancel();
            }
        }
    }
}

并且,在您的代码中,当您需要为editText密码禁用自动填充时...

editTextPassword.perform(..., ViewActions.closeSoftKeyboard(), DisableAutofillAction())

0
投票

根据文档:当视图聚焦并且是数据集的一部分时。通过registerCallback(AutofillCallback)注册AutofillManager.AutofillCallback,可以在显示可供性时通知应用程序。当用户从示能表中选择数据集时,通过调用自动填充(AutofillValue)或自动填充(SparseArray)自动填充数据集中存在的所有视图。

然后在出现以下情况之一时完成上下文:

  1. 调用commit()或者所有可保存的视图都消失了。
  2. 调用cancel()。

从任何线程调用其方法是安全的。

必须使用带有参数AutofillManager.class的Context.getSystemService(Class)获取此类的实例。

使用:disableAutofillServices()方法禁用该服务。


0
投票

以下代码段可用于忽略新的android建议:

getWindow().getDecorView().setImportantForAutofill(View.IMPORTANT_FOR_AUTOFILL_NO_EXCLUDE_DESCENDANTS);

-2
投票

测试时禁用自动填充。在gradle中定义TestRunner类

defaultConfig {
    testInstrumentationRunner "com.cover.android.TestRunner"
}

然后

public class TestRunner extends AndroidJUnitRunner {

@Override
public void onCreate(Bundle arguments) {
    super.onCreate(arguments);
    CustomEditText.TESTING = TRUE;
    }

然后使用EditText的自定义版本

public class CustomEditText extends AppCompatEditText {
public static boolean TESTING = false;
public CustomEditText(Context context) {
    super(context);
}

@Override
public int getAutofillType() {
    return TESTING? AUTOFILL_TYPE_NONE : super.getAutofillType();
}
© www.soinside.com 2019 - 2024. All rights reserved.