首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >testability.whenStable()返回,testability.isStable()返回false

testability.whenStable()返回,testability.isStable()返回false
EN

Stack Overflow用户
提问于 2019-02-04 02:51:55
回答 1查看 1.8K关注 0票数 5

注意,这并不是特定于量角器。问题是角2的内置可测性服务,而量角器恰好使用。量角器通过调用Testability.whenStable调用waitForAngular。我撞到了一些代码这是失败的。

我的测试代码如下所示:

代码语言:javascript
复制
await renderFooView();
await interactWithFooView();

第二行失败:

代码语言:javascript
复制
 Failed: No element found using locator: By(css selector, foo-view)

当Protractor继续使用试图与其交互的代码时,角不是完成呈现'foo-view‘的。

如果我在中间加了一个睡眠,它就会起作用:

代码语言:javascript
复制
await renderFooView();
await browser.sleep(1000);
await interactWithFooView();

显然我不想那样做。对于我来说,“量角器”的大部分价值是“等待角度”机制,它消除了脚本中的“等待X”噪音。我想要的是:

代码语言:javascript
复制
await renderFooView();
await browser.waitForAngular();
await interactWithFooView();

事实上,我不应该手动执行这个中间行。每次我打电话与浏览器交互时,量角器都会自动完成。

在进行了一些深入研究之后,我发现Protractor正在进行调用,它工作正常,但是角2中的底层可测性机制出现了故障。

在角2下,量角器的"waitForAngular“执行如下操作:

代码语言:javascript
复制
let rootElement = window.getAllAngularRootElements()[0];
let testability = window.getAngularTestability(rootElement);
testability.whenStable(callbackThatResumesScriptExecution);

换句话说,它调用角的testability.whenStable,只有当角报告它是稳定的时才恢复执行。如果我在回调中添加了一些日志记录:

代码语言:javascript
复制
testability.whenStable(() => {
    console.log("isStable:", testability.isStable());
    callback();
});

isStable()whenStable回调中始终是正确的,因此角绝对是在正确的时间调用的。

但是,如果在此回调返回之后,我再次轮询isStable(),则它的计算结果为false。

代码语言:javascript
复制
    let pollAngularIsStable = `{ 
        let rootElement = window.getAllAngularRootElements()[0];
        let testability = window.getAngularTestability(rootElement);
        return testability.isStable();
    }`;

    await renderFooView();
    await browser.waitForAngular();
    console.log(await browser.executeScript(pollAngularIsStable)); // => false
    await interactWithFooView();

我编写了我自己版本的browser.waitForAngular,我看到了完全相同的结果:

代码语言:javascript
复制
    let waitForAngularStable = `
        let callback = arguments[arguments.length - 1];
        let rootElement = window.getAllAngularRootElements()[0];
        let testability = window.getAngularTestability(rootElement);
        testability.whenStable(callback);
    `;
    await renderFooView();
    await browser.executeAsyncScript(waitForAngularStable);
    console.log(await browser.executeScript(pollAngularIsStable)); // => false
    await interactWithFooView();

如果我编写了一个手动轮询isStable()直到返回true的例程,则修复我的脚本:

代码语言:javascript
复制
    async function waitForAngular() {
        let ms;
        for (ms=0; ms<10000; ++ms) {
            await browser.sleep(1);
            if (await browser.executeScript(pollAngularIsStable)) {
                break;
            }
        }
        console.log(`Waited ${ms}ms for Angular to be stable.`);
    }

    await renderFooView();
    await waitForAngular(); // usually waits < 50ms
    console.log(await browser.executeScript(pollAngularIsStable)); // => true
    await interactWithFooView(); // always works now

所以..。为什么轮询isStable()工作,但等待whenStable()回调不起作用?更重要的是,为什么whenStable()报告应用程序是稳定的,而下一个调用(没有中间代码)显示isStable()是假的?

EN

回答 1

Stack Overflow用户

发布于 2019-12-23 10:58:52

过去,当我使用量角器和角度应用时,我也曾遇到过类似的问题。在我的例子中,有一个第三方插件运行的时间比预期的要长。因此,isStable标志将显示false,直到它完全加载为止。我们挖得很深,认为有两种方法可以解决这个问题:

1)删除端到端测试套件中的第三方集成并运行测试(这解决了问题,我们不需要使用browser.sleep )。

2)编写一个助手函数,该函数将持续地ping可测试性api并监视isStable标志。它将等待标志变为真,然后继续进行测试。这就像在等待角包装的基础上添加一个等待角包装器。

我们选择了第一个解决方案,因为这很有帮助。

顺便提一句:您还可能在代码中的某个地方遗漏了等待,因为在搜索元素之前,承诺没有得到解决,而且测试也没有等待isStable标志。您能否在测试中关闭selenium允诺管理器,并尝试查看是否有任何承诺被拒绝?您可以通过在量角器配置文件中添加一个标志: SELENIUM_PROMISE_MANAGER: false来做到这一点。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/54509647

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档