26

在 android 设备上运行测试sdk 26会导致它们失败,因为新的自动填充功能会在 espresso 尝试单击它们时隐藏字段。

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

一些图片:

1. 在点击用户名字段之前,密码是可见的。

在此处输入图像描述

2. 点击用户名字段密码字段被此自动填充对话框隐藏后:

在此处输入图像描述

3.登录后显示另一个填充对话框:

在此处输入图像描述

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

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

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

4

8 回答 8

12

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

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

用法:


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

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

于 2017-10-24T02:25:25.840 回答
10

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

于 2018-01-18T04:21:46.763 回答
6

基于@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();
            }
        }
    }
}

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

editTextPassword.perform(..., ViewActions.closeSoftKeyboard(), DisableAutofillAction())
于 2019-02-13T21:06:30.227 回答
4

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

getWindow().getDecorView().setImportantForAutofill(View.IMPORTANT_FOR_AUTOFILL_NO_EXCLUDE_DESCENDANTS);
于 2019-09-08T11:19:35.813 回答
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();
                            }
                        }
                    });
于 2018-09-19T07:33:15.553 回答
-1

在您的设备中,转到此路线设置>系统>语言和输入>高级>自动填充服务并取消它

于 2020-11-07T12:52:00.033 回答
-1

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

当发生以下情况之一时,上下文将完成:

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

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

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

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

于 2017-10-30T17:47:32.767 回答
-1

测试时禁用自动填充。在 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();
}
于 2017-10-24T21:49:41.650 回答