0
votes

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);
    });


 });

This is screenshot of HTML: HTML screenshot

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.

2
I don't know Protractor, and don't know if this has anything to do with it, or just a formatting issue here on stackoverflow, but you have some faulty spaces on this line: element(by.css("#result > tr:nth-child("+row+") > td:nth- child("+column+")")); ... before last child.curly_brackets
It must be formatting. There are no spaces in my code: this.getResult = function(row, column){ element(by.css("#result>tr:nth-child("+row+")>td:nth-child("+column+")")); };dave

2 Answers

3
votes

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+")"));
    };
0
votes

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');
});