Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular 2 how to test content shown / hidden by *ngIf

I am having some difficulties with a unit test that is reading some html which is being added/removed from the DOM with *ngIf.

This is the DOM:

<div class="detailacc" (click)="showDet()">    
    <i class="fa" [class.fa-caret-right]="!showHideDet " [class.fa-caret-down]="showHideDet " aria-hidden="true"></i> 
    <h4>Expandable</h4>
</div>
<div *ngIf="showHideDet">
    <p class="detailHeader">Details header</p>
</div>

This is the component function which gets called on the click event of the first div:

private showDet() { 
    console.log('show called');
    this.showHideDet = !this.showHideDet;
}

And finally this is the spec:

it('should show the header when the expandable elem is clicked', async(() => 
{
    const fixture = TestBed.createComponent(DetailsComponent);
    const compiled = fixture.debugElement.nativeElement;
    let detPresent: boolean = false;
    for (let node of compiled.querySelectorAll('.detailacc')) {
        node.click();
    }

    setTimeout(() => {          
        console.log(compiled.querySelectorAll('.detailHeader'));
        for (let node of compiled.querySelectorAll('.detailHeader')) {
            if (node.textContent === 'Details header') {
                detPresent = true;
                break;
            }
        }
        expect(detPresent).toBeFalsy();
    }, 0);  
}));

As you can see I've wrapped the code which searches for those DOM elements that are shown only when the *ngIf is true in a setTimeout as in this How to check whether ngIf has taken effect but I still do not get anything.

Also if you're wondering if the click gets called in that test, it does because that console.log in the component function gets shown in the Karma console. The console.log inside the setTimeout shows a NodeList(0), basically no nodes with the class .detailHeader where found.

like image 840
Hazerd Avatar asked Jun 06 '17 13:06

Hazerd


1 Answers

Ok, so after more trial and error I found out that if you call fixture.detectChanges() inside the setTimeout it will show the *ngIf DOM

like image 51
Hazerd Avatar answered Sep 20 '22 14:09

Hazerd