Agile Testers TechTalks | Test War Stories - Andreia Gaita @ Tech Lead do GitHub. Saiba mais aqui

Selenium: timeout no carregamento da página.



  • Gostaria de saber se existe alguma maneira continuar a execução dos testes no selenium , enquanto a página ainda não foi carregada.

    Ocorre o seguinte: a página fica recarregando os seus elementos frequentemente pois recebe dados do servidor em tempo real, porém o selenium não executa os passos programados, pois a mesma ainda não foi completamente carregada.

    Existe algum meio de ignorar o “page load” e continuar a execução do código?

    Estou utilizando Python + Selenium + Behave nos testes.
    Já procurei conteúdo na web e ainda não consegui resolver o problema.



  • Isso aconteceu comigo quando eu estava automatizando testes para uma empresa de telecom que tinha um ambiente de teste bem bosta, que dava timeout e includes que ficava uma eternidade carregado…

    Na epoca eu usei java… uma thread especifica para abrir a pagina e outra thread para realizar os testes…

    Agora não sei como está a API… mas como isso é “anormal” e a comunidade entende que um ambiente não estável não é um ambiente testável e que timeouts são bugs / erros a serem corrigidos, você vai ter que usar o #gohorse :)



  • Entendi.
    Obrigado pelo conselho.
    Vou tentar implementar os Threads nos testes. Pode ser que funcione a longo prazo, mas se isso não funcionar kkkkk
    Ai é outra história…



  • @Leonardo-Galani

    Os Threads funcionaram.
    Obrigado pela dica, valeu a pena gastar um tempinho implementando.



  • EU imagino a dor de cabeça e stress que vc passou com seu ambiente…rsrs e fico feliz da minha gambiarra ter funcionado xD

    []s e boa sorte !



  • @daniel-ferreira, você pode iniciar o selenium em uma thread

    from queue import Queue
    from time import sleep
    from threading import Thread
    from selenium import webdriver
    
    q = Queue()  # Queue são thread safe
    driver = webdriver.Firefox()
    
    
    def wait_page_load():
        """Espera explicita d carregamento da thread."""
        value = None
        while value != 'Done':
            value = q.get()
            print('esperando')
        print('pronto')
    
    
    def selenium_get(page):
        """
        Executa uma espera explicita do load da página.
    
        Args:
            - page: Página a ser carregada
        """
        q.put('xpto')
        q.put('lalala')
        q.put('eu, ein')
        driver.get(page)
        q.put('Done')
    
    
    browser_thread = Thread(target=selenium_get,
                            kwargs={'page': 'http://google.com'})
    
    wait_page = Thread(target=wait_page_load)
    
    wait_page.start()
    browser_thread.start()
    
    wait_page.join()
    browser_thread.join()
    driver.quit()
    
    

    Isso pode resolver seu problema relacionado a espera do selenium para continuar os testes.

    Caso você tente executar um cenário enquanto outro cenário carrega, você vai ter vários problemas relacionados. Vamos analisar:

    before_all
    for feature in all_features:
        before_feature
        for scenario in feature.scenarios:
            before_scenario
            for step in scenario.steps:
                before_step
                    step.run()
                after_step
            after_scenario
        after_feature
    after_all
    

    Como você pode ver no fluxo de execução do Context.Runner roda os cenários sequencialmente. Não existindo uma maneira de pular um cenário específico e retomar ao mesmo quando a execução estiver finalizada. Para que isso seja feito, você teria que modificar o framework para que você passe uma ‘tag’ quando o runner for iniciado e caso o cenário ainda não tenha o ambiente preparado, que ele seja realocado em scenario.steps. Algo como um realoc na fila de execução.

    Uma outra maneira, sem modificar a fila do behave é pedir que a pagina seja carregada em um hook, antes da execução do cenário. Por exemplo:

    def before_feature(context, feature):
        if feature.name == 'funcionalidade com problema':
            """
            Montar o esquema do driver assincrono aqui.
    
            Aí você pode iniciar uma nova thread, que retornar um novo driver
                para o contexto.
            """
            context.assync_driver = start_browser_assync()  # Isso deixaria um novo driver rolando
    

    Com isso, no inicio da feature um driver do selenium já estaria carregando o driver assíncrono para ser usado em um cenário específico. E antes do cenário iniciar você poderia trocar o driver oficial do contexto, contando nesse caso que você tenha um driver para executar todos os testes e nesse caso específico tenha que rodar com o alternativo:

    def before_step(context, step):
        if step.name == 'step do driver alternativo':
            context.driver = context.assync_driver
    

    Dessa maneira você conseguiria rodar somente esse cenário com esse driver, pq o que é definido em before_step só dura até after_step .

    Não sei se isso deu uma luz, mas realmente é uma gambiarra infinita. SUHAUSAHSA

    Um abraço.



  • @du da uma lida na thread ;) ele ja implementou as threads :)… mas a sua repsosta de como poderia ficar tb tá legal ;’)



  • @Leonardo-Galani, sim. Eu vi que já tinha funcionado. Só achei que poderia deixar o contexto de maneira menos macarrônica. Se não vira uma salada de frutas. USHAUSHAUSA.

    Desculpa pela resposta atrasada, só respondi pq achei que poderia contribuir um pouco. Não briga comigo =(

    USHAUSHSHUA



  • @du hmmm um exemplo funcional no gist seria uma bom… é só uma idea… :3



  • @du
    @Leonardo-Galani

    Fiz a implementação de duas Threads.
    Em uma fiz a execução do navegador e a outra cuida de executar os passos do Behave com Selenium no navegador aberto pelo driver.
    Com isso o problema foi resolvido e implementado com poucas linhas de código.