1 minute read

Currently, we are working on a big refactoring project. We are rewriting a big chunk of legacy javascript with Angular.js. We also write end-to-end tests with protractor to keep our system more robust.

My colleagues used UI Bootstrap module’s alert function to display different things to our clients. And they wanted to test if the alert is displayed properly.

The first attempts returned with a strange error message:

10:55:37.099 WARN - Exception thrown org.openqa.selenium.TimeoutException: asynchronous script timeout: result was not received in 11 seconds

Essentially, the test clicked a button and wanted to check if there is an alert or not. It was very strange that - based on the logs - the click happened properly, but if we removed anything after the click() action the timeout remained still there. It took a bit of time to understand what happened in the background.

Unfortunately the alert’s internal dismiss functionality has been implemented with Angular’s $timeout service which increments $browser’s outstanding request count and protractor with ignoreSynchronization=false waits correctly until there are any outstanding requests. This means if you do not disable the synchronization, you cannot see the opened alert, because protractor suspends execution until it is visible.

So in our case, the click() opened the alert, which started the $timeout, and protractor suspended the execution and then it timed out.

This link helped us a lot to understand the situation:

If you want to test any $timeout based functionality you have to turn on ignoreSynchronization which is basically a hack for non-Angular apps.

There they suggest to use $interval because it fits better to this case.

As a work around currently we turned on ignoreSynchronization, but for a proper solution we implemented the suggested $interval transition and sent a Pull Request.

It seems that there are different opinions regarding this $timeout vs $interval debate. (See the comments in the PR.)