How to getText on an input in protractor

2020-01-26 05:52发布

问题:

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?

回答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.



回答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.



回答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


回答4:

This code works. I have a date input field that has been set to read only which forces the user to select from the calendar.

for a start date:

var updateInput = "var input = document.getElementById('startDateInput');" +
    "input.value = '18-Jan-2016';" +
    "angular.element(input).scope().$apply(function(s) { s.$parent..searchForm[input.name].$setViewValue(input.value);})";
browser.executeScript(updateInput);

for an end date:

var updateInput = "var input = document.getElementById('endDateInput');" +
    "input.value = '22-Jan-2016';" +
    "angular.element(input).scope().$apply(function(s) { s.$parent.searchForm[input.name].$setViewValue(input.value);})";
    browser.executeScript(updateInput);


回答5:

below code works for me, for getting text from input

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


回答6:

You have to use Promise to print or store values of element.

 var ExpectedValue:string ="AllTestings.com";
          element(by.id("xyz")).getAttribute("value").then(function (Text) {

                        expect(Text.trim()).toEqual("ExpectedValue", "Wrong page navigated");//Assertion
        console.log("Text");//Print here in Console

                    });


回答7:

You can try something like this

var access_token = driver.findElement(webdriver.By.name("AccToken"))

        var access_token_getTextFunction = function() {
            access_token.getText().then(function(value) {
                console.log(value);
                return value;
            });
        }

Than you can call this function where you want to get the value..



回答8:

You can use jQuery to get text in textbox (work well for me), check in image detail

Code:

$(document.evaluate( "xpath" ,document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null ).singleNodeValue).val()

Example: 
$(document.evaluate( "//*[@id='mail']" ,document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null ).singleNodeValue).val()

Inject this above query to your code. Image detail: