Как отключить новую функцию автозаполнения от Android Oreo для эспрессо-тестов
Выполнение тестов на устройствах Android с помощью sdk 26
приводит к сбою их из-за новой функции автозаполнения, которая скрывает поля, когда эспрессо пытается их щелкнуть.
Я запускаю свои тесты в тестовой лаборатории Firebase, поэтому я не могу отключить их вручную на своих тестовых устройствах.
Некоторые изображения:
1. Пароль отображается перед нажатием поля имени пользователя.
2. После нажатия поля поля имени поля пользователя скрывается в этом диалоговом окне автозаполнения:
3. После входа в систему отображается другое диалоговое окно Fill:
Espresso can not click now password field, так как диалог автозаполнения скрывает мое поле и fail
.
Использование AutofillManager#disableAutofillServices()
отключено только # 2. диалога, но №3. все еще там.
Как отключить автозаполнение на тестовых устройствах?
Ответы
Ответ 1
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
Ответ 2
На основе документации вы можете отключить службы AutofillManager#disableAutofillServices()
используя API-интерфейс AutofillManager#disableAutofillServices()
:
Если приложение, вызывающее этот 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();
}
}
});
Ответ 4
Альтернативная организация кода, основанная на решении @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())
Ответ 5
Согласно документации: когда представление сосредоточено и является частью набора данных. Приложение может быть уведомлено, когда доступность показана путем регистрации AutofillManager.AutofillCallback через registerCallback (AutofillCallback). Когда пользователь выбирает набор данных из допущения, все виды, представленные в наборе данных, автоматически заполняются посредством вызовов автозаполнения (AutofillValue) или автозаполнения (SparseArray).
Затем контекст завершается, когда происходит одно из следующих событий:
- Вызывается commit() или исчезают все полезные сведения.
- вызывается cancel().
Безопасно вызывать его методы из любого потока.
Экземпляры этого класса должны быть получены с помощью Context.getSystemService(Class) с аргументом AutofillManager.class.
Используйте метод disableAutofillServices() для отключения службы.
Ответ 6
Следующий фрагмент может быть использован для игнорирования новых предложений Android:
getWindow().getDecorView().setImportantForAutofill(View.IMPORTANT_FOR_AUTOFILL_NO_EXCLUDE_DESCENDANTS);
Ответ 7
При тестировании отключите автозаполнение. Определить класс 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();
}