代码之家  ›  专栏  ›  技术社区  ›  Stefan R.

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

  •  1
  • Stefan R.  · 技术社区  · 6 年前

    我有一些跨平台离子应用的E2E测试。测试是用Ruby编写的,它们使用 appium_capybara , capybara selenium-webdriver .

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

    然而,虽然我有证据证明异步函数实际上是执行的,但我从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从未注意到函数已经完成。

    1 回复  |  直到 6 年前
        1
  •  1
  •   Thomas Walpole    6 年前

    从文件中 Session#evaluate_async_script - https://www.rubydoc.info/gems/capybara/Capybara/Session#evaluate_async_script-instance_method -重要的部分是“从回调函数,它将作为最后一个参数传递给脚本”。你的脚本没有调用回调函数 arguments[0] 所以水豚无法知道它已经完成了。

    为了让它工作,你需要一些(未经测试的)东西

    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] ,因为你要先传递另外两个参数。

    更大的问题是你是否需要使用 evaluate_async_script . 只有当您真正需要异步函数的响应时才需要它,如果不需要,您可以用 execute_script 然后像平常一样等待可见的页面更改。