Подтвердить что ты не робот

Таргетирование элементов в директиве элементов с помощью Protractor

Рассмотрим следующую модель представления:

$scope.data = {};
$scope.data.person = {};
$scope.data.person.firstname = "";
$scope.data.person.lastname = "";
$scope.data.person.username = "";

и следующую директиву элемента:

<custom-form-directive ng-model="data.person"></custom-form-directive>

который содержит три входных тега для отображения данных. Как использовать транспортир для заполнения полей ввода путем таргетинга на ng-model="data.person"?

4b9b3361

Ответ 1

Это зависит от того, как вы получаете данные в/из входов в директиве. Однако во всех случаях вы можете объединить element(<locator>) вызовы для поиска sub-elements директивы:

var directive = element(by.model('data.person'));
var subElement = directive.element(by.<something>);

Если вы используете ng-model в самой директиве на каждом из входов, вы можете сделать что-то вроде:

var directive = element(by.model('data.person'));

// Assuming the inputs have attributes like `ng-model="firstname"` in the directive template
var firstnameInput = directive.element(by.model('firstname'));
var lastnameInput = directive.element(by.model('lastname'));
var usernameInput = directive.element(by.model('surnamname'));

а затем на каждый вызов sendKeys

firstnameInput.sendKeys('Peter');
secondnameInput.sendKeys('Piper');
usernameInput.sendKeys('PickledPumpernickle');

Если вы не используете ng-model в шаблоне директивы, вы можете использовать другие локаторы, чтобы найти подэлементы вместе с get, если это необходимо, и зависеть от порядка, который они находятся в DOM

var inputs = directive.element(by.css('input'));
var firstnameInput = inputs.get(0);
var secondnameInput = inputs.get(1);
var usernameInput = inputs.get(2);

Однако я подозреваю, что ни одно из вышеперечисленных действий не будет работать, если у вас есть replace: true, указанный в директиве, поскольку он зависит от исходного элемента, с атрибутом ng-model, находящимся в DOM.

Ответ 2

Это именно то, что метод оценки предназначен для: http://angular.github.io/protractor/#/api?view=ElementFinder.prototype.evaluate

element(by.model('data.person')).evaluate('data.person.firstname = "yourvaluehere"');

Я предполагаю, что с помощью "таргетинга на модель" вы хотите изменить значение контроллера и изменить директиву ng-model в представлении, а не наоборот.

Ответ 3

Я думаю, вы хотите создать что-то вроде "pageObject" (см. https://github.com/angular/protractor/blob/master/docs/page-objects.md) для вашей директивы custom-form-directive. Этот объект поймет, как эта директива будет отображать примитивы, которые будет понимать Протрактор (например, конкретные поля ввода). Он должен взять локатор, чтобы его вызывающие лица могли передать, как найти директиву на странице, но после этого объект должен обрабатывать все.

var object = new customFormDirectiveObject(by.model('data.person'));

в зависимости от того, как работает ваша директива, вы бы сделали что-то вроде:

object.setName(first, last, user);

или если его более dyanmic может быть что-то вроде этого:

object.setName({firstname: first, lastname: last, username: user });

Ответ 4

С помощью нескольких вспомогательных функций вы можете сделать это довольно легко. Вспомогательный объект просто обертывает транспортир и делает его более разумным и безопасным в использовании. Особенно при работе на удаленных системах.

var helper = {
  getElement: function (selector) {
    return element(by.css(selector));
  },

  resolveSelector: function (selector) {
    var el;
    if (typeof selector === 'string') {
      el = self.getElement(selector);
    } else {
      el = selector;
    }
    return el;
  },

  waitForElementClickable: function (selector) {
    var el = self.resolveSelector(selector);
    var condition = function () {
      return self.waitForElement(el).then(function () {
        return self.isElementEnabled(el);
      });
    };
    return self.wait(condition, 15000, 'Element not clickable. (' + selector + ')');
  },

  setElementValue: function (selector, value) {
    var el = self.resolveSelector(selector);
    return self.waitForElementClickable(el).then(function () {
      el.click().clear().sendKeys(value);
    });
  },

  getElementValue: function (selector) {
    var el = self.resolveSelector(selector);
    return el ? el.getAttribute('value') : '';
  }

}

Затем вы можете просто использовать обычные селектор CSS для установки ваших значений:

helper.setElementValue('[ng-model="data.person"] input:nth-child(1)', '1st Input Value');
helper.setElementValue('[ng-model="data.person"] input:nth-child(2)', '2nd Input Value');
helper.setElementValue('[ng-model="data.person"] input:nth-child(3)', '3rd Input Value');

И вы можете проверить ожидаемые значения примерно так:

expect(helper.getElementValue('[ng-model="data.person"] input:nth-child(1)')).toEqual('something')