Creating a Page Object in webdriver.io has error .setValue is not a function / cannot read property 'setValue' of undefined

Viewed 2550

I'm creating a webdriver.io automation with a page object file (login.po.js) and a test spec file (test.spec.js), but it seem to be not able to recognize the object when i call it on the test spec file (test.spec.js), it shows an error LoginPage.username.setValue is not a function.

Here are my code below:

login.po.js

    var LoginPage =  {

    username: { get: function () { return $('#email'); } },
    password: { get: function () { return $('#password'); } },
    form:     { get: function () { return $('#login'); } },
    flash:    { get: function () { return $('#flash'); } },

    submit: { value: function() {
        this.form.click();
    } }
};
module.exports = LoginPage;

test.spec.js

var LoginPage = require('../page/login.po');

const userObj = {
    user: 'username@email.com',
    password: 'password',
}
var assert = require('assert');


describe('login form', () => {

    it('should deny access with wrong creds', function () {
        LoginPage.username.setValue('username');
        LoginPage.password.setValue('password');
        LoginPage.submit();
        browser.pause(5000);
        expect(LoginPage.flash.getText()).to.contain('Your username is invalid!');
    });

    it('should allow access with correct creds', function () {
        LoginPage.username.setValue(userObj.user);
        LoginPage.password.setValue(userObj.password);
        LoginPage.submit();
        browser.pause(5000);
        expect(LoginPage.flash.getText()).to.contain('You logged into a secure area!');
    });
});

error that would appear upon running it are:

 1) login form should deny access with wrong creds
 LoginPage.username.setValue is not a function
 TypeError: LoginPage.username.setValue is not a function
     at Context.<anonymous> (D:\MyTest00\specs\test.spec.js:31:28)
     at Context.executeSync (D:\MyTest00\node_modules\@wdio\sync\build\index.js:56:18)
     at D:\MyTest00\node_modules\@wdio\sync\build\index.js:82:70

 2) login form should allow access with correct creds
 LoginPage.username.setValue is not a function
 TypeError: LoginPage.username.setValue is not a function
     at Context.<anonymous> (D:\MyTest00\specs\test.spec.js:45:28)
     at Context.executeSync (D:\MyTest00\node_modules\@wdio\sync\build\index.js:56:18)
     at D:\MyTest00\node_modules\@wdio\sync\build\index.js:82:70

assistance on this would be greatly appreaciated, and if you also found other problem on my code, please assist me on correcting it, many thanks


changing the last line of code in login.po.js

exports.LoginPage = LoginPage;

shows an error:

  1) login form should deny access with wrong creds
  Cannot read property 'setValue' of undefined
  TypeError: Cannot read property 'setValue' of undefined
      at Context.<anonymous> (D:\MyTest00\specs\test.spec.js:20:28)
      at Context.executeSync (D:\MyTest00\node_modules\@wdio\sync\build\index.js:56:18)
      at D:\MyTest00\node_modules\@wdio\sync\build\index.js:82:70

  2) login form should allow access with correct creds
  Cannot read property 'setValue' of undefined
  TypeError: Cannot read property 'setValue' of undefined
      at Context.<anonymous> (D:\MyTest00\specs\test.spec.js:28:28)
      at Context.executeSync (D:\MyTest00\node_modules\@wdio\sync\build\index.js:56:18)
      at D:\MyTest00\node_modules\@wdio\sync\build\index.js:82:70

Editing the first line of code in test.spec.js:

var LoginPage = require('../page/login.po').LoginPage

still shows an error:

  1) login form should deny access with wrong creds
  LoginPage.username.setValue is not a function
  TypeError: LoginPage.username.setValue is not a function
      at Context.<anonymous> (D:\MyTest00\specs\test.spec.js:31:28)
      at Context.executeSync (D:\MyTest00\node_modules\@wdio\sync\build\index.js:56:18)
      at D:\MyTest00\node_modules\@wdio\sync\build\index.js:82:70

  2) login form should allow access with correct creds
  LoginPage.username.setValue is not a function
  TypeError: LoginPage.username.setValue is not a function
      at Context.<anonymous> (D:\MyTest00\specs\test.spec.js:45:28)
      at Context.executeSync (D:\MyTest00\node_modules\@wdio\sync\build\index.js:56:18)
      at D:\MyTest00\node_modules\@wdio\sync\build\index.js:82:70

github repository for the full code on this is: github.com/seanray7/pageobject-webdriverio

1 Answers

spec file

const LoginPage = require('../page/login.po').LoginPage;
const userObj = {
    user: 'username@email.com',
    password: 'password',
}
const assert = require('assert');
const expect = require('chai').use(require('chai-as-promised')).expect;


describe('login form', () => {

    it('should have the right title ', async ()=> {
        await browser.url('http://the-internet.herokuapp.com/login');
        // expect(browser.getTitle()).to.eventually.equal('The Internet');
        let title = await browser.getTitle();
        console.log(title);
       return assert.equal(title, 'The Internet');
    });
    it('should deny access with creds', ()=> {
       return LoginPage.LoginPageLibs.Login(userObj.user,userObj.password);   
    });
});

page file

const LoginPageLocator = {

    username: '#username',
    password: '#password',
    form: '//i[contains(text(),"Login")]',
    flash: '#flash'

};

const LoginPageLibs = {
    Login : async (username, password) => {
        let name_ele = await browser.$(LoginPageLocator.username);
       await name_ele.setValue(username);
        let password_ele = await browser.$(LoginPageLocator.password);
       await password_ele.setValue(password);
        let sumbit = await browser.$(LoginPageLocator.form)
       return sumbit.click();
    },
    getText:async(elem)=>{
        let element = await browser.$(elem);
        return element.getText();
    }
}

exports.LoginPage = {LoginPageLocator,LoginPageLibs};

Refer this screenshot it ran succesfully.

enter image description here

Github - https://github.com/Bharath-Kumar-S/Wdio_sample.git

Related