У меня есть несколько тестов E2E для приложения с поперечной платформой Ionic. Тесты написаны на Ruby, и они используют appium_capybara, водосвинку и селен WebDriver.
Приложение Ionic имеет функцию async javascript, которая может использоваться с консоли разработчика для входа в приложение. Я хочу вызвать это из тестов, и мне удалось сделать это из Ruby с помощью функции, называемой valu_async_script.
Однако, хотя у меня есть доказательство того, что функция async фактически выполняется, я получаю эту ошибку от Ruby:
Сроки ожидания асинхронного результата скрипта после 10033 мс (Selenium :: WebDriver :: Error :: ScriptTimeoutError)
Почему это происходит? Любые предложения о том, как заставить его работать?
Функция async выглядит примерно так:
export async function signin(user: string, pass: string,
callback: (result: object) => object):
Promise<object> {
if (typeof(window.authService) === 'object') {
const credentials: ICredentials = {
email: user,
password: pass,
rememberMe: false
};
await window.authService.authenticate(credentials);
const result = { message: 'YES!!' };
callback(result);
return result;
}
return { message: 'EMPTY STRING!!' };
}
Вызов Ruby выглядит следующим образом:
result = Capybara.current_session
.evaluate_async_script("window.signin('#{user.email}',
'#{user.password}', (result) => { return result; })
.then(function(value) { alert(value.message); })")
Появляется предупреждение, показывающее "ДА !!" сообщение, поэтому я знаю, что функция выполнена. Но по какой-то причине Ruby никогда не замечает, что функция закончена.
Из документов для Session#evaluate_async_script
- https://www.rubydoc.info/gems/capybara/Capybara/Session#evaluate_async_script-instance_method - важная часть - это "из функции обратного вызова, которая будет передана в качестве последнего аргумента скрипту ". Ваш скрипт не вызывает функцию обратного вызова, которая будет доступна в качестве arguments[0]
поэтому у Capybara нет способа узнать, что это сделано.
Чтобы он работал, вам понадобилось бы что-то вроде (непроверенных)
result = Capybara.current_session.evaluate_async_script("
var cb = arguments[0];
window.signin('#{user.email}','#{user.password}', cb);")
Вы также можете передать адрес электронной почты и пароль в качестве аргументов
result = Capybara.current_session.evaluate_async_script('
var cb = arguments[2];
window.signin(arguments[0], arguments[1], cb);', user.email, user.password)
Обратите внимание, что это перемещает функцию обратного вызова в arguments[2]
, поскольку сначала вы передаете еще 2 аргумента.
Больший вопрос заключается в том, нужно ли вам даже использовать evaluate_async_script
. Это необходимо только в том случае, если вам действительно нужен ответ от функции async, если вы не можете просто вызвать его с помощью execute_script
и дождаться изменения видимой страницы в обычном режиме.