Page objects in Protractor / Jasmine cause error: Failed: Cannot read property 'sendKeys' of undefined

Page objects in Protractor / Jasmine cause error: Failed: Cannot read property 'sendKeys' of undefined

我试图让页面对象为 Protractor 和 Jasmine 工作,但当我尝试使用页面对象时出现“失败:无法读取未定义的 属性 'sendKeys'” .

我看过类似的帖子,但他们没有为我提供任何答案,或者情况差异太大,对我没有任何帮助。

我检查了两个文件的每个字符。由于某种原因,测试似乎看不到页面对象文件。顺便说一句,Protractor 是全局安装的,所以我不需要将它包含在脚本中。

在转换为使用“test_page.js”文件而不是硬编码值之前一切正常。

这是来自他的代码运行良好的教程。

/superhero-tests/test/test_spec.js文件

//require() is a notjs function - https://nodejs.org/en/knowledge/getting-started/what-is-require/
const TestPage = require("../page-objects/test.page")
 
//This file runs the browser and executes the script.
describe('Super Hero Page',function(){
 
    var testPage
 
    //Jasmine: Before each test case, do something
    beforeEach(function(){    
        
        testPage = new TestPage()
 
        //Protractor: For non-angular sites
        browser.ignoreSynchronization = true
 
        //Open URL
        browser.get('file:///C:/projects/Protractor/Superhero/index.html') 
        
    })
 
    //Jasmine: After each test case, do something
    afterEach(function(){
 
        //Timer to prevent immediate closure of the window
        //browser.sleep(5000)
    })
 
    it('should load the correct URL',function(){
 
        //Enter text into form fields
        testPage.emailFld.sendKeys('a@b.com')
        testPage.passwordFld.sendKeys('Test.123')
 
        //Check some text in an element
        expect(testPage.loginTitleTxt.getText()).toEqual('Welcome. Please Log In.')
                
        //Check a HTML element's attribute
        expect( testPage.emailFld.getAttribute('value')).toEqual('a@b.com')
        
        //Non-precise matching - don't use with an empty string, will pass
        //expect( testPage.loginTitleTxt.getText() ).toContain('Welcome.')
 
    })
})
 

/superhero-tests/page-objects/test_page.js文件

var TestPage = function(){}
 
TestPage.prototype = Object.create({},{
    emailFld: { get: function(){ return element( by.id('loginEmail') ) } }, //this is a page object
    passswordFld: { get: function(){ return element( by.id('loginPassword') ) } }, //this is a page object
    loginTitleTxt: { get: function(){ return element( by.id('login-title') ) } } //this is a page object
})
 
module.exports = TestPage
 

我不知道什么样的教程会使逻辑过于复杂。试试这个

/superhero-tests/page-objects/test_page.js 文件

module.exports = function() {
  this.emailFld = element( by.id('loginEmail') )
  this.passswordFld = element( by.id('loginPassword') )
  this.loginTitleTxt = element( by.id('login-title') )
}

另外请记住,本教程教您 protractor 3 或 4 的过时语法,自几年前发布 protractor 7 以来不再使用

最后我找到了可行的替代页面对象代码(教程链接如下):

页面对象:

var TestPage = (function () {
    function TestPage() {
        this.emailFld = element( by.id('loginEmail') )
        this.passswordFld = element( by.id('loginPassword') )
        this.loginTitleTxt = element( by.id('login-title') )
    }

    return TestPage;

})();

module.exports = TestPage;

规范(测试)文件:

//Test for Login page

var TestPage = require("../page-objects/test.page")

//Appears in command line
describe('Login page tests', function(){

    var test = new TestPage();

    //Executed before the tests
    beforeEach(function(){
        //Protractor: For non-angular sites
        browser.ignoreSynchronization = true

        //Open URL
        browser.get('file:///C:/projects/Protractor/Superhero/index.html')
    })

    //Executed after the tests
    afterEach(function(){

        //Timer so we can see what is going on
        //browser.sleep(5000)        

    })

    //The test statements themselves
    it('should display all the Login page elements',function(){
        
        //With page object
        expect(  test.emailFld.getAttribute('placeholder')  ).toEqual('Enter email')
    })

})

看来还是先利用初始函数再做最后的module.exports吧。我能看到的唯一其他区别是他们在测试文件中使用了 var 而不是 const,但我不知道这会有多大变化。

https://teamgaslight.com/blog/getting-started-with-protractor-and-page-objects-for-angularjs-e2e-testing