gpt4 book ai didi

angular - testability.whenStable() 返回, testability.isStable() 返回 false

转载 作者:行者123 更新时间:2023-12-03 10:06:22 27 4
gpt4 key购买 nike

请注意,这并非特定于 Protractor。问题在于 Angular 2 的内置 Testability service Protractor 碰巧使用。 Protractor 调用 Testability.whenStable通过调用 waitForAngular .我遇到了一些失败的代码。

我的测试代码如下所示:

await renderFooView();
await interactWithFooView();

第二行失败:
 Failed: No element found using locator: By(css selector, foo-view)

当 Protractor 继续尝试与其交互的代码时,Angular 没有完成渲染“foo-view”。

如果我在两者之间添加一个 sleep ,它会起作用:
await renderFooView();
await browser.sleep(1000);
await interactWithFooView();

显然我不想那样做。对我来说,Protractor 的大部分值(value)是“等待 Angular ”机制,它消除了我的脚本中的“等待 X”噪音。我想要的是这样的:
await renderFooView();
await browser.waitForAngular();
await interactWithFooView();

事实上,我永远不必手动执行那条中间线。每当我调用与浏览器交互的电话时, Protractor 都会自动执行此操作。

在进行了一些挖掘之后,我发现 Protractor 正在调用,它工作正常,但是 Angular 2 中的底层可测试性机制似乎被破坏了。

在 Angular 2 下,Protractor 的“waitForAngular”执行如下操作:
let rootElement = window.getAllAngularRootElements()[0];
let testability = window.getAngularTestability(rootElement);
testability.whenStable(callbackThatResumesScriptExecution);

换句话说,它调用了 Angular 的 testability.whenStable并且仅在 Angular 报告它稳定时恢复执行。如果我在回调中添加一些日志记录:
testability.whenStable(() => {
console.log("isStable:", testability.isStable());
callback();
});
isStable()whenStable 内部总是正确的回调,所以 Angular 肯定是在正确的时间调用。

但是,如果在此回调返回后立即轮询 isStable()再次,它评估为假。
    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 版本,我看到完全相同的结果:
    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,这修复了我的脚本:
    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()是假的?

最佳答案

过去在使用 Protractor 和 Angular 应用程序时,我也遇到过类似的问题。就我而言,有一个第三方插件运行的时间比预期的要长。因此,isStable 标志将显示为 false,直到它完全加载。我们深入挖掘并认为有两种方法可以解决此问题:

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

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

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

附带说明:您也可能在代码中的某处缺少等待,因为没有解决 promise 并且测试在搜索元素之前没有等待 isStable 标志。您能否在测试中关闭 selenium promise 管理器并尝试查看是否有任何 promise 被拒绝?您可以通过在 Protractor 配置文件中添加一个标志来执行此操作: SELENIUM_PROMISE_MANAGER: false

关于angular - testability.whenStable() 返回, testability.isStable() 返回 false,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54509647/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com