How to getText on an input in protractor

In the documentation for protractor, I see the following example:

describe('by model', function() {
  it('should find an element by text input model', function() {
    var username = element(by.model('username'));
    username.clear();
    username.sendKeys('Jane Doe');

    var name = element(by.binding('username'));

    expect(name.getText()).toEqual('Jane Doe');
  });

What appears clear here is that you can use "by.model" to set values in an input box, but if you want to look at an input box and see what's in it, you need to use "by.binding".

I have a set of code where (in summary) I do:

element(by.model('risk.name')).sendKeys('A value');
expect(element(by.model('risk.name')).getText()).toEqual('A value');

(in my real code I save the entity then come back to it in edit mode, and I'm checking my value was actually saved. But it still boils down to the same thing, and this sample code gives the same problem).

This gives me an error:

Error: Expected '' to equal 'A value'.

In theory, following the example from the docs, I can instead do:

element(by.model('risk.name')).sendKeys('A value');
expect(element(by.binding('risk.name)).getText()).toEqual('A value');

But the by.binding doesn't appear to like the fully qualified model, I get an error:

Error: No element found using locator: by.binding("risk.name")

It does work (after a fashion) if I do:

element(by.model('risk.name')).sendKeys('A value');
expect(element(by.binding('name')).getText()).toEqual('A value');

This finds an element, but also gives a warning that I have more than one element that matches 'name'. And unfortunately the one it picks isn't the right one.

So, two questions:

  1. Should the by.model be able to return a getText(), or is there a design decision that it not do that and we need to use by.binding instead?
  2. Should I be able to use a fully qualified entity in the by.binding, or is there a design decision that by.binding doesn't like the full model name? If so, what other qualifier can I use to select between my different bindings?

EDIT:

I have also tried the solution suggested by vdrulerz, I modified the code as follows:

element(by.model('risk.name')).getText().then(function(text) {
  console.log(text);
  expect(text).toEqual('A risk name');  
});

The console.log is returning a blank value (not a promise or an object), and the expect fails giving the message:

Expected '' to equal 'A risk name'.

My understanding is that protractor already patches the expect to deal with the promise, so I feel that the underlying problem is the getText not working on a field identified via a model (I can successfully getText on labels and other widgets).

I can also run the following code, using getAttribute rather than getText():

expect(element(by.model('risk.name')).getAttribute('autofocus')).toEqual('true');
element(by.model('risk.name')).getAttribute('autofocus').then(function(text) {
  console.log(text);
  expect(text).toEqual('true');  
});

The first part passes - the expect works. The second part also works, suggesting that vdrulerz' syntax is also valid, and it logs 'true' to the console. I think there is potentially a defect with getText?


Solution 1:

This is answered in the Protractor FAQ: https://github.com/angular/protractor/blob/master/docs/faq.md#the-result-of-gettext-from-an-input-element-is-always-empty

The result of getText from an input element is always empty

This is a webdriver quirk. and elements always have empty getText values. Instead, try:

element.getAttribute('value')

As for question 2, yes, you should be able to use a fully qualified name for by.binding. I suspect that your template does not actually having an element that is bound to risk.name via {{}} or ng-bind.

Solution 2:

getText() function won't work like the way it used to be for webdriver, in order to get it work for protractor you will need to wrap it in a function and return the text something like we did for our protractor framework we have kept it in a common function like -

getText : function(element, callback) {
        element.getText().then (function(text){             
            callback(text);
         });        

    },

By this you can have the text of an element.

Let me know if it is still unclear.

Solution 3:

I had this issue I tried Jmr's solution however it didn't work for me. As all input fields have ng-model attributes I could pull the the attribute and evaluate it and get the value.

HTML

<input ng-model="qty" type="number">

Protractor

var qty = element( by.model('qty') );
qty.sendKeys('10');
qty.evaluate(qty.getAttribute('ng-model')) //-> 10

Solution 4:

below code works for me, for getting text from input

return(this.webelement.getAttribute('value').then(function(text)
    {
        console.log("--------" + text);
}))