如何在Protractor中从父元素中返回子元素

时间:2015-02-19 16:13:23

标签: javascript angularjs testing protractor end-to-end

我正在寻找一种从给定父元素块(使用页面对象)返回子元素的方法,并且能够通过链接调用它们。例如,给定页面上的一些小部件:

<div id="widget-1">
  <div class="name">Widget 42</div>
  <div class="color">Blue</div>
</div>
<div id="widget-2">
  <div class="name">Widget 23</div>
  <div class="color">Red</div>
</div>

页面对象,widgetPage:

this.widget = function(num) { return $('div#widget-' + num) };

我想只从第一个小部件块中获取名称和颜色。这适用于我的规范:

expect(widgetPage.widget('42').$('color').getText()).toBe('Blue');

但我不希望在我的规范中有选择器代码;我希望它在页面对象中,它属于它。我找不到一个很好的方法来做到这一点。我尝试过各种各样的事情......

this.getWidgetElms = function(num) {
    return this.widget(num).then(function(w) {
        return {
            name: w.$('div.name'),
            color: w.$('div.color')
        };
    });
};
// fails because name and color are undefined... 

最终,我希望能够做这样的事情(不工作):

expect(widgetPage.getWidgetElms('42').color.getText()).toBe('Blue');

显然我做错了什么......我怎样才能只返回第一个widget块的子元素?

3 个答案:

答案 0 :(得分:4)

如果您要从widget函数中返回一个对象,该怎么办:

this.widget = function (num) {
    var elm = element(by.css('div#widget-' + num));
    return {
        widget: elm,
        name: elm.element(by.css('div.name')),
        color: elm.element(by.css('div.color'))
    };  
};

然后,在您的规范中:

var widget = widgetPage.widget('42');
expect(widget.name.getText()).toBe('Widget 42');
expect(widget.color.getText()).toBe('Blue');

答案 1 :(得分:0)

我并不特别了解Protractor,但这里有两种jQuery方式来自&#34; Widget 42&#34;到&#34;蓝色。&#34;任何一个都可以变成页面对象中的一个函数。第一个取决于名称和颜色节点的顺序,而第二个不取决于

$('div.name:contains("Widget 42")').next().text()

$('div.name:contains("Widget 42")').parent().find('.color').text();

(但我更喜欢alecxe&#39的解决方案。)

答案 2 :(得分:0)

我发现element.all上map()函数的示例对这种情况非常有用:https://github.com/angular/protractor/issues/392#issuecomment-33237672

调整该示例会导致您的情况(未经测试)中的以下内容

element.all(by.css('div[id*="widget"]')).map(function(el) {
  return {
    name: el.element(by.css('div.name')).getText(),
    color: el.element(by.css('div.color')).getText()
  }
});

因此,如果您可以使用all来获取所有小部件,则可以创建名称和颜色的地图。