Reputation: 175
I'm working on some end-to-end tests using JavaScript (Protractor). I've got 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 the 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 attempts to execute someClass.person.setTitle(data.title)
, I get a Failed: undefined is not a function
message.
Any idea what I'm doing wrong? I'm only using setters, no getters. Don't think I need to return anything.
Upvotes: 3
Views: 770
Reputation: 87203
You need to make some changes in your code to access inner
functions of person()
. Added return this
at the end of person()
, so that the inner properties and methods of person()
can be accessed from outside of the 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 follow.
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!');
Upvotes: 2