2

The following code in the $timeout is never called. I can put any wrong test I like in there and the test always passes (there is a similar question (Karma e2e testing: how to know when the DOM is ready?) but it does not provide a solution):

it('should display a filter row when attribute sg-live-filtering is present', function()   
{
   angular.mock.inject(function($compile, $rootScope, $timeout) {
      var elem = $compile('<div sg-grid sg-data="api/grid/accounts" sg-live-filtering></div>')(scope); // the angular-kendo grid
      $rootScope.$apply();            
      var table = elem.find('table[role="grid"]'); // find the kendo grid
      expect(table.length).toBe(1);
      var header = table.find('thead'); // find the grid's table header 
      expect(header.length).toBe(1);
      $timeout(function () {
         // get the second row in the header and check it has a specific class
         expect(header.find('tr').eq(1).hasClass('sg-grid-filter-row')).toBeTruthy();
         // e.g. I could do this and it would still pass!!!             
         expect(header.find('tr').eq(500));
      });
   }
} 

PhantomJS 1.9.2 (Windows 7): Executed 1 of 871 (skipped 383) SUCCESS (0 secs / 0

This is what it looks like in the browser:

enter image description here

The kendo grid is created using a standard angularjs directive:

angular.module('sgComponents').directive('sgGrid', [
   templateUrl: 'sg-grid.html',
   // lots of kendo code follows to build the grid       
]);

The external sg-grid.html template:

<div sg-grid sg-data="api/grid/accounts"             
     sg-live-filtering> <!-- the attribute I want to test -->        
</div>

When the directive code runs, there is a check to see if the sg-live-filtering attr is present. If it is, a utility function is called to append the row you see highlighted in the image to the grid's table header:

if (attrs.sgLiveFiltering) {
   /*
    timeout is needed to ensure DOM is ready. COULD THIS BE THE PROBLEM?
   */
   $timeout(function () { 
      /*
      this function adds the filter row to the grid. 
      THE NEW ROW HAS CLASS 'sg-grid-filter-row' THAT I USE FOR TESTING
      */
      buildGridFilterRow(elm, scope, attrs);
    });
}
Community
  • 1
  • 1
Tone
  • 990
  • 4
  • 14
  • 31

2 Answers2

2

Can you display your test code ??? Because you have to wait in order to execute timeout or just use $timeout.flush(); Here is an example: Unit testing an asynchronous service in angularjs

Community
  • 1
  • 1
igorzg
  • 1,506
  • 14
  • 17
  • You can see my test code in the first grey block on this question (it('should...). $timeout.flush() was recommended by idursun above but I can't get it to work. Thanks for the link, I'll have a read of that. – Tone Jan 24 '14 at 10:16
  • Use the runs and waitsFor methods from jasmine in order to wait that code executes – igorzg Jan 24 '14 at 10:19
2

Finally (2 weeks later!) got this to work. @idursun and igorzg were correct when they suggested using $timeout.flush(100) but it also needed, as @idursun further mentioned in his comments, that the $timeout block be removed too.

When I initially tried this, it didn't work but now it does. Don't ask me why, all I care is that it is working! Here's my full test case for reference:

it('should display a filter row when attribute sg-live-filtering is present', function () {
   angular.mock.inject(function($compile, $rootScope, $timeout) {
   var scope = $rootScope.$new();
   scope.accountColumnsForAdvSearch = [
      {field: 'accountId', title: 'AccountId', dataType: 'string'},
      {field: 'name', title: 'Account Name', dataType: 'string'},
      {field: 'shortName', title: 'Short Name', dataType: 'string'},
      {field: 'status', title: 'Status', dataType: 'string'}
   ];

   $httpBackend.when('GET', 'api/grid/accounts').respond(accountData);    

   var elem = $compile('<div sg-grid sg-data="api/grid/accounts" sg-columns="accountColumnsForAdvSearch" sg-live-filtering="true"></div>')(scope);
   $rootScope.$apply();
   $httpBackend.flush();
   $timeout.flush(100); // wait for DOM to load
   var table = elem.find('table[role="grid"]'); // the kendo grid
   expect(table.length).toBe(1);
   var filterRow = table.find('.sg-grid-filter-row'); // the filter row
   expect(filterRow.length).toBe(1);
});
Tone
  • 990
  • 4
  • 14
  • 31
  • What are you using for sg-grid? Is there something other than http://kendo-labs.github.io/angular-kendo? – Wayne Brantley Feb 08 '14 at 19:09
  • @WayneBrantley - just seen your comment. sg-grid is kendo grid, it's just that we have our own directive called sgGrid that is then responsible for creating the kendo grid. – Tone Jun 25 '14 at 12:29