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 sur
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.
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.
This involves tweaking the Zone.js code, but gives you a more persistent debug information.
node_modules/zone.js/dist/zone.js
.function Zone(parent, zoneSpec)
this._tasks = {}
let counter = 0
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;
Look for Zone.prototype.scheduleTask
and add the following right before the call to this._updateTaskCount(task,-1)
:
delete this._tasks[task.id]
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.