Reputation: 25
I'm stuck on that error: TypeError: Cannot read property 'getText' of undefined When I run my test in Protractor v.4.0.14 What I understand is that getText() is not able to get a text from table cell, because CSS selector is not picking it correctly or I'm using wrong method to retrieve text from the cell?!
My page object file's code:
var HomePage = function(){
//methods
this.clearForm = function(){
element(by.css("#nameInput")).clear();
element(by.css("#surnameInput")).clear();
element(by.css("#emailInput")).clear();
element(by.css("#phoneInput")).clear();
};
this.fillForm = function(name, surname, email, phone){
element(by.css("#nameInput")).sendKeys(name);
element(by.css("#surnameInput")).sendKeys(surname);
element(by.css("#emailInput")).sendKeys(email);
element(by.css("#phoneInput")).sendKeys(phone);
};
this.clickSave = function(){
element(by.css("#saveBTN")).click();
};
this.clickSearch = function(){
element(by.css("#searchBTN")).click();
};
this.getResult = function(row, column){
element(by.css("#result > tr:nth-child("+row+") > td:nth- child("+column+")"));
};
this.clickEdit = function(row){
element(by.css("input.button-primary:nth-child("+row+")")).click();
};
this.clickRemove = function(row){
element(by.css("input.button:nth-child("+row+")")).click();
};
this.clickDeleteLocalStorage = function(){
element(by.css("#delAllBTN")).click();
};
};
module.exports = new HomePage();
And here is spec file's code:
describe("Contact book", function(){
var page = require('./page/home_page.js');
//input data
var name = 'Vladimir';
var surname = 'Putin';
var email = '[email protected]';
var phone = '+01 1234 567';
beforeEach(function(){
browser.ignoreSynchronization = true;
browser.get("https://ddaawwiidd.github.io/contactbook/");
});
it("Should be able to save new contact", function(){
page.fillForm(name, surname, email, phone);
page.clickSave();
});
it("Should be able to search for saved contact", function(){
page.clearForm();
page.fillForm(name, surname, email, phone);
page.clickSearch();
var result = page.getResult(1,1).getText(); //that's the part causing the error
expect(result).toContain('Vladimir');
});
it("Should be able to edit contact details", function(){
page.fillForm(name, surname, email, phone);
page.clickSearch();
page.clickEdit(1);
page.clearForm();
page.fillForm('Barack', 'Obama', email, phone);
page.clickSave();
});
it("Should be able to remove contact", function(){
page.fillForm('Barack','','','');
page.clickSearch();
page.clickRemove(1);
});
it("Should be able to list all saved contacts", function(){
page.clearForm();
page.clickSearch();
});
xit("Should be able to delete localStorage", function(){
page.clickDeleteLocalStorage();
expect(page.getFirstRowResult().isDisplayed()).toBe(false);
});
});
And this is error message:
Failures: 1) Contact book Should be able to search for saved contact Message: Failed: Cannot read property 'getText' of undefined Stack: TypeError: Cannot read property 'getText' of undefined at Object. (C:\Users\djankowski\AppData\Roaming\npm\node_modules\protractor\example\contactBook_spec.js:25:35) at C:\Users\djankowski\AppData\Roaming\npm\node_modules\protractor\node_modules\jasminewd2\index.js:94:23 at new ManagedPromise (C:\Users\djankowski\AppData\Roaming\npm\node_modules\protractor\node_modules\selenium-webdriver\lib\promise.js:1082:7) at controlFlowExecute (C:\Users\djankowski\AppData\Roaming\npm\node_modules\protractor\node_modules\jasminewd2\index.js:80:18) at TaskQueue.execute_ (C:\Users\djankowski\AppData\Roaming\npm\node_modules\protractor\node_modules\selenium-webdriver\lib\promise.js:2913:14) at TaskQueue.executeNext_ (C:\Users\djankowski\AppData\Roaming\npm\node_modules\protractor\node_modules\selenium-webdriver\lib\promise.js:2896:21) at asyncRun (C:\Users\djankowski\AppData\Roaming\npm\node_modules\protractor\node_modules\selenium-webdriver\lib\promise.js:2820:25) at C:\Users\djankowski\AppData\Roaming\npm\node_modules\protractor\node_modules\selenium-webdriver\lib\promise.js:639:7 at process._tickCallback (internal/process/next_tick.js:103:7) From: Task: Run it("Should be able to search for saved contact") in control flow at Object. (C:\Users\djankowski\AppData\Roaming\npm\node_modules\protractor\node_modules\jasminewd2\index.js:79:14) at C:\Users\djankowski\AppData\Roaming\npm\node_modules\protractor\node_modules\jasminewd2\index.js:16:5 at ManagedPromise.invokeCallback_ (C:\Users\djankowski\AppData\Roaming\npm\node_modules\protractor\node_modules\selenium-webdriver\lib\promise.js:1379:14) at TaskQueue.execute_ (C:\Users\djankowski\AppData\Roaming\npm\node_modules\protractor\node_modules\selenium-webdriver\lib\promise.js:2913:14) at TaskQueue.executeNext_ (C:\Users\djankowski\AppData\Roaming\npm\node_modules\protractor\node_modules\selenium-webdriver\lib\promise.js:2896:21) at asyncRun (C:\Users\djankowski\AppData\Roaming\npm\node_modules\protractor\node_modules\selenium-webdriver\lib\promise.js:2775:27) From asynchronous test: Error at Suite. (C:\Users\djankowski\AppData\Roaming\npm\node_modules\protractor\example\contactBook_spec.js:21:2) at Object. (C:\Users\djankowski\AppData\Roaming\npm\node_modules\protractor\example\contactBook_spec.js:1:1) at Module._compile (module.js:570:32) at Object.Module._extensions..js (module.js:579:10) at Module.load (module.js:487:32) at tryModuleLoad (module.js:446:12)
I'm 4 days fresh with Protractor, so it may be a stupid mistake.
Any other suggestions regarding code are welcome too.
Thank you.
Upvotes: 0
Views: 8944
Reputation: 5231
In addition to @AdityaReddy's answer few points to stress on:
getText()
returns a promise, you have resolve it to get the actual text. Basically most of the Protractor API methods return promises.You could also do something like this in your spec.js
-
it("Should be able to search for saved contact", function(){
page.clearForm();
page.fillForm(name, surname, email, phone);
page.clickSearch();
page.getResult(1,1).getText().then(function (text) {
expect(text).toContain('Vladimir');
});
// or you could directly use expect which resolves the promise internally.
expect(page.getResult(1,1).getText()).toContain('Vladimir');
});
Upvotes: 0
Reputation: 3645
Your getResult()
doesnt return an elementFinder
object, hence it throws undefined
error
You need return the element
back. Please check below
this.getResult = function(row, column){
return element(by.css("#result > tr:nth-child("+row+") > td:nth- child("+column+")"));
};
Upvotes: 3