Comment obtenir du texte sur une entrée dans le rapporteur

105

Dans la documentation du rapporteur, je vois l'exemple suivant:

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

Ce qui semble clair ici, c'est que vous pouvez utiliser "by.model" pour définir des valeurs dans une zone de saisie, mais si vous voulez regarder une zone de saisie et voir ce qu'elle contient, vous devez utiliser "by.binding".

J'ai un ensemble de code où (en résumé) je fais:

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

(dans mon vrai code, j'enregistre l'entité puis j'y reviens en mode édition, et je vérifie que ma valeur a bien été enregistrée. Mais cela revient toujours à la même chose, et cet exemple de code pose le même problème).

Cela me donne une erreur:

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

En théorie, en suivant l'exemple de la documentation, je peux plutôt faire:

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

Mais by.binding ne semble pas aimer le modèle complet, j'obtiens une erreur:

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

Cela fonctionne (en quelque sorte) si je fais:

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

Cela trouve un élément, mais donne également un avertissement que j'ai plus d'un élément qui correspond à «nom». Et malheureusement, celui qu'il choisit n'est pas le bon.

Donc, deux questions:

  1. Le by.model devrait-il être capable de retourner un getText (), ou y a-t-il une décision de conception selon laquelle il ne le fait pas et que nous devons utiliser à la place by.binding?
  2. Dois-je pouvoir utiliser une entité entièrement qualifiée dans by.binding, ou y a-t-il une décision de conception qui n'apprécie pas le nom complet du modèle par by.binding? Si tel est le cas, quel autre qualificatif puis-je utiliser pour choisir entre mes différentes liaisons?

ÉDITER:

J'ai également essayé la solution proposée par vdrulerz, j'ai modifié le code comme suit:

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

Le console.log renvoie une valeur vide (pas une promesse ou un objet), et l'attente échoue en donnant le message:

Expected '' to equal 'A risk name'.

Je crois comprendre que le rapporteur corrige déjà l'attente pour traiter la promesse, donc je pense que le problème sous-jacent est que getText ne fonctionne pas sur un champ identifié via un modèle (je peux réussir à obtenir le texte sur les étiquettes et autres widgets).

Je peux également exécuter le code suivant, en utilisant getAttribute plutôt que 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 première partie passe - l'attente fonctionne. La deuxième partie fonctionne également, suggérant que la syntaxe de vdrulerz est également valide, et elle enregistre «true» sur la console. Je pense qu'il y a potentiellement un défaut avec getText?

PaulL
la source

Réponses:

202

Cela est répondu dans la FAQ du rapporteur: https://github.com/angular/protractor/blob/master/docs/faq.md#the-result-of-gettext-from-an-input-element-is-always- vide

Le résultat de getText à partir d'un élément d'entrée est toujours vide

C'est une bizarrerie de webdriver. et les éléments ont toujours des valeurs getText vides. Essayez plutôt:

element.getAttribute('value')

En ce qui concerne la question 2, oui, vous devriez pouvoir utiliser un nom complet pour by.binding. Je soupçonne que votre modèle n'a pas réellement d'élément lié à risk.name via {{}} ou ng-bind.

Jmr
la source
Ah, je pensais avoir cherché partout, y compris la chercher. Et j'ai juste soulevé cela comme un problème dans le github du rapporteur aujourd'hui au motif que je n'avais pas trouvé de réponse. Déranger. Mon élément est lié à ng-model, donc il a "ng-model =" risk.name "" dans le html. Mais ce n'est peut-être pas ce qui est nécessaire pour que cela fonctionne. Je vous suggère de mettre à jour le doco pour suggérer d'utiliser getAttribute.
PaulL
1
Ajouter ceci pour la postérité puisque je viens de passer trop de temps à comprendre ceci: getAttribute renvoie en fait une promesse, pas une chaîne. github.com/angular/protractor/issues/673
boredlamer
Et je pense que cette magie fonctionne à cause du comportement de getAttribute, qui obtiendra en fait une propriété (c'est-à-dire que cela renverra une valeur même si aucun attribut "value" n'est présent dans votre DOM): "..., sauf si cet attribut n'est pas présent, auquel cas la valeur de la propriété portant le même nom est renvoyée "
The Red Pea
6

getText() La fonction ne fonctionnera pas comme avant pour le pilote Web, afin de le faire fonctionner pour le rapporteur, vous devrez l'envelopper dans une fonction et renvoyer le texte comme nous l'avons fait pour notre cadre de rapporteur, nous l'avons conservé dans un fonction commune comme -

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

    },

Par cela, vous pouvez avoir le texte d'un élément.

Faites-moi savoir si ce n'est toujours pas clair.

vdrulerz
la source
Je comprends que je dois le faire si je veux utiliser le texte directement, mais je pensais que Protractor avait corrigé le Jasmine s'attendre à ce que les correspondants gèrent la promesse - de sorte que expect (element.getText ()). ToEqual était effectivement le même que element .getText (). then (expect (texte) .toEqual). N'est-ce pas correct?
PaulL
Cela ne fonctionne pas non plus pour moi. J'ai étendu ma question ci-dessus pour que vous puissiez voir cela formaté.
PaulL
essayez d'utiliser element (by.locator ('abc'). getText (). then (function (text) {console.log (text) expect (text) .toEqual ("someext");});
vdrulerz
Il signale que Object [object Object] n'a pas de méthode 'locator'. Je ne vois pas de méthode dans l'api du rapporteur de 'by.locator', et je ne peux pas en voir non plus dans le code - et s'il y avait une méthode by.locator, alors ce serait quelque chose comme 'by. locator ('model', 'risk.name') '?
PaulL
avec by.locator, je voulais dire que vous pouvez utiliser quelque chose comme prot.findelement (By.id), CSS, Xpath ou n'importe quel attribut de localisateur .... si cela ne fonctionne toujours pas, veuillez partager votre code et vos attributs html avec moi ... sera certainement help you out ...
vdrulerz
2

J'ai eu ce problème, j'ai essayé la solution de Jmr mais cela n'a pas fonctionné pour moi. Comme tous les champs d'entrée ont des attributs ng-model, je pourrais extraire l'attribut et l'évaluer et obtenir la valeur.

HTML

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

Rapporteur

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

Ce code fonctionne. J'ai un champ de saisie de date qui a été mis en lecture seule, ce qui oblige l'utilisateur à sélectionner dans le calendrier.

pour une date de début:

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

pour une date de fin:

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
la source
0

le code ci-dessous fonctionne pour moi, pour obtenir du texte à partir de l'entrée

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

Vous devez utiliser Promise pour imprimer ou stocker les valeurs de l'élément.

 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
la source
-1

Vous pouvez essayer quelque chose comme ça

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

Ensuite, vous pouvez appeler cette fonction là où vous souhaitez obtenir la valeur.

Sohel Saiyed
la source
-3

Vous pouvez utiliser jQuery pour obtenir du texte dans la zone de texte (fonctionne bien pour moi), vérifier les détails de l'image

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

Injectez cette requête ci-dessus dans votre code. Détail de l'image:

entrez la description de l'image ici

Barrage de Dao Minh
la source