Как использовать элемент protractor.все в функции aync / await

#selenium #jasmine #protractor #e2e-testing #angular-e2e

#selenium #jasmine #транспортир #e2e-тестирование #angular-e2e

Вопрос:

Мой код похож

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

Этот код выдает приведенную ниже ошибку

 '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
  

В документах говорится, что « element.all » возвращает « ElementArrayFinder «.

но когда « element.all » используется в функции async / await, кажется, что она возвращает « ElementFinder[] «.

Как это возможно? из-за этого я не могу использовать такие методы, как « each() » или « get() » в « ElementArrayFinder «.

Каков наилучший возможный способ использовать « element.all » внутри « ElementArrayFinder «?

Это мой 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"
  }
  

Ответ №1:

Какую версию protractor вы используете? ElementFinder[] Синтаксис используется внутри protractor и, должно быть, каким-то образом ускользнул. Это была проблема в версии 5.2.0, но я полагаю, что она исправлена в текущей версии (5.4.2). Если вы посмотрите на исходный код, там есть изменение в функции, которая обрабатывает это, начиная примерно со строки 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);
}
}
  

Тогда как раньше это было просто

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

Короче говоря, на какой версии вы работаете и помогает ли обновление?

Комментарии:

1. Это мой пакет.json я использую protractor 5.4.2 «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- поставщик данных»: «^2.2.0», «транспортир-jasmine2-html-reporter»: «0.0.7» }

2. Черт возьми, я думал, что у меня это есть. Вы могли бы попробовать добавить promise.USE_PROMISE_MANAGER = false перед вашей функцией, которая вызывает element.all or element.each , а затем promise.USE_PROMISE_MANAGER = true после. Я не знаю, повлияет ли это негативно на ваш код, но это может решить эту проблему.

Ответ №2:

Ответ прост: element.all имеет свою собственную функцию then, объявленную отдельно.

Итак, когда вы делаете вот так

 let result = element.all();
  

В результате вы получите ElementArrayFinder результат, указанный в разделе «Возвращает«. ElementArrayFinder это объект, который имеет все указанные функции, которые вы хотели get , each и т.д.

Но если превратить это в обещание,

 let result = await element.all();
  

затем он вернет, A promise which will resolve to an array of ElementFinders represented by the ElementArrayFinder. который в основном ElementFinder[] соответствует указанному в разделе Returns ElementArrayFinder.prototype.then функции.