Consigo logar na página (sem que o protractor aponte nenhum erro) porém a página inicial do sistema não é carregada.



  • Olá pessoal,
    Boa noite!

    Sou iniciante no uso do protractor e estou apenas tentando me logar num sistema cuja página inicial não é em angular. Fiz um código baseado no descrito por:
    http://agiletesters.com.br/topic/71/protractor-page-objects-typeerror-object-object-has-no-method-metodo/7

    O que está havendo? Quando executo o comando protractor conf.js , o protractor aparentemente se loga no site, não aponta erros sendo a mensagem exibida (simplificada): 2 specs, 0 errors. Porém, a página exibida ao final da execução continua sendo a página inicial (como se eu não tivesse realizado o login) sem também mensagem de erro alguma. Vale salientar que as informações de login e senha funcionam normalmente quando o login é feito de forma manual.

    Segue:
    //arquivo de configuração (conf.js): Para executar faço protractor conf.js

    exports.config = {
        framework: 'jasmine',
        specs: ['login.js'],
        directConnect: true
    }
    

    //arquivo de login: login.js

        describe('Protractor Demo App', function() {
             browser.driver.ignoreSynchronization = true;
             var originalTimeout;
       
        beforeEach(function() {
            browser.driver.ignoreSynchronization = true;
            originalTimeout = jasmine.DEFAULT_TIMEOUT_INTERVAL;
            jasmine.DEFAULT_TIMEOUT_INTERVAL = 100000;
            browser.driver.get('http://www.maisbolao.com.br');
        });
    
        afterEach(function() {
            jasmine.DEFAULT_TIMEOUT_INTERVAL = originalTimeout;
        });
    
        it('should fill user and password and logins', function() {
    
            var loginNameInputElm = browser.driver.findElement(by.xpath('//*[@id="Email"]')); 
            var passwordInputElm = browser.driver.findElement(by.xpath('//*[@id="Senha"]'));
            var loginBtnElm = browser.driver.findElement(by.xpath('//*[@id="form-login"]'));
            loginNameInputElm.sendKeys('login');//omiti as infos de login e senha por questão de segurança
            passwordInputElm.sendKeys('senha');
    
            loginBtnElm.click();
        });
    
        it('conseguiu?', function() {
            console.log("browser.driver.getCurrentUrl(): "+browser.driver.getCurrentUrl());
            browser.driver.sleep(5000);
        });
    
    });

  • MVP

    Olha, entendo pouco de protractor…Mas o que está sendo validado depois do login? Pelo que entendi tem um fluxo para entrar, mas não vi nenhuma asserção para validar algo depois de logado… Eu vi um passo para pegar o URL atual, mas nada de validação. Chegou a depois de logar colocar algum elemento e verificar se ele existe? Pois quando ve está tendo alguma mensagem de erro ao logar, mas como tu não está comparando com nada…erro não vai dar…



  • @ramses-saccol-de-almeida eu cheguei a colocar algumas validações/asserções (após o login) mas como a página correta não é carregada após o login, o(s) elemento(s) da mesma não são encontrado(s). Erros são apresentados sim, se invertemos a ordem de algumas linhas de código e/ou colocarmos informações de login e/ou senha incorretas. Apesar de o código ser simples, para chegar nele sem dar erro, deu trabalho. Também não tenho experiência com o protractor mas quando rodamos o script, vemos nitidamente o software carregando a página inicial, inserindo as informações de login e senha, e o botão de login sendo “clicado”. No entanto, quando este clique ocorre, a mesma página de login é carregada. Se fosse informações (de login ou senha) incorretas, bem como outro erro , o protractor apontaria (assim como apontou anteriormente à medida que fui fazendo o código).



  • @Tarcianadias, veja de colocar uma asserção como a seguinte:

    const tituloPagina = browser.getTitle();
    tituloEsperado = ‘Título Esperado’

    expect(tituloPagina).toBe(tituloEsperado);

    (Alguém me passa a dica de como colocar isso como código /\)

    Sem asserção não ocorre falha, apenas se houver erro de sintaxe se não me engano.



  • Tem algumas refatorações que você pode fazer no seu código pra ficar mais legível, por exemplo:

    Ao invés de passar a URL no .get:
    browser.driver.get('http://www.maisbolao.com.br');

    Você pode ir no arquivo de configuração e inserir:
    baseUrl: 'http://www.maisbolao.com.br

    E no .get, você passaria:
    browser.get(browser.baseUrl);

    Isso ajuda a centralizar as informações.

    E leia sobre os ‘by’ do protractor: https://www.protractortest.org/#/api?view=ProtractorBy
    Uma refatoração que pode fazer é alterar
    var loginNameInputElm = browser.driver.findElement(by.xpath('//*[@id="Email"]'));

    para:
    var loginNameInputElm = browser.driver.findElement(by.id('id="Email"]'));

    Xpath é nosso inimigo.

    Entre vários outros ajustes, como utilizar de page objects.



  • E claro, se puder gastar um pouco, tem o livro sobre automação com Protractor do @Walmyr que é muito bom: https://www.casadocodigo.com.br/products/livro-protractor
    R$ 29,90 o PDF.



  • @tarcianadias tudo bem?
    O teste não retornou falha, porque não tem assert, pois é nesse momento que é verificado se o teste passou, ou falhou.

    Quanto ao fato do login não ter sido realizado no navegador, acredito que seja por causa da espera utilizada.

    Ao acessar um endereço, vc precisa garantir que o elemento html desejado esteja disponível para interação. Essa necessidade também precede à asserção, ou seja, após confirmar o login, é preciso garantir que a validação ocorra após o elemento aparecer (sendo que, vai existir uma tolerância de tempo para interação com elemento).

    Uma sugestão extra é pesquisar sobre refatoração e boas práticas. O livro do @Walmyr é ótimo e explica isso tudo com uma linguagem super agradável, tem em www.casadocodigo.com.br, “Protractor - Lições sobre testes end-to-end automatizados” .

    Em paralelo, tem essa série dele tb.

    Youtube Video



  • @tarcianadias refiz os testes de outra forma.
    Talvez fique mais fácil para compreender…

    // conf.js

     exports.config = {  
    
      /* URL do Selenium Server que o Protractor usará para executar os testes.*/
       seleniumAddress: 'http://localhost:4444/wd/hub',
    
      /* Um array de arquivos de testes são definidos nesse parâmetro, os quais, o Protractor irá executar. O caminho dos arquivos de teste devem ser relativos ao arquivo de configuração.*/
       specs: ['spec.js'],
    
     /*Uma URL de acesso padrão pode ser passada para o Protractor através do parâmetro "baseUrl". */
       baseUrl: 'http://www.maisbolao.com.br/', 
    
      capabilities: {
        /*É informado O browser contra qual o Protractor vai executar os testes.
           E se nada for informado, o padrão é Chrome mesmo :)*/
          'browserName': 'chrome'
      },
    
       jasmineNodeOpts: {
           /* O tempo padrão para esperar em ms antes de um teste falhar.*/
          defaultTimeoutInterval: 1000000
       }
    }
    

    // spec.js

    // Condição para testar aplicações que não são em angular
        browser.ignoreSynchronization = true
    
    
        beforeEach(function() {
         // Antes de cada Teste, acesse a url padrão
            browser.get('/');
        });
    
      // Elementos ref. o login e após login
         var inputEmail = element(by.id('Email')),
             inputPassword = element(by.id('Senha')),
             btnLogin = element(by.buttonText('Entrar')),
             linkMinhaConta = element(by.cssContainingText('.dropdown-toggle', 'Minha conta'));
    
     /* Observe que:
        i)  a variável foi declarada uma vez, isso é devido a convenção js 
        ii) utilizei os elementos fora do teste, para que, pudesse reutilizar sem duplicar. Essa questão da refatoração pode ser melhor ainda com o uso de page objects
        iii) Preferi utilizar os seletores id ao invés de xpath, pois, na maioria das vezes, esse será o pior tipo de seletor. Para entender melhor, pesquise sobre boas práticas automação de testes */
    
    
     describe('Teste Login', function() {
    
       it('Validar credencial de login Válida', function() {
    	// aguardar 5 segundos para carregamento da página. Pesquise sobre ExpectedConditions, para soluções melhores de espera.
    	browser.driver.sleep(5000) 
    	inputEmail.sendKeys('[email protected]');
    	inputPassword.sendKeys('******');
    	btnLogin.click();
    	// Mais uma espera de 6s
    	browser.driver.sleep(6000) 
    	// Válida a existência da opção minha conta
    	expect(linkMinhaConta.isPresent()).toBe(true);
      });
    
    /* Caso fosse fazer um teste com credencial inválida, iria ter que duplicar o código, dificultando a manutenção.
    Por isso, o ideal é que fosse criado uma função de login e encapsulada.
    Uma vez que elementos e métodos são encapsulados, eles podem ser utilizados em vários testes, mas, com um ponto de manutenção.
    Para saber mais, pesquise também sobre: helper e como funciona herança e protótipos em JS */
    });


  • @paulo-gonçalves tive esse problema de passar como código tb.

    Resolvi com indentação. Ao passar um espaçamento em relação a margem esquerda, o mesmo foi mostrado como código 😉



  • Oi @Tarcianadias, parace que o problema esta na definiçao do elemento do botao de login. Voce esta definindo-o com o id do form, e nao com o seletor do botao.

    Tente a seguinte implementaçao:

    // protractor.conf.js
    
    exports.config = {
      baseUrl: "http://www.maisbolao.com.br",
      specs: ["*.spec.js"],
      onPrepare: () => browser.ignoreSynchronization = true
    }
    
    // login.spec.js
    
    const helper = require("protractor-helper");
    
    describe("Login", () => {
      beforeEach(() => browser.get(""));
    
      it("should login successfully after filling the login form with valid credentials and click submit", () => {
        const emailField = element(by.id("Email"));
        const passwordField = element(by.id("Senha"));
        const submitButton = element(by.css("#form-login button[type='submit']"));
        // Let's say that after login an element with avatar id is displayed
        const avatar = element(by.id("avatar"));
    
        helper.fillFieldWithTextWhenVisible(emailField, "[email protected]");
        helper.fillFieldWithTextWhenVisible(passwordField, "validpassword");
        helper.clickWhenClickable(submitButton);
    
        helper.waitForElementVisibility(avatar);
      });
    });
    

    Obs.: Voce precisara instalar a biblioteca protractor-helper para fazer o codigo acima funcionar. Use npm i protractor-helper -D.

    Obs.2: Executando este codigo a partir da minha maquina recebo o seguinte erro:

    Failed: unknown error: Element <button type="submit" class="btn btn-group btn-default btn-sm">...</button> is not clickable at point (482, 701). Other element would receive the click: <div id="alerta-privacidade" class="alert-privacidade">...</div>
          (Session info: chrome=67.0.3396.99)
          (Driver info: chromedriver=2.41.578706 (5f725d1b4f0a4acbf5259df887244095596231db),platform=Mac OS X 10.13.6 x86_64)
    

    Ou seja, ao tentar clicar no botao de login o Protractor clica no elemento com id alerta-privacidade, referente a barra informando sobre o uso de cookies. Voce precisara fechar tal elemento antes de seguir adiante.

    Espero ter ajudado.

    Walmyr