Search code examples
javascriptangularjasminekarma-jasmineag-grid

AgGrid selectors always return null / no elements even when table correctly renders


I have an ag grid:

<app-my-component>
  <ag-grid-angular
    [gridOptions]="gridOptions"
    (gridReady)="setGridReady()">
  </ag-grid-angular>
</app-my-component>

And in my Karma-Jasmine tests, I am testing that the table renders on the page:

it('Should render data table', async(() => { 

  // Wait for ag grid to render rows
  fixture.detectChanges();

  fixture.whenStable().then(() => {
    const agGrid = element.query(By.css('ag-grid-angular'));
    expect(agGrid).toBeTruthy();
  });

}));

So far so good. everything works. I can see the table rendered on the page on chrome when karma runs (I haven't removed the element in afterEach so I can debug)

Now, I'm trying to test that the number of rows match the mockData that I've got. I can see the three rows that's rendered on the page.

it('Should display all three rows from mock data', async(() => {

  // Wait for ag grid to render rows
  fixture.detectChanges();

  fixture.whenStable().then(() => {
    let rows = element.queryAll(By.css('.my-custom-class'));
    expect(rows.length).toBe(3);
  });

}));

This test, however, fails. .my-custom-class selector always seems to return null. No worries, maybe I'm mistyping the class or something, or so I thought. I opened up the developer console and typed in $('.my-custom-class'). To my surprise, this returns null as well!

If I try to select any cell value elements with $('.ag-cell-value'), that's null as well.

But I can see all the data and the table on the page! so I right click on the table and inspect element > check for the class... and try $('.my-custom-class') - Now it returns 3 elements! $('.ag-cell-value') works as expected as well!

What's happening here? Why can't I select the elements with css selector before I expand the DOM in html, and more importantly, how do I select and test for my three rows in my unit test please?


Solution

  • When I was using ag-grid, I faced the same issue. It seems like it renders on its own and we have no control of when the rendering is done.

    What I did to circumvent this was create a waitUntil utility function outlined here: Cannot wait until DOM rendering has finished in Angular/Jasmine unit test

    With the wait until, what you can maybe do is:

    import { waitUntil } from './where/waitUntil/is';
    ....
    it('should display all three rows from mock data', async () => {
      fixture.detectChanges();
    
      await fixture.whenStable();
      
      // Basically, in this waitUntil, wait until everything in AgGrid is painted
      // before moving on with your test. The waitUntil has to return true before
      // it can proceed to the next line.
      await waitUntil(() => { 
         const rows = appElement.queryAll(By.css('.my-custom-class'));
         return rows.length === 3; 
      });
      
      // do other expectations
    });