_sdk 26
_を使用してAndroidデバイスでテストを実行すると、エスプレッソがフィールドをクリックしようとしたときにフィールドを非表示にする新しい Autofill 機能が原因で失敗します。
Firebaseテストラボでテストを実行しているため、テストデバイスでテストを手動で無効にできません。
いくつかの画像:
自動入力ダイアログが私のフィールドとfail
を非表示にしているため、Espressoは今すぐパスワードフィールドをクリックできません。
AutofillManager#disableAutofillServices()
を使用すると、#2のみが無効になります。ダイアログが#3。まだあります。
テストデバイスで自動入力を無効にする方法
adb Shell pm disable com.google.Android.gms/com.google.Android.gms.autofill.service.AutofillService
これにより、自動入力サービスが無効になります。システム設定で自動入力サービスを手動でオフにするのと同じです。少なくともエミュレーターで機能しました。ただし、これにはルートアクセスが必要です。
自動入力サービスを無効にする別の方法は、autofill_service
設定。
adb Shell settings put secure autofill_service null
ドキュメントに基づいて、 AutofillManager#disableAutofillServices()
APIを使用して自動入力サービスを無効にできます。
このAPIを呼び出すアプリが自動入力サービスを有効にしている場合、それらは無効になります。
使用法:
val autofillManager: AutofillManager = context.getSystemService(AutofillManager::class.Java)
autofillManager.disableAutofillServices()
これは、テストの@Before
ステップで実行できます。
テキストが入力されるたびにカスタムViewActionsが適用されたEspressoテスト中に自動入力を無効にすることができました。
.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();
}
}
});
@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())
ドキュメントによれば:ビューがデータセットの一部であり、そのビューにフォーカスしている場合。 registerCallback(AutofillCallback)を介してAutofillManager.AutofillCallbackを登録することにより、アフォーダンスが表示されたときにアプリケーションに通知できます。ユーザーがアフォーダンスからデータセットを選択すると、データセットに存在するすべてのビューは、autofill(AutofillValue)またはautofill(SparseArray)の呼び出しを通じて自動入力されます。
次のいずれかが発生すると、コンテキストが終了します。
任意のスレッドからメソッドを呼び出すのは安全です。
このクラスのインスタンスは、引数AutofillManager.classを指定してContext.getSystemService(Class)を使用して取得する必要があります。
DisableAutofillServices()メソッドを使用して、サービスを無効にします。
次のスニペットを使用して、新しいAndroidの提案を無視できます。
getWindow().getDecorView().setImportantForAutofill(View.IMPORTANT_FOR_AUTOFILL_NO_EXCLUDE_DESCENDANTS);