So erhalten Sie Text für eine Eingabe in Winkelmesser

105

In der Dokumentation für Winkelmesser sehe ich folgendes Beispiel:

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

Was hier klar erscheint, ist, dass Sie "by.model" verwenden können, um Werte in einem Eingabefeld festzulegen. Wenn Sie jedoch ein Eingabefeld betrachten und sehen möchten, was darin enthalten ist, müssen Sie "by.binding" verwenden.

Ich habe eine Reihe von Codes, in denen ich (zusammenfassend) Folgendes tue:

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

(In meinem realen Code speichere ich die Entität und kehre dann im Bearbeitungsmodus zu ihr zurück. Ich überprüfe, ob mein Wert tatsächlich gespeichert wurde. Aber es läuft immer noch auf dasselbe hinaus, und dieser Beispielcode gibt das gleiche Problem.)

Dies gibt mir einen Fehler:

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

Theoretisch kann ich nach dem Beispiel aus den Dokumenten stattdessen Folgendes tun:

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

Aber die by.binding scheint das vollqualifizierte Modell nicht zu mögen, ich erhalte eine Fehlermeldung:

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

Es funktioniert (auf eine Art und Weise), wenn ich:

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

Dies findet ein Element, gibt aber auch eine Warnung aus, dass ich mehr als ein Element habe, das mit 'Name' übereinstimmt. Und leider ist der, den es auswählt, nicht der richtige.

Also zwei Fragen:

  1. Sollte das by.model in der Lage sein, ein getText () zurückzugeben, oder gibt es eine Entwurfsentscheidung, dass dies nicht der Fall ist und wir stattdessen by.binding verwenden müssen?
  2. Sollte ich in der Lage sein, eine vollständig qualifizierte Entität in by.binding zu verwenden, oder gibt es eine Entwurfsentscheidung, bei der by.binding den vollständigen Modellnamen nicht mag? Wenn ja, mit welchem ​​anderen Qualifikationsmerkmal kann ich zwischen meinen verschiedenen Bindungen auswählen?

BEARBEITEN:

Ich habe auch die von vdrulerz vorgeschlagene Lösung ausprobiert und den Code wie folgt geändert:

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

Das console.log gibt einen leeren Wert zurück (kein Versprechen oder Objekt), und die Erwartung gibt die folgende Meldung nicht aus:

Expected '' to equal 'A risk name'.

Meines Wissens nach korrigiert der Winkelmesser bereits die Erwartung, das Versprechen zu erfüllen, und ich bin der Meinung, dass das zugrunde liegende Problem darin besteht, dass getText nicht in einem über ein Modell identifizierten Feld funktioniert (ich kann erfolgreich Text auf Etiketten und anderen Widgets abrufen).

Ich kann auch den folgenden Code mit getAttribute anstelle von getText () ausführen:

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

Der erste Teil geht vorbei - die Erwartung funktioniert. Der zweite Teil funktioniert ebenfalls und legt nahe, dass die Syntax von vdrulerz ebenfalls gültig ist und "true" in der Konsole protokolliert. Ich denke, es gibt möglicherweise einen Fehler mit getText?

PaulL
quelle

Antworten:

202

Dies wird in den Winkelmesser-FAQ beantwortet: https://github.com/angular/protractor/blob/master/docs/faq.md#the-result-of-gettext-from-an-input-element-is-always- leer

Das Ergebnis von getText aus einem Eingabeelement ist immer leer

Dies ist eine Webdriver-Eigenart. und Elemente haben immer leere getText-Werte. Versuchen Sie stattdessen:

element.getAttribute('value')

Zu Frage 2: Ja, Sie sollten in der Lage sein, einen vollständig qualifizierten Namen für by.binding zu verwenden. Ich vermute, dass Ihre Vorlage kein Element enthält, das über {{}} oder ng-bind an risk.name gebunden ist.

Jmr
quelle
Ah, ich dachte, ich hätte überall gesucht, auch danach gesucht. Und ich habe dies heute als Problem im Winkelmesser-Github angesprochen, weil ich keine Antwort gefunden hatte. Mühe. Mein Element ist an ng-model gebunden, daher hat es "ht-model =" risk.name "" im HTML. Aber das ist möglicherweise nicht das, was benötigt wird, damit es funktioniert. Ich werde vorschlagen, das Dokument zu aktualisieren, um die Verwendung von getAttribute vorzuschlagen.
PaulL
1
Hinzufügen für die Nachwelt, da ich einfach zu lange damit verbracht habe, dies herauszufinden: getAttribute gibt tatsächlich ein Versprechen zurück, keine Zeichenfolge. github.com/angular/protractor/issues/673
Langeweile
Und ich denke, diese Magie funktioniert aufgrund des Verhaltens von getAttribute, das tatsächlich eine Eigenschaft erhält (dh dies gibt einen Wert zurück, selbst wenn in Ihrem DOM kein "Wert" -Attribut vorhanden ist): "..., es sei denn, dieses Attribut ist nicht vorhanden vorhanden, in diesem Fall wird der Wert der Eigenschaft mit dem gleichen Namen zurückgegeben "
The Red Pea
6

getText() Die Funktion funktioniert nicht mehr so ​​wie früher für Webdriver. Damit sie für Winkelmesser funktioniert, müssen Sie sie in eine Funktion einbinden und den Text so zurückgeben, wie wir es für unser Winkelmesser-Framework getan haben, in dem wir ihn gespeichert haben gemeinsame Funktion wie -

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

    },

Auf diese Weise können Sie den Text eines Elements haben.

Lassen Sie mich wissen, wenn es noch unklar ist.

vdrulerz
quelle
Ich verstehe, dass ich das tun muss, wenn ich den Text direkt verwenden möchte, aber ich dachte, dass Protractor die Jasmine-Erwartungs-Matcher gepatcht hat, um mit dem Versprechen fertig zu werden - so dass Expect (element.getText ()). ToEqual effektiv dasselbe ist wie Element .getText (). then (erwarten (Text) .toEqual). Ist das nicht richtig?
PaulL
Das funktioniert auch bei mir nicht. Ich habe meine Frage oben erweitert, damit Sie diese formatiert sehen können.
PaulL
versuche das Element (by.locator ('abc'). getText (). then (function (text) {console.log (text) expected (text) .toEqual ("sometext");});
vdrulerz
Es wird berichtet, dass Object [object Object] keine Methode 'locator' hat. Ich sehe keine Methode in der Winkelmesser-API von 'by.locator', und ich kann auch keine im Code sehen - und wenn es eine by.locator-Methode gäbe, wäre es sicherlich so etwas wie 'by. locator ('model', 'risk.name') '?
PaulL
Mit by.locator meinte ich, dass Sie so etwas wie prot.findelement (By.id), CSS, Xpath oder ein beliebiges Locator-Attribut verwenden können. Wenn es immer noch nicht funktioniert, teilen Sie mir bitte Ihren Code und Ihre HTML-Attribute mit hilf dir raus ...
vdrulerz
2

Ich hatte dieses Problem. Ich habe Jmrs Lösung ausprobiert, aber es hat bei mir nicht funktioniert. Da alle Eingabefelder ng-Modellattribute haben, könnte ich das Attribut abrufen und auswerten und den Wert erhalten.

HTML

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

Winkelmesser

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

Dieser Code funktioniert. Ich habe ein Datumseingabefeld, das so eingestellt ist, dass es schreibgeschützt ist, wodurch der Benutzer gezwungen wird, aus dem Kalender auszuwählen.

für ein Startdatum:

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

für ein Enddatum:

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
quelle
0

Der folgende Code funktioniert für mich, um Text von der Eingabe zu erhalten

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

Sie müssen Promise verwenden, um Werte von Elementen zu drucken oder zu speichern.

 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
quelle
-1

Sie können so etwas versuchen

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

Dann können Sie diese Funktion aufrufen, wo Sie den Wert erhalten möchten.

Sohel Saiyed
quelle
-3

Sie können jQuery verwenden, um Text in das Textfeld abzurufen (funktioniert gut für mich). Überprüfen Sie die Bilddetails

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

Fügen Sie diese obige Abfrage in Ihren Code ein. Bilddetail:

Geben Sie hier die Bildbeschreibung ein

Dao Minh Dam
quelle