Удаленка для jenkins+selenide+selenoid+allure+docker спецов на 2-3 часа в день. 100% remote! Присоединиться к проекту

Как из промисов getText вытащить значения, сложить их, а сумму сравнить с другой такой же суммой?

protractor
jasmine
webdriver
javascript
Теги: #<Tag:0x00007fedc3c5b210> #<Tag:0x00007fedc3c5b0d0> #<Tag:0x00007fedc3c5af90> #<Tag:0x00007fedc3c5ae50>

(Antony Marcial) #1

Использую версию Protractor 5.3.0
node version 8.9.4

Делаю следующее:
есть вспомогательная функция, которая по идее должна резолвить промис и парсить в целое число.

foo = function(ele){       
		return ele.getText().then(function(val){
		  return parseInt(val);
		});
	};

Далее есть два элемента на одной странице “elementM” и “elementP”, которые мы передаем в функцию выше и результат загоняем в переменную.

 let Merg = foo(elementM);  
 let Part =  foo(elementP);  
 let Total = Merg+ Part; // пытаемся получить сумму двух целых чисел, вытащенных из наших двух элементов

Потом пытаюсь сравнить
expect(Total).toBeGreaterThan(Total2); // Total2 - некое число полученное агалогичным образом

ИТОГ: ошибка типа Expected ‘ManagedPromise::17198 {[[PromiseStatus]]: “pending”}ManagedPromise::17212 {[[PromiseStatus]]: “pending”}’ to be greater than ‘ManagedPromise::17324 {[[PromiseStatus]]: “pending”}ManagedPromise::17338 {[[PromiseStatus]]: “pending”}’.

что я делаю не так? как привильно читать, сохранять и манипулировать числами в элементах ?

вид элемента<div title="1506">1506</div>
нас интересует число “1506” внутри.

Заранее спасибо


(Sergei Chipiga) #2

Здесь поддерживается язык разметки markdown. Так что если вы отформатируете свой код, то вам с большей вероятностью помогут, т.к. читать.:

module.exports.sleep = (timeout, blocking) => {
    blocking = !!blocking;
    if (blocking) {
        (ms => {
            ms += new Date().getTime();
            while (new Date() < ms) { /* nothing */ }
        })(timeout);
    } else {
        return new Promise(resolve => {
            setTimeout(resolve, timeout);
        });
    }
};

гораздо приятнее чем,

module.exports.sleep = (timeout, blocking) => {
blocking = !!blocking;
if (blocking) {
(ms => {
ms += new Date().getTime();
while (new Date() < ms) { /* nothing */ }
})(timeout);
} else {
return new Promise(resolve => {
setTimeout(resolve, timeout);
});
}
};


(Sergei Chipiga) #3

А в целом по вопросу, можете использовать:

  • либо промисы:
let Merg;

foo(elementM).then(res => {
    Merg = res;
    return foo(elementP);
}).then(res => {
    let Total = Merg + res;
    expect(Total).toBeGreaterThan(Total2);
});
  • либо async/await (в вашей версии nodejs поддерживается нативно):
let Merg = await foo(elementM);
let Part = await foo(elementP);
let Total = Merg + Part;
expect(Total).toBeGreaterThan(Total2);

Только не забудьте пометить функцию, где используете await, как async.
И второй вариант лучше, т.к. код не выглядит как г-о.


(Oleksii Ihnatiuk) #4

Начать использовать ES6 для начала. async/await, стрелочные функции, let и const.


(Antony Marcial) #5

спасибо. Но у меня Total2 еще не получен, он будет получен позднее на другой странице, соответственно тогда сравниваем.
Но в итоге пишет Total undefined. как можно вытащить Total за пределы then функции?
заранее извиняюсь за возможно глупые вопросы, т.к. я еще новичок


(Oleksandr Khotemskyi) #6

Promise не станет магически int - ваша функция foo всеравно возвращает промис, но он уже зарезолвится не в строку, а в результат parseInt.

попробуйте

let total = parseInt(await elementM.getText()) + parseInt(await elementP.getText()) 

ну или без async/await

let Merg = foo(elementM);  
let Part =  foo(elementP);  
let Total = Promise.all(Merg, Part).then(vals => vals[0] + vals[1])
Total.then((resolved)=> console.log(resolved))

(Sergei Chipiga) #7

Никак, нужно работать внутри промиса. И все-таки лучше перейти на async/await, т.к. это даст больше гибкости кода. И скорее всего вы выбрали не тот язык для вхождения в автоматизацию, JS изначально ориентирован на неблокирующий i/o. И это трудно к пониманию.


(Antony Marcial) #8

@xotabu4, спасибо, попробовал, но пишет “Failed: undefined is not a function” для строки “let Total = Promise.all…”. но все равно спасибо.

@Sergei_Chipiga Спасибо также и вам, но к сожалению не могу использовать async/await для этого конкретного проекта, т.к. ранее написанный код был без использования async/await, соответственно я не могу отключить control flow / promise manager без последствий.

UPDATE: только что решил задачу, у меня эйфория, напишу чуть позже как, чтобы другие могли воспользоваться )))


(Antony Marcial) #9

@xotabu4, доработал ваш вариант, который в итоге и заработал:


let Merg = foo(elementM);
let Part = foo(elementP);
let sumPromiseValues = () => Promise.all( [Merg, Part]).then(vals =>
 vals[0] + vals[1]).then(resolved => {return resolved});

let Total = sumPromiseValues();

т.о. удалось вытащить целые числа из элементов с помощью .getText, сложить их и значение суммы загнать в переменную.

Ну и далее успешно сравнили значения как и было задумано далее по ходу теста:

expect(Total).toBeGreaterThan(Total2);

И все это за пределами промиса.:thumbsup:

Большое спасибо за помощь.


(Oleksandr Khotemskyi) #10

Ну раз такое дело то можно просто

let Merg = foo(elementM);
let Part = foo(elementP);
let Total = Promise.all( [Merg, Part]).then(vals =>
 vals[0] + vals[1])