I have a component with tabs. I need to navigate to a tab and then test the viewable inputs, etc. I can see from the console log that the actions that I am taking are calling the function that I am spying on using the process below. I can also see that this is happening in the correct order.
Unfortunately, this produces a successful test with no errors, there is no expectation found within the test according to ng test. (SPEC HAS NO EXPECTATIONS)
Placing the expectation outside of the whenStable command makes the expectation run before the blur command.
it('should call to save changes when project name is blurred',
fakeAsync(() => {
component.ngOnInit();
tick();
const tabLabels = fixture.debugElement.queryAll(By.css('.mat-tab-label'));
console.log(tabLabels);
tabLabels[1].triggerEventHandler('click', null);
fixture.detectChanges();
fixture.whenStable().then(() => {
const projectName = fixture.debugElement.query(By.css('#projectName'));
console.log(projectName);
let mySpy = spyOn(component, 'saveProject');
projectName.triggerEventHandler('blur', null);
console.log('Lowered expectations');
expect(mySpy).toHaveBeenCalled();
});
})
);
Here is the HTML associated with the test.
<!-- HEADER -->
<div class="header accent" fxLayout="row"></div>
<!-- / HEADER -->
<!-- CONTENT -->
<div class="content">
<!-- CENTER -->
<div class="center p-24" fusePerfectScrollbar>
<!-- CONTENT -->
<div class="content p-24" style="box-shadow:0px 0px 0px rgba(0,0,0,0) !important;">
<mat-tab-group fxFlex="80%"
style="margin:0px 10%">
<mat-tab id="projectSelectionTab" label="Project Selection">
<div fxFlex="80%"
fxLayout="column"
style="margin:0px 10%"
*ngIf="versionList && projectList">
<h1 class="mt-32 mb-20">Select a Project</h1>
<mat-divider></mat-divider>
<div *ngIf="projectList.length==0">
You currently have no designs. Go to the marketplace and select a design to add to your list of projects.
</div>
<table class="displayTable">
<tr (click)="setCurrentProject( project ) "
target="_blank"
class="projectRow"
[ngClass]="{'currentItem' : project==currentProject}"
*ngFor="let project of projectList">
<td class="mat-subheading-2"
style="width:10%">
<mat-icon style="cursor:pointer"
matTooltip="Open in design studio"
[routerLink]="['/designStudio/project/'+project.uid]">
color_lens
</mat-icon>
<mat-icon style="cursor:pointer"
matTooltip="View Quotes for this project"
[routerLink]="['/invoice/'+versionList[versionList.length-1]['uid']]">
attach_money
</mat-icon>
</td>
<td class="mat-subheading-2"
style="width:25%">
{{ project.name }}
</td>
<td class="mat-subheading-2"
style="width:20%">
{{ project.dateCreated | date:'short' }}
</td>
<td class="mat-body-1" >
<span style="font-weight:bold; margin-right:10px;">Type : {{project.designType}}</span>
<span style="font-weight:bold; margin-right:10px;">Versions : {{project.versions.length}}</span>
{{ project.description }}
</td>
</tr>
</table>
</div>
</mat-tab>
<mat-tab id="projectDataTab" label="Project Data" flex="100%">
<div flex="100%"
layout="column"
style="width:100%"
*ngIf="currentProject.uid">
<h2 class="mt-32 mb-20">
Project Data -
<mat-icon style="cursor:pointer"
matTooltip="Open in design studio"
[routerLink]="['/designStudio/project/'+currentProject.uid]">
color_lens
</mat-icon>
</h2>
<!-- TOP ROW OF PROJECT DATA -->
<div fxLayout="row" fxLayoutAlign="center" flex="100%">
<div fxFlex="50%"fxLayout="column" class="text-center">
<mat-form-field appearance="outline" floatLabel="always" class="w-100-p">
<mat-label>Project Name</mat-label>
<input matInput
id="projectName"
class="form-control"
placeholder="Product Name"
name="projectName"
#projectName="ngModel"
[(ngModel)]="currentProject['name']"
(blur)="saveProject()"
minlength="5"
maxlength="150"
required>
</mat-form-field>
<div [hidden]="projectName.valid || projectName.pristine || !projectName.errors?.minlength"
class="alert alert-danger">
Project name is required with at least 5 characters
</div>
<mat-form-field style="min-height:190px" appearance="outline" floatLabel="always" class="w-100-p">
<mat-label>Project Description</mat-label>
<textarea style="min-height:190px"
matInput
id="projectDescription"
placeholder="Product Description"
name="description"
#projectDescription="ngModel"
[(ngModel)]="currentProject['description']"
(blur)="saveProject()"
rows="5"
required
minlength="25">
</textarea>
</mat-form-field>
<div [hidden]="projectDescription.valid || projectDescription.pristine || !projectDescription.errors?.minlength"
class="alert alert-danger">
Project description is required with at least 25 characters
</div>
</div>
<div fxFlex="50" fxLayout="column" fxLayoutAlign="center center">
<div fxFlex="80" style="margin:0px 10%">
<img [src]="(designImageUrl | async)">
</div>
<div fxLayout="row"
fxLayoutAlign="center"
class="w-80-p">
<button mat-raised-button
color="primary"
*ngIf="changesExist"
(click)="saveProject(); changesExist=false;"
style="margin:10px 25%; width:50%">
Save Project Changes
</button>
</div>
</div>
</div>
</div>
<!-- / TOP ROW OF PROJECT DATA -->
</mat-tab>
<mat-tab id="versionDataTab" label="Version Data">
<div layout="column"
flex="100%"
style="width:100%"
*ngIf="currentProject !== undefined">
<h2 class="mt-32 mb-20">Version Data</h2>
<!-- Row showing button to create default version -->
<div fxLayout="row"
fxLayoutAlign="center center"
flex="100%">
<div fxFlex="20" style="margin:20px 5%">
<button mat-stroked-button
color="accent"
(click)="createNewVersion('default')">
New version (default)
</button>
</div>
</div>
<!-- Row showing the version list -->
<div fxLayout="row" fxLayoutAlign="center" flex="100%">
<table class="displayTable"
fxFlex="60" style="margin:0px 5%">
<thead>
<tr>
<th>VERSION NUMBER AND NAME</th>
<th></th>
</tr>
</thead>
<tbody>
<tr *ngFor="let version of versionList; index as j"
class="projectRow"
[ngClass]="{'currentItem' : version==currentVersion}"
(click)="onVersionSelected( j )">
<td>{{j+1}} - {{version.name}}</td>
<td>
<mat-icon style="cursor:pointer"
matTooltip="View Quotes for this version"
[routerLink]="['/invoice/'+version['uid']]">
attach_money
</mat-icon>
<mat-icon style="cursor:pointer"
matTooltip="Make copy as latest version"
(click)="createNewVersion( j )">
add_circle
</mat-icon>
</td>
</tr>
</tbody>
</table>
<!--
<div fxFlex="40" style="margin:0px 5%">
<mat-form-field class="w-100-p ml-10-p mt-20 form-group">
<mat-label>Select a version to see the details</mat-label>
<mat-select (selectionChange)="onVersionSelected(versionIndex)"
name="versionIndex"
#name="ngModel"
[(ngModel)]="versionIndex">
<mat-option *ngFor="let version of versionList; index as i" [value]="i">
{{i+1}} - {{version.name}}
</mat-option>
</mat-select>
</mat-form-field>
</div>
<div fxLayoutAlign="center center" fxFlex="40" style="margin:0px 5%">
<button mat-button class="red-900 mt-8" *ngIf="currentVersion.latest">Submit for purchase</button>
<button mat-button class="primary mt-8" *ngIf="!currentVersion.latest">Recreate as latest version</button>
</div>
-->
</div>
<div fxLayout="row" fxLayoutAlign="center" flex="100%">
<!-- VERSIONS DATA -->
<div fxLayout="column"
class="mt-32"
flex="45%"
style="width:40%; margin:0px 5%">
<h3>Data</h3>
<div fxLayout="row"
class="mt-20 mb-32">
<div fxFlex="50">
Estimated price - {{currentVersion.price}}
</div>
<div fxFlex="50">
Date Created - {{currentVersion.dateCreated | date:'short'}}
</div>
</div>
<mat-form-field appearance="outline"
floatLabel="always"
class="w-100-p">
<mat-label>Version Name</mat-label>
<input matInput
class="form-control"
placeholder="Version Name"
name="vName"
#versionName="ngModel"
(blur)="versionChangesExist=true"
[(ngModel)]="currentVersion.name"
required
minlength="5"
maxlength="150">
</mat-form-field>
<div [hidden]="versionName.valid || versionName.pristine || !versionName.errors?.minlength"
class="alert alert-danger">
Version name is required with at least 5 characters
</div>
<mat-form-field appearance="outline"
floatLabel="always"
class="w-100-p">
<mat-label>Version Description</mat-label>
<textarea matInput
placeholder="Version Description"
class="form-control"
name="versionDescription"
#versionDescription="ngModel"
(blur)="versionChangesExist=true"
[(ngModel)]="currentVersion.description"
rows="5"
required>
</textarea>
</mat-form-field>
<div [hidden]="versionDescription.valid || versionDescription.pristine || !versionDescription.errors?.minlength"
class="alert alert-danger">
Version description is required with at least 25 characters
</div>
</div>
<!--/ VERSION DATA -->
<!-- MEASUREMENT LIST -->
<div fxLayout="column"
class="mt-32"
flex="45%"
style="width:40%; margin:0px 5%">
<div fxLayout="row" fxLayoutAlign="center" flex="100%">
<button mat-raised-button
color="primary"
*ngIf="versionChangesExist"
(click)="saveVersion(); versionChangesExist=false;"
style="margin:10px 15%; width:70%">
Save Version
</button>
</div>
<h3>Measurements</h3>
<table mat-table [dataSource]="currentVersion.measurements"
class="mat-elevation-z8"
style="box-shadow:none;">
<ng-container matColumnDef="name">
<th mat-header-cell *matHeaderCellDef> Name </th>
<td mat-cell *matCellDef="let meas"> {{meas.name}} </td>
</ng-container>
<ng-container matColumnDef="value">
<th mat-header-cell *matHeaderCellDef> Value </th>
<td mat-cell *matCellDef="let meas"> {{meas.value}} </td>
</ng-container>
<tr mat-header-row *matHeaderRowDef="columnsToDisplayMeas"></tr>
<tr mat-row *matRowDef="let row; columns: columnsToDisplayMeas;"></tr>
</table>
</div>
<!--/ MEASUREMENT LIST -->
</div>
</div>
</mat-tab>
<mat-tab id="designAndPurchaseTab" label="Design and Purchase Status">
<div flex="100%"
layout="column"
style="width:100%"
*ngIf="currentProject !== undefined">
<h2 class="mt-32 mb-20">Design and Purchase Status</h2>
<div fxLayout="row"
fxLayoutAlign="center center">
<div *ngFor="let stage of projectStages; index as j;"
fxLayoutAlign="center center"
[class]="projectStatus[j] ? 'arrow_box_green' : 'arrow_box_red' "
[ngStyle]="{'z-index':1000-j}"
(click)="setSelected( j )">
<span>{{stage}}</span>
</div>
</div>
<div fxLayout="row"
fxLayoutAlign="center center">
<div *ngFor="let stage of projectStages; index as j;"
fxLayoutAlign="center center">
<div [class]="projectStatus[j] ? 'green_right' : '' "
*ngIf="selectedStatus[j]"></div>
<div [class]="!projectStatus[j] ? 'red_right' : '' "
*ngIf="selectedStatus[j]"></div>
<div *ngIf="!selectedStatus[j]"
class="filler"></div>
<div class="filler"></div>
</div>
</div>
<div fxLayout="row"
fxLayoutAlign="center center">
<div *ngFor="let text of stageTexts; index as j;"
fxLayoutAlign="center center">
<div fxFlex="50"
*ngIf="selectedStatus[j] && projectStatus[j]">{{text.done}}</div>
<div fxFlex="50"
*ngIf="selectedStatus[j] && !projectStatus[j]">{{text.notdone}}</div>
</div>
</div>
</div>
</mat-tab>
</mat-tab-group>
</div>
<!-- / CONTENT -->
</div>
<!-- / CENTER -->
</div>
<!-- / CONTENT -->
</div>
console.log('Lowered expectations')
executed? – Dyer