【问题标题】:Targeting elements within an element directive with Protractor使用 Protractor 定位元素指令中的元素
【发布时间】:2015-05-08 06:24:58
【问题描述】:

考虑以下视图模型:

$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" 填充输入字段?

【问题讨论】:

    标签: javascript angularjs protractor


    【解决方案1】:

    这取决于您如何将数据输入/输出指令中的输入。但是,在所有情况下,您都可以将 element(&lt;locator&gt;) 调用链接在一起以搜索指令的 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】:

        我认为您想为您的custom-form-directive 指令构建类似“pageObject”的东西(参见https://github.com/angular/protractor/blob/master/docs/page-objects.md)。该对象将理解指令如何映射到 Protractor 将理解的原语(例如,特定的输入字段)。它应该采用定位器,以便其调用者可以传递如何在页面上找到指令,但对象应该处理之后的所有事情。

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

        根据您的指令的工作方式,您可以执行以下操作:

        object.setName(first, last, user);
        

        或者如果它更动态可能是这样的:

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

        【讨论】:

          猜你喜欢
          • 2017-07-15
          • 1970-01-01
          • 2018-03-17
          • 2014-01-27
          • 1970-01-01
          • 2020-03-21
          • 2019-11-19
          • 1970-01-01
          • 2020-06-22
          相关资源
          最近更新 更多