如何使用capybara从ruby调用异步javascript函数?

如何使用capybara从ruby调用异步javascript函数?,javascript,ruby,cucumber,capybara,appium,Javascript,Ruby,Cucumber,Capybara,Appium,我有一些跨平台离子应用的E2E测试。这些测试是用Ruby编写的,它们使用、和 Ionic应用程序有一个异步javascript函数,可以从开发人员控制台使用该函数登录应用程序。我想从测试中调用它,我通过一个名为 然而,虽然我有证据证明异步函数确实执行了,但我从Ruby得到了以下错误: 10033毫秒后等待异步脚本结果超时(Selenium::WebDriver::Error::ScriptTimeoutError) 为什么会发生这种情况?有没有关于如何让它工作的建议 异步函数的外观如下所示: e

我有一些跨平台离子应用的E2E测试。这些测试是用Ruby编写的,它们使用、和

Ionic应用程序有一个异步javascript函数,可以从开发人员控制台使用该函数登录应用程序。我想从测试中调用它,我通过一个名为

然而,虽然我有证据证明异步函数确实执行了,但我从Ruby得到了以下错误:

10033毫秒后等待异步脚本结果超时(Selenium::WebDriver::Error::ScriptTimeoutError)

为什么会发生这种情况?有没有关于如何让它工作的建议

异步函数的外观如下所示:

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!!' };
}
result = Capybara.current_session
    .evaluate_async_script("window.signin('#{user.email}',
        '#{user.password}', (result) => { return result; })
            .then(function(value) { alert(value.message); })")

警报弹出显示“是!!”消息,因此我知道该函数已执行。但由于某些原因,Ruby从未注意到函数已经完成。

来自
会话的文档#evaluate_async_脚本
——重要的部分是“来自回调函数,它将作为最后一个参数传递给脚本”。您的脚本没有调用回调函数,回调函数将作为
参数[0]
提供,因此Capybara无法知道它是否完成了

为了让它发挥作用,你需要一些类似的东西(未经测试)

如果需要,您也可以将电子邮件和密码作为参数传入

result = Capybara.current_session.evaluate_async_script('
  var cb = arguments[2];
  window.signin(arguments[0], arguments[1], cb);', user.email, user.password)
注意,这会将回调函数移动到
参数[2]
,因为您首先要传递另外两个参数


更大的问题是您是否需要使用
评估异步脚本
。只有当您确实需要异步函数的响应时才需要它,如果不需要,您可以使用
execute\u script
调用它,然后像往常一样等待可见页面的更改。

谢谢您的回答。我将尽快测试它,看看它是否有效。但是,我想知道作为参数[0]传递的函数的接口是什么样子的。根据文档,我猜它是(object)=>object,因为Ruby必须从函数中获取结果。@StefanR。实际上,根据WebDriver规范,它应该是(object)=>未定义的
result = Capybara.current_session.evaluate_async_script('
  var cb = arguments[2];
  window.signin(arguments[0], arguments[1], cb);', user.email, user.password)