Jeff
Jeff

Reputation: 4433

protractor getText() not being set to a variable

I'm testing the ability of my admins to edit other users. The user.firstname model is what I'm checking. I want to be able to set the first name back to what it originally was after testing.

it("should be able to edit a different profile.", function () {
        browser.get('#/user/2');
        var fname = element(by.model('user.firstName'));
        var originalName = '';
        fname.getText().then(function (txt) {
            originalName = txt;
        });
        console.log('here');
        console.log(originalName);
        fname.sendKeys('New Name');
}

I haven't gotten to theexpect part yet. Right now, I'm not able to get the current name (Bob) stored in a variable. It prints out blank:

Using the selenium server at http://localhost:4444/wd/hub
[launcher] Running 1 instances of WebDriver
Started
..............here

....

If I console.log inside the function, it prints out the proper name, but it looks like my promise is not being fulfilled until later?

        fname.getText().then(function (txt) {
            console.log(txt);
            originalName = txt;
        });
        console.log('here');
        console.log(originalName);
        fname.sendKeys('New Name');
}

gives me this:

Using the selenium server at http://localhost:4444/wd/hub
[launcher] Running 1 instances of WebDriver
Started
..............here

Bob
....

How do I get that value outside of the promise (via a variable)? Am I just doing it way wrong?

Upvotes: 1

Views: 1579

Answers (1)

David Pisoni
David Pisoni

Reputation: 3447

In short, yes, you're doing it way wrong. The code inside the then() is executing after the code that follows it because the promise is fulfilled after the latter code runs. This is frankly one of the trickier parts of writing protractor tests.

There are a few possible solutions to this:

  • Add your code to the then() block.
  • Put your code in a subsequent then() block.
  • "Wait" for the browser to do the work

So the first one is obvious, the second one looks like:

fname.getText().then(function (txt) {
    console.log(txt);
    originalName = txt;
}).then(function () {
    console.log('here');
    console.log(originalName);
});
fname.sendKeys('New Name');

The third looks like:

fname.getText().then(function (txt) {
    console.log(txt);
    originalName = txt;
});
// ... do stuff ...
browser.wait(function() {
    return originalName !== undefined;
}).then(function() {
    console.log('here');
    console.log(originalName);
});
fname.sendKeys('New Name');

Also noteworthy here, this is only if you care about the console.log() business. You notice the fname.sendKeys() code is outside the block – protractor will take care of waiting for the last operation to finish regardless before doing the next one. Protractor will also take care of fulfilling the promises for you if you are using getText() within a jasmine expect().

Upvotes: 7

Related Questions