简体   繁体   中英

'TypeError: undefined is not a function' using Protractor

I am aware there are many topics on this error code. However, I am struggling to find any solutions that help (or maybe I'm just stupid).

I am building a Protractor test for a web page, and my original JavaScript worked perfectly. But I wanted to convert it all into using page objects, to make it easier to edit and understand as well as avoid code repetition.

The first page object I use for logging in works perfectly fine, however my second page object for adding new users does not.

The main test document from which I am linking the page objects to and from contains both instances of the code that do and don't work, respectively.

  • The first instance that works is line 12.

  • The second instance that doesn't is on line 23.

    This is shown below:

     var util = require('util') describe ('This is to test the functionality of the Admin page.', function() { beforeEach(function(){ browser.ignoreSynchronization = true; browser.get('https://website'); }); it ('Should log in and move to the Users page.', function() { var login_page = require('../page/login_page.js'); var loginPage = new login_page; loginPage.login('user', 'pass'); beforeEach(function () { expect(browser.getCurrentUrl()).toEqual('https://website'); }); describe('This should hold all the tests while logged in to Admin site', function () { it('Should create first new User.', function() { var users_page = require('../page/users_page.js'); var usersPage = new login_page; usersPage.addUserButton().click(); usersPage.addUser('Test', 'Smith', 'Test100@testing.co.nz', 'Password', 'Password', '0') usersPage.userRole[0]; usersPage.confirm().click(); usersPage.back().click(); }); it('Should logout', function () { element(by.cssContainingText('span', 'Logout')).element(by.linkText('Logout')).click(); }); }); }); });

The error I get when running the Protractor test in cmd is:

1) This should hold all the tests while logged in to Admin site Should create first new User.

       Message:
         TypeError: undefined is not a function
       Stacktrace:
         TypeError: undefined is not a function
        at [object Object].<anonymous> (C:\\\\\\test
    04_spec.js:25:27)

The page that the first instance references is:

require ('../page/users_page.js');

var login_page = function(){

    this.username = element(by.id('username'));
    this.password = element(by.id('password'));

    this.get = function(urlVal){
        browser.get(urlVal);
    };

    this.login = function(un, pass){
        this.username.sendKeys(un);
        this.password.sendKeys(pass);
        element(by.tagName('button')).click();
    };
};

module.exports = login_page;

And the page that the second instance references is:

require ('../page/users_page.js');

var users_page = function(){

    this.addUserButton = element(by.css('[role="button"]'));
    this.firstName = element(by.model('firstname'));
    this.lastName = element(by.model('lastname'));
    this.userName = element(by.model('username'));
    this.password = element(by.model('password'));
    this.confirmPassword = element(by.model('confirmpassword'));
    this.confirm = element(by.css('[class="btn btn-success marginRight10px floatLeft"]'));
    this.back = element(by.css('[class="btn floatLeft"]'));

    this.addUser = function(fn, ln, un, pw, cpw){
        this.firstname.sendKeys(fn);
        this.lastword.sendKeys(ln);
        this.username.sendKeys(un);
        this.password.sendKeys(pw);
        this.confirmpassword.sendKeys(cpw);
    };

    this.userRole = function(index){
        element(by.model('tes.userRole')).$('[value="'+index+'"]').click();
    };

    return require('./users_page.js');

};
module.exports = new users_page();

There is at least one problem: addUserButton is not a function. Replace:

usersPage.addUserButton().click();

with:

usersPage.addUserButton.click();

And the same for confirm and back page object fields.


Also, instead of:

usersPage.userRole[0];

you probably meant to call the underlying page object function:

usersPage.userRole(0);

Aside from that, you probably meant to instantiate a new "users page" object. Replace:

var usersPage = new login_page;

with:

var usersPage = new users_page;

 require ('../page/users_page.js'); var login_page = function(){ this.username = element(by.id('username')); this.password = element(by.id('password')); this.get = function(urlVal){ browser.get(urlVal); }; this.login = function(un, pass){ this.username.sendKeys(un); this.password.sendKeys(pass); element(by.tagName('button')).click(); }; }; module.exports = login_page;

 require ('../page/users_page.js'); var users_page = function(){ this.addUserButton = element(by.css('[role="button"]')); this.firstName = element(by.model('firstname')); this.lastName = element(by.model('lastname')); this.userName = element(by.model('username')); this.password = element(by.model('password')); this.confirmPassword = element(by.model('confirmpassword')); this.confirm = element(by.css('[class="btn btn-success marginRight10px floatLeft"]')); this.back = element(by.css('[class="btn floatLeft"]')); this.addUser = function(fn, ln, un, pw, cpw){ this.firstname.sendKeys(fn); this.lastword.sendKeys(ln); this.username.sendKeys(un); this.password.sendKeys(pw); this.confirmpassword.sendKeys(cpw); }; this.userRole = function(index){ element(by.model('tes.userRole')).$('[value="'+index+'"]').click(); }; return require('./users_page.js'); }; module.exports = new users_page();

Note the last line of each page:

The working document has no 'new' statement or brackets after the 'module.exports'

Noticed the 'new' part due to Phil's comment, but didn't realise the brackets until just now, so credit to Phil!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM