[Solved] Protractor Page objects - TypeError: Object #<Object> has no method 'Metodo'



  • Estou iniciando com o Protractor (para testes em aplicações feitas em AngularJS) e estou tentando criar um teste simples usando page objects, baseado no exemplo do framework.
    Criei um arquivo para a ‘page object’ e outro para usar este objeto:

    //page object
    var LoginPage = function() {
    
    this.userInput = browser.driver.findElement(by.id('username'));
    this.pwdInput  = browser.driver.findElement(by.id('password'));
    this.btnEnter  = browser.driver.findElement(by.id('btnLogin'));
    
    this.get = function(){
    	browser.get('http://example.com');
    };
    
    this.setUser = function (user){
    	this.userInput.sendKeys(user);	
    };
    
    this.setPasswd = function (password) {
    	this.pwdInput.sendKeys(password);
    };
    
    this.clickBtnEnter = function (){
    	btnEnter.click();
    };};
    

    spec file:

    var loginPage = require('./LoginPage.js');
    describe('myApp', function() {
      it('should save contract config', function (){		
    	loginPage.get();
    	loginPage.setUser('userid');
    	loginPage.setPasswd('passwd');
    	loginPage.clickBtnEnter();
      });
    });
    

    Quando executo este teste o seguinte erro é exibido: TypeError: Object # has no method ‘get’ - na linha: loginPage.get();.

    Na pesquisa que fiz encontrei diferentes abordagens para utilizar page objects com Protractor, como Astrolable e CoffeeScript. Isso me deixou um pouco confuso.
    Alguma ideia de como corrigir este teste?

    Obrigado.



  • @Flávio-Meira Opa, blz? O método get() pode ser substituído pelo método go() . Não é necessário escrever um escrever um método para fazer esta funcionalidade, sendo assim substitua o uso browser.get()/loginPage.get() para loginPage.go().



  • Veja um exemplo utilizando o page object usando o Astrolable: https://github.com/stuplum/astrolabe/tree/master/examples



  • Acho que te respondi errado no email… estava lendo por cima…

    Eu nunca usei esses caras… mas javascript é javascript né? :)

    Não tenho nada para testar aqui… mas acho que isso resolve seu problema: (visto que vc 'importou um arquivo .js inteiro em uma variavel e dentro dele vc tem uma função que agrupa… e não métodos (como o get) jogados…

    var loginPage = require('./LoginPage.js').LoginPage 
    

    ou

    loginPage.LoginPage.get
    

    ? veja se isso resolve :)


  • ADM

    É muito coincidência rsrs
    Fui alocado essa semana em um time aqui na empresa que está desenvolvendo aplicações usando AngularJs e estou automatizando testes com o Protractor.
    No seu caso eu acho que falta um:

    module.exports = LoginPage; // No seu page object

    Eu usei este link do Thiago da TW para entender e usar como base para meus scripts.

    Caso não resolva avise que procuramos uma solução, mas comigo tem funcionado. Tenho apoio dos desenvolvedores aqui do meu time e estarei disponível para ajudar.

    Abraços,



  • @Leonardo-Galani: vai resolver desta forma --> LoginPage.loginPage.get . Primeiro a classe, depois o atributo e assim vem depois o método. Deu certo aqui conforme o exemplo do Flávio. :D



  • Ufa, enfim deu certo. Tentei todas as alternativas antes de apelar pro Astrolable.
    @Leonardo-Galani:

    • As duas maneiras (require(’./LoginPage.js’).LoginPage e loginPage.LoginPage.get) apresentaram o mesmo erro: TypeError: Cannot call method ‘get’ of undefined

    @brunofarinadev:

    • Usando a sintaxe --> LoginPage.loginPage.get(); também não deu certo. O teste finaliza com sucesso, mas sem executar nenhum comando. O output é o seguinte: Finished in 0.026 seconds - 1 test, 0 assertions, 0 failures.

    Depois de todas as tentativas, reescrevi a page object usando a extensão Astrolable (conforme sugestão do pessoal). Aí funcionou!

    //pageobject
    'use strict';
    var env = require('./environment.js')
    
    var LoginPage = function () {
      browser.driver.get('http://example.com');
    };
    
    LoginPage.prototype = Object.create({}, {
    
    userInput: 		{	get: function()	{ return browser.driver.findElement(by.id('username'));}},
    pwdInput:  		{	get: function() { return browser.driver.findElement(by.id('password'));}},
    btnEnter:  		{	get: function()	{ return browser.driver.findElement(by.id('btnLogin'));}},
    
    setUser:   		{ 	value: function (loginName) {
    	this.userInput.sendKeys(loginName);		
    }},
    
    setPasswd: { value: function (loginPass) {
    	this.pwdInput.sendKeys(loginPass);
    }},
    
    clickBtnEnter:	{	get: function()	{ return this.btnEnter.click();}}	
    });
    
    module.exports = LoginPage;
    

    Spec file:

    'use strict';
    var loginPage = require('./LoginPage.js');
    
    describe('myApp', function() {
    	var poLogin = new loginPage();
    
    	it('should save contract config', function (){		
    		poLogin.setUser('userid');
    		poLogin.setPasswd('passwd');
    		poLogin.clickBtnEnter;
    	});
    });
    

    Agora está funcionando certinho :).
    OBS: Fiz inspirado neste link, sugerido por @frederico_moreira.
    Agradeço a todos que colaboraram.



  • Po cara… legal que funcionou e vc colocou a sua solução aqui : )

    Sobre o module export… nao sabia que o angular tb usava desta forma (node.js)

    Você vai estregar a tag “resolvido” do fórum :)