I am trying to write some tests for a component that uses Angular Material Components. I read about the CDK Test Harness https://material.angular.io/guide/using-component-harnesses and I want to fetch the count of options in the Mat Select component based on that.
<mat-card>
<mat-card-content>
<form [formGroup]="filterLikelihoodForm" (ngSubmit)="onSearchClick()">
<div class="container">
<div class="row align-items-center">
<div class="col-sm">
<mat-form-field class="full-width" id="periodField">
<mat-label>Select Period</mat-label>
<mat-select formControlName="period" id="period">
<mat-option *ngFor="let period of periodList" [value]="period.id">
{{ period.monthName }}
</mat-option>
</mat-select>
<mat-error *ngIf="f.period.errors">
Please select a valid period
</mat-error>
</mat-form-field>
</div>
<div class="col-sm">
<mat-form-field class="full-width">
<input
matInput
type="number"
formControlName="finishedDeals"
placeholder="Enter no of finished deals"
/>
<mat-error *ngIf="f.finishedDeals.errors">
Please enter a valid number
</mat-error>
</mat-form-field>
</div>
<div class="col-sm">
<button
mat-flat-button
color="primary"
[disabled]="filterLikelihoodForm.invalid"
class="full-width"
>
Search
</button>
</div>
</div>
</div>
</form>
</mat-card-content>
</mat-card>
Here is my spec file code:
import { HarnessLoader } from "@angular/cdk/testing";
import { TestbedHarnessEnvironment } from "@angular/cdk/testing/testbed";
import { TestBed, async, ComponentFixture } from "@angular/core/testing";
import { FilterLikelihoodComponent } from "./filter-likelihood.component";
import { MatFormFieldHarness } from "@angular/material/form-field/testing";
import { MatFormFieldModule } from "@angular/material/form-field";
import { ReactiveFormsModule } from "@angular/forms";
import { MatSelectModule } from "@angular/material/select";
import { MatCardModule } from "@angular/material/card";
import { MatButtonModule } from "@angular/material/button";
import { MatInputModule } from "@angular/material/input";
import { NoopAnimationsModule } from "@angular/platform-browser/animations";
import { periodListMock } from "./mock/filter-likelihood.mock";
import { MatSelectHarness } from "@angular/material/select/testing";
import { MatButtonHarness } from "@angular/material/button/testing";
import { Component } from "@angular/core";
import { MatInputHarness } from "@angular/material/input/testing";
describe("Filter Likelihood Component", () => {
let testHostComponent: TestHostComponent;
let testHostFixture: ComponentFixture<TestHostComponent>;
let component: FilterLikelihoodComponent;
let fixture: ComponentFixture<FilterLikelihoodComponent>;
let loader: HarnessLoader;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [FilterLikelihoodComponent, TestHostComponent],
imports: [
ReactiveFormsModule,
MatFormFieldModule,
MatSelectModule,
MatCardModule,
MatButtonModule,
MatInputModule,
NoopAnimationsModule,
],
}).compileComponents();
}));
beforeEach(() => {
testHostFixture = TestBed.createComponent(TestHostComponent);
testHostComponent = testHostFixture.componentInstance;
testHostFixture.detectChanges();
loader = TestbedHarnessEnvironment.loader(testHostFixture);
});
it("should have correct period label", async () => {
const expectedLabel = "Select Period";
const periodFieldHarness = await loader.getHarness<MatFormFieldHarness>(
MatFormFieldHarness.with({ selector: "#periodField" })
);
const actual = await periodFieldHarness.getLabel();
expect(actual).toBe(expectedLabel);
});
it("should have 3 recent periods in the dropdown", async () => {
const expectedCount = 3;
const selectHarness = await loader.getHarness<MatSelectHarness>(
MatSelectHarness
);
const actual = ((await selectHarness.getOptions()).length);
expect(actual).toBe(expectedCount);
});
it("should have a search button", async () => {
const expectedLabel = "Search";
const buttonHarness = await loader.getHarness<MatButtonHarness>(
MatButtonHarness
);
const actual = await buttonHarness.getText();
expect(actual).toBe(expectedLabel);
});
it("should have 10 finished deals by default", async () => {
const expectedFinishedDeals = 10;
const inputHarness = await loader.getHarness<MatInputHarness>(
MatInputHarness
);
const actual = await inputHarness.getValue();
expect(parseInt(actual)).toBe(expectedFinishedDeals);
});
it("should have a enabled button by default", async () => {
const expectedDisabledState = false;
const buttonHarness = await loader.getHarness<MatButtonHarness>(
MatButtonHarness
);
const actual = await buttonHarness.isDisabled();
expect(actual).toBe(expectedDisabledState);
});
@Component({
selector: `host-component`,
template: `<app-filter-likelihood
[periodList]="periodList"
[initialFinishedDeals]="defaultFinishedDeals"
></app-filter-likelihood>`,
})
class TestHostComponent {
periodList = new Helper().mockPeriodList;
defaultFinishedDeals = 10;
}
});
class Helper {
mockPeriodList = periodListMock;
}
The second spec with title "should have 3 recent periods in the dropdown" is failing as I am getting the options count as 0 always.
Can someone help me figure out my bug and let me know the correct way to write this spec using Mat test harness?
Thanks in advance!
await (await selectHarness.host()).click();
I didawait selectHarness.open()
and got the same (working) results. Seems like it has trouble loading theMatOptionHarness
if the select isn't "opened"? – Inscription