Как получить текст на входе в транспортире

105

В документации к транспортиру я вижу следующий пример:

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

Здесь ясно то, что вы можете использовать «by.model» для установки значений в поле ввода, но если вы хотите взглянуть на поле ввода и увидеть, что в нем, вам нужно использовать «by.binding».

У меня есть набор кода, в котором (вкратце) я делаю:

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

(в моем реальном коде я сохраняю объект, а затем возвращаюсь к нему в режиме редактирования, и я проверяю, что мое значение было действительно сохранено. Но это все равно сводится к тому же самому, и этот пример кода дает ту же проблему).

Это дает мне ошибку:

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

Теоретически, следуя примеру из документации, я могу вместо этого сделать:

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

Но by.binding не нравится полностью квалифицированная модель, я получаю сообщение об ошибке:

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

Это работает (в некотором роде), если я:

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

Это находит элемент, но также выдает предупреждение о том, что у меня есть несколько элементов, соответствующих 'name'. И, к сожалению, тот, который он выбрал, не тот.

Итак, два вопроса:

  1. Должен ли by.model возвращать getText (), или есть дизайнерское решение, что он этого не делает, и вместо этого нам нужно использовать by.binding?
  2. Должен ли я использовать полностью квалифицированную сущность в by.binding или есть проектное решение, которому by.binding не нравится полное название модели? Если да, то какой еще квалификатор я могу использовать для выбора между разными привязками?

РЕДАКТИРОВАТЬ:

Я также попробовал решение, предложенное vdrulerz, я изменил код следующим образом:

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

Console.log возвращает пустое значение (не обещание или объект), а ожидание не дает сообщения:

Expected '' to equal 'A risk name'.

Насколько я понимаю, транспортир уже исправляет ожидание обработки обещания, поэтому я чувствую, что основная проблема заключается в том, что getText не работает с полем, идентифицированным с помощью модели (я могу успешно getText для меток и других виджетов).

Я также могу запустить следующий код, используя getAttribute вместо 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');  
});

Первая часть проходит - ожидание работает. Вторая часть также работает, предполагая, что синтаксис vdrulerz также действителен и выводит в консоль «true». Я думаю, что в getText потенциально есть дефект?

PaulL
источник

Ответы:

203

Ответ на этот вопрос можно найти в FAQ по транспортиру: https://github.com/angular/protractor/blob/master/docs/faq.md#the-result-of-gettext-from-an-input-element-is-always- пустой

Результат getText из входного элемента всегда пуст

Это причуда веб-драйвера. и элементы всегда имеют пустые значения getText. Вместо этого попробуйте:

element.getAttribute('value')

Что касается вопроса 2, да, вы должны иметь возможность использовать полное имя для by.binding. Я подозреваю, что в вашем шаблоне на самом деле нет элемента, привязанного к risk.name через {{}} или ng-bind.

JMR
источник
Ах, я думал, что искал везде, в том числе и искал. И я только что поднял это как проблему в github транспортира сегодня на том основании, что я не нашел ответа. Беспокойство. Мой элемент привязан к ng-модели, поэтому в html есть "ng-model =" risk.name "". Но, возможно, это не то, что нужно для работы. Я предлагаю обновить документ, чтобы предложить использовать getAttribute.
PaulL
1
Добавляю это для потомков, поскольку я слишком долго разбирался в этом: getAttribute фактически возвращает обещание, а не строку. github.com/angular/protractor/issues/673
boredlamer
И я думаю, что эта магия работает из-за поведения getAttribute, который фактически получит свойство (т.е. он вернет значение, даже если в вашей DOM нет атрибута value): "... если этот атрибут не присутствует, и в этом случае возвращается значение свойства с тем же именем »
The Red Pea
6

getText() функция не будет работать так, как раньше для webdriver, чтобы заставить ее работать для транспортира, вам нужно будет обернуть ее в функцию и вернуть текст примерно так, как мы сделали для нашей структуры транспортира, мы сохранили его в общая функция, такая как -

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

    },

Таким образом вы можете получить текст элемента.

Дайте мне знать, если это все еще непонятно.

vdrulerz
источник
Я понимаю, что мне нужно это сделать, если я хочу использовать текст напрямую, но я подумал, что Protractor исправил сопоставители ожиданий Jasmine для работы с обещанием - так что expect (element.getText ()). ToEqual фактически был таким же, как element .getText (). затем (ожидать (текст) .toEqual). Это не так?
PaulL 03
У меня это тоже не работает. Я расширил свой вопрос выше, чтобы вы могли видеть его в формате.
PaulL
попробуйте использовать element (by.locator ('abc'). getText (). then (function (text) {console.log (text) expect (text) .toEqual ("sometext");});
vdrulerz
Он сообщает, что Object [объект Object] не имеет метода 'locator'. Я не вижу метода в api транспортира для 'by.locator', и я не вижу его в коде - и, конечно, если бы был метод by.locator, то это было бы что-то вроде 'by. локатор ('модель', 'риск.имя') '?
PaulL
с by.locator я имел в виду, что вы можете использовать что-то вроде prot.findelement (By.id), CSS, Xpath или любой атрибут локатора .... если он все еще не работает, пожалуйста, поделитесь со мной своим кодом и атрибутами html ... обязательно
выручу
2

У меня была эта проблема, я попробовал решение Jmr, но у меня это не сработало. Поскольку все поля ввода имеют атрибуты ng-модели, я мог бы вытащить атрибут, оценить его и получить значение.

HTML

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

Транспортир

var qty = element( by.model('qty') );
qty.sendKeys('10');
qty.evaluate(qty.getAttribute('ng-model')) //-> 10
Майкл Уорнер
источник
0

Этот код работает. У меня есть поле ввода даты, которое настроено только для чтения, что заставляет пользователя выбирать из календаря.

на дату начала:

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

на дату окончания:

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
источник
0

ниже код работает для меня, для получения текста с ввода

return(this.webelement.getAttribute('value').then(function(text)
    {
        console.log("--------" + text);
}))
Навин Каттимани
источник
0

Вы должны использовать Promise для печати или сохранения значений элемента.

 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

                    });
Пранава Мишра
источник
-1

Вы можете попробовать что-то вроде этого

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

Затем вы можете вызвать эту функцию там, где хотите получить значение ..

Сохель Сайед
источник
-3

Вы можете использовать jQuery для получения текста в текстовом поле (хорошо работает для меня), проверьте детали изображения

Код:

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

Вставьте этот запрос в свой код. Детали изображения:

введите описание изображения здесь

Дао Минь Дам
источник