oreo funciones compatibilidad android testing android-espresso android-testing android-autofill-manager

funciones - compatibilidad android 8



Cómo deshabilitar la nueva función Autocompletar de Android Oreo para las pruebas de espresso (6)

La ejecución de pruebas en dispositivos Android con sdk 26 hace que fallen debido a la nueva función Autofill que oculta los campos cuando el espresso intenta hacer clic en ellos.

Estoy ejecutando mis pruebas en el laboratorio de pruebas de Firebase, por lo que no puedo desactivarlas manualmente en mis dispositivos de prueba.

Algunas imagenes

1. La contraseña es visible antes de hacer clic en el campo de nombre de usuario.

2. Después de hacer clic en el campo de nombre de usuario, el campo de contraseña está oculto por este diálogo de Autocompletar:

3. Después de iniciar sesión se muestra otro diálogo de relleno:

Espresso no puedo hacer clic en el campo de contraseña ya que el cuadro de diálogo Autocompletar oculta mi campo y fail .

El uso de AutofillManager#disableAutofillServices() solo deshabilitó el # 2. diálogo pero # 3. todavía está ahí.

¿Cómo deshabilitar Autocompletar en dispositivos de prueba?


Desactivar autocompletar al probar. Definir una clase de TestRunner en Gradle

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

entonces

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

luego usa una versión personalizada de 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(); }


He tenido la suerte de deshabilitar el relleno automático durante las pruebas de Espresso con ViewActions personalizados aplicados cada vez que se ingresa un texto.

.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(); } } });


Sobre la base de la documentación, puede deshabilitar los servicios de AutofillManager#disableAutofillServices() usando la API AutofillManager#disableAutofillServices() :

Si la aplicación que llama a esta API ha habilitado los servicios de autocompletar, se desactivarán.

Uso:

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

Puedes hacer esto en @Before paso de tu prueba.


Una organización de código alternativa basada en la solución de @Alan K.

Crear la clase 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(); } } } }

Y, en su código cuando necesite deshabilitar la función Autocompletar para editTextPassword ...

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


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

Esto debería deshabilitar el servicio de autocompletar. Es lo mismo que desactivar el servicio de llenado automático en la configuración del sistema manualmente. Al menos funcionó en el emulador. Pero esto necesita acceso de root.

Otra forma de deshabilitar el servicio de autocompletar es cambiar la configuración del servicio de autofill_service .

adb shell settings put secure autofill_service null


Según la documentación: cuando la vista se centra y forma parte de un conjunto de datos. Se puede notificar a la aplicación cuando se muestre la disponibilidad al registrar un AutofillManager.AutofillCallback a través de registerCallback (AutofillCallback). Cuando el usuario selecciona un conjunto de datos de la disponibilidad, todas las vistas presentes en el conjunto de datos se completan automáticamente, a través de llamadas a autocompletar (AutofillValue) o autocompletar (SparseArray).

El contexto finaliza cuando ocurre una de las siguientes situaciones:

  1. Se llama a commit () o todas las vistas guardadas se han ido.
  2. Se llama cancel ().

Es seguro llamar a sus métodos desde cualquier hilo.

Las instancias de esta clase deben obtenerse utilizando Context.getSystemService (Class) con el argumento AutofillManager.class.

Utilice el método: disableAutofillServices () para deshabilitar el servicio.