I'm trying to create an array of a custom object that requires an ElementFinder as a parameter.
The custom object, StatusObj, takes an ElementFinder object.
The code I'm trying to do create my objects and return that array looks like this:
function getStatusObjs() {
var arr;
arr = $$('li').each(function(el) {
return new StatusObj(el);
}
return arr;
}
This doesn't work. It locks up and times out or runs out of space. I've tried '.map()' and I've tried putting arr = new StatusObj(el);
but, of course, arr isn't in scope (for lack of a better term) within the .each function.
Update for Alexce:
Here is the stack trace I get when I try your solution:
<--- 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
Is this a problem with my object creation code or that I'm not handling the promise correctly?
You need the map()
:
function getStatusObjs() {
return $$('li').map(function(el) {
return new StatusObj(el);
});
}
Now, the result of getStatusObjs()
call would be a promise that would be resolved into an array of StatusObj
objects:
getStatusObjs().then(function (objs) {
console.log(objs);
});
There is currently bug reported for this - https://github.com/angular/protractor/issues/2227
I did dirty hack that works for me while i waiting for that bug to be fixed.
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();
}
}
Notice .map() function does not return anything in my hack
Usage is -
var checkboxes = ArrayContainer($$('.checkbox'), Checkbox);
checkboxes.first() // returns Checkbox object, not ElementFinder
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.