简体   繁体   English

如何从量角器的父元素内返回子元素

[英]How to return child elements from within parent element in Protractor

I'm looking for a way to return the child elements from within a given parent element block (using page objects), and to be able to call them via chaining. 我正在寻找一种从给定的父元素块(使用页面对象)中返回子元素,并能够通过链接调用它们的方法。 For example, given a number of widgets on a page: 例如,假设页面上有许多小部件:

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

And a page object, widgetPage: 还有一个页面对象,widgetPage:

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

I want to ONLY grab the name and color from the first widget block. 我只想从第一个小部件中获取名称和颜色。 This works in my spec: 这在我的规范中有效:

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

But I don't want to have selector code in my spec; 但我不想在规范中包含选择器代码; I want it in the page object, where it belongs. 我想要它在它所属的页面对象中。 I've not been able to find a good way to do this. 我还没有找到一个好的方法来做到这一点。 I've tried various things like... 我已经尝试过各种方法,例如...

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... 

Ultimately, I'm looking to be able to do something like this (not working): 最终,我希望能够执行以下操作(不起作用):

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

Obviously I'm doing something wrong... How can I return only the child elements for the first widget block? 显然我做错了...我如何仅返回第一个小部件块的子元素?

What if you would return an object out of the widget function: 如果您要从小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'))
    };  
};

Then, in your spec: 然后,按照您的规范:

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

I don't know about Protractor in particular, but here are two jQuery ways to get from "Widget 42" to "blue." 我不特别了解Protractor,但这里有两种jQuery方式,可将“小部件42”转换为“蓝色”。 Either one could be turned into a function in the page object. 可以在页面对象中将任一函数转换为函数。 The first depends on the order of the name and color nodes, while the second doesn't. 第一个取决于名称和颜色节点的顺序,而第二个则不取决于。

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

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

(But I like alecxe's solution better.) (但我更喜欢alecxe的解决方案。)

I found the example for the map() function on element.all really helpful for this type of situation : https://github.com/angular/protractor/issues/392#issuecomment-33237672 . 我在element.all上找到了map()函数的示例,对于这种情况真的很有帮助: https : //github.com/angular/protractor/issues/392#issuecomment-33237672

Adapting that example would lead to something like the following in your case (not tested) 根据您的情况改编该示例将导致以下内容(未经测试)

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

So if you can use all to get all the widgets, you can then create a map of the name and color. 因此,如果可以使用all获取所有小部件,则可以创建名称和颜色的映射。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM