Mud*_*Mud 5 protractor angular angular-testing
请注意,这并非特定于量角器。问题出在Angular 2内置的可测试性服务上,而Protractor恰好使用了该服务。量角器Testability.whenStable通过调用进行调用waitForAngular。我已经打了一些失败的代码。
我的测试代码如下所示:
await renderFooView();
await interactWithFooView();
Run Code Online (Sandbox Code Playgroud)
第二行失败:
Failed: No element found using locator: By(css selector, foo-view)
Run Code Online (Sandbox Code Playgroud)
当量角器继续尝试与之交互的代码时,Angular不会呈现“ foo-view”。
如果我在两者之间添加睡眠,那么它可以工作:
await renderFooView();
await browser.sleep(1000);
await interactWithFooView();
Run Code Online (Sandbox Code Playgroud)
显然我不想那样做。对于我来说,量角器最有价值的是“等待角度”机制,该机制消除了脚本中的“等待X”噪声。我想要的是:
await renderFooView();
await browser.waitForAngular();
await interactWithFooView();
Run Code Online (Sandbox Code Playgroud)
实际上,我永远不必手动执行该中间线。每当我拨打与浏览器互动的电话时,量角器都会自动执行。
做一些挖后,我发现,量角器时进行调用,它工作正常,但在角2次出现潜在的可测试性机制打破。
在Angular 2下,量角器的“ waitForAngular”类似于以下内容:
let rootElement = window.getAllAngularRootElements()[0];
let testability = window.getAngularTestability(rootElement);
testability.whenStable(callbackThatResumesScriptExecution);
Run Code Online (Sandbox Code Playgroud)
换句话说,它调用Angular的,testability.whenStable并且仅在Angular报告其稳定后才恢复执行。如果我在回调中添加一些日志记录:
testability.whenStable(() => {
console.log("isStable:", testability.isStable());
callback();
});
Run Code Online (Sandbox Code Playgroud)
isStable()永远是真正的内部whenStable回调,所以角在肯定什么叫似乎是合适的时间。
但是,如果此回调返回后立即返回,则我isStable()再次轮询,它的值为false。
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();
Run Code Online (Sandbox Code Playgroud)
我已经编写了自己的版本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();
Run Code Online (Sandbox Code Playgroud)
如果我编写了一个手动轮询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
Run Code Online (Sandbox Code Playgroud)
那么...为什么轮询isStable()有效,但是等待whenStable()回调不起作用?更重要whenStable()的是,当下一次调用(无插入代码)显示isStable()错误时,为什么还要报告应用程序稳定?
我过去在使用 Protractor 和 Angular 应用程序时遇到过类似的问题。就我而言,有一个第三方插件的运行时间比预期的要长。因此,isStable 标志将显示 false,直到完全加载为止。我们深入研究并发现有两种方法可以解决这个问题:
1)删除端到端测试套件中的第三方集成并运行测试(这解决了问题,我们不需要使用 browser.sleep
2) 编写一个辅助函数,它将持续 ping 可测试性 api 并监视 isStable 标志。它将等待标志变为真,然后继续测试。这就像在等待角度之上添加等待角度包装器。
我们选择了第一个解决方案,因为这有帮助。
附带说明:您也可能在代码中的某处缺少等待,因为承诺未得到解决,并且测试在搜索元素之前不会等待 isStable 标志。您可以在测试中关闭 Selenium Promise 管理器并尝试查看是否有任何 Promise 被拒绝?您可以通过在量角器配置文件中添加一个标志来做到这一点:SELENIUM_PROMISE_MANAGER: false
| 归档时间: |
|
| 查看次数: |
322 次 |
| 最近记录: |