Why is Angular $ End-To-End timeout blocking?

I made a directive that is used to display notifications to the user. To show the notification, I wrote the following:

$scope.$watch($messaging.isUpdated, function() { $scope.messages = $messaging.getMessages(); if ($scope.messages.length > 0) { $timeout(function() { for (var i = 0; i < $scope.messages.length; i++) { if (i + 1 < $scope.messages.length) { $messaging.removeMessage($scope.messages[i]); } else { $messaging.removeMessage($scope.messages[i]); } } }, 5000); } }); 

I use $ timeout to make sure messages stay on screen for 5 seconds.

Now I want to write an End-To-End test so that I can make sure the notification is displayed. The problem is when a notification is displayed stating that End-To-End also expires in the same way as notification. This makes it impossible to verify that the correct notification is displayed. .

This is my test code:

 it('submit update Center', function() { input('center.Name').enter('New Name'); input('center.Department').enter('New Department'); input('center.Contact').enter('New contact'); input('center.Street').enter('New street'); input('center.City').enter('New city'); input('center.Country').enter('New Country'); element('button#center_button').click(); expect(element('.feedback').count()).toBe(1); expect(element('.feedback:first').attr('class')).toMatch(/success/); expect(element('.error.tooltip').count()).toBe(0); }); 

I like to avoid using javascript setTimeout () and hope this is another solution (Angular) for this problem.

+7
source share
2 answers

Bad news, buddy. This is a known issue in AngularJs. It discusses the β€œsomehow related” issue here.

Fortunately, you can work around this by minimizing your own $timeout service by calling setTimeout and calling $apply manually (this is a suggestion from the discussion I mentioned). It is really simple, although it is really ugly. A simple example:

 app.service('myTimeout', function($rootScope) { return function(fn, delay) { return setTimeout(function() { fn(); $rootScope.$apply(); }, delay); }; }); 

Please note that this is not compatible with Angular $timeout , but you can extend your functionality if you need to.

+11
source

tiny note about you if / else statement

 $scope.$watch($messaging.isUpdated, function() { $scope.messages = $messaging.getMessages(); if ($scope.messages.length > 0) { $timeout(function() { for (var i = 0; i < $scope.messages.length; i++) { if (i + 1 < $scope.messages.length) { $messaging.removeMessage($scope.messages[i]); } else { /**** unnecessay else here *****/ $messaging.removeMessage($scope.messages[i]); } } }, 5000); }}); 
0
source

All Articles