When trying to access a nested function, "undefined is not a function"
I am working on some end-to-end tests using JavaScript (Protractor). I have a PageObjects file that contains the following:
var SomeClass = function() {
this.get = function() {
browser.get('http://blah');
};
this.person = function() {
var firstNameInput = element(by.id('firstName'));
var lastNameInput = element(by.id('lastName'));
this.setTitle = function(title) {
element(by.xpath('//select[@id="title"]/option[text()="' + title +'"]')).click();
};
this.setFirstName = function(firstName) {
firstNameInput.sendKeys(firstName);
};
this.setLastName = function(lastName) {
lastNameInput.sendKeys(lastName);
};
};
};
module.exports = new SomeClass();
In my spec, I'm trying to access a nested function like this:
describe('some test', function() {
var someClass = require('./some_class.po.js');
var data = require('./some_class.data.json');
it('do stuff', function() {
someClass.get();
someClass.person.setTitle(data.title);
someClass.person.setFirstName(data.firstName);
someClass.person.setLastName(data.lastName);
});
});
When I try to run this test, the higher level someClass.get()
works just fine, but when it tries to run someClass.person.setTitle(data.title)
I get a message Failed: undefined is not a function
.
Any idea what I am doing wrong? I am using setters, no getters. Don't feel like I need to return anything.
source to share
You need to make some changes to your code in order to access the inner
functions person()
. Added return this
at the end person()
so that internal properties and methods person()
can be accessed externally person()
.
See the changes highlighted in the code below.
var SomeClass = function() {
this.get = function() {
browser.get('http://blah');
};
this.person = function() {
var firstNameInput = element(by.id('firstName'));
var lastNameInput = element(by.id('lastName'));
this.setTitle = function(title) {
element(by.xpath('//select[@id="title"]/option[text()="' + title + '"]')).click();
};
this.setFirstName = function(firstName) {
firstNameInput.sendKeys(firstName);
};
this.setLastName = function(lastName) {
lastNameInput.sendKeys(lastName);
};
return this;
// ^^^^^^^^^
};
};
module.exports = new SomeClass();
Then you can access setTitle
as follows.
someClass.person().setTitle(data.title)
// ^^
Demo
var SomeClass = function() {
this.person = function() {
this.setTitle = function(title) {
document.write(title);
};
return this;
// ^^^^^^^^^
};
};
var myObj = new SomeClass();
myObj.person().setTitle('Hello World!');
source to share