Cómo obtener texto en una entrada en transportador

105

En la documentación del transportador, veo el siguiente ejemplo:

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

Lo que parece claro aquí es que puede usar "by.model" para establecer valores en un cuadro de entrada, pero si desea ver un cuadro de entrada y ver qué hay en él, debe usar "by.binding".

Tengo un conjunto de código donde (en resumen) hago:

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

(en mi código real guardo la entidad y luego vuelvo a ella en modo de edición, y estoy verificando que mi valor se haya guardado realmente. Pero aún se reduce a lo mismo, y este código de muestra da el mismo problema).

Esto me da un error:

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

En teoría, siguiendo el ejemplo de los documentos, puedo hacer en su lugar:

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

Pero al by.binding no parece gustarle el modelo totalmente calificado, aparece un error:

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

Funciona (de alguna manera) si lo hago:

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

Esto encuentra un elemento, pero también advierte que tengo más de un elemento que coincide con 'nombre'. Y, lamentablemente, el que elige no es el correcto.

Entonces, dos preguntas:

  1. ¿Debería by.model poder devolver un getText (), o hay una decisión de diseño de que no lo haga y que necesitemos usar by.binding en su lugar?
  2. ¿Debo poder usar una entidad totalmente calificada en by.binding, o hay una decisión de diseño que a by.binding no le gusta el nombre completo del modelo? Si es así, ¿qué otro calificador puedo usar para seleccionar entre mis diferentes enlaces?

EDITAR:

También probé la solución sugerida por vdrulerz, modifiqué el código de la siguiente manera:

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

Console.log está devolviendo un valor en blanco (no una promesa o un objeto), y la expectativa falla dando el mensaje:

Expected '' to equal 'A risk name'.

Tengo entendido que el transportador ya parchea la expectativa de lidiar con la promesa, por lo que creo que el problema subyacente es que getText no funciona en un campo identificado a través de un modelo (puedo getText con éxito en etiquetas y otros widgets).

También puedo ejecutar el siguiente código, usando getAttribute en lugar de 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');  
});

La primera parte pasa, lo esperado funciona. La segunda parte también funciona, lo que sugiere que la sintaxis de vdrulerz también es válida, y registra "verdadero" en la consola. Creo que existe un defecto potencial con getText.

PaulL
fuente

Respuestas:

202

Esto se responde en las Preguntas frecuentes sobre transportadores: https://github.com/angular/protractor/blob/master/docs/faq.md#the-result-of-gettext-from-an-input-element-is-always- vacío

El resultado de getText de un elemento de entrada siempre está vacío

Esta es una peculiaridad del controlador web. y los elementos siempre tienen valores getText vacíos. En su lugar, intente:

element.getAttribute('value')

En cuanto a la pregunta 2, sí, debería poder utilizar un nombre completo para by.binding. Sospecho que su plantilla en realidad no tiene un elemento que esté vinculado a risk.name a través de {{}} o ng-bind.

Jmr
fuente
Ah, pensé que había buscado por todas partes, incluso buscándolo. Y acabo de plantear esto como un problema en el transportador github hoy sobre la base de que no había encontrado una respuesta. Molestia. Mi elemento está vinculado con ng-model, por lo que tiene "ng-model =" risk.name "" en el html. Pero puede que eso no sea lo que se necesita para que funcione. Sugeriré actualizar el documento para sugerir el uso de getAttribute.
PaulL
1
Agregando esto para la posteridad, ya que pasé demasiado tiempo averiguando esto: getAttribute en realidad devuelve una promesa, no una cadena. github.com/angular/protractor/issues/673
boredlamer
Y creo que esta magia funciona debido al comportamiento de getAttribute, que en realidad obtendrá una propiedad (es decir, esto devolverá un valor incluso si no hay ningún atributo "valor" presente en su DOM): "..., a menos que ese atributo no esté presente, en cuyo caso se devuelve el valor de la propiedad con el mismo nombre "
The Red Pea
6

getText() la función no funcionará como solía ser para webdriver, para que funcione para transportador, necesitará envolverlo en una función y devolver el texto algo como lo hicimos para nuestro marco de transportador lo hemos mantenido en un función común como -

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

    },

Con esto puede tener el texto de un elemento.

Avísame si aún no está claro.

vdrulerz
fuente
Entiendo que necesito hacer eso si quiero usar el texto directamente, pero pensé que Protractor parcheó los comparadores de espera de Jasmine para lidiar con la promesa, por lo que esperar (element.getText ()). ToEqual era efectivamente lo mismo que element .getText (). luego (espera (texto) .toEqual). ¿No es eso correcto?
PaulL
Esto tampoco funciona para mí. He ampliado mi pregunta anterior para que pueda ver este formato.
PaulL
intente utilizar element (by.locator ('abc'). getText (). then (function (text) {console.log (text) hope (text) .toEqual ("sometext");});
vdrulerz
Informa que Object [object Object] no tiene un método 'localizador'. No veo un método en la api del transportador de 'by.locator', y tampoco puedo ver uno en el código, y seguramente si hubiera un método by.locator, entonces sería algo como 'by. locator ('modelo', 'riesgo.nombre') '?
PaulL
con by.locator quise decir que puede usar algo como prot.findelement (By.id), CSS, Xpath o cualquier atributo de localizador ... si aún no funciona, por favor comparta su código y atributos html conmigo ... definitivamente ayudarte ...
vdrulerz
2

Tuve este problema, probé la solución de Jmr, sin embargo, no funcionó para mí. Como todos los campos de entrada tienen atributos de modelo ng, podría extraer el atributo y evaluarlo y obtener el valor.

HTML

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

Transportador

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

Este código funciona. Tengo un campo de entrada de fecha que se ha configurado para leer solo, lo que obliga al usuario a seleccionar del calendario.

para una fecha de inicio:

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

para una fecha de finalización:

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);
usuario5817055
fuente
0

el siguiente código funciona para mí, para obtener texto de la entrada

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

Tienes que usar Promise para imprimir o almacenar valores de elemento.

 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

                    });
Pranawa Mishra
fuente
-1

Puedes probar algo como esto

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

Entonces puede llamar a esta función donde desee obtener el valor.

Sohel Saiyed
fuente
-3

Puede usar jQuery para obtener texto en el cuadro de texto (funciona bien para mí), verifique los detalles de la imagen

Código:

$(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()

Inyecte esta consulta anterior a su código. Detalle de la imagen:

ingrese la descripción de la imagen aquí

Presa de Dao Minh
fuente