Angular 2 with protractorjs Failed:在等待Protractor与page "窗

Angular 2 with protractorjs Failed: Error while waiting for Protractor to sync with the page: "window.getAllAngularTestabilities is not a function"

本文关键字:page quot Protractor 在等待 with protractorjs Failed Angular      更新时间:2023-09-26

[测试angular 2 web应用]

browser.ignoreSynchronization = false设置为true时,这个错误发生,这个错误没有发生,为什么会这样?

我也有useAllAngular2AppRoots: true设置在我的量角器配置

Protractor运行在WebDriverJS之上。WebDriverJS是一个Javascript接口,相当于Java的Webdriver,它可以让你以编程方式控制浏览器,这反过来又有助于编写自动化的测试用例

使用WebDriverJS测试Angular应用的问题在于,Angular有自己的事件循环,与浏览器的事件循环是分开的。这意味着当你执行WebDriverJS命令时,Angular可能还在做它自己的事情。

解决这个问题的一种方法是告诉WebDriverJS等待一段任意的时间(比如3000ms),这样Angular就可以完成渲染工作,但这不是正确的做法。因此,创建Protractor是为了让你的测试与Angular的事件循环同步,方法是在Angular处理完前一个命令之后再运行下一个命令。

但是这里有一个问题,当你测试非angular应用程序时,即使没有angular完成它的循环,Protractor也会一直等待angular同步,并会抛出一个你正在观察的错误!

因此,对于非Angular页面,你可以通过设置browser.ignoreSynchronization = true来告诉Protractor不要寻找Angular——这实际上意味着你只是在使用WebDriverJS。

所以,当Protractor在你的页面上找不到Angular时,把它添加到你的配置中,你就放弃了所有让测试Angular应用比纯WebDriverJS更容易的东西。是的,添加浏览器。在你所有的命令之后睡觉可能会工作,但它很麻烦,一旦Angular花的时间超过了你设置的暂停时间,它就会中断,让你的测试花的时间过长。

结论:仅在测试不使用Angular的页面时使用browser.ignoreSynchronization = true

参考:

https://vincenttunru.com/Error-Error-while-waiting-for-Protractor-to-sync-with-the-page/

您绝对应该确保您的页面在测试中只加载一次。我们在一个登录模型中遇到了这个问题,它会导致加载的页面在第一次加载完成后立即重新加载,这是在Angular 2应用程序的引导代码中。这会导致各种不可预测的行为,如测试因超时或上述错误而失败,或运行正常。

所以,在测试之前,确保你有一个一致的页面生命周期。

对@ram-pasala的观点进行扩展:

解决这个问题的一种方法是告诉WebDriverJS等待任意数量的时间(例如3000ms),以便Angular完成渲染工作,但这不是正确的做事方式

下面是等待函数变得可用的样子。它是用于TestCafe的,但应该很容易适应其他测试框架:

export const waitForAngular = ClientFunction((timeoutMs: number = 60_000) => {
  const waitForGetAllAngularTestabilities = (timeoutMs: number) => {
    if (timeoutMs <= 0) throw new Error('Waited for window.getAllAngularTestabilities, but timed out.')
    const win = (window as any);
    if (win.getAllAngularTestabilities) {
      return Promise.resolve(win.getAllAngularTestabilities)
    } else {
      return new Promise(res => setTimeout(() => res(true), 100)).then(() => waitForGetAllAngularTestabilities(timeoutMs - 100))
    }
  }
  return waitForGetAllAngularTestabilities(30_000).then((getAllAngularTestabilities) => {
    return Promise.all(
      getAllAngularTestabilities().map(
        (t) =>
          new Promise((res, rej) => {
            setTimeout(() => rej(`Waited ${timeoutMs}ms for Angular to stabilize but timed out.`), timeoutMs);
            return t.whenStable(() => {
              res(true);
              console.log('Angular stable');
            });
          }),
      ),
    )
  })
});