最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Angular 2 with protractorjs Failed: Error while waiting for Protractor to sync with the page: "window.getA

programmeradmin5浏览0评论

[Testing angular 2 web app]

This error occurs with browser.ignoreSynchronization = false when set to true, this error does not occur, why is this ?

I also have useAllAngular2AppRoots: true set in my protractor config.

[Testing angular 2 web app]

This error occurs with browser.ignoreSynchronization = false when set to true, this error does not occur, why is this ?

I also have useAllAngular2AppRoots: true set in my protractor config.

Share Improve this question asked Jun 27, 2016 at 9:42 Jordan .MuscatJordan .Muscat 531 silver badge5 bronze badges
Add a ment  | 

3 Answers 3

Reset to default 8

Protractor runs on top of WebDriverJS. WebDriverJS is a Javascript interface equivalent to Java's Webdriver that let's you control browsers programmatically, which in turn helps to write automated test cases

The problem in testing Angular apps using WebDriverJS is that Angular has its own event loop separate from the browser's. This means that when you execute WebDriverJS mands, Angular might still be doing its thing.

One work around for this is by telling WebDriverJS to wait for an arbitrary amount of time (i.e. 3000ms) so that Angular finishes its work of rendering but this was not the right way of doing things.Therefore Protractor was created to synchronize your tests with Angular's event loop, by deferring running your next mand until after Angular has finished processing the previous one.

But again there is a catch here, this bees problematic when you are testing Non-Angular Applications, Protractor keeps on waiting for angular to synchronise even though there is no Angular to plete its cycle and will throw an error which you are observing!

Thus, for non-Angular pages, you can tell Protractor not to look for Angular by setting browser.ignoreSynchronization = true -- which in practical terms will mean that you're just using WebDriverJS.

So by adding that to your configuration when Protractor cannot find Angular on your page, you're giving up on all that makes testing Angular apps easier than plain WebDriverJS. And yes, adding browser.sleep after all your mands will likely work, but it's cumbersome, will break as soon as Angular takes longer than the pause you set, and makes your tests take excessively long.

Conclusion : Only use browser.ignoreSynchronization = true when testing a page that does not use Angular.

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

You should absolutely make sure that your page only gets loaded one single time on the test. We had this problem with a login mockup that caused the loaded page to reload right after the first load was done inside the boostrap code of the Angular 2 application. This caused all sorts of unpredictable behaviour with tests failing with timeouts or the above error - or running fine.

So, make sure you have a consistent page lifecycle prior to the test.

To extend on the point @ram-pasala made:

One work around for this is by telling WebDriverJS to wait for an arbitrary amount of time (i.e. 3000ms) so that Angular finishes its work of rendering but this was not the right way of doing things

Here's how waiting for the function to bee available might look like. It's for TestCafe, but should be easy to adapt to other testing frameworks:

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');
            });
          }),
      ),
    )
  })
});

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论