如何使用.each或.map在量角器

时间:2016-05-28 02:06:48

标签: javascript promise protractor

我正在尝试创建一个需要ElementFinder作为参数的自定义对象数组。

自定义对象StatusObj采用ElementFinder对象。

我正在尝试创建的代码并返回该数组,如下所示:

function getStatusObjs() {
    var arr;

    arr = $$('li').each(function(el) {
        return new StatusObj(el);
    }

    return arr;
}

这不起作用。它会锁定并超时或耗尽空间。我尝试了'.map()'并且我尝试了arr = new StatusObj(el);但是,当然,在.each函数中,arr不在范围内(缺少更好的术语)。

Alexce更新:

以下是我尝试解决方案时获得的堆栈跟踪:

<--- Last few GCs --->

  118309 ms: Mark-sweep 1254.4 (1434.1) -> 1239.4 (1434.1) MB, 2124.7 / 0 ms [allocation failure] [GC in old space requested].
  120614 ms: Mark-sweep 1239.4 (1434.1) -> 1239.4 (1434.1) MB, 2305.0 / 0 ms [allocation failure] [GC in old space requested].
  122702 ms: Mark-sweep 1239.4 (1434.1) -> 1239.4 (1434.1) MB, 2088.9 / 0 ms [last resort gc].
  124818 ms: Mark-sweep 1239.4 (1434.1) -> 1239.4 (1434.1) MB, 2115.1 / 0 ms [last resort gc].


<--- JS stacktrace --->

==== JS stack trace =========================================

Security context: 0x30c99fec9fa9 <JS Object>
    1: get stack [native messages.js:595] [pc=0x32edf1d73957] (this=0x82e2251cb1 <a RangeError with map 0x206aaf5b8ae9>)
    3: resolve_ [/usr/local/lib/node_modules/protractor/node_modules/selenium-webdriver/lib/promise.js:1115] [pc=0x32edf1dfdbe5] (this=0x82e2247b99 <a Promise with map 0x206aaf58ff81>,newState=0x29909e1edd89 <String[8]: rejected>,newValue=0x82e2251cb1 <a RangeError with map 0...

FAbort trap: 6

这是我的对象创建代码的问题还是我没有正确处理承诺?

2 个答案:

答案 0 :(得分:2)

您需要map()

function getStatusObjs() {
    return $$('li').map(function(el) {
        return new StatusObj(el);
    });
}

现在,getStatusObjs()调用的结果将是 promise ,它将被解析为StatusObj个对象的数组:

getStatusObjs().then(function (objs) {
    console.log(objs);
});

答案 1 :(得分:1)

目前有针对此报告的错误 - https://github.com/angular/protractor/issues/2227

在我等待修复该错误时,我做了肮脏的黑客攻击。

class ArrayContainer {
    /**
     * Special wrapper around array element finder,
     * but wraps returned elements to provided classToWrap.
     *
     * TODO: Find way to wrap elements with $$('div').map(elem => new WrappedElem(elem))
     * Currently bug is reported - https://github.com/angular/protractor/issues/2227
     * @param arrayFinder
     * @param classToWrap
     */
    constructor (arrayFinder, classToWrap) {
        this.classToWrap = classToWrap;
        this.arrayFinder = arrayFinder;
    }

    get(index) {
        return new this.classToWrap(this.arrayFinder.get(index), this.arrayFinder.ptor_);
    }

    first() {
        return new this.classToWrap(this.arrayFinder.first(), this.arrayFinder.ptor_);
    }

    last() {
        return new this.classToWrap(this.arrayFinder.last(), this.arrayFinder.ptor_);
    }

    /**
     * Wraps .map() function, so provided function will receive wrapped object as first param, not ElementFinder.
     */
    map(func) {
        return this.arrayFinder.map((elem, index) => {
            // No return, since i am not sure that it will not fail with this bug -
            // https://github.com/angular/protractor/issues/2227
            func(new this.classToWrap(elem, this.arrayFinder.ptor_), index)
        });
    }
    /**
     * Wraps .filter() function, so provided function will receive wrapped object as first param, not ElementFinder.
     */
    filter(func) {
        let filtered = this.arrayFinder.filter((elem, index) => {
            return func(new this.classToWrap(elem, this.arrayFinder.ptor_), index)
        });
        return new ArrayContainer(filtered, this.classToWrap);
    }

    count() {
        return this.arrayFinder.count();
    }
} 

注意.map()函数不会在我的hack中返回任何内容

用法是 -

var checkboxes = ArrayContainer($$('.checkbox'), Checkbox);
checkboxes.first() // returns Checkbox object, not ElementFinder