I have a LoginView
component in which I have Angular Material Tabs. In one tab there's a LoginForm
component displayed and in a second tab there's a RegistrationForm
component.
What I try to test in LoginView
is that when I click on a second tab, a RegistrationForm
would be displayed. However, I have no idea how to click a tab. I've tried adding name
or id
to mat-tab but it isn't being generated in DOM, querySelectorAll()
also returns null
.
Source:
<mat-tab-group dynamicHeight class="py-5">
<mat-tab label="{{'form.letsLogIn' | translate}}">
<app-login-form></app-login-form>
</mat-tab>
<mat-tab label="{{'form.letsRegister' | translate}}">
<app-registration-form></app-registration-form>
</mat-tab>
</mat-tab-group>
Spec file:
import { Component } from '@angular/core';
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { LoginViewComponent } from './login-view.component';
import { TranslateModule } from '@ngx-translate/core';
import { MatTabsModule } from '@angular/material';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
@Component({selector: 'app-login-form', template: ''})
class LoginFormStubComponent {}
@Component({selector: 'app-registration-form', template: ''})
class RegistrationFormStubComponent {}
describe('LoginViewComponent', () => {
let component: LoginViewComponent;
let fixture: ComponentFixture<LoginViewComponent>;
let compiled: any;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [
LoginViewComponent,
LoginFormStubComponent,
RegistrationFormStubComponent ],
imports: [
TranslateModule.forRoot(),
MatTabsModule,
BrowserAnimationsModule
]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(LoginViewComponent);
component = fixture.componentInstance;
compiled = fixture.nativeElement;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
it('should have a title', () => {
expect(compiled.querySelector('h1')).toBeTruthy();
});
it('should display login form at start', () => {
expect(compiled.querySelector('app-login-form')).toBeTruthy();
});
it('should display registration form after clicking second tab', () => {
compiled = fixture.nativeElement;
compiled.querySelectorAll('mat-tab')[1].click();
fixture.detectChanges();
expect(compiled.querySelector('app-registration-form')).toBeTruthy();
});
});
The solution 🕶 First, we need to add a click listener on the mat-tab-group and disable all tabs because if tabs are not disabled then the user will be able to navigate on them and we want to navigate on tabs conditionally not manually.
TestBed is the primary api for writing unit tests for Angular applications and libraries.
Material tabs (with matTabContent ) are rendering multiple instances of the tab body inside the same tab when switching away and back too fast.
I just worked the same problem. Your test is fine. Just add async() and use whenStable().
it('should display registration form after clicking second tab', async(() => {
compiled = fixture.nativeElement;
compiled.querySelectorAll('mat-tab')[1].click();
fixture.detectChanges();
fixture.whenStable().then(() => {
expect(compiled.querySelector('app-registration-form')).toBeTruthy();
});
}));
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With