Jak pobrać tekst na wejściu w kątomierzu

105

W dokumentacji kątomierza widzę następujący przykład:

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

Jasne wydaje się tutaj to, że możesz użyć „by.model” do ustawienia wartości w polu wprowadzania, ale jeśli chcesz spojrzeć na pole wprowadzania i zobaczyć, co w nim jest, musisz użyć „by.binding”.

Mam zestaw kodu, w którym (podsumowując) robię:

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

(w moim prawdziwym kodzie zapisuję encję, a następnie wracam do niej w trybie edycji i sprawdzam, czy moja wartość została faktycznie zapisana. Ale nadal sprowadza się to do tego samego, a ten przykładowy kod daje ten sam problem).

To daje mi błąd:

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

Teoretycznie, idąc za przykładem z dokumentacji, mogę zamiast tego zrobić:

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

Ale by.binding nie wygląda na w pełni kwalifikowany model, pojawia się błąd:

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

Działa (w pewnym sensie), jeśli:

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

Znajduje element, ale także wyświetla ostrzeżenie, że mam więcej niż jeden element, który pasuje do słowa „nazwa”. I niestety ten, który wybiera, nie jest właściwy.

A więc dwa pytania:

  1. Czy by.model powinien być w stanie zwrócić metodę getText (), czy też istnieje decyzja projektowa, że ​​tego nie robi i musimy zamiast tego użyć by.binding?
  2. Czy powinienem być w stanie użyć w pełni kwalifikowanej jednostki w by.binding, czy też istnieje decyzja projektowa, która przez.binding nie lubi pełnej nazwy modelu? Jeśli tak, jakiego innego kwalifikatora mogę użyć do wybrania między moimi różnymi powiązaniami?

EDYTOWAĆ:

Wypróbowałem też rozwiązanie sugerowane przez vdrulerza, zmodyfikowałem kod w następujący sposób:

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

Console.log zwraca pustą wartość (nie obietnicę ani obiekt), a oczekiwanie nie powiedzie się, podając wiadomość:

Expected '' to equal 'A risk name'.

Rozumiem, że kątomierz już łata oczekiwanie, aby poradzić sobie z obietnicą, więc czuję, że podstawowym problemem jest to, że getText nie działa na polu zidentyfikowanym przez model (mogę z powodzeniem getText na etykietach i innych widżetach).

Mogę również uruchomić następujący kod, używając metody getAttribute zamiast 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');  
});

Pierwsza część mija - oczekiwanie działa. Druga część również działa, co sugeruje, że składnia vdrulerz jest również poprawna i rejestruje „prawda” w konsoli. Myślę, że w getText istnieje potencjalna wada?

Paul L.
źródło

Odpowiedzi:

202

Odpowiedź na to znajduje się w FAQ Protractor: https://github.com/angular/protractor/blob/master/docs/faq.md#the-result-of-gettext-from-an-input-element-is-always- pusty

Wynik getText z elementu wejściowego jest zawsze pusty

To jest dziwactwo webdrivera. a elementy zawsze mają puste wartości getText. Zamiast tego spróbuj:

element.getAttribute('value')

Jeśli chodzi o pytanie 2, tak, powinieneś być w stanie użyć w pełni kwalifikowanej nazwy dla by.binding. Podejrzewam, że twój szablon w rzeczywistości nie zawiera elementu, który jest powiązany z risk.name za pośrednictwem {{}} lub ng-bind.

Jmr
źródło
Ach, myślałem, że szukałem wszędzie, w tym szukając tego. I właśnie podniosłem to jako problem na githubie kątomierza dzisiaj, ponieważ nie znalazłem odpowiedzi. Niepokoić. Mój element jest powiązany z ng-model, więc w kodzie HTML ma ciąg „ng-model =" risk.name "". Ale to może nie być to, co jest potrzebne, aby to zadziałało. Zasugeruję zaktualizowanie doco, aby zasugerować użycie getAttribute.
PaulL
1
Dodając to dla potomności, ponieważ spędziłem zbyt dużo czasu na zastanawianiu się nad tym: getAttribute w rzeczywistości zwraca obietnicę, a nie ciąg. github.com/angular/protractor/issues/673
boredlamer
I myślę, że ta magia działa z powodu zachowania getAttribute, który faktycznie otrzyma właściwość (tj. Zwróci wartość, nawet jeśli w Twoim DOM nie ma atrybutu "value"): "..., chyba że ten atrybut nie jest obecny, w takim przypadku zwracana jest wartość nieruchomości o tej samej nazwie "
The Red Pea.
6

getText() funkcja nie będzie działać tak jak kiedyś dla webdrivera, aby sprawić, że będzie działać dla kątomierza, będziesz musiał zawinąć ją w funkcję i zwrócić tekst tak, jak zrobiliśmy to dla naszego frameworka kątomierza, który trzymaliśmy w wspólna funkcja, taka jak -

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

    },

Dzięki temu możesz mieć tekst elementu.

Daj mi znać, jeśli nadal jest niejasne.

vdrulerz
źródło
Rozumiem, że muszę to zrobić, jeśli chcę użyć tekstu bezpośrednio, ale pomyślałem, że Protractor załatał Jasmine, oczekując dopasowań, aby poradzić sobie z obietnicą - tak, że oczekiwanie (element.getText ()). ToEqual było w rzeczywistości tym samym, co element .getText (). then (oczekiwać (tekst) .toEqual). Czy to nie jest poprawne?
PaulL
U mnie to też nie działa. Rozszerzyłem moje pytanie powyżej, abyś mógł zobaczyć to sformatowane.
PaulL
spróbuj użyć elementu (by.locator ('abc'). getText (). then (function (text) {console.log (text) oczekiwać (text) .toEqual ("someext");});
vdrulerz
Informuje, że Object [object Object] nie ma „lokalizatora” metody. Nie widzę metody w api kątomierza „by.locator”, a także nie widzę jej w kodzie - i na pewno gdyby istniała metoda by.locator, byłoby to coś w rodzaju „by. locator ('model', 'risk.name') '?
PaulL
z by.locator miałem na myśli, że możesz użyć czegoś takiego jak prot.findelement (By.id), CSS, Xpath lub dowolny atrybut lokalizatora .... jeśli nadal nie działa, udostępnij mi swój kod i atrybuty html ... na pewno pomóc ci ...
vdrulerz
2

Miałem ten problem, wypróbowałem rozwiązanie Jmr, ale nie zadziałało. Ponieważ wszystkie pola wejściowe mają atrybuty modelu ng, mogę wyciągnąć atrybut, ocenić go i uzyskać wartość.

HTML

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

Kątomierz

var qty = element( by.model('qty') );
qty.sendKeys('10');
qty.evaluate(qty.getAttribute('ng-model')) //-> 10
Michael Warner
źródło
0

Ten kod działa. Mam pole wprowadzania daty, które zostało ustawione jako tylko do odczytu, co zmusza użytkownika do wybrania z kalendarza.

na datę rozpoczęcia:

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

na datę końcową:

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
źródło
0

poniższy kod działa dla mnie, aby uzyskać tekst z wejścia

return(this.webelement.getAttribute('value').then(function(text)
    {
        console.log("--------" + text);
}))
Naveen Kattimani
źródło
0

Musisz użyć Promise, aby wydrukować lub zapisać wartości elementu.

 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
źródło
-1

Możesz spróbować czegoś takiego

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

Niż możesz wywołać tę funkcję, w której chcesz uzyskać wartość.

Sohel Saiyed
źródło
-3

Możesz użyć jQuery, aby uzyskać tekst w polu tekstowym (dla mnie działa dobrze), sprawdź szczegóły obrazu

Kod:

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

Wprowadź powyższe zapytanie do swojego kodu. Szczegóły obrazu:

wprowadź opis obrazu tutaj

Dao Minh Dam
źródło