Prueba de interfaz de usuario de Xcode - Error de prueba de interfaz de usuario - No se pudo desplazar a visible (por acción de AX) cuando se toca el botón "Cancelar" del campo de búsqueda

85

Estoy tratando de descartar el campo de búsqueda tocando el botón "Cancelar" en la barra de búsqueda.

El caso de prueba no encuentra el botón cancelar. Funcionaba bien en Xcode 7.0.1

He añadido predicado para esperar a que aparezca el botón. El caso de prueba falla cuando tocamos el botón "cancelar"

let button = app.buttons[“Cancel”]
let existsPredicate = NSPredicate(format: "exists == 1")

expectationForPredicate(existsPredicate, evaluatedWithObject: button, handler: nil)
waitForExpectationsWithTimeout(5, handler: nil)

button.tap() // Failing here

registros :

    t =     7.21s     Tap SearchField
t =     7.21s         Wait for app to idle
t =     7.29s         Find the SearchField
t =     7.29s             Snapshot accessibility hierarchy for com.test.mail
t =     7.49s             Find: Descendants matching type SearchField
t =     7.49s             Find: Element at index 0
t =     7.49s             Wait for app to idle
t =     7.55s         Synthesize event
t =     7.84s         Wait for app to idle
t =     8.97s     Type '[email protected]' into
t =     8.97s         Wait for app to idle
t =     9.03s         Find the "Search" SearchField
t =     9.03s             Snapshot accessibility hierarchy for com.test.mail
t =     9.35s             Find: Descendants matching type SearchField
t =     9.35s             Find: Element at index 0
t =     9.36s             Wait for app to idle
t =     9.42s         Synthesize event
t =    10.37s         Wait for app to idle
t =    10.44s     Check predicate `exists == 1` against object `"Cancel" Button`
t =    10.44s         Snapshot accessibility hierarchy for com.test.mail
t =    10.58s         Find: Descendants matching type Button
t =    10.58s         Find: Elements matching predicate '"Cancel" IN identifiers'
t =    10.58s     Tap "Cancel" Button
t =    10.58s         Wait for app to idle
t =    10.64s         Find the "Cancel" Button
t =    10.64s             Snapshot accessibility hierarchy for com.test.mail
t =    10.78s             Find: Descendants matching type Button
t =    10.78s             Find: Elements matching predicate '"Cancel" IN identifiers'
t =    10.79s             Wait for app to idle
t =    11.08s         Synthesize event
t =    11.13s             Scroll element to visible
t =    11.14s             Assertion Failure: UI Testing Failure - Failed to scroll to visible (by AX action) Button 0x7f7fcaebde40: traits: 8589934593, {{353.0, 26.0}, {53.0, 30.0}}, label: 'Cancel', error: Error -25204 performing AXAction 2003
Vinpai
fuente
@ Joe Masilotti ¿alguna idea?
Vinpai
Solo una comprobación de cordura, pero ¿está el botón Cancelar en la pantalla o es necesario desplazarse hasta él? Sé que todavía hay problemas en los que el desplazamiento a los elementos no siempre funciona.
Joe Masilotti
El botón de cancelación de @JoeMasilotti está en la pantalla. El botón Cancelar es el botón predeterminado del sistema que forma parte de UISearchbar. Funcionaba bien en Xcode 7.0.1 cuando hice [self.buttons [@ "Cancel"] tap];
Vinpai
1
@Vinpai, ¿qué sucede cuando agregas un app.tables.cells.allElementsBoundByAccessibilityElement.countantes de tocar el botón? Solo por curiosidad, esto me ha ayudado a 'actualizar' la pantalla a veces.
tortas88
@Konnor, lo intenté con la API que sugirió, pero falla cuando toco el botón Cancelar. Cuando
consulto

Respuestas:

140

Creo que aquí "Cancelar" retornos botón falsede hittablela propiedad, que le impide tocar.

Si ves tap()en la documentación dice

/*!
 * Sends a tap event to a hittable point computed for the element.
 */
- (void)tap;

Parece que las cosas están rotas con XCode 7.1. Para mantenerme (y tú también;)) desbloqueado de estos problemas, escribí una extensión XCUIElementque permite tocar el elemento incluso si no es accesible. Lo siguiente puede ayudarte.

/*Sends a tap event to a hittable/unhittable element.*/
extension XCUIElement {
    func forceTapElement() {
        if self.hittable {
            self.tap()
        }
        else {
            let coordinate: XCUICoordinate = self.coordinateWithNormalizedOffset(CGVectorMake(0.0, 0.0))
            coordinate.tap()
        }
    }
}

Ahora puedes llamar como

button.forceTapElement()

Actualización : para swift 3 use lo siguiente:

extension XCUIElement {
    func forceTapElement() {
        if self.isHittable {
            self.tap()
        }
        else {
            let coordinate: XCUICoordinate = self.coordinate(withNormalizedOffset: CGVector(dx:0.0, dy:0.0))
            coordinate.tap()
        }
    }
}
Arenoso
fuente
Gracias por la solución. Me estaba encontrando con un problema similar cell.tap()y esto lo solucionó. Algo parece haber cambiado en Xcode7.1 causando que algún elemento ya no se pueda
golpear
Tengo un navigationBar backButtonItem personalizado que no es 'accesible' en Xcode7.1, y esta solución me funcionaself.app.navigationBars["Nav Title"].staticTexts["Custom Back Btn Title"].forceTapElement()
Alex
Gracias - Trabajé para mi mismo problema.
Tache
7
En mi caso funcionó cuando el grifo está en el centro de la vista. Cambie la compensación a (0.5, 0.5). let coordinate: XCUICoordinate = self.coordinateWithNormalizedOffset(CGVectorMake(0.5, 0.5))
Graham Perks
1
buen trabajo. Casi estaba empezando a matar mi macbook antes de ver esto.
ChaosSpeeder
11

Para mí, la causa principal fue que los objetos que quería tocar

  • se han configurado como oculto (y viceversa)
  • se han eliminado y vuelto a adjuntar

En ambos casos la isAccessibilityElementpropiedad fue falseposterior. Poniéndolo de nuevo para truearreglarlo.

perros dios
fuente
3
Este era exactamente mi problema. Extrañamente, comenzó a suceder en iOS 11 (funcionaba bien en iOS 10).
Ricardo Sanchez-Saez
4

Esta pregunta se clasifica bien para las consultas de Google sobre el término "No se pudo desplazar al botón visible (mediante la acción de AX)" . Dada la antigüedad de la pregunta, me inclinaba a pensar que esto ya no era un problema con el marco XCUITest como sugiere la respuesta aceptada.

Encontré que este problema se debía a que XCElementexistía, pero estaba oculto detrás del teclado del software. El marco emite el error, ya que no puede desplazar una vista que existe en la vista para poder tocarla. En mi caso, el botón en cuestión estaba detrás del teclado del software a veces .

Encontré que el teclado del software del simulador de iOS puede desactivarse en algunos casos (por ejemplo, en su máquina) y activarse en otros (por ejemplo, en su CI). En mi caso, había desactivado el teclado del software en una máquina y, de forma predeterminada, estaba activado en otras.

Solución: descarte el teclado antes de intentar tocar los botones que pueden estar detrás de él.

Encontré que tocar en algún lugar que descartaba explícitamente el teclado antes de tocar el botón resolvió mi problema en todos los entornos.

Agregué agregar algunas acciones para que el respondedor actual resigneFirstResponder. Las vistas detrás de mis vistas de texto obligarán al primer respondedor a renunciar, así que toco en algún lugar justo debajo de la última área de texto.

 /// The keyboard may be up, dismiss it by tapping just below the password field
let pointBelowPassword = passwordSecureTextField.coordinate(withNormalizedOffset: CGVector(dx: 0.5, dy: 1))
pointBelowPassword.press(forDuration: 0.1)
Jessedc
fuente
2

Verifique el rasgo del elemento, estaba enfrentando el mismo problema con TableViewSectionHeader, estaba tratando de tocar pero fallaba en todos los puntos

ingrese la descripción de la imagen aquí

Nagaraj
fuente
1

La solución alternativa de Sandy pareció ayudar por un tiempo, pero luego no más; luego la cambié así:

func waitAndForceTap(timeout: UInt32 = 5000) {
    XCTAssert(waitForElement(timeout: timeout))
    coordinate(withNormalizedOffset: CGVector(dx:0.5, dy:0.5)).tap()
}

El punto principal es que, dado que el problema es que la verificación isHittable arroja una excepción, no hago esta verificación en absoluto y voy directamente a las coordenadas después de encontrar el elemento.

Aistė Stikliūtė
fuente
0

En mi caso, tenía un elemento de interfaz de usuario agregado mediante programación que cubría el botón.

PruitIgoe
fuente
0

Si está utilizando el simulador de AppCenter para ejecutar las pruebas, debe asegurarse de ejecutar las pruebas en la misma versión de dispositivo que su simulador local. Perdí 3 días de trabajo por esto.

fdelam
fuente
0

En el espíritu de las cosas que pueden cubrir su elemento, tenía el depurador RN parcialmente superpuesto en la parte superior de mi icono:

ingrese la descripción de la imagen aquí

Jeroen Vannevel
fuente