I have a custom cell renderer component which wil convert the text to link. Its all working fine. I am trying to unit test the renderer component. The issue am facing in unit testing is Grid is displaying with link but its not available when I query through native element, I am getting the value as empty other grid values are already present I am able to see it. I think this is to do with the lifecycle of testing or AG Grid rendering. How do I tell the test framework to wait untill the component is rendered?
link renderer component
@Component({
template: '<a [routerLink]="[params.inRouterLink,params.value]" (click)="navigate(params.inRouterLink)">{{params.value}}</a>'
})
export class RouterLinkRendererComponent implements AgRendererComponent {
params: any;
constructor(
private ngZone: NgZone,
private router: Router) { }
agInit(params: any): void {
this.params = params;
}
refresh(params: any): boolean {
return false;
}
}
Test Component:
@Component({
template: `
<ag-grid-angular
style="width: 500px; height: 500px;"
class="custom-theme"
[rowData]="rowData"
[columnDefs]="columnDefs"
(gridReady)="onGridReady($event)"
>
</ag-grid-angular>
`
})
export class TestCustomComponent {
columnDefs = [
{
headerName: 'Make',
field: 'make',
cellRendererFramework: RouterLinkRendererComponent,
cellRendererParams: {
inRouterLink: '/#'
}
},
{ headerName: 'Model', field: 'model' },
{ headerName: 'Price', field: 'price' }
];
rowData = [
{ make: 'Toyota', model: 'Celica', price: 35000 },
{ make: 'Ford', model: 'Mondeo', price: 32000 },
{ make: 'Porsche', model: 'Boxter', price: 72000 }
];
}
Unit Testing
fdescribe('AgnavigatorComponent', () => {
let component: TestCustomComponent;
let fixture: ComponentFixture<TestCustomComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [RouterLinkRendererComponent, TestCustomComponent],
imports: [
RouterTestingModule,
AgGridModule.withComponents([RouterLinkRendererComponent])
]
}).compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(TestCustomComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
const appElement = fixture.nativeElement;
// here the values are empty only for the first column which uses custom renderer.
const cellElements = appElement.querySelectorAll('.ag-cell-value');
});
});
once the test execution completes I can see the column with proper value with href in it.
The issue is at the time of execution the component isnt loaded yet. so have to introduce a wait function as mentioned in SO.post that I have to wait untill this guy comes in.
export const waitUntil = async (
untilTruthy: () => boolean
): Promise<boolean> => {
while (!untilTruthy()) {
await interval(25)
.pipe(take(1))
.toPromise();
}
return Promise.resolve(true);
};
and the test is like below
it('should render the component', async done => {
let appElement: any;
let cellElement: any;
fixture.detectChanges();
await fixture.whenStable();
await waitUntil(() => {
appElement = fixture.nativeElement;
cellElement = appElement.querySelectorAll('.ag-cell-value');
if (cellElement[0].textContent !== '') {
return true;
}
return false;
});
expect(cellElement[0].children[0].children[0].href.split('/')[3]).toEqual(
'Toyota'
);
done();
});