Como obter texto em uma entrada no transferidor

105

Na documentação do transferidor, vejo o seguinte exemplo:

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

O que parece claro aqui é que você pode usar "by.model" para definir valores em uma caixa de entrada, mas se quiser olhar para uma caixa de entrada e ver o que há nela, você precisa usar "by.binding".

Eu tenho um conjunto de códigos onde (em resumo) eu faço:

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

(em meu código real, salvo a entidade e depois volto a ela no modo de edição e estou verificando se meu valor foi realmente salvo. Mas ainda assim se resume à mesma coisa, e este código de amostra apresenta o mesmo problema).

Isso me dá um erro:

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

Em teoria, seguindo o exemplo dos documentos, posso fazer:

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

Mas o by.binding não parece gostar do modelo totalmente qualificado, recebo um erro:

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

Funciona (depois de uma moda) se eu:

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

Isso encontra um elemento, mas também avisa que tenho mais de um elemento que corresponde a 'nome'. E, infelizmente, aquele que ele escolhe não é o certo.

Então, duas perguntas:

  1. O by.model deve ser capaz de retornar getText () ou há uma decisão de design de que ele não faça isso e precisamos usar by.binding em vez disso?
  2. Devo ser capaz de usar uma entidade totalmente qualificada no by.binding ou há uma decisão de design que o by.binding não gosta do nome completo do modelo? Em caso afirmativo, que outro qualificador posso usar para selecionar entre minhas diferentes ligações?

EDITAR:

Também tentei a solução sugerida por vdrulerz, modifiquei o código da seguinte maneira:

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

O console.log está retornando um valor em branco (não uma promessa ou um objeto), e o expect falha ao fornecer a mensagem:

Expected '' to equal 'A risk name'.

Meu entendimento é que o transferidor já corrige a expectativa para lidar com a promessa, então sinto que o problema subjacente é o getText não funcionar em um campo identificado por meio de um modelo (posso obter o texto em rótulos e outros widgets).

Também posso executar o seguinte código, usando getAttribute em vez 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');  
});

A primeira parte passa - a expectativa funciona. A segunda parte também funciona, sugerindo que a sintaxe de vdrulerz também é válida e registra 'true' no console. Eu acho que há um defeito potencial com getText?

PaulL
fonte

Respostas:

202

Isso é respondido nas Perguntas frequentes do transferidor: https://github.com/angular/protractor/blob/master/docs/faq.md#the-result-of-gettext-from-an-input-element-is-always- vazio

O resultado de getText de um elemento de entrada está sempre vazio

Esta é uma peculiaridade do webdriver. e os elementos sempre têm valores getText vazios. Em vez disso, tente:

element.getAttribute('value')

Quanto à pergunta 2, sim, você deve ser capaz de usar um nome totalmente qualificado para by.binding. Suspeito que seu template não tenha realmente um elemento vinculado a risk.name via {{}} ou ng-bind.

Jmr
fonte
Ah, pensei ter procurado em todos os lugares, inclusive procurando por ele. E eu apenas levantei isso como um problema no github do transferidor hoje, com base no fato de não ter encontrado uma resposta. Bother. Meu elemento está vinculado ao ng-model, portanto, tem "ng-model =" risk.name "" no html. Mas isso pode não ser o que é necessário para fazer funcionar. Vou sugerir atualizar o doco para sugerir o uso de getAttribute.
PaulL
1
Adicionando isso para a posteridade, já que passei muito tempo tentando descobrir isso: getAttribute na verdade retorna uma promessa, não uma string. github.com/angular/protractor/issues/673
boredlamer
E acho que essa mágica funciona por causa do comportamento de getAttribute, que realmente obterá uma propriedade (ou seja, retornará um valor mesmo se nenhum atributo "valor" estiver presente em seu DOM): "..., a menos que esse atributo não seja presente, caso em que o valor da propriedade com o mesmo nome é retornado "
The Red Pea
6

getText() função não funcionará como costumava ser para o webdriver, a fim de fazê-la funcionar para o transferidor, você precisará envolvê-la em uma função e retornar o texto, como fizemos para nossa estrutura de transferidor que o mantemos em um função comum como -

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

    },

Com isso, você pode ter o texto de um elemento.

Avise-me se ainda não estiver claro.

Vdrulerz
fonte
Eu entendo que preciso fazer isso se quiser usar o texto diretamente, mas pensei que o Protractor corrigiu os matchers esperados do Jasmine para lidar com a promessa - então, expect (element.getText ()). ToEqual era efetivamente o mesmo que element .getText (). then (expect (text) .toEqual). Isso não é correto?
PaulL
Isso também não funciona para mim. Eu estendi minha pergunta acima para que você possa ver isso formatado.
PaulL
tente usar o elemento (by.locator ('abc'). getText (). then (function (text) {console.log (text) expect (text) .toEqual ("something");});
vdrulerz
Ele relata que Object [object Object] não tem nenhum método 'localizador'. Não vejo um método na api do transferidor de 'by.locator' e também não consigo ver nenhum no código - e certamente se houvesse um método by.locator, seria algo como 'by. localizador ('modelo', 'risco.nome') '?
PaulL
com by.locator eu quis dizer que você pode usar algo como prot.findelement (By.id), CSS, Xpath ou qualquer atributo de localizador ... se ainda não funcionar, por favor, compartilhe seu código e atributos html comigo ... com certeza te ajudar ...
vdrulerz
2

Eu tive esse problema, tentei a solução de Jmr, mas não funcionou para mim. Como todos os campos de entrada têm atributos de modelo ng, eu poderia puxar o atributo e avaliá-lo e obter o valor.

HTML

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

Transferidor

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

Este código funciona. Eu tenho um campo de entrada de data que foi definido para somente leitura, o que força o usuário a selecionar no calendário.

para uma data de início:

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 uma data de término:

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);
user5817055
fonte
0

o código abaixo funciona para mim, para obter texto de entrada

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

Você tem que usar Promise para imprimir ou armazenar 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
fonte
-1

Você pode tentar algo assim

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

Então, você pode chamar esta função de onde deseja obter o valor ..

Sohel Saiyed
fonte
-3

Você pode usar jQuery para obter texto na caixa de texto (funciona bem para mim), verifique os detalhes da imagem

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

Injete a consulta acima em seu código. Detalhe da imagem:

insira a descrição da imagem aqui

Dao Minh Dam
fonte