如何跟踪量角器正在等待哪些异步任务? [英] How to track which async tasks protractor is waiting on?

查看:100
本文介绍了如何跟踪量角器正在等待哪些异步任务?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个中等大小的Angular应用程序,由于某些原因,我的一些量角器测试在我的实时生产环境中运行时已超时.

我相当确定发生超时是因为量角器正在等待一些异步任务.我了解区域,因此我尝试将所有长时间运行的异步任务排除在ngZone之外(按照 https://github.com/angular/protractor/blob/master/docs/timeouts.md#waiting-for-angular

在等待带有定位符的元素时-定位符:By(css选择器,[data-e2e ='滚动到提供'])

该元素存在于页面上(我已经手动验证过),但是量角器仍然超时.

解决方案

我遇到了类似的问题,可测试性不稳定,我只知道我有一些pendingMacroTasks.本地化这些任务确实有点棘手(您不会遍历整个代码库并寻找setTimeout).
但是我最终还是做到了.

相对简单的解决方案

您可以做的第一件事是在Chrome中打开开发工具,按Ctrl+O,键入 zone.js ,然后按Enter.
这将打开 zone.js 源文件(不是Typescript,还是其他东西).
zone.js 内查找Zone.prototype.runTask,然后在此方法内放置一个断点.
在加载应用程序后启用断点 ,否则断点将被击中太多次.

如果您的可测试性不稳定,则可能意味着您有一些重复宏任务重新安排了自己的时间.至少那是我的情况.
如果是这种情况,则在加载应用程序后每X次就会命中一个断点.

一旦遇到断点,请转到task.callback.[[FunctionLocation]],这将带您(最可能是)一些setTimeoutsetInterval.
要对其进行修复,请运行 在Angular区域之外 .

更棘手的解决方案

这涉及到调整Zone.js代码,但为您提供了更持久的调试信息.

  1. 转到node_modules/zone.js/dist/zone.js.
  2. 寻找区域的构造函数:function Zone(parent, zoneSpec)
  3. 在内部添加以下内容:this._tasks = {}
  4. 全局范围内添加计数器变量:let counter = 0
  5. 查找Zone.prototype.scheduleTask,并在对this._updateTaskCount(task,1)的调用之前添加以下内容:

     task.id = counter++;
    this._tasks[task.id] = task;
     

  6. 查找Zone.prototype.scheduleTask,并在对this._updateTaskCount(task,-1)的调用之前添加以下内容:

     delete this._tasks[task.id]
     

  7. 重新编译应用程序并运行它

假设您做了上述调整,您始终可以像这样访问待处理的任务:

 tasks = Object.values(window.getAllAngularTestabilities()[0]._ngZone._inner._tasks)
 

要获取所有影响可测试性状态的待处理宏任务,请执行以下操作:

 tasks.filter(t => t.type === 'macroTask' && t._state === 'scheduled')
 

此后,与之前的解决方案类似,签出.callback.[[FunctionLocation]]并通过在Angular区域之外运行进行修复.

I have a medium sized Angular application and for some reasons some of my protractor tests are timing out when run against my live production environment.

I am fairly sure the timeouts happen because of protractor waiting on some asynchronous task. I know about zones and I tried to keep all long running async tasks out of the ngZone (as per the FAQ), but for some reason protractor is still timing out.

It's possible I missed something but I don't know how to debug the problem. Is there any way to find out which part of the code protractor is waiting on?

The NgZone only exposes functions to determine if there are microtasks or macrotasks running, but doesn't tell me which one.

EDIT: A typical example of such a timeout error as shown by protractor:

Failed: Timed out waiting for asynchronous Angular tasks to finish after 11 seconds. This may be because the current page is not an Angular application. Please see the FAQ for more details: https://github.com/angular/protractor/blob/master/docs/timeouts.md#waiting-for-angular

While waiting for element with locator - Locator: By(css selector, [data-e2e='scroll-to-offer'])

The element exists on the page (I have verified this manually), but protractor still times out.

解决方案

I had a similar problem, the Testability was unstable and all I knew is that I have some pendingMacroTasks. It's indeed a bit tricky to localize these tasks (you won't go through the whole code base and look for setTimeout).
However I managed to do this eventually.

Relatively simple solution

First thing you can do is open your Dev Tools in Chrome, press Ctrl+O, type zone.js and press Enter.
This will open zone.js source file (not Typescript, yet something).
Inside zone.js look for Zone.prototype.runTask and put a breakpoint inside this method.
Enable the breakpoint after your application is loaded, otherwise it will get hit too many times.

If your Testability is not stabilizing, it probably means that you have some repetitive macro task that reschedules itself. At least that was my case.
If this is the case, the breakpoint will get hit every X time after the application is loaded.

Once the breakpoint is hit, go to task.callback.[[FunctionLocation]] this will take you to (most probably) some setTimeout or setInterval.
To fix it run it outside of Angular zone.

A bit trickier solution

This involves tweaking the Zone.js code, but gives you a more persistent debug information.

  1. Go to node_modules/zone.js/dist/zone.js.
  2. Look for Zone's constructor function: function Zone(parent, zoneSpec)
  3. Add the following inside: this._tasks = {}
  4. Add counter variable in global scope: let counter = 0
  5. Look for Zone.prototype.scheduleTask and add the following right before the call to this._updateTaskCount(task,1):

    task.id = counter++;
    this._tasks[task.id] = task;
    

  6. Look for Zone.prototype.scheduleTask and add the following right before the call to this._updateTaskCount(task,-1):

    delete this._tasks[task.id]
    

  7. Recompile the application and run it

Assuming you did the above tweaks you can always access the pending tasks like this:

tasks = Object.values(window.getAllAngularTestabilities()[0]._ngZone._inner._tasks)

To get all the pending macro tasks that affect the testability state:

tasks.filter(t => t.type === 'macroTask' && t._state === 'scheduled')

After that similarly to the previous solution check out the .callback.[[FunctionLocation]] and fix by running outside of Angular zone.

这篇关于如何跟踪量角器正在等待哪些异步任务?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆