1
votes

My Code is like

async function myTestFunc(){
               let items:ElementArrayFinder = await element.all( by.xpath("./li"));
}

That code gives below error

'items' is declared but its value is never read.ts(6133)
Type 'any[] | ElementFinder[]' is not assignable to type 'ElementArrayFinder'.
Type 'any[]' is missing the following properties from type 'ElementArrayFinder': browser_, getWebElements, locator_, actionResults_, and 35 more

Docs say "element.all" returns "ElementArrayFinder".

but when "element.all" used within async/await function it seems to be returning "ElementFinder[]".

How is that possible ? because of this I can't use methods like "each()" or "get()" in "ElementArrayFinder".

What is the best possible way to use "element.all" within "ElementArrayFinder" ?

This is my package.json

"devDependencies": {
    "@types/jasmine": "^3.3.5",
    "@types/node": "^10.12.18",
    "protractor": "^5.4.2",
    "typescript": "^3.2.2"
  },
  "dependencies": {
    "@types/jasmine-data-provider": "^2.2.1",
    "jasmine-data-provider": "^2.2.0",
    "protractor-jasmine2-html-reporter": "0.0.7"
  }
2

2 Answers

0
votes

What version of protractor are you using? The ElementFinder[] syntax is used internally by protractor and must have snuck out somehow. This was an issue in 5.2.0 but I believe it is fixed in the current version (5.4.2). If you look at the source code, there is a change to the function that handles this, Starting around line 550,

* @param {function(Array.<ElementFinder>)} fn
* @param {function(Error)} errorFn
*
* @returns {!webdriver.promise.Promise} A promise which will resolve to
*     an array of ElementFinders represented by the ElementArrayFinder.
*/
then<T>(
    fn?: (value: ElementFinder[] | any[]) => T | wdpromise.IThenable<T>,
    errorFn?: (error: any) => any): wdpromise.Promise<T> {
      if (this.actionResults_) {
      return this.actionResults_.then(fn, errorFn);
} else {
  return this.asElementFinders_().then(fn, errorFn);
}
}

Whereas it used to just be

@param {function(Array.<ElementFinder>)} fn
* @param {function(Error)} errorFn
*
* @returns {!webdriver.promise.Promise} A promise which will resolve to
*     an array of ElementFinders represented by the ElementArrayFinder.
*/
then<T>(fn?: (value: ElementFinder[] | any[]) => T | wdpromise.IThenable<T>, 
errorFn?: (error: any) => any): wdpromise.Promise<T>;

Long story short, what version are you on and does an upgrade help?

0
votes

The answer is simple: element.all has it's own then function, declared separately.

So when you doing like so

let result = element.all();

You will get ElementArrayFinder as a result, as it specified in Returns section. ElementArrayFinder is an object, that has all the specified functions you wanned get, each and etc.

But if turn it into a promise,

let result = await element.all();

then it will return A promise which will resolve to an array of ElementFinders represented by the ElementArrayFinder. which is basically ElementFinder[] as specified in Returns section of ElementArrayFinder.prototype.then function.