Teste de IU do Xcode - Falha no teste de IU - Falha ao rolar para visível (por ação AX) ao tocar no campo Pesquisar botão "Cancelar"


85

Estou tentando descartar o campo de pesquisa tocando no botão 'Cancelar' na barra de pesquisa.

O caso de teste está falhando em encontrar o botão Cancelar. Estava funcionando bem no Xcode 7.0.1

Eu adicionei predicado para aguardar o botão aparecer. O caso de teste está falhando quando tocamos no botão "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

logs :

    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 'vinayak@xmd.net' 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

@Joe Masilotti alguma ideia?
— Vinpai,

É apenas uma verificação de integridade, mas o botão Cancelar está na tela ou precisa ser rolado até ele? Sei que ainda há problemas em que rolar para os elementos nem sempre funciona.
— Joe Masilotti

@JoeMasilotti botão cancelar está na tela. O botão Cancelar é o botão padrão do sistema que faz parte do UISearchbar. Estava funcionando bem no Xcode 7.0.1 quando eu fiz [self.buttons [@ "Cancelar"] toquei];
— Vinpai

1
@Vinpai o que acontece quando você adiciona um app.tables.cells.allElementsBoundByAccessibilityElement.countantes de tocar no botão? Só por curiosidade - às vezes isso me ajudou a "atualizar" a tela.
— bolos88,

@Konnor, tentei com a API que você sugeriu, mas está falhando quando toco no botão Cancelar. Quando eu
— consulto o

Respostas:


140

Eu acho que aqui o botão "Cancelar" retorna falsepara a hittablepropriedade, que está impedindo que ele toque.

Se você ver tap()na documentação diz

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

Parece que as coisas estão quebradas com o XCode 7.1. Para me manter (e você também;)) desbloqueado contra esses problemas, escrevi uma extensão XCUIElementque permite tocar no elemento mesmo que ele não seja atingível. Seguir pode ajudá-lo.

/*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()
        }
    }
}

Agora você pode ligar como

button.forceTapElement()

Atualização - Para o swift 3, use o seguinte:

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

Obrigado pela correção. Eu estava encontrando um problema semelhante com cell.tap()e isso corrigiu. Algo parece ter mudado no Xcode7.1 fazendo com que alguns elementos não sejam mais atingíveis
— francisOpt

Eu tenho uma barra de navegação personalizada backButtonItem que não é 'atingível' no Xcode 7.1, e esta solução funciona para mimself.app.navigationBars["Nav Title"].staticTexts["Custom Back Btn Title"].forceTapElement()
— Alex

Obrigado - funcionou para o meu mesmo problema.
— Tache

7
No meu caso funcionou quando a torneira está no centro da vista. Altere o deslocamento para (0,5, 0,5). let coordinate: XCUICoordinate = self.coordinateWithNormalizedOffset(CGVectorMake(0.5, 0.5))
— Graham Perks de

1
Ótimo trabalho. Eu estava quase começando a matar meu macbook antes de ver isso.
— ChaosSpeeder

11

Para mim, a causa raiz era que os objetos que eu queria tocar

  • foram definidos como ocultos (e para trás)
  • foram removidos e reconectados

Em ambos os casos, a isAccessibilityElementpropriedade foi falseposteriormente. Definindo de volta para trueconsertá-lo.


3
Esse era exatamente o meu problema. Estranhamente, começou a acontecer no iOS 11 (estava funcionando bem no iOS 10).
— Ricardo Sanchez-Saez

4

Esta questão se classifica bem para as consultas do Google em torno do termo "Falha ao rolar para o botão visível (por ação AX)" . Dada a idade da pergunta, estava inclinado a pensar que esse não era mais um problema com a estrutura do XCUITest, como sugere a resposta aceita.

Achei que esse problema era devido ao fato de XCElementexistir, mas estar escondido atrás do teclado do software. O erro é emitido pela estrutura, uma vez que é incapaz de rolar uma exibição existente para ser tocada. No meu caso, o botão em questão às vezes ficava atrás do teclado do software .

Descobri que o teclado do software do Simulador iOS pode ser desativado em alguns casos (por exemplo: em sua máquina) e ativado em outros (por exemplo: em seu CI). No meu caso, desliguei o teclado do software em uma máquina e, por padrão, ele foi ativado em outras.

Solução: ignore o teclado antes de tentar tocar nos botões que podem estar atrás dele.

Descobri que tocar em algum lugar que dispensava explicitamente o teclado antes de tocar no botão resolveu meu problema em todos os ambientes.

Eu adicionei algumas ações para fazer o respondente atual resignFirstResponder. As visualizações por trás das minhas visualizações de texto forçarão o primeiro respondente a renunciar, então toco em algum lugar logo abaixo da ú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)

2

Por favor, verifique a característica do elemento, eu estava enfrentando o mesmo problema com TableViewSectionHeader, eu estava tentando tocar, mas estava falhando em todos os pontos

insira a descrição da imagem aqui


1

A solução alternativa de Sandy pareceu ajudar por um tempo, mas depois não mais - mudei assim:

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

O ponto principal é que, como o problema é que a verificação isHittable lança uma exceção, eu não faço essa verificação e vou direto para as coordenadas depois que o elemento é encontrado.


0

No meu caso, foi um elemento de interface do usuário adicionado de forma programática cobrindo o botão.


0

Se você estiver usando o simulador AppCenter para executar os testes, certifique-se de que está executando os testes na mesma versão do dispositivo que o simulador local. Perdi 3 dias de trabalho por causa disso.


0

No espírito das coisas que podem abranger seu elemento, coloquei o depurador RN parcialmente sobreposto no topo do meu ícone:

insira a descrição da imagem aqui

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.